GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/rdist/gram.c Lines: 0 176 0.0 %
Date: 2017-11-07 Branches: 0 142 0.0 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#define YYBYACC 1
4
#define YYMAJOR 1
5
#define YYMINOR 9
6
#define YYLEX yylex()
7
#define YYEMPTY -1
8
#define yyclearin (yychar=(YYEMPTY))
9
#define yyerrok (yyerrflag=0)
10
#define YYRECOVERING() (yyerrflag!=0)
11
#define YYPREFIX "yy"
12
#line 2 "gram.y"
13
/*	$OpenBSD: gram.y,v 1.12 2015/01/20 09:00:16 guenther Exp $	*/
14
15
/*
16
 * Copyright (c) 1993 Michael A. Cooper
17
 * Copyright (c) 1993 Regents of the University of California.
18
 * All rights reserved.
19
 *
20
 * Redistribution and use in source and binary forms, with or without
21
 * modification, are permitted provided that the following conditions
22
 * are met:
23
 * 1. Redistributions of source code must retain the above copyright
24
 *    notice, this list of conditions and the following disclaimer.
25
 * 2. Redistributions in binary form must reproduce the above copyright
26
 *    notice, this list of conditions and the following disclaimer in the
27
 *    documentation and/or other materials provided with the distribution.
28
 * 3. Neither the name of the University nor the names of its contributors
29
 *    may be used to endorse or promote products derived from this software
30
 *    without specific prior written permission.
31
 *
32
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
33
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
36
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42
 * SUCH DAMAGE.
43
 */
44
45
#include "client.h"
46
47
static struct namelist *addnl(struct namelist *, struct namelist *);
48
static struct namelist *subnl(struct namelist *, struct namelist *);
49
static struct namelist *andnl(struct namelist *, struct namelist *);
50
static int innl(struct namelist *nl, char *p);
51
52
struct	cmd *cmds = NULL;
53
struct	cmd *last_cmd;
54
struct	namelist *last_n;
55
struct	subcmd *last_sc;
56
int	parendepth = 0;
57
58
#line 62 "gram.y"
59
#ifndef YYSTYPE_DEFINED
60
#define YYSTYPE_DEFINED
61
typedef union {
62
	opt_t 			optval;
63
	char 		       *string;
64
	struct subcmd 	       *subcmd;
65
	struct namelist        *namel;
66
} YYSTYPE;
67
#endif /* YYSTYPE_DEFINED */
68
#line 69 "gram.c"
69
#define ARROW 1
70
#define COLON 2
71
#define DCOLON 3
72
#define NAME 4
73
#define STRING 5
74
#define INSTALL 6
75
#define NOTIFY 7
76
#define EXCEPT 8
77
#define PATTERN 9
78
#define SPECIAL 10
79
#define CMDSPECIAL 11
80
#define OPTION 12
81
#define YYERRCODE 256
82
const short yylhs[] =
83
	{                                        -1,
84
    0,    0,    8,    8,    8,    8,    8,    8,    4,    4,
85
    4,    4,    7,    7,    5,    5,    2,    2,    3,    3,
86
    3,    3,    3,    3,    1,    1,    6,    6,
87
};
88
const short yylen[] =
89
	{                                         2,
90
    0,    2,    3,    4,    6,    4,    6,    1,    1,    3,
91
    3,    3,    1,    3,    0,    2,    0,    2,    4,    3,
92
    3,    3,    4,    4,    0,    2,    0,    1,
93
};
94
const short yydefred[] =
95
	{                                      1,
96
    0,    8,    0,   15,    0,    0,    2,    0,    0,    0,
97
    0,    0,    0,    0,    0,   13,    0,    3,   16,   14,
98
   17,   17,   10,   11,   12,    0,    0,    0,    0,   17,
99
   17,   25,    0,    0,    0,    0,    0,   18,    0,    0,
100
    0,    0,    0,    0,   28,    0,    0,   26,    0,   20,
101
   21,   22,    0,    0,   19,   23,   24,
102
};
103
const short yydgoto[] =
104
	{                                       1,
105
   41,   28,   38,   45,   10,   46,    6,    7,
106
};
107
const short yysindex[] =
108
	{                                      0,
109
   -4,    0,   19,    0,   70,  -15,    0,   23,   23,   -1,
110
   23,   28,   23,   23,   23,    0,   76,    0,    0,    0,
111
    0,    0,    0,    0,    0,   23,   29,   37,   37,    0,
112
    0,    0,   23,   23,   23,   23,   23,    0,   37,   37,
113
   22,  -34,  -20,   -8,    0,   52,   53,    0,    2,    0,
114
    0,    0,    6,   24,    0,    0,    0,};
115
const short yyrindex[] =
116
	{                                      0,
117
    0,    0,   21,    0,    0,    1,    0,    0,    0,    0,
118
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
119
    0,    0,    0,    0,    0,    0,    0,   13,   14,    0,
120
    0,    0,    0,    0,    0,   67,   67,    0,   15,   16,
121
   25,    0,    0,    0,    0,    0,    0,    0,    0,    0,
122
    0,    0,    0,    0,    0,    0,    0,};
123
const short yygindex[] =
124
	{                                      0,
125
    0,    7,    0,   41,    0,   -6,   55,    0,
126
};
127
#define YYTABLESIZE 272
128
const short yytable[] =
129
	{                                       3,
130
    9,    9,   19,    9,    9,    9,    9,    9,    9,    9,
131
    9,    9,    4,    6,    5,    7,    4,    6,    5,    7,
132
    8,   13,   15,   13,   50,   16,   16,   14,   29,   13,
133
   47,   22,   31,   48,   49,    4,   39,   40,   51,   20,
134
    9,    5,   32,   33,   34,   35,   36,   37,   17,   18,
135
   52,   21,    4,    6,    5,    7,   53,   54,   13,    9,
136
   55,    4,    4,   13,   56,   13,   30,   23,   24,   25,
137
   11,   27,   12,   42,   43,   44,   26,    0,   27,    9,
138
    0,    0,   57,   27,    0,    0,    0,    0,    0,    0,
139
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
140
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
141
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
142
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
143
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
144
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
145
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
146
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
147
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
148
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
149
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
150
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
151
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
152
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
153
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
154
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
155
    0,    2,    0,    0,    0,    0,    9,    0,    0,    0,
156
    0,    0,    0,    0,    0,    0,    0,    0,    4,    6,
157
    5,    7,
158
};
159
const short yycheck[] =
160
	{                                       4,
161
    0,    1,    4,    3,    4,    5,    6,    7,    8,    9,
162
   10,   11,    0,    0,    0,    0,    4,    4,    4,    4,
163
    2,    1,   38,    3,   59,    4,    4,   43,   22,   45,
164
   37,    4,    4,   12,   41,   40,   30,   31,   59,   41,
165
   40,    1,    6,    7,    8,    9,   10,   11,    8,    9,
166
   59,   11,   40,   40,   40,   40,    5,    5,   38,   59,
167
   59,   40,   40,   43,   59,   45,   26,   13,   14,   15,
168
    1,    5,    3,   33,   34,   35,    1,   -1,    3,   61,
169
   -1,   -1,   59,   59,   -1,   -1,   -1,   -1,   -1,   -1,
170
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
171
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
172
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
173
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
174
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
175
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
176
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
177
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
178
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
179
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
180
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
181
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
182
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
183
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
184
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
185
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
186
   -1,  256,   -1,   -1,   -1,   -1,  256,   -1,   -1,   -1,
187
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  256,  256,
188
  256,  256,
189
};
190
#define YYFINAL 1
191
#ifndef YYDEBUG
192
#define YYDEBUG 0
193
#endif
194
#define YYMAXTOKEN 61
195
#if YYDEBUG
196
const char * const yyname[] =
197
	{
198
"end-of-file","ARROW","COLON","DCOLON","NAME","STRING","INSTALL","NOTIFY",
199
"EXCEPT","PATTERN","SPECIAL","CMDSPECIAL","OPTION",0,0,0,0,0,0,0,0,0,0,0,0,0,0,
200
0,0,0,0,0,0,0,0,0,0,0,"'&'",0,"'('","')'",0,"'+'",0,"'-'",0,0,0,0,0,0,0,0,0,0,0,
201
0,0,"';'",0,"'='",
202
};
203
const char * const yyrule[] =
204
	{"$accept : file",
205
"file :",
206
"file : file command",
207
"command : NAME '=' namelist",
208
"command : namelist ARROW namelist cmdlist",
209
"command : NAME COLON namelist ARROW namelist cmdlist",
210
"command : namelist DCOLON NAME cmdlist",
211
"command : NAME COLON namelist DCOLON NAME cmdlist",
212
"command : error",
213
"namelist : nlist",
214
"namelist : nlist '-' nlist",
215
"namelist : nlist '+' nlist",
216
"namelist : nlist '&' nlist",
217
"nlist : NAME",
218
"nlist : '(' names ')'",
219
"names :",
220
"names : names NAME",
221
"cmdlist :",
222
"cmdlist : cmdlist cmd",
223
"cmd : INSTALL options opt_namelist ';'",
224
"cmd : NOTIFY namelist ';'",
225
"cmd : EXCEPT namelist ';'",
226
"cmd : PATTERN namelist ';'",
227
"cmd : SPECIAL opt_namelist STRING ';'",
228
"cmd : CMDSPECIAL opt_namelist STRING ';'",
229
"options :",
230
"options : options OPTION",
231
"opt_namelist :",
232
"opt_namelist : namelist",
233
};
234
#endif
235
#ifdef YYSTACKSIZE
236
#undef YYMAXDEPTH
237
#define YYMAXDEPTH YYSTACKSIZE
238
#else
239
#ifdef YYMAXDEPTH
240
#define YYSTACKSIZE YYMAXDEPTH
241
#else
242
#define YYSTACKSIZE 10000
243
#define YYMAXDEPTH 10000
244
#endif
245
#endif
246
#define YYINITSTACKSIZE 200
247
/* LINTUSED */
248
int yydebug;
249
int yynerrs;
250
int yyerrflag;
251
int yychar;
252
short *yyssp;
253
YYSTYPE *yyvsp;
254
YYSTYPE yyval;
255
YYSTYPE yylval;
256
short *yyss;
257
short *yysslim;
258
YYSTYPE *yyvs;
259
unsigned int yystacksize;
260
int yyparse(void);
261
#line 224 "gram.y"
262
263
int	yylineno = 1;
264
extern	FILE *fin;
265
266
int
267
yylex(void)
268
{
269
	static char yytext[INMAX];
270
	int c;
271
	char *cp1, *cp2;
272
	static char quotechars[] = "[]{}*?$";
273
274
again:
275
	switch (c = getc(fin)) {
276
	case EOF:  /* end of file */
277
		return(0);
278
279
	case '#':  /* start of comment */
280
		while ((c = getc(fin)) != EOF && c != '\n')
281
			;
282
		if (c == EOF)
283
			return(0);
284
	case '\n':
285
		yylineno++;
286
	case ' ':
287
	case '\t':  /* skip blanks */
288
		goto again;
289
290
	case '=':  /* EQUAL */
291
	case ';':  /* SM */
292
	case '+':
293
	case '&':
294
		return(c);
295
296
	case '(':  /* LP */
297
		++parendepth;
298
		return(c);
299
300
	case ')':  /* RP */
301
		--parendepth;
302
		return(c);
303
304
	case '-':  /* -> */
305
		if ((c = getc(fin)) == '>')
306
			return(ARROW);
307
		(void) ungetc(c, fin);
308
		c = '-';
309
		break;
310
311
	case '"':  /* STRING */
312
		cp1 = yytext;
313
		cp2 = &yytext[INMAX - 1];
314
		for (;;) {
315
			if (cp1 >= cp2) {
316
				yyerror("command string too long\n");
317
				break;
318
			}
319
			c = getc(fin);
320
			if (c == EOF || c == '"')
321
				break;
322
			if (c == '\\') {
323
				if ((c = getc(fin)) == EOF) {
324
					*cp1++ = '\\';
325
					break;
326
				}
327
			}
328
			if (c == '\n') {
329
				yylineno++;
330
				c = ' '; /* can't send '\n' */
331
			}
332
			*cp1++ = c;
333
		}
334
		if (c != '"')
335
			yyerror("missing closing '\"'\n");
336
		*cp1 = '\0';
337
		yylval.string = xstrdup(yytext);
338
		return(STRING);
339
340
	case ':':  /* : or :: */
341
		if ((c = getc(fin)) == ':')
342
			return(DCOLON);
343
		(void) ungetc(c, fin);
344
		return(COLON);
345
	}
346
	cp1 = yytext;
347
	cp2 = &yytext[INMAX - 1];
348
	for (;;) {
349
		if (cp1 >= cp2) {
350
			yyerror("input line too long\n");
351
			break;
352
		}
353
		if (c == '\\') {
354
			if ((c = getc(fin)) != EOF) {
355
				if (any(c, quotechars))
356
					*cp1++ = QUOTECHAR;
357
			} else {
358
				*cp1++ = '\\';
359
				break;
360
			}
361
		}
362
		*cp1++ = c;
363
		c = getc(fin);
364
		if (c == EOF || any(c, " \"'\t()=;:\n")) {
365
			(void) ungetc(c, fin);
366
			break;
367
		}
368
	}
369
	*cp1 = '\0';
370
	if (yytext[0] == '-' && yytext[1] == CNULL)
371
		return '-';
372
	if (yytext[0] == '-' && parendepth <= 0) {
373
		opt_t opt = 0;
374
		static char ebuf[BUFSIZ];
375
376
		switch (yytext[1]) {
377
		case 'o':
378
			if (parsedistopts(&yytext[2], &opt, TRUE)) {
379
				(void) snprintf(ebuf, sizeof(ebuf),
380
					        "Bad distfile options \"%s\".",
381
					        &yytext[2]);
382
				yyerror(ebuf);
383
			}
384
			break;
385
386
			/*
387
			 * These options are obsoleted by -o.
388
			 */
389
		case 'b':	opt = DO_COMPARE;		break;
390
		case 'R':	opt = DO_REMOVE;		break;
391
		case 'v':	opt = DO_VERIFY;		break;
392
		case 'w':	opt = DO_WHOLE;			break;
393
		case 'y':	opt = DO_YOUNGER;		break;
394
		case 'h':	opt = DO_FOLLOW;		break;
395
		case 'i':	opt = DO_IGNLNKS;		break;
396
		case 'q':	opt = DO_QUIET;			break;
397
		case 'x':	opt = DO_NOEXEC;		break;
398
		case 'N':	opt = DO_CHKNFS;		break;
399
		case 'O':	opt = DO_CHKREADONLY;		break;
400
		case 's':	opt = DO_SAVETARGETS;		break;
401
		case 'r':	opt = DO_NODESCEND;		break;
402
403
		default:
404
			(void) snprintf(ebuf, sizeof(ebuf),
405
					"Unknown option \"%s\".", yytext);
406
			yyerror(ebuf);
407
		}
408
409
		yylval.optval = opt;
410
		return(OPTION);
411
	}
412
	if (!strcmp(yytext, "install"))
413
		c = INSTALL;
414
	else if (!strcmp(yytext, "notify"))
415
		c = NOTIFY;
416
	else if (!strcmp(yytext, "except"))
417
		c = EXCEPT;
418
	else if (!strcmp(yytext, "except_pat"))
419
		c = PATTERN;
420
	else if (!strcmp(yytext, "special"))
421
		c = SPECIAL;
422
	else if (!strcmp(yytext, "cmdspecial"))
423
		c = CMDSPECIAL;
424
	else {
425
		yylval.string = xstrdup(yytext);
426
		return(NAME);
427
	}
428
	yylval.subcmd = makesubcmd(c);
429
	return(c);
430
}
431
432
/*
433
 * XXX We should use strchr(), but most versions can't handle
434
 * some of the characters we use.
435
 */
436
int any(int c, char *str)
437
{
438
	while (*str)
439
		if (c == *str++)
440
			return(1);
441
	return(0);
442
}
443
444
/*
445
 * Insert or append ARROW command to list of hosts to be updated.
446
 */
447
void
448
insert(char *label, struct namelist *files, struct namelist *hosts,
449
    struct subcmd *scmds)
450
{
451
	struct cmd *c, *prev, *nc;
452
	struct namelist *h, *lasth;
453
454
	debugmsg(DM_CALL, "insert(%s, %p, %p, %p) start, files = %s",
455
		 label == NULL ? "(null)" : label,
456
		 files, hosts, scmds, getnlstr(files));
457
458
	files = expand(files, E_VARS|E_SHELL);
459
	hosts = expand(hosts, E_ALL);
460
	for (h = hosts; h != NULL; lasth = h, h = h->n_next,
461
	     free((char *)lasth)) {
462
		/*
463
		 * Search command list for an update to the same host.
464
		 */
465
		for (prev = NULL, c = cmds; c!=NULL; prev = c, c = c->c_next) {
466
			if (strcmp(c->c_name, h->n_name) == 0) {
467
				do {
468
					prev = c;
469
					c = c->c_next;
470
				} while (c != NULL &&
471
					strcmp(c->c_name, h->n_name) == 0);
472
				break;
473
			}
474
		}
475
		/*
476
		 * Insert new command to update host.
477
		 */
478
		nc = ALLOC(cmd);
479
		nc->c_type = ARROW;
480
		nc->c_name = h->n_name;
481
		nc->c_label = label;
482
		nc->c_files = files;
483
		nc->c_cmds = scmds;
484
		nc->c_flags = 0;
485
		nc->c_next = c;
486
		if (prev == NULL)
487
			cmds = nc;
488
		else
489
			prev->c_next = nc;
490
		/* update last_cmd if appending nc to cmds */
491
		if (c == NULL)
492
			last_cmd = nc;
493
	}
494
}
495
496
/*
497
 * Append DCOLON command to the end of the command list since these are always
498
 * executed in the order they appear in the distfile.
499
 */
500
void
501
append(char *label, struct namelist *files, char *stamp, struct subcmd *scmds)
502
{
503
	struct cmd *c;
504
505
	c = ALLOC(cmd);
506
	c->c_type = DCOLON;
507
	c->c_name = stamp;
508
	c->c_label = label;
509
	c->c_files = expand(files, E_ALL);
510
	c->c_cmds = scmds;
511
	c->c_next = NULL;
512
	if (cmds == NULL)
513
		cmds = last_cmd = c;
514
	else {
515
		last_cmd->c_next = c;
516
		last_cmd = c;
517
	}
518
}
519
520
/*
521
 * Error printing routine in parser.
522
 */
523
void
524
yyerror(char *s)
525
{
526
	error("Error in distfile: line %d: %s", yylineno, s);
527
}
528
529
/*
530
 * Allocate a namelist structure.
531
 */
532
struct namelist *
533
makenl(char *name)
534
{
535
	struct namelist *nl;
536
537
	debugmsg(DM_CALL, "makenl(%s)", name == NULL ? "null" : name);
538
539
	nl = ALLOC(namelist);
540
	nl->n_name = name;
541
	nl->n_regex = NULL;
542
	nl->n_next = NULL;
543
544
	return(nl);
545
}
546
547
548
/*
549
 * Is the name p in the namelist nl?
550
 */
551
static int
552
innl(struct namelist *nl, char *p)
553
{
554
	for ( ; nl; nl = nl->n_next)
555
		if (!strcmp(p, nl->n_name))
556
			return(1);
557
	return(0);
558
}
559
560
/*
561
 * Join two namelists.
562
 */
563
static struct namelist *
564
addnl(struct namelist *n1, struct namelist *n2)
565
{
566
	struct namelist *nl, *prev;
567
568
	n1 = expand(n1, E_VARS);
569
	n2 = expand(n2, E_VARS);
570
	for (prev = NULL, nl = NULL; n1; n1 = n1->n_next, prev = nl) {
571
		nl = makenl(n1->n_name);
572
		nl->n_next = prev;
573
	}
574
	for (; n2; n2 = n2->n_next)
575
		if (!innl(nl, n2->n_name)) {
576
			nl = makenl(n2->n_name);
577
			nl->n_next = prev;
578
			prev = nl;
579
		}
580
	return(prev);
581
}
582
583
/*
584
 * Copy n1 except for elements that are in n2.
585
 */
586
static struct namelist *
587
subnl(struct namelist *n1, struct namelist *n2)
588
{
589
	struct namelist *nl, *prev;
590
591
	n1 = expand(n1, E_VARS);
592
	n2 = expand(n2, E_VARS);
593
	for (prev = NULL; n1; n1 = n1->n_next)
594
		if (!innl(n2, n1->n_name)) {
595
			nl = makenl(n1->n_name);
596
			nl->n_next = prev;
597
			prev = nl;
598
		}
599
	return(prev);
600
}
601
602
/*
603
 * Copy all items of n1 that are also in n2.
604
 */
605
static struct namelist *
606
andnl(struct namelist *n1, struct namelist *n2)
607
{
608
	struct namelist *nl, *prev;
609
610
	n1 = expand(n1, E_VARS);
611
	n2 = expand(n2, E_VARS);
612
	for (prev = NULL; n1; n1 = n1->n_next)
613
		if (innl(n2, n1->n_name)) {
614
			nl = makenl(n1->n_name);
615
			nl->n_next = prev;
616
			prev = nl;
617
		}
618
	return(prev);
619
}
620
621
/*
622
 * Make a sub command for lists of variables, commands, etc.
623
 */
624
struct subcmd *
625
makesubcmd(int type)
626
{
627
	struct subcmd *sc;
628
629
	sc = ALLOC(subcmd);
630
	sc->sc_type = type;
631
	sc->sc_args = NULL;
632
	sc->sc_next = NULL;
633
	sc->sc_name = NULL;
634
635
	return(sc);
636
}
637
#line 630 "gram.c"
638
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
639
static int yygrowstack(void)
640
{
641
    unsigned int newsize;
642
    long sslen;
643
    short *newss;
644
    YYSTYPE *newvs;
645
646
    if ((newsize = yystacksize) == 0)
647
        newsize = YYINITSTACKSIZE;
648
    else if (newsize >= YYMAXDEPTH)
649
        return -1;
650
    else if ((newsize *= 2) > YYMAXDEPTH)
651
        newsize = YYMAXDEPTH;
652
    sslen = yyssp - yyss;
653
#ifdef SIZE_MAX
654
#define YY_SIZE_MAX SIZE_MAX
655
#else
656
#define YY_SIZE_MAX 0xffffffffU
657
#endif
658
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
659
        goto bail;
660
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
661
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
662
    if (newss == NULL)
663
        goto bail;
664
    yyss = newss;
665
    yyssp = newss + sslen;
666
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
667
        goto bail;
668
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
669
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
670
    if (newvs == NULL)
671
        goto bail;
672
    yyvs = newvs;
673
    yyvsp = newvs + sslen;
674
    yystacksize = newsize;
675
    yysslim = yyss + newsize - 1;
676
    return 0;
677
bail:
678
    if (yyss)
679
            free(yyss);
680
    if (yyvs)
681
            free(yyvs);
682
    yyss = yyssp = NULL;
683
    yyvs = yyvsp = NULL;
684
    yystacksize = 0;
685
    return -1;
686
}
687
688
#define YYABORT goto yyabort
689
#define YYREJECT goto yyabort
690
#define YYACCEPT goto yyaccept
691
#define YYERROR goto yyerrlab
692
int
693
yyparse(void)
694
{
695
    int yym, yyn, yystate;
696
#if YYDEBUG
697
    const char *yys;
698
699
    if ((yys = getenv("YYDEBUG")))
700
    {
701
        yyn = *yys;
702
        if (yyn >= '0' && yyn <= '9')
703
            yydebug = yyn - '0';
704
    }
705
#endif /* YYDEBUG */
706
707
    yynerrs = 0;
708
    yyerrflag = 0;
709
    yychar = (-1);
710
711
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
712
    yyssp = yyss;
713
    yyvsp = yyvs;
714
    *yyssp = yystate = 0;
715
716
yyloop:
717
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
718
    if (yychar < 0)
719
    {
720
        if ((yychar = yylex()) < 0) yychar = 0;
721
#if YYDEBUG
722
        if (yydebug)
723
        {
724
            yys = 0;
725
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
726
            if (!yys) yys = "illegal-symbol";
727
            printf("%sdebug: state %d, reading %d (%s)\n",
728
                    YYPREFIX, yystate, yychar, yys);
729
        }
730
#endif
731
    }
732
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
733
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
734
    {
735
#if YYDEBUG
736
        if (yydebug)
737
            printf("%sdebug: state %d, shifting to state %d\n",
738
                    YYPREFIX, yystate, yytable[yyn]);
739
#endif
740
        if (yyssp >= yysslim && yygrowstack())
741
        {
742
            goto yyoverflow;
743
        }
744
        *++yyssp = yystate = yytable[yyn];
745
        *++yyvsp = yylval;
746
        yychar = (-1);
747
        if (yyerrflag > 0)  --yyerrflag;
748
        goto yyloop;
749
    }
750
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
751
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
752
    {
753
        yyn = yytable[yyn];
754
        goto yyreduce;
755
    }
756
    if (yyerrflag) goto yyinrecovery;
757
#if defined(__GNUC__)
758
    goto yynewerror;
759
#endif
760
yynewerror:
761
    yyerror("syntax error");
762
#if defined(__GNUC__)
763
    goto yyerrlab;
764
#endif
765
yyerrlab:
766
    ++yynerrs;
767
yyinrecovery:
768
    if (yyerrflag < 3)
769
    {
770
        yyerrflag = 3;
771
        for (;;)
772
        {
773
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
774
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
775
            {
776
#if YYDEBUG
777
                if (yydebug)
778
                    printf("%sdebug: state %d, error recovery shifting\
779
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
780
#endif
781
                if (yyssp >= yysslim && yygrowstack())
782
                {
783
                    goto yyoverflow;
784
                }
785
                *++yyssp = yystate = yytable[yyn];
786
                *++yyvsp = yylval;
787
                goto yyloop;
788
            }
789
            else
790
            {
791
#if YYDEBUG
792
                if (yydebug)
793
                    printf("%sdebug: error recovery discarding state %d\n",
794
                            YYPREFIX, *yyssp);
795
#endif
796
                if (yyssp <= yyss) goto yyabort;
797
                --yyssp;
798
                --yyvsp;
799
            }
800
        }
801
    }
802
    else
803
    {
804
        if (yychar == 0) goto yyabort;
805
#if YYDEBUG
806
        if (yydebug)
807
        {
808
            yys = 0;
809
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
810
            if (!yys) yys = "illegal-symbol";
811
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
812
                    YYPREFIX, yystate, yychar, yys);
813
        }
814
#endif
815
        yychar = (-1);
816
        goto yyloop;
817
    }
818
yyreduce:
819
#if YYDEBUG
820
    if (yydebug)
821
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
822
                YYPREFIX, yystate, yyn, yyrule[yyn]);
823
#endif
824
    yym = yylen[yyn];
825
    if (yym)
826
        yyval = yyvsp[1-yym];
827
    else
828
        memset(&yyval, 0, sizeof yyval);
829
    switch (yyn)
830
    {
831
case 3:
832
#line 80 "gram.y"
833
 {
834
			(void) lookup(yyvsp[-2].string, INSERT, yyvsp[0].namel);
835
		}
836
break;
837
case 4:
838
#line 83 "gram.y"
839
 {
840
			insert((char *)NULL, yyvsp[-3].namel, yyvsp[-1].namel, yyvsp[0].subcmd);
841
		}
842
break;
843
case 5:
844
#line 86 "gram.y"
845
 {
846
			insert(yyvsp[-5].string, yyvsp[-3].namel, yyvsp[-1].namel, yyvsp[0].subcmd);
847
		}
848
break;
849
case 6:
850
#line 89 "gram.y"
851
 {
852
			append((char *)NULL, yyvsp[-3].namel, yyvsp[-1].string, yyvsp[0].subcmd);
853
		}
854
break;
855
case 7:
856
#line 92 "gram.y"
857
 {
858
			append(yyvsp[-5].string, yyvsp[-3].namel, yyvsp[-1].string, yyvsp[0].subcmd);
859
		}
860
break;
861
case 9:
862
#line 98 "gram.y"
863
{
864
			yyval.namel = yyvsp[0].namel;
865
		}
866
break;
867
case 10:
868
#line 101 "gram.y"
869
{
870
			yyval.namel = subnl(yyvsp[-2].namel, yyvsp[0].namel);
871
		}
872
break;
873
case 11:
874
#line 104 "gram.y"
875
{
876
			yyval.namel = addnl(yyvsp[-2].namel, yyvsp[0].namel);
877
		}
878
break;
879
case 12:
880
#line 107 "gram.y"
881
{
882
			yyval.namel = andnl(yyvsp[-2].namel, yyvsp[0].namel);
883
		}
884
break;
885
case 13:
886
#line 112 "gram.y"
887
 {
888
			yyval.namel = makenl(yyvsp[0].string);
889
		}
890
break;
891
case 14:
892
#line 115 "gram.y"
893
 {
894
			yyval.namel = yyvsp[-1].namel;
895
		}
896
break;
897
case 15:
898
#line 120 "gram.y"
899
{
900
			yyval.namel = last_n = NULL;
901
		}
902
break;
903
case 16:
904
#line 123 "gram.y"
905
 {
906
			if (last_n == NULL)
907
				yyval.namel = last_n = makenl(yyvsp[0].string);
908
			else {
909
				last_n->n_next = makenl(yyvsp[0].string);
910
				last_n = last_n->n_next;
911
				yyval.namel = yyvsp[-1].namel;
912
			}
913
		}
914
break;
915
case 17:
916
#line 134 "gram.y"
917
{
918
			yyval.subcmd = last_sc = NULL;
919
		}
920
break;
921
case 18:
922
#line 137 "gram.y"
923
 {
924
			if (last_sc == NULL)
925
				yyval.subcmd = last_sc = yyvsp[0].subcmd;
926
			else {
927
				last_sc->sc_next = yyvsp[0].subcmd;
928
				last_sc = yyvsp[0].subcmd;
929
				yyval.subcmd = yyvsp[-1].subcmd;
930
			}
931
		}
932
break;
933
case 19:
934
#line 148 "gram.y"
935
 {
936
			struct namelist *nl;
937
938
			yyvsp[-3].subcmd->sc_options = yyvsp[-2].optval | options;
939
			if (yyvsp[-1].namel != NULL) {
940
				nl = expand(yyvsp[-1].namel, E_VARS);
941
				if (nl) {
942
					if (nl->n_next != NULL)
943
					    yyerror("only one name allowed\n");
944
					yyvsp[-3].subcmd->sc_name = nl->n_name;
945
					free(nl);
946
				} else
947
					yyvsp[-3].subcmd->sc_name = NULL;
948
			}
949
			yyval.subcmd = yyvsp[-3].subcmd;
950
		}
951
break;
952
case 20:
953
#line 164 "gram.y"
954
 {
955
			if (yyvsp[-1].namel != NULL)
956
				yyvsp[-2].subcmd->sc_args = expand(yyvsp[-1].namel, E_VARS);
957
			yyval.subcmd = yyvsp[-2].subcmd;
958
		}
959
break;
960
case 21:
961
#line 169 "gram.y"
962
 {
963
			if (yyvsp[-1].namel != NULL)
964
				yyvsp[-2].subcmd->sc_args = expand(yyvsp[-1].namel, E_ALL);
965
			yyval.subcmd = yyvsp[-2].subcmd;
966
		}
967
break;
968
case 22:
969
#line 174 "gram.y"
970
 {
971
			struct namelist *nl;
972
			char ebuf[BUFSIZ];
973
			regex_t reg;
974
			int ecode;
975
976
			for (nl = yyvsp[-1].namel; nl != NULL; nl = nl->n_next) {
977
				/* check for a valid regex */
978
				ecode = regcomp(&reg, nl->n_name, REG_NOSUB);
979
				if (ecode) {
980
					regerror(ecode, &reg, ebuf,
981
					    sizeof(ebuf));
982
					yyerror(ebuf);
983
				}
984
				regfree(&reg);
985
			}
986
			yyvsp[-2].subcmd->sc_args = expand(yyvsp[-1].namel, E_VARS);
987
			yyval.subcmd = yyvsp[-2].subcmd;
988
		}
989
break;
990
case 23:
991
#line 193 "gram.y"
992
 {
993
			if (yyvsp[-2].namel != NULL)
994
				yyvsp[-3].subcmd->sc_args = expand(yyvsp[-2].namel, E_ALL);
995
			yyvsp[-3].subcmd->sc_name = yyvsp[-1].string;
996
			yyval.subcmd = yyvsp[-3].subcmd;
997
		}
998
break;
999
case 24:
1000
#line 199 "gram.y"
1001
 {
1002
			if (yyvsp[-2].namel != NULL)
1003
				yyvsp[-3].subcmd->sc_args = expand(yyvsp[-2].namel, E_ALL);
1004
			yyvsp[-3].subcmd->sc_name = yyvsp[-1].string;
1005
			yyval.subcmd = yyvsp[-3].subcmd;
1006
		}
1007
break;
1008
case 25:
1009
#line 207 "gram.y"
1010
 {
1011
			yyval.optval = 0;
1012
		}
1013
break;
1014
case 26:
1015
#line 210 "gram.y"
1016
 {
1017
			yyval.optval |= yyvsp[0].optval;
1018
		}
1019
break;
1020
case 27:
1021
#line 215 "gram.y"
1022
 {
1023
			yyval.namel = NULL;
1024
		}
1025
break;
1026
case 28:
1027
#line 218 "gram.y"
1028
 {
1029
			yyval.namel = yyvsp[0].namel;
1030
		}
1031
break;
1032
#line 1025 "gram.c"
1033
    }
1034
    yyssp -= yym;
1035
    yystate = *yyssp;
1036
    yyvsp -= yym;
1037
    yym = yylhs[yyn];
1038
    if (yystate == 0 && yym == 0)
1039
    {
1040
#if YYDEBUG
1041
        if (yydebug)
1042
            printf("%sdebug: after reduction, shifting from state 0 to\
1043
 state %d\n", YYPREFIX, YYFINAL);
1044
#endif
1045
        yystate = YYFINAL;
1046
        *++yyssp = YYFINAL;
1047
        *++yyvsp = yyval;
1048
        if (yychar < 0)
1049
        {
1050
            if ((yychar = yylex()) < 0) yychar = 0;
1051
#if YYDEBUG
1052
            if (yydebug)
1053
            {
1054
                yys = 0;
1055
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1056
                if (!yys) yys = "illegal-symbol";
1057
                printf("%sdebug: state %d, reading %d (%s)\n",
1058
                        YYPREFIX, YYFINAL, yychar, yys);
1059
            }
1060
#endif
1061
        }
1062
        if (yychar == 0) goto yyaccept;
1063
        goto yyloop;
1064
    }
1065
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1066
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1067
        yystate = yytable[yyn];
1068
    else
1069
        yystate = yydgoto[yym];
1070
#if YYDEBUG
1071
    if (yydebug)
1072
        printf("%sdebug: after reduction, shifting from state %d \
1073
to state %d\n", YYPREFIX, *yyssp, yystate);
1074
#endif
1075
    if (yyssp >= yysslim && yygrowstack())
1076
    {
1077
        goto yyoverflow;
1078
    }
1079
    *++yyssp = yystate;
1080
    *++yyvsp = yyval;
1081
    goto yyloop;
1082
yyoverflow:
1083
    yyerror("yacc stack overflow");
1084
yyabort:
1085
    if (yyss)
1086
            free(yyss);
1087
    if (yyvs)
1088
            free(yyvs);
1089
    yyss = yyssp = NULL;
1090
    yyvs = yyvsp = NULL;
1091
    yystacksize = 0;
1092
    return (1);
1093
yyaccept:
1094
    if (yyss)
1095
            free(yyss);
1096
    if (yyvs)
1097
            free(yyvs);
1098
    yyss = yyssp = NULL;
1099
    yyvs = yyvsp = NULL;
1100
    yystacksize = 0;
1101
    return (0);
1102
}