diff options
Diffstat (limited to 'awkgram.y')
-rw-r--r-- | awkgram.y | 69 |
1 files changed, 65 insertions, 4 deletions
@@ -52,6 +52,7 @@ static INSTRUCTION *make_assignable(INSTRUCTION *ip); static void dumpintlstr(const char *str, size_t len); static void dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2); static int include_source(INSTRUCTION *file); +static int load_library(INSTRUCTION *file); static void next_sourcefile(void); static char *tokexpand(void); @@ -164,7 +165,7 @@ extern double fmod(double x, double y); %token LEX_AND LEX_OR INCREMENT DECREMENT %token LEX_BUILTIN LEX_LENGTH %token LEX_EOF -%token LEX_INCLUDE LEX_EVAL +%token LEX_INCLUDE LEX_EVAL LEX_LOAD %token NEWLINE /* Lowest to highest */ @@ -239,6 +240,11 @@ rule want_source = FALSE; yyerrok; } + | '@' LEX_LOAD library statement_term + { + want_source = FALSE; + yyerrok; + } ; source @@ -256,6 +262,21 @@ source { $$ = NULL; } ; +library + : FILENAME + { + if (load_library($1) < 0) + YYABORT; + efree($1->lextok); + bcfree($1); + $$ = NULL; + } + | FILENAME error + { $$ = NULL; } + | error + { $$ = NULL; } + ; + pattern : /* empty */ { $$ = NULL; rule = Rule; } @@ -2296,8 +2317,12 @@ add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int *errcode = errno_val; return NULL; } - fatal(_("can't open source file `%s' for reading (%s)"), - src, errno_val ? strerror(errno_val) : _("reason unknown")); + /* use full messages to ease translation */ + fatal(stype != SRC_EXTLIB + ? _("can't open source file `%s' for reading (%s)") + : _("can't open shared library `%s' for reading (%s)"), + src, + errno_val ? strerror(errno_val) : _("reason unknown")); } for (s = srcfiles->next; s != srcfiles; s = s->next) { @@ -2378,6 +2403,41 @@ include_source(INSTRUCTION *file) return 0; } +/* load_library --- load a shared library */ + +static int +load_library(INSTRUCTION *file) +{ + SRCFILE *s; + char *src = file->lextok; + int errcode; + int already_included; + + if (do_traditional || do_posix) { + error_ln(file->source_line, _("@load is a gawk extension")); + return -1; + } + + if (strlen(src) == 0) { + if (do_lint) + lintwarn_ln(file->source_line, _("empty filename after @load")); + return 0; + } + + s = add_srcfile(SRC_EXTLIB, src, sourcefile, &already_included, &errcode); + if (s == NULL) { + if (already_included) + return 0; + error_ln(file->source_line, + _("can't open shared library `%s' for reading (%s)"), + src, errcode ? strerror(errcode) : _("reason unknown")); + return -1; + } + + (void) load_ext(s->fullpath, "dlload", NULL); + return 0; +} + /* next_sourcefile --- read program from the next source in srcfiles */ static void @@ -3504,7 +3564,7 @@ retry: static int warntab[sizeof(tokentab) / sizeof(tokentab[0])]; int class = tokentab[mid].class; - if ((class == LEX_INCLUDE || class == LEX_EVAL) + if ((class == LEX_INCLUDE || class == LEX_LOAD || class == LEX_EVAL) && lasttok != '@') goto out; @@ -3540,6 +3600,7 @@ retry: switch (class) { case LEX_INCLUDE: + case LEX_LOAD: want_source = TRUE; break; case LEX_EVAL: |