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: #ifndef lint
   9: static  char *sccsid = "@(#)gram.y	5.2 (Berkeley) 85/06/21";
  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
_append defined in line 384; used 2 times
_insert defined in line 334; used 3 times
_makenl defined in line 442; used 9 times
_makestr defined in line 425; used 3 times
_makesubcmd defined in line 459; used 3 times
_yyerror defined in line 412; used 19 times
_yylex defined in line 171; never used

Defined variables

_yylineno defined in line 168; used 3 times
Last modified: 1986-03-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1400
Valid CSS Valid XHTML 1.0 Strict