static char *sccsid = "@(#)gram.y 4.7 (Berkeley) 83/11/29";
%type <blk> NAME, INSTALL, NOTIFY, EXCEPT, SPECIAL
%type <blk> namelist, names, opt_name, opt_namelist, cmdlist, cmd
%type <intval> OPTION, options
command: NAME EQUAL namelist = {
(void) lookup($1->b_name, $1, 1);
| namelist ARROW namelist cmdlist = {
| namelist DCOLON NAME cmdlist = {
cmd: INSTALL options opt_name SM = {
register struct block *b;
$1->b_options = $2 | options;
b = expand($3, E_VARS|E_SHELL);
yyerror("only one name allowed\n");
$1->b_args = expand($2, E_VARS);
| SPECIAL opt_namelist STRING SM = {
$1->b_args = expand($2, E_ALL);
opt_namelist: /* VOID */ = {
static char yytext[INMAX];
register char *cp1, *cp2;
static char quotechars[] = "[]{}*?$";
case EOF: /* end of file */
case '#': /* start of comment */
while ((c = getc(fin)) != EOF && c != '\n')
case '\t': /* skip blanks */
if ((c = getc(fin)) == '>')
cp2 = &yytext[INMAX - 1];
yyerror("command string too long\n");
if (c == EOF || c == '"')
if ((c = getc(fin)) == EOF) {
c = ' '; /* can't send '\n' */
yyerror("missing closing '\"'\n");
yylval.string = cp2 = malloc(cp1 - yytext);
fatal("ran out of memory\n");
if ((c = getc(fin)) == ':')
cp2 = &yytext[INMAX - 1];
yyerror("input line too long\n");
if ((c = getc(fin)) != EOF) {
if (c == EOF || any(c, " \t()=;\n")) {
if (yytext[0] == '-' && yytext[2] == '\0') {
if (!strcmp(yytext, "install"))
else if (!strcmp(yytext, "notify"))
else if (!strcmp(yytext, "except"))
else if (!strcmp(yytext, "special"))
yylval.blk = makeblock(c, yytext);
* Error printing routine in parser.
fprintf(stderr, "rdist: line %d: %s\n", yylineno, s);