summaryrefslogtreecommitdiff
path: root/usr.bin/rdist/gram.y
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/rdist/gram.y')
-rw-r--r--usr.bin/rdist/gram.y326
1 files changed, 224 insertions, 102 deletions
diff --git a/usr.bin/rdist/gram.y b/usr.bin/rdist/gram.y
index 1eb190f6a4b..9e4d4515e1a 100644
--- a/usr.bin/rdist/gram.y
+++ b/usr.bin/rdist/gram.y
@@ -1,7 +1,8 @@
%{
/*
- * Copyright (c) 1983, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1993 Michael A. Cooper
+ * Copyright (c) 1993 Regents of the University of California.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,48 +34,58 @@
*/
#ifndef lint
-/* from: static char sccsid[] = "@(#)gram.y 8.1 (Berkeley) 6/9/93"; */
-static char *rcsid = "$Id: gram.y,v 1.1 1995/10/18 08:45:59 deraadt Exp $";
+static char RCSid[] =
+"$Id: gram.y,v 1.2 1996/02/03 12:12:26 dm Exp $";
+
+static char *sccsid = "@(#)gram.y 5.2 (Berkeley) 85/06/21";
+
+static char copyright[] =
+"@(#) Copyright (c) 1983 Regents of the University of California.\n\
+ All rights reserved.\n";
#endif /* not lint */
+/*
+ * Tell defs.h not to include y.tab.h
+ */
+#ifndef yacc
+#define yacc
+#endif
+
#include "defs.h"
+static struct namelist *addnl(), *subnl(), *andnl();
struct cmd *cmds = NULL;
struct cmd *last_cmd;
struct namelist *last_n;
struct subcmd *last_sc;
-
-static char *makestr __P((char *));
+int parendepth = 0;
%}
-%term EQUAL 1
-%term LP 2
-%term RP 3
-%term SM 4
-%term ARROW 5
-%term COLON 6
-%term DCOLON 7
-%term NAME 8
-%term STRING 9
-%term INSTALL 10
-%term NOTIFY 11
-%term EXCEPT 12
-%term PATTERN 13
-%term SPECIAL 14
-%term OPTION 15
+%term ARROW 1
+%term COLON 2
+%term DCOLON 3
+%term NAME 4
+%term STRING 5
+%term INSTALL 6
+%term NOTIFY 7
+%term EXCEPT 8
+%term PATTERN 9
+%term SPECIAL 10
+%term CMDSPECIAL 11
+%term OPTION 12
%union {
- int intval;
- char *string;
- struct subcmd *subcmd;
- struct namelist *namel;
+ opt_t optval;
+ char *string;
+ struct subcmd *subcmd;
+ struct namelist *namel;
}
-%type <intval> OPTION, options
+%type <optval> OPTION, options
%type <string> NAME, STRING
-%type <subcmd> INSTALL, NOTIFY, EXCEPT, PATTERN, SPECIAL, cmdlist, cmd
-%type <namel> namelist, names, opt_namelist
+%type <subcmd> INSTALL, NOTIFY, EXCEPT, PATTERN, SPECIAL, CMDSPECIAL, cmdlist, cmd
+%type <namel> namelist, names, opt_namelist nlist
%%
@@ -82,17 +93,17 @@ file: /* VOID */
| file command
;
-command: NAME EQUAL namelist = {
+command: NAME '=' namelist = {
(void) lookup($1, INSERT, $3);
}
| namelist ARROW namelist cmdlist = {
- insert(NULL, $1, $3, $4);
+ insert((char *)NULL, $1, $3, $4);
}
| NAME COLON namelist ARROW namelist cmdlist = {
insert($1, $3, $5, $6);
}
| namelist DCOLON NAME cmdlist = {
- append(NULL, $1, $3, $4);
+ append((char *)NULL, $1, $3, $4);
}
| NAME COLON namelist DCOLON NAME cmdlist = {
append($1, $3, $5, $6);
@@ -100,10 +111,24 @@ command: NAME EQUAL namelist = {
| error
;
-namelist: NAME = {
+namelist: nlist {
+ $$ = $1;
+ }
+ | nlist '-' nlist {
+ $$ = subnl($1, $3);
+ }
+ | nlist '+' nlist {
+ $$ = addnl($1, $3);
+ }
+ | nlist '&' nlist {
+ $$ = andnl($1, $3);
+ }
+ ;
+
+nlist: NAME = {
$$ = makenl($1);
}
- | LP names RP = {
+ | '(' names ')' = {
$$ = $2;
}
;
@@ -136,7 +161,7 @@ cmdlist: /* VOID */ {
}
;
-cmd: INSTALL options opt_namelist SM = {
+cmd: INSTALL options opt_namelist ';' = {
register struct namelist *nl;
$1->sc_options = $2 | options;
@@ -152,17 +177,17 @@ cmd: INSTALL options opt_namelist SM = {
}
$$ = $1;
}
- | NOTIFY namelist SM = {
+ | NOTIFY namelist ';' = {
if ($2 != NULL)
$1->sc_args = expand($2, E_VARS);
$$ = $1;
}
- | EXCEPT namelist SM = {
+ | EXCEPT namelist ';' = {
if ($2 != NULL)
$1->sc_args = expand($2, E_ALL);
$$ = $1;
}
- | PATTERN namelist SM = {
+ | PATTERN namelist ';' = {
struct namelist *nl;
char *cp, *re_comp();
@@ -172,7 +197,13 @@ cmd: INSTALL options opt_namelist SM = {
$1->sc_args = expand($2, E_VARS);
$$ = $1;
}
- | SPECIAL opt_namelist STRING SM = {
+ | SPECIAL opt_namelist STRING ';' = {
+ if ($2 != NULL)
+ $1->sc_args = expand($2, E_ALL);
+ $1->sc_name = $3;
+ $$ = $1;
+ }
+ | CMDSPECIAL opt_namelist STRING ';' = {
if ($2 != NULL)
$1->sc_args = expand($2, E_ALL);
$1->sc_name = $3;
@@ -201,7 +232,6 @@ opt_namelist: /* VOID */ = {
int yylineno = 1;
extern FILE *fin;
-int
yylex()
{
static char yytext[INMAX];
@@ -226,21 +256,23 @@ again:
goto again;
case '=': /* EQUAL */
- return(EQUAL);
+ case ';': /* SM */
+ case '+':
+ case '&':
+ return(c);
case '(': /* LP */
- return(LP);
+ ++parendepth;
+ return(c);
case ')': /* RP */
- return(RP);
-
- case ';': /* SM */
- return(SM);
+ --parendepth;
+ return(c);
case '-': /* -> */
if ((c = getc(fin)) == '>')
return(ARROW);
- ungetc(c, fin);
+ (void) ungetc(c, fin);
c = '-';
break;
@@ -276,7 +308,7 @@ again:
case ':': /* : or :: */
if ((c = getc(fin)) == ':')
return(DCOLON);
- ungetc(c, fin);
+ (void) ungetc(c, fin);
return(COLON);
}
cp1 = yytext;
@@ -289,7 +321,7 @@ again:
if (c == '\\') {
if ((c = getc(fin)) != EOF) {
if (any(c, quotechars))
- c |= QUOTE;
+ *cp1++ = QUOTECHAR;
} else {
*cp1++ = '\\';
break;
@@ -298,41 +330,51 @@ again:
*cp1++ = c;
c = getc(fin);
if (c == EOF || any(c, " \"'\t()=;:\n")) {
- ungetc(c, fin);
+ (void) ungetc(c, fin);
break;
}
}
*cp1 = '\0';
- if (yytext[0] == '-' && yytext[2] == '\0') {
- switch (yytext[1]) {
- case 'b':
- yylval.intval = COMPARE;
- return(OPTION);
-
- case 'R':
- yylval.intval = REMOVE;
- return(OPTION);
-
- case 'v':
- yylval.intval = VERIFY;
- return(OPTION);
-
- case 'w':
- yylval.intval = WHOLE;
- return(OPTION);
-
- case 'y':
- yylval.intval = YOUNGER;
- return(OPTION);
+ if (yytext[0] == '-' && yytext[1] == CNULL)
+ return '-';
+ if (yytext[0] == '-' && parendepth <= 0) {
+ opt_t opt = 0;
+ static char ebuf[BUFSIZ];
- case 'h':
- yylval.intval = FOLLOW;
- return(OPTION);
+ switch (yytext[1]) {
+ case 'o':
+ if (parsedistopts(&yytext[2], &opt, TRUE)) {
+ (void) sprintf(ebuf,
+ "Bad distfile options \"%s\".",
+ &yytext[2]);
+ yyerror(ebuf);
+ }
+ break;
- case 'i':
- yylval.intval = IGNLNKS;
- return(OPTION);
+ /*
+ * These options are obsoleted by -o.
+ */
+ case 'b': opt = DO_COMPARE; break;
+ case 'R': opt = DO_REMOVE; break;
+ case 'v': opt = DO_VERIFY; break;
+ case 'w': opt = DO_WHOLE; break;
+ case 'y': opt = DO_YOUNGER; break;
+ case 'h': opt = DO_FOLLOW; break;
+ case 'i': opt = DO_IGNLNKS; break;
+ case 'q': opt = DO_QUIET; break;
+ case 'x': opt = DO_NOEXEC; break;
+ case 'N': opt = DO_CHKNFS; break;
+ case 'O': opt = DO_CHKREADONLY; break;
+ case 's': opt = DO_SAVETARGETS; break;
+ case 'r': opt = DO_NODESCEND; break;
+
+ default:
+ (void) sprintf(ebuf, "Unknown option \"%s\".", yytext);
+ yyerror(ebuf);
}
+
+ yylval.optval = opt;
+ return(OPTION);
}
if (!strcmp(yytext, "install"))
c = INSTALL;
@@ -344,6 +386,8 @@ again:
c = PATTERN;
else if (!strcmp(yytext, "special"))
c = SPECIAL;
+ else if (!strcmp(yytext, "cmdspecial"))
+ c = CMDSPECIAL;
else {
yylval.string = makestr(yytext);
return(NAME);
@@ -352,8 +396,11 @@ again:
return(c);
}
-int
-any(c, str)
+/*
+ * XXX We should use strchr(), but most versions can't handle
+ * some of the characters we use.
+ */
+extern int any(c, str)
register int c;
register char *str;
{
@@ -366,18 +413,22 @@ 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;
struct subcmd *subcmds;
{
register struct cmd *c, *prev, *nc;
- register struct namelist *h;
+ register struct namelist *h, *lasth;
+
+ debugmsg(DM_CALL, "insert(%s, %x, %x, %x) start, files = %s",
+ label == NULL ? "(null)" : label,
+ files, hosts, subcmds, getnlstr(files));
files = expand(files, E_VARS|E_SHELL);
hosts = expand(hosts, E_ALL);
- for (h = hosts; h != NULL; free(h), h = h->n_next) {
+ for (h = hosts; h != NULL; lasth = h, h = h->n_next,
+ free((char *)lasth)) {
/*
* Search command list for an update to the same host.
*/
@@ -395,13 +446,12 @@ insert(label, files, hosts, subcmds)
* Insert new command to update host.
*/
nc = ALLOC(cmd);
- if (nc == NULL)
- fatal("ran out of memory\n");
nc->c_type = ARROW;
nc->c_name = h->n_name;
nc->c_label = label;
nc->c_files = files;
nc->c_cmds = subcmds;
+ nc->c_flags = 0;
nc->c_next = c;
if (prev == NULL)
cmds = nc;
@@ -417,7 +467,6 @@ 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.
*/
-void
append(label, files, stamp, subcmds)
char *label;
struct namelist *files;
@@ -427,8 +476,6 @@ append(label, files, stamp, subcmds)
register struct cmd *c;
c = ALLOC(cmd);
- if (c == NULL)
- fatal("ran out of memory\n");
c->c_type = DCOLON;
c->c_name = stamp;
c->c_label = label;
@@ -446,30 +493,26 @@ append(label, files, stamp, subcmds)
/*
* Error printing routine in parser.
*/
-void
yyerror(s)
char *s;
{
- ++nerrs;
- fflush(stdout);
- fprintf(stderr, "rdist: line %d: %s\n", yylineno, s);
+ error("Error in distfile: line %d: %s", yylineno, s);
}
/*
* Return a copy of the string.
*/
-static char *
+char *
makestr(str)
char *str;
{
- register char *cp, *s;
+ char *cp;
- str = cp = malloc(strlen(s = str) + 1);
+ cp = strdup(str);
if (cp == NULL)
- fatal("ran out of memory\n");
- while (*cp++ = *s++)
- ;
- return(str);
+ fatalerr("ran out of memory");
+
+ return(cp);
}
/*
@@ -481,29 +524,108 @@ makenl(name)
{
register struct namelist *nl;
+ debugmsg(DM_CALL, "makenl(%s)", name == NULL ? "null" : name);
+
nl = ALLOC(namelist);
- if (nl == NULL)
- fatal("ran out of memory\n");
nl->n_name = name;
nl->n_next = NULL;
+
return(nl);
}
+
+/*
+ * Is the name p in the namelist nl?
+ */
+static int
+innl(nl, p)
+ struct namelist *nl;
+ char *p;
+{
+ for ( ; nl; nl = nl->n_next)
+ if (!strcmp(p, nl->n_name))
+ return(1);
+ return(0);
+}
+
+/*
+ * Join two namelists.
+ */
+static struct namelist *
+addnl(n1, n2)
+ struct namelist *n1, *n2;
+{
+ struct namelist *nl, *prev;
+
+ n1 = expand(n1, E_VARS);
+ n2 = expand(n2, E_VARS);
+ for (prev = NULL, nl = NULL; n1; n1 = n1->n_next, prev = nl) {
+ nl = makenl(n1->n_name);
+ nl->n_next = prev;
+ }
+ for (; n2; n2 = n2->n_next)
+ if (!innl(nl, n2->n_name)) {
+ nl = makenl(n2->n_name);
+ nl->n_next = prev;
+ prev = nl;
+ }
+ return(prev);
+}
+
+/*
+ * Copy n1 except for elements that are in n2.
+ */
+static struct namelist *
+subnl(n1, n2)
+ struct namelist *n1, *n2;
+{
+ struct namelist *nl, *prev;
+
+ n1 = expand(n1, E_VARS);
+ n2 = expand(n2, E_VARS);
+ for (prev = NULL; n1; n1 = n1->n_next)
+ if (!innl(n2, n1->n_name)) {
+ nl = makenl(n1->n_name);
+ nl->n_next = prev;
+ prev = nl;
+ }
+ return(prev);
+}
+
+/*
+ * Copy all items of n1 that are also in n2.
+ */
+static struct namelist *
+andnl(n1, n2)
+ struct namelist *n1, *n2;
+{
+ struct namelist *nl, *prev;
+
+ n1 = expand(n1, E_VARS);
+ n2 = expand(n2, E_VARS);
+ for (prev = NULL; n1; n1 = n1->n_next)
+ if (innl(n2, n1->n_name)) {
+ nl = makenl(n1->n_name);
+ nl->n_next = prev;
+ prev = nl;
+ }
+ return(prev);
+}
+
/*
* Make a sub command for lists of variables, commands, etc.
*/
-struct subcmd *
+extern struct subcmd *
makesubcmd(type)
int type;
{
register struct subcmd *sc;
sc = ALLOC(subcmd);
- if (sc == NULL)
- fatal("ran out of memory\n");
sc->sc_type = type;
sc->sc_args = NULL;
sc->sc_next = NULL;
sc->sc_name = NULL;
+
return(sc);
}