Bug Summary

File:src/bin/chio/obj/parse.c
Warning:line 618, column 13
Attempt to free released memory

Annotated Source Code

Press '?' to see keyboard shortcuts

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