added -r option to remove extra files.
[unix-history] / usr / src / usr.bin / rdist / gram.y
CommitLineData
d0dc5e26
RC
1%{
2#ifndef lint
d1dee8e8 3static char *sccsid = "@(#)gram.y 4.5 (Berkeley) 83/10/20";
d0dc5e26
RC
4#endif
5
6#include "defs.h"
7
82572cb6
RC
8struct block *lastn;
9struct block *lastc;
d0dc5e26
RC
10
11%}
12
13%term EQUAL 1
82572cb6
RC
14%term LP 2
15%term RP 3
d1dee8e8
RC
16%term SM 4
17%term ARROW 5
18%term DCOLON 6
19%term NAME 7
20%term INSTALL 8
21%term NOTIFY 9
22%term EXCEPT 10
23%term OPTION 11
d0dc5e26 24
3024eb6f 25%union {
d0dc5e26 26 struct block *blk;
3024eb6f
RC
27 int intval;
28}
d0dc5e26 29
d1dee8e8
RC
30%type <blk> NAME, INSTALL, NOTIFY, EXCEPT
31%type <blk> namelist, names, opt_name, cmdlist, cmd
3024eb6f 32%type <intval> OPTION, options
d0dc5e26
RC
33
34%%
35
36file: /* VOID */
37 | file command
38 ;
39
40command: NAME EQUAL namelist = {
41 $1->b_args = $3;
82572cb6 42 (void) lookup($1->b_name, $1, 1);
d0dc5e26
RC
43 }
44 | namelist ARROW namelist cmdlist = {
82572cb6
RC
45 dohcmds($1, $3, $4);
46 }
47 | namelist DCOLON namelist cmdlist = {
48 dofcmds($1, $3, $4);
d0dc5e26
RC
49 }
50 | error
51 ;
52
53namelist: NAME = {
54 $$ = $1;
55 }
56 | LP names RP = {
57 $$ = $2;
58 }
59 ;
60
61names: /* VOID */ {
82572cb6 62 $$ = lastn = NULL;
d0dc5e26
RC
63 }
64 | names NAME = {
82572cb6
RC
65 if (lastn == NULL)
66 $$ = lastn = $2;
d0dc5e26 67 else {
82572cb6
RC
68 lastn->b_next = $2;
69 lastn = $2;
d0dc5e26
RC
70 $$ = $1;
71 }
72 }
73 ;
74
75cmdlist: /* VOID */ {
82572cb6 76 $$ = lastc = NULL;
d0dc5e26
RC
77 }
78 | cmdlist cmd = {
82572cb6
RC
79 if (lastc == NULL)
80 $$ = lastc = $2;
d0dc5e26 81 else {
82572cb6
RC
82 lastc->b_next = $2;
83 lastc = $2;
d0dc5e26
RC
84 $$ = $1;
85 }
86 }
87 ;
88
d1dee8e8 89cmd: INSTALL options opt_name SM = {
82572cb6
RC
90 register struct block *b;
91
f7770429 92 $1->b_options = $2 | options;
d1dee8e8
RC
93 if ($3 != NULL) {
94 b = expand($3, 0);
95 if (b->b_next != NULL)
96 fatal("exactly one name allowed\n");
97 $1->b_name = b->b_name;
98 }
d0dc5e26
RC
99 $$ = $1;
100 }
d1dee8e8 101 | NOTIFY namelist SM = {
82572cb6 102 $1->b_args = expand($2, 1);
d0dc5e26
RC
103 $$ = $1;
104 }
d1dee8e8 105 | EXCEPT namelist SM = {
82572cb6 106 $1->b_args = expand($2, 0);
d0dc5e26
RC
107 $$ = $1;
108 }
109 ;
d1dee8e8 110
3024eb6f
RC
111options: /* VOID */ = {
112 $$ = 0;
113 }
114 | options OPTION = {
115 $$ |= $2;
116 }
117 ;
d0dc5e26 118
d1dee8e8
RC
119opt_name: /* VOID */ = {
120 $$ = NULL;
121 }
122 | NAME = {
123 $$ = $1;
124 }
125 ;
126
d0dc5e26
RC
127%%
128
129int yylineno = 1;
130extern FILE *fin;
131
132yylex()
133{
134 static char yytext[INMAX];
135 register int c;
136 register char *cp1, *cp2;
3024eb6f 137 static char quotechars[] = "[]{}*?$";
d0dc5e26 138
82572cb6
RC
139again:
140 switch (c = getc(fin)) {
141 case EOF: /* end of file */
142 return(0);
143
144 case '#': /* start of comment */
145 while ((c = getc(fin)) != EOF && c != '\n')
146 ;
147 if (c == EOF)
d0dc5e26 148 return(0);
82572cb6
RC
149 case '\n':
150 yylineno++;
151 case ' ':
152 case '\t': /* skip blanks */
153 goto again;
154
155 case '=': /* EQUAL */
156 return(EQUAL);
157
158 case '(': /* LP */
159 return(LP);
160
161 case ')': /* RP */
162 return(RP);
163
d1dee8e8
RC
164 case ';': /* SM */
165 return(SM);
166
82572cb6
RC
167 case '-': /* -> */
168 if ((c = getc(fin)) == '>')
169 return(ARROW);
170 ungetc(c, fin);
171 c = '-';
172 break;
173
174 case ':': /* :: */
175 if ((c = getc(fin)) == ':')
176 return(DCOLON);
177 ungetc(c, fin);
178 c = ':';
179 }
82572cb6
RC
180 cp1 = yytext;
181 cp2 = &yytext[INMAX - 1];
182 for (;;) {
183 if (cp1 >= cp2) {
184 fatal("input line too long\n");
185 break;
186 }
187 if (c == '\\') {
188 if ((c = getc(fin)) != EOF) {
189 if (any(c, quotechars))
190 c |= QUOTE;
191 } else {
192 *cp1++ = '\\';
d0dc5e26
RC
193 break;
194 }
195 }
82572cb6
RC
196 *cp1++ = c;
197 c = getc(fin);
d1dee8e8 198 if (c == EOF || any(c, " \t()=;\n")) {
82572cb6
RC
199 ungetc(c, fin);
200 break;
201 }
d0dc5e26 202 }
82572cb6 203 *cp1 = '\0';
3024eb6f
RC
204 if (yytext[0] == '-' && yytext[2] == '\0') {
205 switch (yytext[1]) {
d1dee8e8
RC
206 case 'r':
207 yylval.intval = REMOVE;
208 return(OPTION);
209
3024eb6f
RC
210 case 'v':
211 yylval.intval = VERIFY;
212 return(OPTION);
213
214 case 'w':
215 yylval.intval = WHOLE;
216 return(OPTION);
217
218 case 'y':
219 yylval.intval = YOUNGER;
220 return(OPTION);
221 }
222 }
82572cb6
RC
223 if (!strcmp(yytext, "install"))
224 c = INSTALL;
82572cb6
RC
225 else if (!strcmp(yytext, "notify"))
226 c = NOTIFY;
227 else if (!strcmp(yytext, "except"))
228 c = EXCEPT;
229 else
230 c = NAME;
3024eb6f 231 yylval.blk = makeblock(c, yytext);
82572cb6 232 return(c);
d0dc5e26
RC
233}
234
235any(c, str)
236 register int c;
237 register char *str;
238{
239 while (*str)
240 if (c == *str++)
241 return(1);
242 return(0);
243}
244
245/*
246 * Error printing routine in parser.
247 */
248yyerror(s)
249 char *s;
250{
251 extern int yychar;
252
d1dee8e8 253 errs++;
d0dc5e26
RC
254 fprintf(stderr, "rdist: line %d: %s\n", yylineno, s);
255}