X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/d1dee8e8e30711f345b766859f89eac8468f1cbe..48568d94c89b8fbaec5c7f8ebba1bee45c306bb7:/usr/src/usr.bin/rdist/gram.y diff --git a/usr/src/usr.bin/rdist/gram.y b/usr/src/usr.bin/rdist/gram.y index ee73c995b7..323a3ecc8b 100644 --- a/usr/src/usr.bin/rdist/gram.y +++ b/usr/src/usr.bin/rdist/gram.y @@ -1,6 +1,6 @@ %{ #ifndef lint -static char *sccsid = "@(#)gram.y 4.5 (Berkeley) 83/10/20"; +static char *sccsid = "@(#)gram.y 4.7 (Berkeley) 83/11/29"; #endif #include "defs.h" @@ -10,26 +10,30 @@ struct block *lastc; %} -%term EQUAL 1 -%term LP 2 -%term RP 3 -%term SM 4 -%term ARROW 5 -%term DCOLON 6 -%term NAME 7 -%term INSTALL 8 -%term NOTIFY 9 -%term EXCEPT 10 -%term OPTION 11 +%term EQUAL 1 +%term LP 2 +%term RP 3 +%term SM 4 +%term ARROW 5 +%term DCOLON 6 +%term NAME 7 +%term STRING 8 +%term INSTALL 9 +%term NOTIFY 10 +%term EXCEPT 11 +%term SPECIAL 12 +%term OPTION 13 %union { struct block *blk; int intval; + char *string; } -%type NAME, INSTALL, NOTIFY, EXCEPT -%type namelist, names, opt_name, cmdlist, cmd +%type NAME, INSTALL, NOTIFY, EXCEPT, SPECIAL +%type namelist, names, opt_name, opt_namelist, cmdlist, cmd %type OPTION, options +%type STRING %% @@ -44,7 +48,7 @@ command: NAME EQUAL namelist = { | namelist ARROW namelist cmdlist = { dohcmds($1, $3, $4); } - | namelist DCOLON namelist cmdlist = { + | namelist DCOLON NAME cmdlist = { dofcmds($1, $3, $4); } | error @@ -91,19 +95,25 @@ cmd: INSTALL options opt_name SM = { $1->b_options = $2 | options; if ($3 != NULL) { - b = expand($3, 0); + b = expand($3, E_VARS|E_SHELL); if (b->b_next != NULL) - fatal("exactly one name allowed\n"); + yyerror("only one name allowed\n"); $1->b_name = b->b_name; } $$ = $1; } | NOTIFY namelist SM = { - $1->b_args = expand($2, 1); + $1->b_args = expand($2, E_VARS); $$ = $1; } | EXCEPT namelist SM = { - $1->b_args = expand($2, 0); + $1->b_args = $2; + $$ = $1; + } + | SPECIAL opt_namelist STRING SM = { + if ($2 != NULL) + $1->b_args = expand($2, E_ALL); + $1->b_name = $3; $$ = $1; } ; @@ -124,6 +134,14 @@ opt_name: /* VOID */ = { } ; +opt_namelist: /* VOID */ = { + $$ = NULL; + } + | namelist = { + $$ = $1; + } + ; + %% int yylineno = 1; @@ -171,6 +189,38 @@ again: c = '-'; 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++ = '\\'; + break; + } + } + if (c == '\n') + c = ' '; /* can't send '\n' */ + *cp1++ = c; + } + if (c != '"') + yyerror("missing closing '\"'\n"); + *cp1++ = '\0'; + yylval.string = cp2 = malloc(cp1 - yytext); + if (cp2 == NULL) + fatal("ran out of memory\n"); + cp1 = yytext; + while (*cp2++ = *cp1++) + ; + return(STRING); + case ':': /* :: */ if ((c = getc(fin)) == ':') return(DCOLON); @@ -181,7 +231,7 @@ again: cp2 = &yytext[INMAX - 1]; for (;;) { if (cp1 >= cp2) { - fatal("input line too long\n"); + yyerror("input line too long\n"); break; } if (c == '\\') { @@ -203,7 +253,11 @@ again: *cp1 = '\0'; if (yytext[0] == '-' && yytext[2] == '\0') { switch (yytext[1]) { - case 'r': + case 'b': + yylval.intval = COMPARE; + return(OPTION); + + case 'R': yylval.intval = REMOVE; return(OPTION); @@ -226,6 +280,8 @@ again: c = NOTIFY; else if (!strcmp(yytext, "except")) c = EXCEPT; + else if (!strcmp(yytext, "special")) + c = SPECIAL; else c = NAME; yylval.blk = makeblock(c, yytext); @@ -251,5 +307,6 @@ yyerror(s) extern int yychar; errs++; + fflush(stdout); fprintf(stderr, "rdist: line %d: %s\n", yylineno, s); }