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