diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2012-08-17 12:38:04 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2012-08-17 12:38:04 +0300 |
commit | e6b05afd9971b457c0b46907a91185b66be8ff4e (patch) | |
tree | e7d3b6fce47a2ac7b32cdf923ceb6e50db9fe441 /awkgram.c | |
parent | 3b23e177cd166e96c700379491b4a99bddf9aa4d (diff) | |
parent | 76cc4d241f328876b18e48639d631823c3d304d6 (diff) | |
download | egawk-e6b05afd9971b457c0b46907a91185b66be8ff4e.tar.gz egawk-e6b05afd9971b457c0b46907a91185b66be8ff4e.tar.bz2 egawk-e6b05afd9971b457c0b46907a91185b66be8ff4e.zip |
Merge branch 'extgawk'
Diffstat (limited to 'awkgram.c')
-rw-r--r-- | awkgram.c | 113 |
1 files changed, 77 insertions, 36 deletions
@@ -120,7 +120,7 @@ static int count_expressions(INSTRUCTION **list, bool isarg); static INSTRUCTION *optimize_assignment(INSTRUCTION *exp); static void add_lint(INSTRUCTION *list, LINTTYPE linttype); -enum defref { FUNC_DEFINE, FUNC_USE }; +enum defref { FUNC_DEFINE, FUNC_USE, FUNC_EXT }; static void func_use(const char *name, enum defref how); static void check_funcs(void); @@ -2368,7 +2368,7 @@ yyreduce: if (len == 0) lintwarn_ln((yyvsp[(3) - (3)])->source_line, _("regexp constant `//' looks like a C++ comment, but is not")); - else if ((re)[0] == '*' && (re)[len-1] == '*') + else if (re[0] == '*' && re[len-1] == '*') /* possible C comment */ lintwarn_ln((yyvsp[(3) - (3)])->source_line, _("regexp constant `/%s/' looks like a C comment, but is not"), re); @@ -4542,7 +4542,7 @@ static const struct token tokentab[] = { #ifdef ARRAYDEBUG {"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_adump, 0}, #endif -{"and", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_and, MPF(and)}, +{"and", Op_builtin, LEX_BUILTIN, GAWKX, do_and, MPF(and)}, {"asort", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asort, 0}, {"asorti", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asorti, 0}, {"atan2", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2, MPF(atan2)}, @@ -4562,7 +4562,6 @@ static const struct token tokentab[] = { {"eval", Op_symbol, LEX_EVAL, 0, 0, 0}, {"exit", Op_K_exit, LEX_EXIT, 0, 0, 0}, {"exp", Op_builtin, LEX_BUILTIN, A(1), do_exp, MPF(exp)}, -{"extension", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_ext, 0}, {"fflush", Op_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush, 0}, {"for", Op_K_for, LEX_FOR, BREAK|CONTINUE, 0, 0}, {"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0, 0}, @@ -4584,7 +4583,7 @@ static const struct token tokentab[] = { {"mktime", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime, 0}, {"next", Op_K_next, LEX_NEXT, 0, 0, 0}, {"nextfile", Op_K_nextfile, LEX_NEXTFILE, GAWKX, 0, 0}, -{"or", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_or, MPF(or)}, +{"or", Op_builtin, LEX_BUILTIN, GAWKX, do_or, MPF(or)}, {"patsplit", Op_builtin, LEX_BUILTIN, GAWKX|A(2)|A(3)|A(4), do_patsplit, 0}, {"print", Op_K_print, LEX_PRINT, 0, 0, 0}, {"printf", Op_K_printf, LEX_PRINTF, 0, 0, 0}, @@ -4596,6 +4595,9 @@ static const struct token tokentab[] = { {"sprintf", Op_builtin, LEX_BUILTIN, 0, do_sprintf, 0}, {"sqrt", Op_builtin, LEX_BUILTIN, A(1), do_sqrt, MPF(sqrt)}, {"srand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand, MPF(srand)}, +#if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */ +{"stopme", Op_builtin, LEX_BUILTIN, GAWKX|A(0), stopme, 0}, +#endif {"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3), do_strftime, 0}, {"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum, MPF(strtonum)}, {"sub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0, 0}, @@ -4606,7 +4608,7 @@ static const struct token tokentab[] = { {"tolower", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower, 0}, {"toupper", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper, 0}, {"while", Op_K_while, LEX_WHILE, BREAK|CONTINUE, 0, 0}, -{"xor", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor, MPF(xor)}, +{"xor", Op_builtin, LEX_BUILTIN, GAWKX, do_xor, MPF(xor)}, }; #if MBS_SUPPORT @@ -4704,7 +4706,7 @@ warning_ln(int line, const char *mesg, ...) sourceline = line; print_included_from(); va_start(args, mesg); - err(_("warning: "), mesg, args); + err(false, _("warning: "), mesg, args); va_end(args); sourceline = saveline; } @@ -4722,9 +4724,9 @@ lintwarn_ln(int line, const char *mesg, ...) print_included_from(); va_start(args, mesg); if (lintfunc == r_fatal) - err(_("fatal: "), mesg, args); + err(true, _("fatal: "), mesg, args); else - err(_("warning: "), mesg, args); + err(false, _("warning: "), mesg, args); va_end(args); sourceline = saveline; if (lintfunc == r_fatal) @@ -4744,7 +4746,7 @@ error_ln(int line, const char *m, ...) print_included_from(); errcount++; va_start(args, m); - err("error: ", m, args); + err(false, "error: ", m, args); va_end(args); sourceline = saveline; } @@ -4822,7 +4824,7 @@ yyerror(const char *m, ...) *bp++ = ' '; } strcpy(bp, mesg); - err("", buf, args); + err(false, "", buf, args); va_end(args); efree(buf); } @@ -5045,25 +5047,41 @@ add_srcfile(int stype, char *src, SRCFILE *thisfile, bool *already_included, int errno_val ? strerror(errno_val) : _("reason unknown")); } + /* N.B. We do not eliminate duplicate SRC_FILE (-f) programs. */ for (s = srcfiles->next; s != srcfiles; s = s->next) { - if ((s->stype == SRC_FILE || s->stype == SRC_INC || s->stype == SRC_EXTLIB) - && files_are_same(path, s) - ) { - if (do_lint) { - int line = sourceline; - /* Kludge: the line number may be off for `@include file'. - * Since, this function is also used for '-f file' in main.c, - * sourceline > 1 check ensures that the call is at - * parse time. - */ - if (sourceline > 1 && lasttok == NEWLINE) - line--; - lintwarn_ln(line, _("already included source file `%s'"), src); + if ((s->stype == SRC_FILE || s->stype == SRC_INC || s->stype == SRC_EXTLIB) && files_are_same(path, s)) { + if (stype == SRC_INC || stype == SRC_EXTLIB) { + /* eliminate duplicates */ + if ((stype == SRC_INC) && (s->stype == SRC_FILE)) + fatal(_("can't include `%s' and use it as a program file"), src); + + if (do_lint) { + int line = sourceline; + /* Kludge: the line number may be off for `@include file'. + * Since, this function is also used for '-f file' in main.c, + * sourceline > 1 check ensures that the call is at + * parse time. + */ + if (sourceline > 1 && lasttok == NEWLINE) + line--; + lintwarn_ln(line, + stype != SRC_EXTLIB + ? _("already included source file `%s'") + : _("already loaded shared library `%s'"), + src); + } + efree(path); + if (already_included) + *already_included = true; + return NULL; + } else { + /* duplicates are allowed for -f */ + if (s->stype == SRC_INC) + fatal(_("can't include `%s' and use it as a program file"), src); + /* no need to scan for further matches, since + * they must be of homogeneous type */ + break; } - efree(path); - if (already_included) - *already_included = true; - return NULL; } } @@ -5154,7 +5172,7 @@ load_library(INSTRUCTION *file) return -1; } - (void) load_ext(s->fullpath, "dlload", NULL); + load_ext(s->fullpath); return 0; } @@ -6932,6 +6950,7 @@ static struct fdesc { char *name; short used; short defined; + short extension; struct fdesc *next; } *ftable[HASHSIZE]; @@ -6951,7 +6970,10 @@ func_use(const char *name, enum defref how) if (strcmp(fp->name, name) == 0) { if (how == FUNC_DEFINE) fp->defined++; - else + else if (how == FUNC_EXT) { + fp->defined++; + fp->extension++; + } else fp->used++; return; } @@ -6965,12 +6987,23 @@ func_use(const char *name, enum defref how) strcpy(fp->name, name); if (how == FUNC_DEFINE) fp->defined++; - else + else if (how == FUNC_EXT) { + fp->defined++; + fp->extension++; + } else fp->used++; fp->next = ftable[ind]; ftable[ind] = fp; } +/* track_ext_func --- add an extension function to the table */ + +void +track_ext_func(const char *name) +{ + func_use(name, FUNC_EXT); +} + /* check_funcs --- verify functions that are called but not defined */ static void @@ -6984,19 +7017,19 @@ check_funcs() for (i = 0; i < HASHSIZE; i++) { for (fp = ftable[i]; fp != NULL; fp = fp->next) { + if (fp->defined == 0 && ! fp->extension) { #ifdef REALLYMEAN - /* making this the default breaks old code. sigh. */ - if (fp->defined == 0) { + /* making this the default breaks old code. sigh. */ error( _("function `%s' called but never defined"), fp->name); errcount++; - } #else - if (do_lint && fp->defined == 0) lintwarn( _("function `%s' called but never defined"), fp->name); #endif - if (do_lint && fp->used == 0) { + } + + if (do_lint && fp->used == 0 && ! fp->extension) { lintwarn(_("function `%s' defined but never called directly"), fp->name); } @@ -7207,6 +7240,14 @@ make_assignable(INSTRUCTION *ip) return NULL; } +/* stopme --- for debugging */ + +NODE * +stopme(int nargs ATTRIBUTE_UNUSED) +{ + return make_number(0.0); +} + /* dumpintlstr --- write out an initial .po file entry for the string */ static void |