# 2.11BSD#431 - /usr/src/ucb/rdist/gram.y

##### Functions

    _any              X
    _append           X
    _insert           X
    _makenl           X
    _makestr          X
    _makesubcmd       X
    _yyerror          X
    _yylex            X

##### Variables

    _yylineno         X

       1: %{
       2: /*
       3:  * Copyright (c) 1980 Regents of the University of California.
       4:  * All rights reserved.  The Berkeley software License Agreement
       5:  * specifies the terms and conditions for redistribution.
       6:  */
       7:
       8: #if !defined(lint) && defined(DOSCCS)
       9: static  char *sccsid = "@(#)gram.y	5.2.1 (2.11BSD) 1995/05/09";
      10: #endif
      11:
      12: #include "defs.h"
      13:
      14: struct  cmd *cmds = NULL;
      15: struct  cmd *last_cmd;
      16: struct  namelist *last_n;
      17: struct  subcmd *last_sc;
      18:
      19: %}
      20:
      21: %term EQUAL 1
      22: %term LP    2
      23: %term RP    3
      24: %term SM    4
      25: %term ARROW 5
      26: %term COLON 6
      27: %term DCOLON    7
      28: %term NAME  8
      29: %term STRING    9
      30: %term INSTALL   10
      31: %term NOTIFY    11
      32: %term EXCEPT    12
      33: %term PATTERN   13
      34: %term SPECIAL   14
      35: %term OPTION    15
      36:
      37: %union {
      38:     int intval;
      39:     char *string;
      40:     struct subcmd *subcmd;
      41:     struct namelist *namel;
      42: }
      43:
      44: %type <intval> OPTION, options
      45: %type <string> NAME, STRING
      46: %type <subcmd> INSTALL, NOTIFY, EXCEPT, PATTERN, SPECIAL, cmdlist, cmd
      47: %type <namel> namelist, names, opt_namelist
      48:
      49: %%
      50:
      51: file:         /* VOID */
      52:         | file command
      53:         ;
      54:
      55: command:      NAME EQUAL namelist = {
      56:             (void) lookup($1, INSERT, $3);
      57:         }
      58:         | namelist ARROW namelist cmdlist = {
      59:             insert(NULL, $1, $3, $4);
      60:         }
      61:         | NAME COLON namelist ARROW namelist cmdlist = {
      62:             insert($1, $3, $5, $6);
      63:         }
      64:         | namelist DCOLON NAME cmdlist = {
      65:             append(NULL, $1, $3, $4);
      66:         }
      67:         | NAME COLON namelist DCOLON NAME cmdlist = {
      68:             append($1, $3, $5, $6);
      69:         }
      70:         | error
      71:         ;
      72:
      73: namelist:     NAME = {
      74:             $$ = makenl($1);
      75:         }
      76:         | LP names RP = {
      77:             $$ = $2;
      78:         }
      79:         ;
      80:
      81: names:        /* VOID */ {
      82:             $$ = last_n = NULL;
      83:         }
      84:         | names NAME = {
      85:             if (last_n == NULL)
      86:                 $$ = last_n = makenl($2);
      87:             else {
      88:                 last_n->n_next = makenl($2);
      89:                 last_n = last_n->n_next;
      90:                 $$ = $1;
      91:             }
      92:         }
      93:         ;
      94:
      95: cmdlist:      /* VOID */ {
      96:             $$ = last_sc = NULL;
      97:         }
      98:         | cmdlist cmd = {
      99:             if (last_sc == NULL)
     100:                 $$ = last_sc = $2;
     101:             else {
     102:                 last_sc->sc_next = $2;
     103:                 last_sc = $2;
     104:                 $$ = $1;
     105:             }
     106:         }
     107:         ;
     108:
     109: cmd:          INSTALL options opt_namelist SM = {
     110:             register struct namelist *nl;
     111:
     112:             $1->sc_options = $2 | options;
     113:             if ($3 != NULL) {
     114:                 nl = expand($3, E_VARS);
     115:                 if (nl->n_next != NULL)
     116:                     yyerror("only one name allowed\n");
     117:                 $1->sc_name = nl->n_name;
     118:                 free(nl);
     119:             }
     120:             $$ = $1;
     121:         }
     122:         | NOTIFY namelist SM = {
     123:             if ($2 != NULL)
     124:                 $1->sc_args = expand($2, E_VARS);
     125:             $$ = $1;
     126:         }
     127:         | EXCEPT namelist SM = {
     128:             if ($2 != NULL)
     129:                 $1->sc_args = expand($2, E_ALL);
     130:             $$ = $1;
     131:         }
     132:         | PATTERN namelist SM = {
     133:             struct namelist *nl;
     134:             char *cp, *re_comp();
     135:
     136:             for (nl = $2; nl != NULL; nl = nl->n_next)
     137:                 if ((cp = re_comp(nl->n_name)) != NULL)
     138:                     yyerror(cp);
     139:             $1->sc_args = expand($2, E_VARS);
     140:             $$ = $1;
     141:         }
     142:         | SPECIAL opt_namelist STRING SM = {
     143:             if ($2 != NULL)
     144:                 $1->sc_args = expand($2, E_ALL);
     145:             $1->sc_name = $3;
     146:             $$ = $1;
     147:         }
     148:         ;
     149:
     150: options:      /* VOID */ = {
     151:             $$ = 0;
     152:         }
     153:         | options OPTION = {
     154:             $$ |= $2;
     155:         }
     156:         ;
     157:
     158: opt_namelist:     /* VOID */ = {
     159:             $$ = NULL;
     160:         }
     161:         | namelist = {
     162:             $$ = $1;
     163:         }
     164:         ;
     165:
     166: %%
     167:
     168: int yylineno = 1;
     169: extern  FILE *fin;
     170:
     171: yylex()
     172: {
     173:     static char yytext[INMAX];
     174:     register int c;
     175:     register char *cp1, *cp2;
     176:     static char *quotechars = "[]{}*?$";
     177:
     178: again:
     179:     switch (c = getc(fin)) {
     180:     case EOF:  /* end of file */
     181:         return(0);
     182:
     183:     case '#':  /* start of comment */
     184:         while ((c = getc(fin)) != EOF && c != '\n')
     185:             ;
     186:         if (c == EOF)
     187:             return(0);
     188:     case '\n':
     189:         yylineno++;
     190:     case ' ':
     191:     case '\t':  /* skip blanks */
     192:         goto again;
     193:
     194:     case '=':  /* EQUAL */
     195:         return(EQUAL);
     196:
     197:     case '(':  /* LP */
     198:         return(LP);
     199:
     200:     case ')':  /* RP */
     201:         return(RP);
     202:
     203:     case ';':  /* SM */
     204:         return(SM);
     205:
     206:     case '-':  /* -> */
     207:         if ((c = getc(fin)) == '>')
     208:             return(ARROW);
     209:         ungetc(c, fin);
     210:         c = '-';
     211:         break;
     212:
     213:     case '"':  /* STRING */
     214:         cp1 = yytext;
     215:         cp2 = &yytext[INMAX - 1];
     216:         for (;;) {
     217:             if (cp1 >= cp2) {
     218:                 yyerror("command string too long\n");
     219:                 break;
     220:             }
     221:             c = getc(fin);
     222:             if (c == EOF || c == '"')
     223:                 break;
     224:             if (c == '\\') {
     225:                 if ((c = getc(fin)) == EOF) {
     226:                     *cp1++ = '\\';
     227:                     break;
     228:                 }
     229:             }
     230:             if (c == '\n') {
     231:                 yylineno++;
     232:                 c = ' '; /* can't send '\n' */
     233:             }
     234:             *cp1++ = c;
     235:         }
     236:         if (c != '"')
     237:             yyerror("missing closing '\"'\n");
     238:         *cp1 = '\0';
     239:         yylval.string = makestr(yytext);
     240:         return(STRING);
     241:
     242:     case ':':  /* : or :: */
     243:         if ((c = getc(fin)) == ':')
     244:             return(DCOLON);
     245:         ungetc(c, fin);
     246:         return(COLON);
     247:     }
     248:     cp1 = yytext;
     249:     cp2 = &yytext[INMAX - 1];
     250:     for (;;) {
     251:         if (cp1 >= cp2) {
     252:             yyerror("input line too long\n");
     253:             break;
     254:         }
     255:         if (c == '\\') {
     256:             if ((c = getc(fin)) != EOF) {
     257:                 if (any(c, quotechars))
     258:                     c |= QUOTE;
     259:             } else {
     260:                 *cp1++ = '\\';
     261:                 break;
     262:             }
     263:         }
     264:         *cp1++ = c;
     265:         c = getc(fin);
     266:         if (c == EOF || any(c, " \"'\t()=;:\n")) {
     267:             ungetc(c, fin);
     268:             break;
     269:         }
     270:     }
     271:     *cp1 = '\0';
     272:     if (yytext[0] == '-' && yytext[2] == '\0') {
     273:         switch (yytext[1]) {
     274:         case 'b':
     275:             yylval.intval = COMPARE;
     276:             return(OPTION);
     277:
     278:         case 'R':
     279:             yylval.intval = REMOVE;
     280:             return(OPTION);
     281:
     282:         case 'v':
     283:             yylval.intval = VERIFY;
     284:             return(OPTION);
     285:
     286:         case 'w':
     287:             yylval.intval = WHOLE;
     288:             return(OPTION);
     289:
     290:         case 'y':
     291:             yylval.intval = YOUNGER;
     292:             return(OPTION);
     293:
     294:         case 'h':
     295:             yylval.intval = FOLLOW;
     296:             return(OPTION);
     297:
     298:         case 'i':
     299:             yylval.intval = IGNLNKS;
     300:             return(OPTION);
     301:         }
     302:     }
     303:     if (!strcmp(yytext, "install"))
     304:         c = INSTALL;
     305:     else if (!strcmp(yytext, "notify"))
     306:         c = NOTIFY;
     307:     else if (!strcmp(yytext, "except"))
     308:         c = EXCEPT;
     309:     else if (!strcmp(yytext, "except_pat"))
     310:         c = PATTERN;
     311:     else if (!strcmp(yytext, "special"))
     312:         c = SPECIAL;
     313:     else {
     314:         yylval.string = makestr(yytext);
     315:         return(NAME);
     316:     }
     317:     yylval.subcmd = makesubcmd(c);
     318:     return(c);
     319: }
     320:
     321: any(c, str)
     322:     register int c;
     323:     register char *str;
     324: {
     325:     while (*str)
     326:         if (c == *str++)
     327:             return(1);
     328:     return(0);
     329: }
     330:
     331: /*
     332:  * Insert or append ARROW command to list of hosts to be updated.
     333:  */
     334: insert(label, files, hosts, subcmds)
     335:     char *label;
     336:     struct namelist *files, *hosts;
     337:     struct subcmd *subcmds;
     338: {
     339:     register struct cmd *c, *prev, *nc;
     340:     register struct namelist *h;
     341:
     342:     files = expand(files, E_VARS|E_SHELL);
     343:     hosts = expand(hosts, E_ALL);
     344:     for (h = hosts; h != NULL; free(h), h = h->n_next) {
     345:         /*
     346: 		 * Search command list for an update to the same host.
     347: 		 */
     348:         for (prev = NULL, c = cmds; c!=NULL; prev = c, c = c->c_next) {
     349:             if (strcmp(c->c_name, h->n_name) == 0) {
     350:                 do {
     351:                     prev = c;
     352:                     c = c->c_next;
     353:                 } while (c != NULL &&
     354:                     strcmp(c->c_name, h->n_name) == 0);
     355:                 break;
     356:             }
     357:         }
     358:         /*
     359: 		 * Insert new command to update host.
     360: 		 */
     361:         nc = ALLOC(cmd);
     362:         if (nc == NULL)
     363:             fatal("ran out of memory\n");
     364:         nc->c_type = ARROW;
     365:         nc->c_name = h->n_name;
     366:         nc->c_label = label;
     367:         nc->c_files = files;
     368:         nc->c_cmds = subcmds;
     369:         nc->c_next = c;
     370:         if (prev == NULL)
     371:             cmds = nc;
     372:         else
     373:             prev->c_next = nc;
     374:         /* update last_cmd if appending nc to cmds */
     375:         if (c == NULL)
     376:             last_cmd = nc;
     377:     }
     378: }
     379:
     380: /*
     381:  * Append DCOLON command to the end of the command list since these are always
     382:  * executed in the order they appear in the distfile.
     383:  */
     384: append(label, files, stamp, subcmds)
     385:     char *label;
     386:     struct namelist *files;
     387:     char *stamp;
     388:     struct subcmd *subcmds;
     389: {
     390:     register struct cmd *c;
     391:
     392:     c = ALLOC(cmd);
     393:     if (c == NULL)
     394:         fatal("ran out of memory\n");
     395:     c->c_type = DCOLON;
     396:     c->c_name = stamp;
     397:     c->c_label = label;
     398:     c->c_files = expand(files, E_ALL);
     399:     c->c_cmds = subcmds;
     400:     c->c_next = NULL;
     401:     if (cmds == NULL)
     402:         cmds = last_cmd = c;
     403:     else {
     404:         last_cmd->c_next = c;
     405:         last_cmd = c;
     406:     }
     407: }
     408:
     409: /*
     410:  * Error printing routine in parser.
     411:  */
     412: yyerror(s)
     413:     char *s;
     414: {
     415:     extern int yychar;
     416:
     417:     nerrs++;
     418:     fflush(stdout);
     419:     fprintf(stderr, "rdist: line %d: %s\n", yylineno, s);
     420: }
     421:
     422: /*
     423:  * Return a copy of the string.
     424:  */
     425: char *
     426: makestr(str)
     427:     char *str;
     428: {
     429:     register char *cp, *s;
     430:
     431:     str = cp = malloc(strlen(s = str) + 1);
     432:     if (cp == NULL)
     433:         fatal("ran out of memory\n");
     434:     while (*cp++ = *s++)
     435:         ;
     436:     return(str);
     437: }
     438:
     439: /*
     440:  * Allocate a namelist structure.
     441:  */
     442: struct namelist *
     443: makenl(name)
     444:     char *name;
     445: {
     446:     register struct namelist *nl;
     447:
     448:     nl = ALLOC(namelist);
     449:     if (nl == NULL)
     450:         fatal("ran out of memory\n");
     451:     nl->n_name = name;
     452:     nl->n_next = NULL;
     453:     return(nl);
     454: }
     455:
     456: /*
     457:  * Make a sub command for lists of variables, commands, etc.
     458:  */
     459: struct subcmd *
     460: makesubcmd(type, name)
     461:     int type;
     462:     register char *name;
     463: {
     464:     register char *cp;
     465:     register struct subcmd *sc;
     466:
     467:     sc = ALLOC(subcmd);
     468:     if (sc == NULL)
     469:         fatal("ran out of memory\n");
     470:     sc->sc_type = type;
     471:     sc->sc_args = NULL;
     472:     sc->sc_next = NULL;
     473:     sc->sc_name = NULL;
     474:     return(sc);
     475: }

#### Defined functions

_any defined in line 321; used 5 times

- in line 257, 266
- in /usr/src/ucb/rdist/docmd.c line 496, 502
- in /usr/src/ucb/rdist/expand.c line 228

_append defined in line 384; used 2 times

- in line 65-68(2)

_insert defined in line 334; used 3 times

- in line 59-62(2)
- in /usr/src/ucb/rdist/main.c line 251

_makenl defined in line 442; used 9 times

- in line 74, 86-88(2)
- in /usr/src/ucb/rdist/defs.h line 122
- in /usr/src/ucb/rdist/expand.c line 91
- in /usr/src/ucb/rdist/lookup.c line 47, 72-74(2)
- in /usr/src/ucb/rdist/main.c line 220

_makestr defined in line 425; used 3 times

- in line 239, 314
- in /usr/src/ucb/rdist/defs.h line 121

_makesubcmd defined in line 459; used 3 times

- in line 317
- in /usr/src/ucb/rdist/defs.h line 123
- in /usr/src/ucb/rdist/main.c line 240

_yyerror defined in line 412; used 19 times

- in line 116, 138, 218, 237, 252
- in /usr/src/ucb/rdist/expand.c line 123, 129-134(2), 176, 293, 323-328(2), 369, 426, 508, 546, 563
- in /usr/src/ucb/rdist/lookup.c line 117, 124

_yylex defined in line 171; never used

#### Defined variables

_yylineno defined in line 168; used 3 times

- in line 189, 231, 419

Last modified: 1995-05-10 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1620 |