8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / cmd-inet / usr.bin / rdist / gram.y
blob552c9d081322ec0d4054b40e7d8d36897cc74aed
1 %{
2 /*
3 * Copyright (c) 1983 Regents of the University of California.
4 * All rights reserved.
6 * Redistribution and use in source and binary forms are permitted
7 * provided that the above copyright notice and this paragraph are
8 * duplicated in all such forms and that any documentation,
9 * advertising materials, and other materials related to such
10 * distribution and use acknowledge that the software was developed
11 * by the University of California, Berkeley. The name of the
12 * University may not be used to endorse or promote products derived
13 * from this software without specific prior written permission.
15 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
16 * Use is subject to license terms.
18 #pragma ident "%Z%%M% %I% %E% SMI"
20 #include "defs.h"
22 struct cmd *cmds = NULL;
23 struct cmd *last_cmd;
24 struct namelist *last_n;
25 struct subcmd *last_sc;
27 static void append(char *label, struct namelist *files, char *stamp,
28 struct subcmd *subcmds);
29 void yyerror(char *s);
33 %term EQUAL 1
34 %term LP 2
35 %term RP 3
36 %term SM 4
37 %term ARROW 5
38 %term COLON 6
39 %term DCOLON 7
40 %term NAME 8
41 %term STRING 9
42 %term INSTALL 10
43 %term NOTIFY 11
44 %term EXCEPT 12
45 %term PATTERN 13
46 %term SPECIAL 14
47 %term OPTION 15
49 %union {
50 int intval;
51 char *string;
52 struct subcmd *subcmd;
53 struct namelist *namel;
56 %type <intval> OPTION, options
57 %type <string> NAME, STRING
58 %type <subcmd> INSTALL, NOTIFY, EXCEPT, PATTERN, SPECIAL, cmdlist, cmd
59 %type <namel> namelist, names, opt_namelist
63 file: /* VOID */
64 | file command
67 command: NAME EQUAL namelist = {
68 (void) lookup($1, INSERT, $3);
70 | namelist ARROW namelist cmdlist = {
71 insert(NULL, $1, $3, $4);
73 | NAME COLON namelist ARROW namelist cmdlist = {
74 insert($1, $3, $5, $6);
76 | namelist DCOLON NAME cmdlist = {
77 append(NULL, $1, $3, $4);
79 | NAME COLON namelist DCOLON NAME cmdlist = {
80 append($1, $3, $5, $6);
82 | error
85 namelist: NAME = {
86 $$ = makenl($1);
88 | LP names RP = {
89 $$ = $2;
93 names: /* VOID */ {
94 $$ = last_n = NULL;
96 | names NAME = {
97 if (last_n == NULL)
98 $$ = last_n = makenl($2);
99 else {
100 last_n->n_next = makenl($2);
101 last_n = last_n->n_next;
102 $$ = $1;
107 cmdlist: /* VOID */ {
108 $$ = last_sc = NULL;
110 | cmdlist cmd = {
111 if (last_sc == NULL)
112 $$ = last_sc = $2;
113 else {
114 last_sc->sc_next = $2;
115 last_sc = $2;
116 $$ = $1;
121 cmd: INSTALL options opt_namelist SM = {
122 register struct namelist *nl;
124 $1->sc_options = $2 | options;
125 if ($3 != NULL) {
126 nl = expand($3, E_VARS);
127 if (nl && nl->n_next != NULL)
128 yyerror("only one name allowed\n");
129 $1->sc_name = nl ? nl->n_name: NULL;
130 if (nl)
131 free(nl);
133 $$ = $1;
135 | NOTIFY namelist SM = {
136 if ($2 != NULL)
137 $1->sc_args = expand($2, E_VARS);
138 $$ = $1;
140 | EXCEPT namelist SM = {
141 if ($2 != NULL)
142 $1->sc_args = expand($2, E_ALL);
143 $$ = $1;
145 | PATTERN namelist SM = {
146 struct namelist *nl;
147 char *cp, *re_comp();
150 * We dup the namelist in $2 because expand()
151 * destroys the list referred to in its first
152 * argument.
154 for (nl = expand(dupnl($2), E_VARS); nl != NULL;
155 nl = nl->n_next)
156 if ((cp = re_comp(nl->n_name)) != NULL)
157 yyerror(cp);
158 $1->sc_args = expand($2, E_VARS);
159 $$ = $1;
161 | SPECIAL opt_namelist STRING SM = {
162 if ($2 != NULL)
163 $1->sc_args = expand($2, E_ALL);
164 $1->sc_name = $3;
165 $$ = $1;
169 options: /* VOID */ = {
170 $$ = 0;
172 | options OPTION = {
173 $$ |= $2;
177 opt_namelist: /* VOID */ = {
178 $$ = NULL;
180 | namelist = {
181 $$ = $1;
187 int yylineno = 1;
188 extern FILE *fin;
191 yylex()
193 static char yytext[INMAX];
194 register int c;
195 register char *cp1, *cp2;
196 static char quotechars[] = "[]{}*?$";
198 again:
199 switch (c = getc(fin)) {
200 case EOF: /* end of file */
201 return(0);
203 case '#': /* start of comment */
204 while ((c = getc(fin)) != EOF && c != '\n')
206 if (c == EOF)
207 return(0);
208 case '\n':
209 yylineno++;
210 case ' ':
211 case '\t': /* skip blanks */
212 goto again;
214 case '=': /* EQUAL */
215 return(EQUAL);
217 case '(': /* LP */
218 return(LP);
220 case ')': /* RP */
221 return(RP);
223 case ';': /* SM */
224 return(SM);
226 case '-': /* -> */
227 if ((c = getc(fin)) == '>')
228 return(ARROW);
229 ungetc(c, fin);
230 c = '-';
231 break;
233 case '"': /* STRING */
234 cp1 = yytext;
235 cp2 = &yytext[INMAX - 1];
236 for (;;) {
237 if (cp1 >= cp2) {
238 yyerror("command string too long\n");
239 break;
241 c = getc(fin);
242 if (c == EOF || c == '"')
243 break;
244 if (c == '\\') {
245 if ((c = getc(fin)) == EOF) {
246 *cp1++ = '\\';
247 break;
250 if (c == '\n') {
251 yylineno++;
252 c = ' '; /* can't send '\n' */
254 *cp1++ = c;
256 if (c != '"')
257 yyerror("missing closing '\"'\n");
258 *cp1 = '\0';
259 yylval.string = makestr(yytext);
260 return(STRING);
262 case ':': /* : or :: */
263 if ((c = getc(fin)) == ':')
264 return(DCOLON);
265 ungetc(c, fin);
266 return(COLON);
268 cp1 = yytext;
269 cp2 = &yytext[INMAX - 1];
270 for (;;) {
271 if (cp1 >= cp2) {
272 yyerror("input line too long\n");
273 break;
275 if (c == '\\') {
276 if ((c = getc(fin)) != EOF) {
277 if (any(c, quotechars))
278 c |= QUOTE;
279 } else {
280 *cp1++ = '\\';
281 break;
284 *cp1++ = c;
285 c = getc(fin);
286 if (c == EOF || any(c, " \"'\t()=;:\n")) {
287 ungetc(c, fin);
288 break;
291 *cp1 = '\0';
292 if (yytext[0] == '-' && yytext[2] == '\0') {
293 switch (yytext[1]) {
294 case 'b':
295 yylval.intval = COMPARE;
296 return(OPTION);
298 case 'R':
299 yylval.intval = REMOVE;
300 return(OPTION);
302 case 'v':
303 yylval.intval = VERIFY;
304 return(OPTION);
306 case 'w':
307 yylval.intval = WHOLE;
308 return(OPTION);
310 case 'y':
311 yylval.intval = YOUNGER;
312 return(OPTION);
314 case 'h':
315 yylval.intval = FOLLOW;
316 return(OPTION);
318 case 'i':
319 yylval.intval = IGNLNKS;
320 return(OPTION);
323 if (!strcmp(yytext, "install"))
324 c = INSTALL;
325 else if (!strcmp(yytext, "notify"))
326 c = NOTIFY;
327 else if (!strcmp(yytext, "except"))
328 c = EXCEPT;
329 else if (!strcmp(yytext, "except_pat"))
330 c = PATTERN;
331 else if (!strcmp(yytext, "special"))
332 c = SPECIAL;
333 else {
334 yylval.string = makestr(yytext);
335 return(NAME);
337 yylval.subcmd = makesubcmd(c);
338 return(c);
342 any(c, str)
343 register int c;
344 register char *str;
346 while (*str)
347 if (c == *str++)
348 return(1);
349 return(0);
353 * Insert or append ARROW command to list of hosts to be updated.
355 void
356 insert(label, files, hosts, subcmds)
357 char *label;
358 struct namelist *files, *hosts;
359 struct subcmd *subcmds;
361 register struct cmd *c, *prev, *nc;
362 register struct namelist *h, *oldh;
364 files = expand(files, E_VARS|E_SHELL);
365 hosts = expand(hosts, E_ALL);
366 if (debug) {
367 printf("insert: files = ");
368 prnames(files);
369 printf("insert: hosts = ");
370 prnames(hosts);
371 if (cmds)
372 prcmd(cmds);
373 else
374 printf("insert: cmds NULL\n");
376 for (h = hosts; h != NULL; oldh = h, h = h->n_next, free(oldh)) {
378 * Search command list for an update to the same host.
380 for (prev = NULL, c = cmds; c!=NULL; prev = c, c = c->c_next) {
381 if (strcmp(c->c_name, h->n_name) == 0) {
382 do {
383 prev = c;
384 c = c->c_next;
385 } while (c != NULL &&
386 strcmp(c->c_name, h->n_name) == 0);
387 break;
391 * Insert new command to update host.
393 nc = ALLOC(cmd);
394 if (nc == NULL)
395 fatal("ran out of memory\n");
396 nc->c_type = ARROW;
397 nc->c_name = h->n_name;
398 nc->c_label = label;
399 nc->c_files = files;
400 nc->c_cmds = subcmds;
401 nc->c_next = c;
402 if (prev == NULL)
403 cmds = nc;
404 else
405 prev->c_next = nc;
406 /* update last_cmd if appending nc to cmds */
407 if (c == NULL)
408 last_cmd = nc;
413 * Append DCOLON command to the end of the command list since these are always
414 * executed in the order they appear in the distfile.
416 static void
417 append(label, files, stamp, subcmds)
418 char *label;
419 struct namelist *files;
420 char *stamp;
421 struct subcmd *subcmds;
423 register struct cmd *c;
425 c = ALLOC(cmd);
426 if (c == NULL)
427 fatal("ran out of memory\n");
428 c->c_type = DCOLON;
429 c->c_name = stamp;
430 c->c_label = label;
431 c->c_files = expand(files, E_ALL);
432 c->c_cmds = subcmds;
433 c->c_next = NULL;
434 if (cmds == NULL)
435 cmds = last_cmd = c;
436 else {
437 last_cmd->c_next = c;
438 last_cmd = c;
443 * Error printing routine in parser.
445 void
446 yyerror(s)
447 char *s;
449 extern int yychar;
451 nerrs++;
452 fflush(stdout);
453 fprintf(stderr, "rdist: line %d: %s\n", yylineno, s);
457 * Return a copy of the string.
459 char *
460 makestr(str)
461 char *str;
463 register char *cp, *s;
465 str = cp = malloc(strlen(s = str) + 1);
466 if (cp == NULL)
467 fatal("ran out of memory\n");
468 while (*cp++ = *s++)
470 return(str);
474 * Allocate a namelist structure.
476 struct namelist *
477 makenl(name)
478 char *name;
480 register struct namelist *nl;
482 nl = ALLOC(namelist);
483 if (nl == NULL)
484 fatal("ran out of memory\n");
485 nl->n_name = name;
486 nl->n_next = NULL;
487 return(nl);
491 * Duplicate an existing namelist structure. Only used by the PATTERN
492 * code, and then only because expand() is destructive.
494 struct namelist *
495 dupnl(old)
496 struct namelist *old;
498 struct namelist *n;
499 struct namelist *new, *newhead = (struct namelist *) NULL;
500 struct namelist *prev = (struct namelist *) NULL;
502 for (n = old; n; n = n->n_next) {
503 new = ALLOC(namelist);
504 if (new == (struct namelist *) NULL)
505 fatal("ran out of memory\n");
506 if (newhead == (struct namelist *) NULL)
507 newhead = new;
508 if (n->n_name) {
509 if ((new->n_name = strdup(n->n_name)) == (char *) NULL)
510 fatal("ran out of memory\n");
511 } else
512 new->n_name = (char *) NULL;
513 if (prev)
514 prev->n_next = new;
515 prev = new;
517 if (prev)
518 prev->n_next = (struct namelist *) NULL;
520 return (newhead);
524 * Make a sub command for lists of variables, commands, etc.
526 struct subcmd *
527 makesubcmd(type, name)
528 int type;
529 register char *name;
531 register char *cp;
532 register struct subcmd *sc;
534 sc = ALLOC(subcmd);
535 if (sc == NULL)
536 fatal("ran out of memory\n");
537 sc->sc_type = type;
538 sc->sc_args = NULL;
539 sc->sc_next = NULL;
540 sc->sc_name = NULL;
541 return(sc);