aboutsummaryrefslogtreecommitdiffstats
path: root/awk.y
diff options
context:
space:
mode:
Diffstat (limited to 'awk.y')
-rw-r--r--awk.y93
1 files changed, 64 insertions, 29 deletions
diff --git a/awk.y b/awk.y
index fb97c16e..504bd2b0 100644
--- a/awk.y
+++ b/awk.y
@@ -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;