|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.