First stable version.
[unix-history] / usr / src / usr.bin / rdist / gram.y
index c9f12c3..34a7c08 100644 (file)
@@ -1,23 +1,25 @@
 %{
 #ifndef lint
 %{
 #ifndef lint
-static char *sccsid = "@(#)gram.y      4.1 (Berkeley) 83/09/07";
+static char *sccsid = "@(#)gram.y      4.2 (Berkeley) 83/09/27";
 #endif
 
 #include "defs.h"
 
 #endif
 
 #include "defs.h"
 
-struct block *last;
+struct block *lastn;
+struct block *lastc;
 
 %}
 
 %term EQUAL 1
 
 %}
 
 %term EQUAL 1
-%term ARROW 2
-%term LP 3
-%term RP 4
-%term NAME 5
-%term INSTALL 6
-%term VERIFY 7
-%term NOTIFY 8
-%term EXCEPT 9
+%term LP 2
+%term RP 3
+%term ARROW 4
+%term DCOLON 5
+%term NAME 6
+%term INSTALL 7
+%term VERIFY 8
+%term NOTIFY 9
+%term EXCEPT 10
 
 %union
        {
 
 %union
        {
@@ -34,10 +36,13 @@ file:                 /* VOID */
 
 command:         NAME EQUAL namelist = {
                        $1->b_args = $3;
 
 command:         NAME EQUAL namelist = {
                        $1->b_args = $3;
-                       (void) lookup($1->b_name, 1, $1);
+                       (void) lookup($1->b_name, $1, 1);
                }
                | namelist ARROW namelist cmdlist = {
                }
                | namelist ARROW namelist cmdlist = {
-                       docmd($1, $3, $4);
+                       dohcmds($1, $3, $4);
+               }
+               | namelist DCOLON namelist cmdlist = {
+                       dofcmds($1, $3, $4);
                }
                | error
                ;
                }
                | error
                ;
@@ -51,49 +56,53 @@ namelist:     NAME = {
                ;
 
 names:           /* VOID */ {
                ;
 
 names:           /* VOID */ {
-                       $$ = last = NULL;
+                       $$ = lastn = NULL;
                }
                | names NAME = {
                }
                | names NAME = {
-                       if (last == NULL)
-                               $$ = last = $2;
+                       if (lastn == NULL)
+                               $$ = lastn = $2;
                        else {
                        else {
-                               last->b_next = $2;
-                               last = $2;
+                               lastn->b_next = $2;
+                               lastn = $2;
                                $$ = $1;
                        }
                }
                ;
 
 cmdlist:         /* VOID */ {
                                $$ = $1;
                        }
                }
                ;
 
 cmdlist:         /* VOID */ {
-                       $$ = last = NULL;
+                       $$ = lastc = NULL;
                }
                | cmdlist cmd = {
                }
                | cmdlist cmd = {
-                       if (last == NULL)
-                               $$ = last = $2;
+                       if (lastc == NULL)
+                               $$ = lastc = $2;
                        else {
                        else {
-                               last->b_next = $2;
-                               last = $2;
+                               lastc->b_next = $2;
+                               lastc = $2;
                                $$ = $1;
                        }
                }
                ;
 
 cmd:             INSTALL NAME = {
                                $$ = $1;
                        }
                }
                ;
 
 cmd:             INSTALL NAME = {
-                       $1->b_name = $2->b_name;
+                       register struct block *b;
+
+               inst_name:
+                       b = expand($2, 0);
+                       if (b == NULL || b->b_next != NULL)
+                               fatal("exactly one name allowed\n");
+                       $1->b_name = b->b_name;
                        free($2);
                        $$ = $1;
                }
                | VERIFY NAME = {
                        free($2);
                        $$ = $1;
                }
                | VERIFY NAME = {
-                       $1->b_name = $2->b_name;
-                       free($2);
-                       $$ = $1;
+                       goto inst_name;
                }
                | NOTIFY namelist = {
                }
                | NOTIFY namelist = {
-                       $1->b_args = $2;
+                       $1->b_args = expand($2, 1);
                        $$ = $1;
                }
                | EXCEPT namelist = {
                        $$ = $1;
                }
                | EXCEPT namelist = {
-                       $1->b_args = expand($2);
+                       $1->b_args = expand($2, 0);
                        $$ = $1;
                }
                ;
                        $$ = $1;
                }
                ;
@@ -109,82 +118,85 @@ yylex()
        register int c;
        register char *cp1, *cp2;
        register struct block *bp;
        register int c;
        register char *cp1, *cp2;
        register struct block *bp;
+       static char quotechars[] = "[]{}*?";
        
        
-       for (;;) {
-               switch (c = getc(fin)) {
-               case EOF:  /* end of file */
+again:
+       switch (c = getc(fin)) {
+       case EOF:  /* end of file */
+               return(0);
+
+       case '#':  /* start of comment */
+               while ((c = getc(fin)) != EOF && c != '\n')
+                       ;
+               if (c == EOF)
                        return(0);
                        return(0);
-
-               case '#':  /* start of comment */
-                       while ((c = getc(fin)) != EOF && c != '\n')
-                               ;
-                       if (c == EOF)
-                               return(0);
-               case '\n':
-                       yylineno++;
-               case ' ':
-               case '\t':  /* skip blanks */
-                       continue;
-
-               case '=':  /* EQUAL */
-                       return(EQUAL);
-
-               case '(':  /* LP */
-                       return(LP);
-
-               case ')':  /* RP */
-                       return(RP);
-
-               case '-':  /* -> */
-                       if ((c = getc(fin)) == '>')
-                               return(ARROW);
-                       ungetc(c, fin);
-                       c = '-';
-               }
-               /*
-                * Start of a name.
-                */
-               cp1 = yytext;
-               cp2 = &yytext[INMAX - 1];
-               for (;;) {
-                       if (cp1 >= cp2) {
-                               fatal("input line too long\n");
-                               break;
-                       }
-                       *cp1++ = c;
-                       c = getc(fin);
-                       if (c == EOF || any(c, " \t()=\n")) {
-                               ungetc(c, fin);
+       case '\n':
+               yylineno++;
+       case ' ':
+       case '\t':  /* skip blanks */
+               goto again;
+
+       case '=':  /* EQUAL */
+               return(EQUAL);
+
+       case '(':  /* LP */
+               return(LP);
+
+       case ')':  /* RP */
+               return(RP);
+
+       case '-':  /* -> */
+               if ((c = getc(fin)) == '>')
+                       return(ARROW);
+               ungetc(c, fin);
+               c = '-';
+               break;
+
+       case ':':  /* :: */
+               if ((c = getc(fin)) == ':')
+                       return(DCOLON);
+               ungetc(c, fin);
+               c = ':';
+       }
+       /*
+        * Start of a name.
+        */
+       cp1 = yytext;
+       cp2 = &yytext[INMAX - 1];
+       for (;;) {
+               if (cp1 >= cp2) {
+                       fatal("input line too long\n");
+                       break;
+               }
+               if (c == '\\') {
+                       if ((c = getc(fin)) != EOF) {
+                               if (any(c, quotechars))
+                                       c |= QUOTE;
+                       } else {
+                               *cp1++ = '\\';
                                break;
                        }
                }
                                break;
                        }
                }
-               *cp1 = '\0';
-               yylval.blk = bp = ALLOC(block);
-               if (bp == NULL)
-                       fatal("ran out of memory\n");
-               if (!strcmp(yytext, "install"))
-                       c = INSTALL;
-               else if (!strcmp(yytext, "verify"))
-                       c = VERIFY;
-               else if (!strcmp(yytext, "notify"))
-                       c = NOTIFY;
-               else if (!strcmp(yytext, "except"))
-                       c = EXCEPT;
-               else
-                       c = NAME;
-               bp->b_type = c;
-               bp->b_next = bp->b_args = NULL;
-               if (c == NAME) {
-                       c = strlen(yytext) + 1;
-                       bp->b_name = cp1 = (char *) malloc(c);
-                       if (cp1 == NULL)
-                               fatal("ran out of memory\n");
-                       for (cp2 = yytext; *cp1++ = *cp2++; )
-                               ;
-               } else
-                       bp->b_name = NULL;
-               return(bp->b_type);
+               *cp1++ = c;
+               c = getc(fin);
+               if (c == EOF || any(c, " \t()=\n")) {
+                       ungetc(c, fin);
+                       break;
+               }
        }
        }
+       *cp1 = '\0';
+       if (!strcmp(yytext, "install"))
+               c = INSTALL;
+       else if (!strcmp(yytext, "verify"))
+               c = VERIFY;
+       else if (!strcmp(yytext, "notify"))
+               c = NOTIFY;
+       else if (!strcmp(yytext, "except"))
+               c = EXCEPT;
+       else
+               c = NAME;
+       yylval.blk = bp = makeblock(c, yytext);
+       return(c);
 }
 
 any(c, str)
 }
 
 any(c, str)