* Copyright (c) 1983 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid[] = "@(#)gram.y 5.4 (Berkeley) %G%";
%type <intval> OPTION, options
%type <string> NAME, STRING
%type <subcmd> INSTALL, NOTIFY, EXCEPT, PATTERN, SPECIAL, cmdlist, cmd
%type <namel> namelist, names, opt_namelist
command: NAME EQUAL namelist = {
(void) lookup($1, INSERT, $3);
| namelist ARROW namelist cmdlist = {
insert(NULL, $1, $3, $4);
| NAME COLON namelist ARROW namelist cmdlist = {
| namelist DCOLON NAME cmdlist = {
append(NULL, $1, $3, $4);
| NAME COLON namelist DCOLON NAME cmdlist = {
$$ = last_n = makenl($2);
last_n->n_next = makenl($2);
cmd: INSTALL options opt_namelist SM = {
register struct namelist *nl;
$1->sc_options = $2 | options;
yyerror("only one name allowed\n");
$1->sc_name = nl->n_name;
$1->sc_args = expand($2, E_VARS);
$1->sc_args = expand($2, E_ALL);
| PATTERN namelist SM = {
for (nl = $2; nl != NULL; nl = nl->n_next)
if ((cp = re_comp(nl->n_name)) != NULL)
$1->sc_args = expand($2, E_VARS);
| SPECIAL opt_namelist STRING SM = {
$1->sc_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 = makestr(yytext);
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, "except_pat"))
else if (!strcmp(yytext, "special"))
yylval.string = makestr(yytext);
yylval.subcmd = makesubcmd(c);
* Insert or append ARROW command to list of hosts to be updated.
insert(label, files, hosts, subcmds)
struct namelist *files, *hosts;
register struct cmd *c, *prev, *nc;
register struct namelist *h;
files = expand(files, E_VARS|E_SHELL);
hosts = expand(hosts, E_ALL);
for (h = hosts; h != NULL; free(h), h = h->n_next) {
* Search command list for an update to the same host.
for (prev = NULL, c = cmds; c!=NULL; prev = c, c = c->c_next) {
if (strcmp(c->c_name, h->n_name) == 0) {
strcmp(c->c_name, h->n_name) == 0);
* Insert new command to update host.
fatal("ran out of memory\n");
/* update last_cmd if appending nc to cmds */
* Append DCOLON command to the end of the command list since these are always
* executed in the order they appear in the distfile.
append(label, files, stamp, subcmds)
fatal("ran out of memory\n");
c->c_files = expand(files, E_ALL);
* Error printing routine in parser.
fprintf(stderr, "rdist: line %d: %s\n", yylineno, s);
* Return a copy of the string.
str = cp = malloc(strlen(s = str) + 1);
fatal("ran out of memory\n");
* Allocate a namelist structure.
register struct namelist *nl;
fatal("ran out of memory\n");
* Make a sub command for lists of variables, commands, etc.
register struct subcmd *sc;
fatal("ran out of memory\n");