diff options
Diffstat (limited to 'awk.y')
-rw-r--r-- | awk.y | 93 |
1 files changed, 64 insertions, 29 deletions
@@ -3,7 +3,7 @@ */ /* - * Copyright (C) 1986, 1988, 1989, 1991, 1992 the Free Software Foundation, Inc. + * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. @@ -56,9 +56,10 @@ static char *thisline = NULL; #define YYDEBUG_LEXER_TEXT (lexeme) static int param_counter; static char *tokstart = NULL; -static char *token = NULL; +static char *tok = NULL; static char *tokend; +#define HASHSIZE 1021 /* this constant only used here */ NODE *variables[HASHSIZE]; extern char *source; @@ -291,7 +292,7 @@ regexp REGEXP '/' { NODE *n; - int len; + size_t len; getnode(n); n->type = Node_regex; @@ -386,10 +387,19 @@ statement if ($2 && $2 == lookup("file")) { if (do_lint) warning("`next file' is a gawk extension"); - else if (do_unix || do_posix) - yyerror("`next file' is a gawk extension"); - else if (! io_allowed) - yyerror("`next file' used in BEGIN or END action"); + if (do_unix || do_posix) { + /* + * can't use yyerror, since may have overshot + * the source line + */ + errcount++; + msg("`next file' is a gawk extension"); + } + if (! io_allowed) { + /* same thing */ + errcount++; + msg("`next file' used in BEGIN or END action"); + } type = Node_K_nextfile; } else { if (! io_allowed) @@ -406,6 +416,20 @@ statement { $$ = node ($3, Node_K_return, (NODE *)NULL); } | LEX_DELETE NAME '[' expression_list ']' statement_term { $$ = node (variable($2,1), Node_K_delete, $4); } + | LEX_DELETE NAME statement_term + { + if (do_lint) + warning("`delete array' is a gawk extension"); + if (do_unix || do_posix) { + /* + * can't use yyerror, since may have overshot + * the source line + */ + errcount++; + msg("`delete array' is a gawk extension"); + } + $$ = node (variable($2,1), Node_K_delete, (NODE *) NULL); + } | exp statement_term { $$ = $1; } ; @@ -746,7 +770,7 @@ comma : ',' opt_nls { yyerrok; } %% struct token { - char *operator; /* text to match */ + const char *operator; /* text to match */ NODETYPE value; /* node type */ int class; /* lexical class */ unsigned flags; /* # of args. allowed and compatability */ @@ -820,10 +844,11 @@ yyerror(va_alist) va_dcl { va_list args; - char *mesg = NULL; + const char *mesg = NULL; register char *bp, *cp; char *scan; char buf[120]; + static char end_of_file_line[] = "(END OF FILE)"; errcount++; /* Find the current line in the input file */ @@ -845,8 +870,8 @@ va_dcl while (bp < lexend && *bp && *bp != '\n') bp++; } else { - thisline = "(END OF FILE)"; - bp = thisline + 13; + thisline = end_of_file_line; + bp = thisline + strlen(thisline); } msg("%.*s", (int) (bp - thisline), thisline); bp = buf; @@ -982,7 +1007,7 @@ get_src_buf() return buf; } -#define tokadd(x) (*token++ = (x), token == tokend ? tokexpand() : token) +#define tokadd(x) (*tok++ = (x), tok == tokend ? tokexpand() : tok) char * tokexpand() @@ -990,15 +1015,15 @@ tokexpand() static int toksize = 60; int tokoffset; - tokoffset = token - tokstart; + tokoffset = tok - tokstart; toksize *= 2; if (tokstart) erealloc(tokstart, char *, toksize, "tokexpand"); else emalloc(tokstart, char *, toksize, "tokexpand"); tokend = tokstart + toksize; - token = tokstart + tokoffset; - return token; + tok = tokstart + tokoffset; + return tok; } #if DEBUG @@ -1053,7 +1078,7 @@ yylex() int in_brack = 0; want_regexp = 0; - token = tokstart; + tok = tokstart; while ((c = nextc()) != 0) { switch (c) { case '[': @@ -1094,7 +1119,7 @@ retry: lexeme = lexptr ? lexptr - 1 : lexptr; thisline = NULL; - token = tokstart; + tok = tokstart; yylval.nodetypeval = Node_illegal; switch (c) { @@ -1115,13 +1140,23 @@ retry: case '\\': #ifdef RELAXED_CONTINUATION - if (!do_unix) { /* strip trailing white-space and/or comment */ - while ((c = nextc()) == ' ' || c == '\t') continue; + /* + * This code puports to allow comments and/or whitespace + * after the `\' at the end of a line used for continuation. + * Use it at your own risk. We think it's a bad idea, which + * is why it's not on by default. + */ + if (!do_unix) { + /* strip trailing white-space and/or comment */ + while ((c = nextc()) == ' ' || c == '\t') + continue; if (c == '#') - while ((c = nextc()) != '\n') if (!c) break; + while ((c = nextc()) != '\n') + if (c == '\0') + break; pushback(); } -#endif /*RELAXED_CONTINUATION*/ +#endif /* RELAXED_CONTINUATION */ if (nextc() == '\n') { sourceline++; goto retry; @@ -1307,7 +1342,7 @@ retry: tokadd(c); } yylval.nodeval = make_str_node(tokstart, - token - tokstart, esc_seen ? SCAN : 0); + tok - tokstart, esc_seen ? SCAN : 0); yylval.nodeval->flags |= PERM; return YSTRING; @@ -1443,14 +1478,14 @@ retry: yyerror("Invalid char '%c' in expression\n", c); /* it's some type of name-type-thing. Find its length */ - token = tokstart; + tok = tokstart; while (is_identchar(c)) { tokadd(c); c = nextc(); } tokadd('\0'); - emalloc(tokkey, char *, token - tokstart, "yylex"); - memcpy(tokkey, tokstart, token - tokstart); + emalloc(tokkey, char *, tok - tokstart, "yylex"); + memcpy(tokkey, tokstart, tok - tokstart); pushback(); /* See if it is a special token. */ @@ -1653,7 +1688,7 @@ NODE *value; register int bucket; len = strlen(name); - bucket = hash(name, len); + bucket = hash(name, len, (unsigned long) HASHSIZE); getnode(hp); hp->type = Node_hashnode; hp->hnext = variables[bucket]; @@ -1668,13 +1703,13 @@ NODE *value; /* find the most recent hash node for name installed by install */ NODE * lookup(name) -char *name; +const char *name; { register NODE *bucket; register size_t len; len = strlen(name); - bucket = variables[hash(name, len)]; + bucket = variables[hash(name, len, (unsigned long) HASHSIZE)]; while (bucket) { if (bucket->hlength == len && STREQN(bucket->hname, name, len)) return bucket->hvalue; @@ -1738,7 +1773,7 @@ int freeit; name = np->param; len = strlen(name); - save = &(variables[hash(name, len)]); + save = &(variables[hash(name, len, (unsigned long) HASHSIZE)]); for (bucket = *save; bucket; bucket = bucket->hnext) { if (len == bucket->hlength && STREQN(bucket->hname, name, len)) { *save = bucket->hnext; |