GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: bin/chio/parse.c Lines: 0 111 0.0 %
Date: 2017-11-07 Branches: 0 103 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 24 "parse.y"
13
#include <sys/types.h>
14
#include <sys/socket.h>
15
#include <sys/queue.h>
16
17
#include <ctype.h>
18
#include <err.h>
19
#include <libgen.h>
20
#include <limits.h>
21
#include <stdarg.h>
22
#include <stdio.h>
23
#include <string.h>
24
25
TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
26
static struct file {
27
	TAILQ_ENTRY(file)	 entry;
28
	FILE			*stream;
29
	char			*name;
30
	int			 lineno;
31
	int			 errors;
32
} *file, *topfile;
33
struct file	*pushfile(const char *);
34
int		 popfile(void);
35
int		 yyparse(void);
36
int		 yylex(void);
37
int		 yyerror(const char *, ...)
38
    __attribute__((__format__ (printf, 1, 2)))
39
    __attribute__((__nonnull__ (1)));
40
int		 kw_cmp(const void *, const void *);
41
int		 lookup(char *);
42
int		 lgetc(int);
43
int		 lungetc(int);
44
int		 findeol(void);
45
char		*parse_tapedev(const char *, const char *, int);
46
struct changer	*new_changer(char *);
47
48
struct changer {
49
	TAILQ_ENTRY(changer)	  entry;
50
	char			 *name;
51
	char			**drives;
52
	u_int			  drivecnt;
53
};
54
TAILQ_HEAD(changers, changer)	 changers;
55
struct changer			*curchanger;
56
57
typedef struct {
58
	union {
59
		int64_t			 number;
60
		char			*string;
61
	} v;
62
	int lineno;
63
} YYSTYPE;
64
65
#line 66 "parse.c"
66
#define CHANGER 257
67
#define DRIVE 258
68
#define ERROR 259
69
#define STRING 260
70
#define NUMBER 261
71
#define YYERRCODE 256
72
const short yylhs[] =
73
	{                                        -1,
74
    0,    0,    0,    0,    2,    2,    3,    5,    1,    4,
75
    4,    6,    6,    7,
76
};
77
const short yylen[] =
78
	{                                         2,
79
    0,    2,    3,    3,    2,    0,    2,    0,    8,    2,
80
    1,    2,    2,    2,
81
};
82
const short yydefred[] =
83
	{                                      1,
84
    0,    0,    0,    2,    0,    4,    0,    3,    0,    0,
85
    5,    0,    8,    0,    0,    0,    0,   11,    0,    0,
86
   13,   14,    9,   10,   12,    7,
87
};
88
const short yydgoto[] =
89
	{                                       1,
90
    5,   10,   21,   17,   14,   18,   19,
91
};
92
const short yysindex[] =
93
	{                                      0,
94
  -10,    2, -255,    0,    3,    0,    4,    0,    4, -107,
95
    0,    4,    0, -248,    7, -242, -123,    0,    7,    4,
96
    0,    0,    0,    0,    0,    0,};
97
const short yyrindex[] =
98
	{                                      0,
99
    0,    0,    0,    0,    0,    0, -104,    0, -122,    0,
100
    0, -247,    0,    0,    0,    0,    0,    0,    0, -119,
101
    0,    0,    0,    0,    0,    0,};
102
const short yygindex[] =
103
	{                                      0,
104
    0,   -5,    1,    0,    0,    5,    0,
105
};
106
#define YYTABLESIZE 247
107
const short yytable[] =
108
	{                                       4,
109
    6,   23,    6,   11,    7,    6,   13,   15,    6,   16,
110
    6,    6,    8,    9,   26,   12,   20,   22,    6,   25,
111
    0,   24,    0,    0,    0,    0,    0,    0,    0,    0,
112
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
113
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
114
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
115
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
116
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
117
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
118
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
119
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
120
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
121
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
122
    0,    0,   15,    6,   16,    6,    6,    0,    6,    0,
123
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
124
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
125
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
126
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
127
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
128
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
129
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
130
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
131
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
132
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
133
    0,    0,    0,    0,    0,    2,    3,
134
};
135
const short yycheck[] =
136
	{                                      10,
137
  123,  125,  125,    9,  260,  125,   12,  256,  256,  258,
138
  258,   10,   10,   10,   20,  123,   10,  260,  123,   19,
139
   -1,   17,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
140
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
141
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
142
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
143
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
144
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
145
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
146
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
147
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
148
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
149
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
150
   -1,   -1,  256,  256,  258,  258,  256,   -1,  258,   -1,
151
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
152
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
153
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
154
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
155
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
156
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
157
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
158
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
159
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
160
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
161
   -1,   -1,   -1,   -1,   -1,  256,  257,
162
};
163
#define YYFINAL 1
164
#ifndef YYDEBUG
165
#define YYDEBUG 0
166
#endif
167
#define YYMAXTOKEN 261
168
#if YYDEBUG
169
const char * const yyname[] =
170
	{
171
"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
172
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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
173
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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
174
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,0,0,0,0,0,0,0,0,0,
175
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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
176
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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
177
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,0,0,0,0,0,"CHANGER","DRIVE",
178
"ERROR","STRING","NUMBER",
179
};
180
const char * const yyrule[] =
181
	{"$accept : grammar",
182
"grammar :",
183
"grammar : grammar '\\n'",
184
"grammar : grammar main '\\n'",
185
"grammar : grammar error '\\n'",
186
"optnl : '\\n' optnl",
187
"optnl :",
188
"nl : '\\n' optnl",
189
"$$1 :",
190
"main : CHANGER STRING optnl '{' optnl $$1 changeropts_l '}'",
191
"changeropts_l : changeropts_l changeroptsl",
192
"changeropts_l : changeroptsl",
193
"changeroptsl : changeropts nl",
194
"changeroptsl : error nl",
195
"changeropts : DRIVE STRING",
196
};
197
#endif
198
#ifdef YYSTACKSIZE
199
#undef YYMAXDEPTH
200
#define YYMAXDEPTH YYSTACKSIZE
201
#else
202
#ifdef YYMAXDEPTH
203
#define YYSTACKSIZE YYMAXDEPTH
204
#else
205
#define YYSTACKSIZE 10000
206
#define YYMAXDEPTH 10000
207
#endif
208
#endif
209
#define YYINITSTACKSIZE 200
210
/* LINTUSED */
211
int yydebug;
212
int yynerrs;
213
int yyerrflag;
214
int yychar;
215
short *yyssp;
216
YYSTYPE *yyvsp;
217
YYSTYPE yyval;
218
YYSTYPE yylval;
219
short *yyss;
220
short *yysslim;
221
YYSTYPE *yyvs;
222
unsigned int yystacksize;
223
int yyparse(void);
224
#line 132 "parse.y"
225
226
struct keywords {
227
	const char	*k_name;
228
	int		 k_val;
229
};
230
231
int
232
yyerror(const char *fmt, ...)
233
{
234
	va_list		 ap;
235
	char		*msg;
236
237
	file->errors++;
238
	va_start(ap, fmt);
239
	if (vasprintf(&msg, fmt, ap) == -1)
240
		err(1, "yyerror vasprintf");
241
	va_end(ap);
242
	err(1, "%s:%d: %s", file->name, yylval.lineno, msg);
243
	free(msg);
244
	return (0);
245
}
246
247
int
248
kw_cmp(const void *k, const void *e)
249
{
250
	return (strcmp(k, ((const struct keywords *)e)->k_name));
251
}
252
253
int
254
lookup(char *s)
255
{
256
	/* this has to be sorted always */
257
	static const struct keywords keywords[] = {
258
		{ "changer",		CHANGER},
259
		{ "drive",		DRIVE}
260
	};
261
	const struct keywords	*p;
262
263
	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
264
	    sizeof(keywords[0]), kw_cmp);
265
266
	if (p)
267
		return (p->k_val);
268
	else
269
		return (STRING);
270
}
271
272
#define MAXPUSHBACK	128
273
274
u_char	*parsebuf;
275
int	 parseindex;
276
u_char	 pushback_buffer[MAXPUSHBACK];
277
int	 pushback_index = 0;
278
279
int
280
lgetc(int quotec)
281
{
282
	int		c, next;
283
284
	if (parsebuf) {
285
		/* Read character from the parsebuffer instead of input. */
286
		if (parseindex >= 0) {
287
			c = parsebuf[parseindex++];
288
			if (c != '\0')
289
				return (c);
290
			parsebuf = NULL;
291
		} else
292
			parseindex++;
293
	}
294
295
	if (pushback_index)
296
		return (pushback_buffer[--pushback_index]);
297
298
	if (quotec) {
299
		if ((c = getc(file->stream)) == EOF) {
300
			yyerror("reached end of file while parsing "
301
			    "quoted string");
302
			if (file == topfile || popfile() == EOF)
303
				return (EOF);
304
			return (quotec);
305
		}
306
		return (c);
307
	}
308
309
	while ((c = getc(file->stream)) == '\\') {
310
		next = getc(file->stream);
311
		if (next != '\n') {
312
			c = next;
313
			break;
314
		}
315
		yylval.lineno = file->lineno;
316
		file->lineno++;
317
	}
318
319
	while (c == EOF) {
320
		if (file == topfile || popfile() == EOF)
321
			return (EOF);
322
		c = getc(file->stream);
323
	}
324
	return (c);
325
}
326
327
int
328
lungetc(int c)
329
{
330
	if (c == EOF)
331
		return (EOF);
332
	if (parsebuf) {
333
		parseindex--;
334
		if (parseindex >= 0)
335
			return (c);
336
	}
337
	if (pushback_index < MAXPUSHBACK-1)
338
		return (pushback_buffer[pushback_index++] = c);
339
	else
340
		return (EOF);
341
}
342
343
int
344
findeol(void)
345
{
346
	int	c;
347
348
	parsebuf = NULL;
349
	pushback_index = 0;
350
351
	/* skip to either EOF or the first real EOL */
352
	while (1) {
353
		c = lgetc(0);
354
		if (c == '\n') {
355
			file->lineno++;
356
			break;
357
		}
358
		if (c == EOF)
359
			break;
360
	}
361
	return (ERROR);
362
}
363
364
int
365
yylex(void)
366
{
367
	u_char	 buf[8096];
368
	u_char	*p;
369
	int	 quotec, next, c;
370
	int	 token;
371
372
	p = buf;
373
	while ((c = lgetc(0)) == ' ' || c == '\t')
374
		; /* nothing */
375
376
	yylval.lineno = file->lineno;
377
	if (c == '#')
378
		while ((c = lgetc(0)) != '\n' && c != EOF)
379
			; /* nothing */
380
381
	switch (c) {
382
	case '\'':
383
	case '"':
384
		quotec = c;
385
		while (1) {
386
			if ((c = lgetc(quotec)) == EOF)
387
				return (0);
388
			if (c == '\n') {
389
				file->lineno++;
390
				continue;
391
			} else if (c == '\\') {
392
				if ((next = lgetc(quotec)) == EOF)
393
					return (0);
394
				if (next == quotec || c == ' ' || c == '\t')
395
					c = next;
396
				else if (next == '\n')
397
					continue;
398
				else
399
					lungetc(next);
400
			} else if (c == quotec) {
401
				*p = '\0';
402
				break;
403
			} else if (c == '\0') {
404
				yyerror("syntax error");
405
				return (findeol());
406
			}
407
			if (p + 1 >= buf + sizeof(buf) - 1) {
408
				yyerror("string too long");
409
				return (findeol());
410
			}
411
			*p++ = c;
412
		}
413
		yylval.v.string = strdup(buf);
414
		if (yylval.v.string == NULL)
415
			err(1, "yylex: strdup");
416
		return (STRING);
417
	}
418
419
#define allowed_to_end_number(x) \
420
	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
421
422
	if (c == '-' || isdigit(c)) {
423
		do {
424
			*p++ = c;
425
			if ((unsigned)(p-buf) >= sizeof(buf)) {
426
				yyerror("string too long");
427
				return (findeol());
428
			}
429
		} while ((c = lgetc(0)) != EOF && isdigit(c));
430
		lungetc(c);
431
		if (p == buf + 1 && buf[0] == '-')
432
			goto nodigits;
433
		if (c == EOF || allowed_to_end_number(c)) {
434
			const char *errstr = NULL;
435
436
			*p = '\0';
437
			yylval.v.number = strtonum(buf, LLONG_MIN,
438
			    LLONG_MAX, &errstr);
439
			if (errstr) {
440
				yyerror("\"%s\" invalid number: %s",
441
				    buf, errstr);
442
				return (findeol());
443
			}
444
			return (NUMBER);
445
		} else {
446
nodigits:
447
			while (p > buf + 1)
448
				lungetc(*--p);
449
			c = *--p;
450
			if (c == '-')
451
				return (c);
452
		}
453
	}
454
455
#define allowed_in_string(x) \
456
	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
457
	x != '{' && x != '}' && x != '<' && x != '>' && \
458
	x != '!' && x != '=' && x != '/' && x != '#' && \
459
	x != ','))
460
461
	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
462
		do {
463
			*p++ = c;
464
			if ((unsigned)(p-buf) >= sizeof(buf)) {
465
				yyerror("string too long");
466
				return (findeol());
467
			}
468
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
469
		lungetc(c);
470
		*p = '\0';
471
		if ((token = lookup(buf)) == STRING)
472
			if ((yylval.v.string = strdup(buf)) == NULL)
473
				err(1, "yylex: strdup");
474
		return (token);
475
	}
476
	if (c == '\n') {
477
		yylval.lineno = file->lineno;
478
		file->lineno++;
479
	}
480
	if (c == EOF)
481
		return (0);
482
	return (c);
483
}
484
485
struct file *
486
pushfile(const char *name)
487
{
488
	struct file	*nfile;
489
490
	if ((nfile = calloc(1, sizeof(struct file))) == NULL)
491
		return (NULL);
492
	if ((nfile->name = strdup(name)) == NULL) {
493
		free(nfile);
494
		return (NULL);
495
	}
496
	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
497
		free(nfile->name);
498
		free(nfile);
499
		return (NULL);
500
	}
501
	nfile->lineno = 1;
502
	TAILQ_INSERT_TAIL(&files, nfile, entry);
503
	return (nfile);
504
}
505
506
int
507
popfile(void)
508
{
509
	struct file	*prev;
510
511
	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
512
		prev->errors += file->errors;
513
514
	TAILQ_REMOVE(&files, file, entry);
515
	fclose(file->stream);
516
	free(file->name);
517
	free(file);
518
	file = prev;
519
	return (file ? 0 : EOF);
520
}
521
522
char *
523
parse_tapedev(const char *filename, const char *changer, int drive)
524
{
525
	struct changer	*p;
526
	char		*tapedev = NULL;
527
	int		 errors = 0;
528
529
	TAILQ_INIT(&changers);
530
531
	if ((file = pushfile(filename)) == NULL) {
532
		warnx("cannot open the main config file!");
533
		goto guess;
534
	}
535
	topfile = file;
536
537
	yyparse();
538
	errors = file->errors;
539
	popfile();
540
541
	TAILQ_FOREACH(p, &changers, entry) {
542
		if (strcmp(basename(changer), p->name) == 0) {
543
			if (drive >= 0 && drive < p->drivecnt) {
544
				if (asprintf(&tapedev, "/dev/%s",
545
				     p->drives[drive]) == -1)
546
					errx(1, "malloc failed");
547
			} else
548
				tapedev = NULL;
549
		}
550
	}
551
552
guess:
553
	/* if no device found, do the default of /dev/rstX */
554
	if (tapedev == NULL)
555
		if (asprintf(&tapedev, "/dev/rst%d", drive) == -1)
556
			errx(1, "malloc failed");
557
	return (tapedev);
558
}
559
560
struct changer *
561
new_changer(char *name)
562
{
563
	struct changer	*p;
564
565
	if ((p = calloc(1, sizeof(*p))) == NULL)
566
		err(1, NULL);
567
568
	if ((p->name = strdup(name)) == NULL)
569
		err(1, NULL);
570
571
	return (p);
572
}
573
574
575
#line 568 "parse.c"
576
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
577
static int yygrowstack(void)
578
{
579
    unsigned int newsize;
580
    long sslen;
581
    short *newss;
582
    YYSTYPE *newvs;
583
584
    if ((newsize = yystacksize) == 0)
585
        newsize = YYINITSTACKSIZE;
586
    else if (newsize >= YYMAXDEPTH)
587
        return -1;
588
    else if ((newsize *= 2) > YYMAXDEPTH)
589
        newsize = YYMAXDEPTH;
590
    sslen = yyssp - yyss;
591
#ifdef SIZE_MAX
592
#define YY_SIZE_MAX SIZE_MAX
593
#else
594
#define YY_SIZE_MAX 0xffffffffU
595
#endif
596
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
597
        goto bail;
598
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
599
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
600
    if (newss == NULL)
601
        goto bail;
602
    yyss = newss;
603
    yyssp = newss + sslen;
604
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
605
        goto bail;
606
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
607
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
608
    if (newvs == NULL)
609
        goto bail;
610
    yyvs = newvs;
611
    yyvsp = newvs + sslen;
612
    yystacksize = newsize;
613
    yysslim = yyss + newsize - 1;
614
    return 0;
615
bail:
616
    if (yyss)
617
            free(yyss);
618
    if (yyvs)
619
            free(yyvs);
620
    yyss = yyssp = NULL;
621
    yyvs = yyvsp = NULL;
622
    yystacksize = 0;
623
    return -1;
624
}
625
626
#define YYABORT goto yyabort
627
#define YYREJECT goto yyabort
628
#define YYACCEPT goto yyaccept
629
#define YYERROR goto yyerrlab
630
int
631
yyparse(void)
632
{
633
    int yym, yyn, yystate;
634
#if YYDEBUG
635
    const char *yys;
636
637
    if ((yys = getenv("YYDEBUG")))
638
    {
639
        yyn = *yys;
640
        if (yyn >= '0' && yyn <= '9')
641
            yydebug = yyn - '0';
642
    }
643
#endif /* YYDEBUG */
644
645
    yynerrs = 0;
646
    yyerrflag = 0;
647
    yychar = (-1);
648
649
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
650
    yyssp = yyss;
651
    yyvsp = yyvs;
652
    *yyssp = yystate = 0;
653
654
yyloop:
655
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
656
    if (yychar < 0)
657
    {
658
        if ((yychar = yylex()) < 0) yychar = 0;
659
#if YYDEBUG
660
        if (yydebug)
661
        {
662
            yys = 0;
663
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
664
            if (!yys) yys = "illegal-symbol";
665
            printf("%sdebug: state %d, reading %d (%s)\n",
666
                    YYPREFIX, yystate, yychar, yys);
667
        }
668
#endif
669
    }
670
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
671
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
672
    {
673
#if YYDEBUG
674
        if (yydebug)
675
            printf("%sdebug: state %d, shifting to state %d\n",
676
                    YYPREFIX, yystate, yytable[yyn]);
677
#endif
678
        if (yyssp >= yysslim && yygrowstack())
679
        {
680
            goto yyoverflow;
681
        }
682
        *++yyssp = yystate = yytable[yyn];
683
        *++yyvsp = yylval;
684
        yychar = (-1);
685
        if (yyerrflag > 0)  --yyerrflag;
686
        goto yyloop;
687
    }
688
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
689
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
690
    {
691
        yyn = yytable[yyn];
692
        goto yyreduce;
693
    }
694
    if (yyerrflag) goto yyinrecovery;
695
#if defined(__GNUC__)
696
    goto yynewerror;
697
#endif
698
yynewerror:
699
    yyerror("syntax error");
700
#if defined(__GNUC__)
701
    goto yyerrlab;
702
#endif
703
yyerrlab:
704
    ++yynerrs;
705
yyinrecovery:
706
    if (yyerrflag < 3)
707
    {
708
        yyerrflag = 3;
709
        for (;;)
710
        {
711
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
712
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
713
            {
714
#if YYDEBUG
715
                if (yydebug)
716
                    printf("%sdebug: state %d, error recovery shifting\
717
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
718
#endif
719
                if (yyssp >= yysslim && yygrowstack())
720
                {
721
                    goto yyoverflow;
722
                }
723
                *++yyssp = yystate = yytable[yyn];
724
                *++yyvsp = yylval;
725
                goto yyloop;
726
            }
727
            else
728
            {
729
#if YYDEBUG
730
                if (yydebug)
731
                    printf("%sdebug: error recovery discarding state %d\n",
732
                            YYPREFIX, *yyssp);
733
#endif
734
                if (yyssp <= yyss) goto yyabort;
735
                --yyssp;
736
                --yyvsp;
737
            }
738
        }
739
    }
740
    else
741
    {
742
        if (yychar == 0) goto yyabort;
743
#if YYDEBUG
744
        if (yydebug)
745
        {
746
            yys = 0;
747
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
748
            if (!yys) yys = "illegal-symbol";
749
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
750
                    YYPREFIX, yystate, yychar, yys);
751
        }
752
#endif
753
        yychar = (-1);
754
        goto yyloop;
755
    }
756
yyreduce:
757
#if YYDEBUG
758
    if (yydebug)
759
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
760
                YYPREFIX, yystate, yyn, yyrule[yyn]);
761
#endif
762
    yym = yylen[yyn];
763
    if (yym)
764
        yyval = yyvsp[1-yym];
765
    else
766
        memset(&yyval, 0, sizeof yyval);
767
    switch (yyn)
768
    {
769
case 4:
770
#line 88 "parse.y"
771
{ file->errors++; }
772
break;
773
case 8:
774
#line 98 "parse.y"
775
{
776
			curchanger = new_changer(yyvsp[-3].v.string);
777
		}
778
break;
779
case 9:
780
#line 101 "parse.y"
781
{
782
			TAILQ_INSERT_TAIL(&changers, curchanger, entry);
783
			curchanger = NULL;
784
		}
785
break;
786
case 14:
787
#line 115 "parse.y"
788
{
789
			void *newp;
790
791
			if ((newp = reallocarray(curchanger->drives,
792
			    curchanger->drivecnt + 1,
793
			    sizeof(curchanger->drives))) == NULL)
794
				err(1, NULL);
795
			curchanger->drives = newp;
796
			if ((curchanger->drives[curchanger->drivecnt] =
797
			    strdup(yyvsp[0].v.string)) == NULL)
798
				err(1, NULL);
799
			curchanger->drivecnt++;
800
			free(yyvsp[0].v.string);
801
		}
802
break;
803
#line 796 "parse.c"
804
    }
805
    yyssp -= yym;
806
    yystate = *yyssp;
807
    yyvsp -= yym;
808
    yym = yylhs[yyn];
809
    if (yystate == 0 && yym == 0)
810
    {
811
#if YYDEBUG
812
        if (yydebug)
813
            printf("%sdebug: after reduction, shifting from state 0 to\
814
 state %d\n", YYPREFIX, YYFINAL);
815
#endif
816
        yystate = YYFINAL;
817
        *++yyssp = YYFINAL;
818
        *++yyvsp = yyval;
819
        if (yychar < 0)
820
        {
821
            if ((yychar = yylex()) < 0) yychar = 0;
822
#if YYDEBUG
823
            if (yydebug)
824
            {
825
                yys = 0;
826
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
827
                if (!yys) yys = "illegal-symbol";
828
                printf("%sdebug: state %d, reading %d (%s)\n",
829
                        YYPREFIX, YYFINAL, yychar, yys);
830
            }
831
#endif
832
        }
833
        if (yychar == 0) goto yyaccept;
834
        goto yyloop;
835
    }
836
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
837
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
838
        yystate = yytable[yyn];
839
    else
840
        yystate = yydgoto[yym];
841
#if YYDEBUG
842
    if (yydebug)
843
        printf("%sdebug: after reduction, shifting from state %d \
844
to state %d\n", YYPREFIX, *yyssp, yystate);
845
#endif
846
    if (yyssp >= yysslim && yygrowstack())
847
    {
848
        goto yyoverflow;
849
    }
850
    *++yyssp = yystate;
851
    *++yyvsp = yyval;
852
    goto yyloop;
853
yyoverflow:
854
    yyerror("yacc stack overflow");
855
yyabort:
856
    if (yyss)
857
            free(yyss);
858
    if (yyvs)
859
            free(yyvs);
860
    yyss = yyssp = NULL;
861
    yyvs = yyvsp = NULL;
862
    yystacksize = 0;
863
    return (1);
864
yyaccept:
865
    if (yyss)
866
            free(yyss);
867
    if (yyvs)
868
            free(yyvs);
869
    yyss = yyssp = NULL;
870
    yyvs = yyvsp = NULL;
871
    yystacksize = 0;
872
    return (0);
873
}