--- src/gram.y.orig 1998-11-10 04:10:42 UTC +++ src/gram.y @@ -61,6 +61,13 @@ static char copyright[] = #include "defs.h" +#define yylex rdist_yylex + +static char * xappend(char *str, size_t *len, char c); +void yyerror(const char *message); +static char *yytext; +static size_t yytextlen; + static struct namelist *addnl(), *subnl(), *andnl(); struct cmd *cmds = NULL; struct cmd *last_cmd; @@ -240,12 +247,14 @@ opt_namelist: /* VOID */ = { int yylineno = 1; extern FILE *fin; +static int yylex() { - static char yytext[INMAX]; register int c; - register char *cp1, *cp2; static char quotechars[] = "[]{}*?$"; + + yytext = NULL; + yytextlen = 0; again: switch (c = getc(fin)) { @@ -285,19 +294,13 @@ again: break; case '"': /* STRING */ - cp1 = yytext; - cp2 = &yytext[INMAX - 1]; for (;;) { - if (cp1 >= cp2) { - yyerror("command string too long\n"); - break; - } c = getc(fin); if (c == EOF || c == '"') break; if (c == '\\') { if ((c = getc(fin)) == EOF) { - *cp1++ = '\\'; + yytext = xappend(yytext, &yytextlen, '\\'); break; } } @@ -305,12 +308,11 @@ again: yylineno++; c = ' '; /* can't send '\n' */ } - *cp1++ = c; + yytext = xappend(yytext, &yytextlen, c); } if (c != '"') yyerror("missing closing '\"'\n"); - *cp1 = '\0'; - yylval.string = makestr(yytext); + yylval.string = xappend(yytext, &yytextlen, '\0'); return(STRING); case ':': /* : or :: */ @@ -319,35 +321,34 @@ again: (void) ungetc(c, fin); return(COLON); } - cp1 = yytext; - cp2 = &yytext[INMAX - 1]; for (;;) { - if (cp1 >= cp2) { - yyerror("input line too long\n"); - break; - } if (c == '\\') { if ((c = getc(fin)) != EOF) { if (any(c, quotechars)) - *cp1++ = QUOTECHAR; + yytext = xappend(yytext, &yytextlen, + QUOTECHAR); } else { - *cp1++ = '\\'; + yytext = xappend(yytext, &yytextlen, '\\'); break; } } - *cp1++ = c; + yytext = xappend(yytext, &yytextlen, c); c = getc(fin); if (c == EOF || any(c, " \"'\t()=;:\n")) { (void) ungetc(c, fin); break; } } - *cp1 = '\0'; - if (yytext[0] == '-' && yytext[1] == CNULL) + if (yytext == NULL) { + yylval.string = NULL; + return(NAME); + } + yytext = xappend(yytext, &yytextlen, '\0'); + if (yytextlen == 2 && yytext[0] == '-') return '-'; if (yytext[0] == '-' && parendepth <= 0) { opt_t opt = 0; - static char ebuf[BUFSIZ]; + char ebuf[BUFSIZ]; switch (yytext[1]) { case 'o': @@ -397,7 +398,7 @@ again: else if (!strcmp(yytext, "cmdspecial")) c = CMDSPECIAL; else { - yylval.string = makestr(yytext); + yylval.string = yytext; return(NAME); } yylval.subcmd = makesubcmd(c); @@ -421,6 +422,7 @@ extern int any(c, str) /* * Insert or append ARROW command to list of hosts to be updated. */ +void insert(label, files, hosts, subcmds) char *label; struct namelist *files, *hosts; @@ -475,6 +477,7 @@ insert(label, files, hosts, subcmds) * Append DCOLON command to the end of the command list since these are always * executed in the order they appear in the distfile. */ +static void append(label, files, stamp, subcmds) char *label; struct namelist *files; @@ -501,24 +504,30 @@ append(label, files, stamp, subcmds) /* * Error printing routine in parser. */ +void yyerror(s) - char *s; + const char *s; { - error("Error in distfile: line %d: %s", yylineno, s); + error("Error in distfile: line %d: %s (offending text: %.*s%s)", + yylineno, s, 11, yytextlen > 0 ? yytext : "", + yytextlen > 11 ? " ..." : ""); } /* - * Return a copy of the string. + * Append character to a string of given length. Return + * the new string, which -- depending on realloc -- may + * or may not have the same address now. */ -char * -makestr(str) - char *str; +static char * +xappend(char *str, size_t *len, char c) { char *cp; - cp = strdup(str); + cp = realloc(str, *len + 1); if (cp == NULL) fatalerr("ran out of memory"); + cp[*len] = c; + (*len)++; return(cp); }