GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* $OpenBSD: misc.c,v 1.19 2015/11/19 23:34:56 mmcc Exp $ */ |
||
2 |
|||
3 |
/* misc - miscellaneous flex routines */ |
||
4 |
|||
5 |
/* Copyright (c) 1990 The Regents of the University of California. */ |
||
6 |
/* All rights reserved. */ |
||
7 |
|||
8 |
/* This code is derived from software contributed to Berkeley by */ |
||
9 |
/* Vern Paxson. */ |
||
10 |
|||
11 |
/* The United States Government has rights in this work pursuant */ |
||
12 |
/* to contract no. DE-AC03-76SF00098 between the United States */ |
||
13 |
/* Department of Energy and the University of California. */ |
||
14 |
|||
15 |
/* This file is part of flex. */ |
||
16 |
|||
17 |
/* Redistribution and use in source and binary forms, with or without */ |
||
18 |
/* modification, are permitted provided that the following conditions */ |
||
19 |
/* are met: */ |
||
20 |
|||
21 |
/* 1. Redistributions of source code must retain the above copyright */ |
||
22 |
/* notice, this list of conditions and the following disclaimer. */ |
||
23 |
/* 2. Redistributions in binary form must reproduce the above copyright */ |
||
24 |
/* notice, this list of conditions and the following disclaimer in the */ |
||
25 |
/* documentation and/or other materials provided with the distribution. */ |
||
26 |
|||
27 |
/* Neither the name of the University nor the names of its contributors */ |
||
28 |
/* may be used to endorse or promote products derived from this software */ |
||
29 |
/* without specific prior written permission. */ |
||
30 |
|||
31 |
/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ |
||
32 |
/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ |
||
33 |
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ |
||
34 |
/* PURPOSE. */ |
||
35 |
|||
36 |
#include "flexdef.h" |
||
37 |
#include "tables.h" |
||
38 |
|||
39 |
#define CMD_IF_TABLES_SER "%if-tables-serialization" |
||
40 |
#define CMD_TABLES_YYDMAP "%tables-yydmap" |
||
41 |
#define CMD_DEFINE_YYTABLES "%define-yytables" |
||
42 |
#define CMD_IF_CPP_ONLY "%if-c++-only" |
||
43 |
#define CMD_IF_C_ONLY "%if-c-only" |
||
44 |
#define CMD_IF_C_OR_CPP "%if-c-or-c++" |
||
45 |
#define CMD_NOT_FOR_HEADER "%not-for-header" |
||
46 |
#define CMD_OK_FOR_HEADER "%ok-for-header" |
||
47 |
#define CMD_PUSH "%push" |
||
48 |
#define CMD_POP "%pop" |
||
49 |
#define CMD_IF_REENTRANT "%if-reentrant" |
||
50 |
#define CMD_IF_NOT_REENTRANT "%if-not-reentrant" |
||
51 |
#define CMD_IF_BISON_BRIDGE "%if-bison-bridge" |
||
52 |
#define CMD_IF_NOT_BISON_BRIDGE "%if-not-bison-bridge" |
||
53 |
#define CMD_ENDIF "%endif" |
||
54 |
|||
55 |
/* we allow the skeleton to push and pop. */ |
||
56 |
struct sko_state { |
||
57 |
bool dc; /**< do_copy */ |
||
58 |
}; |
||
59 |
static struct sko_state *sko_stack = 0; |
||
60 |
static int sko_len = 0, sko_sz = 0; |
||
61 |
static void |
||
62 |
sko_push(bool dc) |
||
63 |
{ |
||
64 |
✓✓ | 1200 |
if (!sko_stack) { |
65 |
10 |
sko_sz = 1; |
|
66 |
10 |
sko_stack = malloc(sizeof(struct sko_state) * sko_sz); |
|
67 |
✗✓ | 10 |
if (!sko_stack) |
68 |
flexfatal(_("allocation of sko_stack failed")); |
||
69 |
10 |
sko_len = 0; |
|
70 |
10 |
} |
|
71 |
✓✓ | 1200 |
if (sko_len >= sko_sz) { |
72 |
20 |
sko_sz *= 2; |
|
73 |
20 |
sko_stack = realloc(sko_stack, sizeof(struct sko_state) * sko_sz); |
|
74 |
20 |
} |
|
75 |
/* initialize to zero and push */ |
||
76 |
1200 |
sko_stack[sko_len].dc = dc; |
|
77 |
1200 |
sko_len++; |
|
78 |
1200 |
} |
|
79 |
static void |
||
80 |
sko_peek(bool * dc) |
||
81 |
{ |
||
82 |
✗✓ | 2400 |
if (sko_len <= 0) |
83 |
flex_die("peek attempt when sko stack is empty"); |
||
84 |
✓✗ | 1200 |
if (dc) |
85 |
1200 |
*dc = sko_stack[sko_len - 1].dc; |
|
86 |
1200 |
} |
|
87 |
static void |
||
88 |
sko_pop(bool * dc) |
||
89 |
{ |
||
90 |
2040 |
sko_peek(dc); |
|
91 |
1020 |
sko_len--; |
|
92 |
✗✓ | 1020 |
if (sko_len < 0) |
93 |
flex_die("popped too many times in skeleton."); |
||
94 |
1020 |
} |
|
95 |
|||
96 |
/* Append "#define defname value\n" to the running buffer. */ |
||
97 |
void |
||
98 |
action_define(defname, value) |
||
99 |
const char *defname; |
||
100 |
int value; |
||
101 |
{ |
||
102 |
24 |
char buf[MAXLINE]; |
|
103 |
12 |
char *cpy; |
|
104 |
|||
105 |
✗✓ | 12 |
if ((int) strlen(defname) > MAXLINE / 2) { |
106 |
format_pinpoint_message(_ |
||
107 |
("name \"%s\" ridiculously long"), |
||
108 |
defname); |
||
109 |
return; |
||
110 |
} |
||
111 |
12 |
snprintf(buf, sizeof(buf), "#define %s %d\n", defname, value); |
|
112 |
12 |
add_action(buf); |
|
113 |
|||
114 |
/* track #defines so we can undef them when we're done. */ |
||
115 |
12 |
cpy = copy_string(defname); |
|
116 |
12 |
buf_append(&defs_buf, &cpy, 1); |
|
117 |
24 |
} |
|
118 |
|||
119 |
|||
120 |
/** Append "m4_define([[defname]],[[value]])m4_dnl\n" to the running buffer. |
||
121 |
* @param defname The macro name. |
||
122 |
* @param value The macro value, can be NULL, which is the same as the empty string. |
||
123 |
*/ |
||
124 |
void |
||
125 |
action_m4_define(const char *defname, const char *value) |
||
126 |
{ |
||
127 |
char buf[MAXLINE]; |
||
128 |
|||
129 |
flexfatal("DO NOT USE THIS FUNCTION!"); |
||
130 |
|||
131 |
if ((int) strlen(defname) > MAXLINE / 2) { |
||
132 |
format_pinpoint_message(_ |
||
133 |
("name \"%s\" ridiculously long"), |
||
134 |
defname); |
||
135 |
return; |
||
136 |
} |
||
137 |
snprintf(buf, sizeof(buf), "m4_define([[%s]],[[%s]])m4_dnl\n", defname, value ? value : ""); |
||
138 |
add_action(buf); |
||
139 |
} |
||
140 |
|||
141 |
/* Append "new_text" to the running buffer. */ |
||
142 |
void |
||
143 |
add_action(new_text) |
||
144 |
const char *new_text; |
||
145 |
{ |
||
146 |
116006 |
int len = strlen(new_text); |
|
147 |
|||
148 |
✓✓ | 116064 |
while (len + action_index >= action_size - 10 /* slop */ ) { |
149 |
29 |
int new_size = action_size * 2; |
|
150 |
|||
151 |
✗✓ | 29 |
if (new_size <= 0) |
152 |
/* |
||
153 |
* Increase just a little, to try to avoid overflow |
||
154 |
* on 16-bit machines. |
||
155 |
*/ |
||
156 |
action_size += action_size / 8; |
||
157 |
else |
||
158 |
action_size = new_size; |
||
159 |
|||
160 |
29 |
action_array = |
|
161 |
29 |
reallocate_character_array(action_array, |
|
162 |
action_size); |
||
163 |
} |
||
164 |
|||
165 |
116006 |
strlcpy(&action_array[action_index], new_text, |
|
166 |
58003 |
action_size - action_index); |
|
167 |
|||
168 |
58003 |
action_index += len; |
|
169 |
58003 |
} |
|
170 |
|||
171 |
|||
172 |
/* allocate_array - allocate memory for an integer array of the given size */ |
||
173 |
|||
174 |
void * |
||
175 |
allocate_array(size, element_size) |
||
176 |
int size; |
||
177 |
size_t element_size; |
||
178 |
{ |
||
179 |
void *mem; |
||
180 |
16162 |
size_t num_bytes = element_size * size; |
|
181 |
|||
182 |
8081 |
mem = malloc(num_bytes); |
|
183 |
✗✓ | 8081 |
if (!mem) |
184 |
flexfatal(_ |
||
185 |
("memory allocation failed in allocate_array()")); |
||
186 |
|||
187 |
8081 |
return mem; |
|
188 |
} |
||
189 |
|||
190 |
|||
191 |
/* all_lower - true if a string is all lower-case */ |
||
192 |
|||
193 |
int |
||
194 |
all_lower(str) |
||
195 |
char *str; |
||
196 |
{ |
||
197 |
✓✓ | 135 |
while (*str) { |
198 |
✓✗✗✓ |
108 |
if (!isascii((u_char) * str) || !islower((u_char) * str)) |
199 |
return 0; |
||
200 |
54 |
++str; |
|
201 |
} |
||
202 |
|||
203 |
9 |
return 1; |
|
204 |
9 |
} |
|
205 |
|||
206 |
|||
207 |
/* all_upper - true if a string is all upper-case */ |
||
208 |
|||
209 |
int |
||
210 |
all_upper(str) |
||
211 |
char *str; |
||
212 |
{ |
||
213 |
✓✓ | 45 |
while (*str) { |
214 |
✓✗✗✓ |
36 |
if (!isascii((u_char) * str) || !isupper((u_char) * str)) |
215 |
return 0; |
||
216 |
18 |
++str; |
|
217 |
} |
||
218 |
|||
219 |
3 |
return 1; |
|
220 |
3 |
} |
|
221 |
|||
222 |
|||
223 |
/* intcmp - compares two integers for use by qsort. */ |
||
224 |
|||
225 |
int |
||
226 |
intcmp(const void *a, const void *b) |
||
227 |
{ |
||
228 |
817302 |
return *(const int *) a - *(const int *) b; |
|
229 |
} |
||
230 |
|||
231 |
|||
232 |
/* check_char - checks a character to make sure it's within the range |
||
233 |
* we're expecting. If not, generates fatal error message |
||
234 |
* and exits. |
||
235 |
*/ |
||
236 |
|||
237 |
void |
||
238 |
check_char(c) |
||
239 |
int c; |
||
240 |
{ |
||
241 |
✗✓ | 116220 |
if (c >= CSIZE) |
242 |
lerrsf(_("bad character '%s' detected in check_char()"), |
||
243 |
readable_form(c)); |
||
244 |
|||
245 |
✗✓ | 58110 |
if (c >= csize) |
246 |
lerrsf(_ |
||
247 |
("scanner requires -8 flag to use the character %s"), |
||
248 |
readable_form(c)); |
||
249 |
58110 |
} |
|
250 |
|||
251 |
|||
252 |
|||
253 |
/* clower - replace upper-case letter to lower-case */ |
||
254 |
|||
255 |
u_char |
||
256 |
clower(c) |
||
257 |
int c; |
||
258 |
{ |
||
259 |
return (u_char) ((isascii(c) && isupper(c)) ? tolower(c) : c); |
||
260 |
} |
||
261 |
|||
262 |
|||
263 |
/* copy_string - returns a dynamically allocated copy of a string */ |
||
264 |
|||
265 |
char * |
||
266 |
copy_string(str) |
||
267 |
const char *str; |
||
268 |
{ |
||
269 |
const char *c1; |
||
270 |
char *c2; |
||
271 |
char *copy; |
||
272 |
unsigned int size; |
||
273 |
|||
274 |
/* find length */ |
||
275 |
✓✓ | 9396 |
for (c1 = str; *c1; ++c1); |
276 |
|||
277 |
636 |
size = (c1 - str + 1) * sizeof(char); |
|
278 |
|||
279 |
636 |
copy = (char *) malloc(size); |
|
280 |
|||
281 |
✗✓ | 636 |
if (copy == NULL) |
282 |
flexfatal(_("dynamic memory failure in copy_string()")); |
||
283 |
|||
284 |
✓✓ | 5016 |
for (c2 = copy; (*c2++ = *str++) != 0;); |
285 |
|||
286 |
636 |
return copy; |
|
287 |
} |
||
288 |
|||
289 |
|||
290 |
/* copy_unsigned_string - |
||
291 |
* returns a dynamically allocated copy of a (potentially) unsigned string |
||
292 |
*/ |
||
293 |
|||
294 |
u_char * |
||
295 |
copy_unsigned_string(str) |
||
296 |
u_char *str; |
||
297 |
{ |
||
298 |
u_char *c; |
||
299 |
u_char *copy; |
||
300 |
|||
301 |
/* find length */ |
||
302 |
✓✓ | 83112 |
for (c = str; *c; ++c); |
303 |
|||
304 |
3014 |
copy = allocate_Character_array(c - str + 1); |
|
305 |
|||
306 |
✓✓ | 43063 |
for (c = copy; (*c++ = *str++) != 0;); |
307 |
|||
308 |
3014 |
return copy; |
|
309 |
} |
||
310 |
|||
311 |
|||
312 |
/* cclcmp - compares two characters for use by qsort with '\0' sorting last. */ |
||
313 |
|||
314 |
int |
||
315 |
cclcmp(const void *a, const void *b) |
||
316 |
{ |
||
317 |
✗✓ | 308766 |
if (!*(const u_char *) a) |
318 |
return 1; |
||
319 |
✗✓ | 154383 |
else if (!*(const u_char *) b) |
320 |
return -1; |
||
321 |
else |
||
322 |
154383 |
return *(const u_char *) a - *(const u_char *) b; |
|
323 |
154383 |
} |
|
324 |
|||
325 |
|||
326 |
/* dataend - finish up a block of data declarations */ |
||
327 |
|||
328 |
void |
||
329 |
dataend() |
||
330 |
{ |
||
331 |
/* short circuit any output */ |
||
332 |
✓✗ | 142 |
if (gentables) { |
333 |
|||
334 |
✓✗ | 71 |
if (datapos > 0) |
335 |
71 |
dataflush(); |
|
336 |
|||
337 |
/* add terminator for initialization; { for vi */ |
||
338 |
71 |
outn(" } ;\n"); |
|
339 |
71 |
} |
|
340 |
71 |
dataline = 0; |
|
341 |
71 |
datapos = 0; |
|
342 |
71 |
} |
|
343 |
|||
344 |
|||
345 |
/* dataflush - flush generated data statements */ |
||
346 |
|||
347 |
void |
||
348 |
dataflush() |
||
349 |
{ |
||
350 |
/* short circuit any output */ |
||
351 |
✓✗ | 10834 |
if (!gentables) |
352 |
return; |
||
353 |
|||
354 |
5417 |
outc('\n'); |
|
355 |
|||
356 |
✓✓ | 5417 |
if (++dataline >= NUMDATALINES) { |
357 |
/* |
||
358 |
* Put out a blank line so that the table is grouped into |
||
359 |
* large blocks that enable the user to find elements easily. |
||
360 |
*/ |
||
361 |
503 |
outc('\n'); |
|
362 |
503 |
dataline = 0; |
|
363 |
503 |
} |
|
364 |
/* Reset the number of characters written on the current line. */ |
||
365 |
5417 |
datapos = 0; |
|
366 |
10834 |
} |
|
367 |
|||
368 |
|||
369 |
/* flexerror - report an error message and terminate */ |
||
370 |
|||
371 |
void |
||
372 |
flexerror(msg) |
||
373 |
const char *msg; |
||
374 |
{ |
||
375 |
fprintf(stderr, "%s: %s\n", program_name, msg); |
||
376 |
flexend(1); |
||
377 |
} |
||
378 |
|||
379 |
|||
380 |
/* flexfatal - report a fatal error message and terminate */ |
||
381 |
|||
382 |
void |
||
383 |
flexfatal(msg) |
||
384 |
const char *msg; |
||
385 |
{ |
||
386 |
fprintf(stderr, _("%s: fatal internal error, %s\n"), |
||
387 |
program_name, msg); |
||
388 |
FLEX_EXIT(1); |
||
389 |
} |
||
390 |
|||
391 |
|||
392 |
/* htoi - convert a hexadecimal digit string to an integer value */ |
||
393 |
|||
394 |
int |
||
395 |
htoi(str) |
||
396 |
u_char str[]; |
||
397 |
{ |
||
398 |
unsigned int result; |
||
399 |
|||
400 |
(void) sscanf((char *) str, "%x", &result); |
||
401 |
|||
402 |
return result; |
||
403 |
} |
||
404 |
|||
405 |
|||
406 |
/* lerrif - report an error message formatted with one integer argument */ |
||
407 |
|||
408 |
void |
||
409 |
lerrif(msg, arg) |
||
410 |
const char *msg; |
||
411 |
int arg; |
||
412 |
{ |
||
413 |
char errmsg[MAXLINE]; |
||
414 |
|||
415 |
snprintf(errmsg, sizeof(errmsg), msg, arg); |
||
416 |
flexerror(errmsg); |
||
417 |
} |
||
418 |
|||
419 |
|||
420 |
/* lerrsf - report an error message formatted with one string argument */ |
||
421 |
|||
422 |
void |
||
423 |
lerrsf(msg, arg) |
||
424 |
const char *msg, arg[]; |
||
425 |
{ |
||
426 |
char errmsg[MAXLINE]; |
||
427 |
|||
428 |
snprintf(errmsg, sizeof(errmsg) - 1, msg, arg); |
||
429 |
errmsg[sizeof(errmsg) - 1] = 0; /* ensure NULL termination */ |
||
430 |
flexerror(errmsg); |
||
431 |
} |
||
432 |
|||
433 |
|||
434 |
/* lerrsf_fatal - as lerrsf, but call flexfatal */ |
||
435 |
|||
436 |
void |
||
437 |
lerrsf_fatal(msg, arg) |
||
438 |
const char *msg, arg[]; |
||
439 |
{ |
||
440 |
char errmsg[MAXLINE]; |
||
441 |
|||
442 |
snprintf(errmsg, sizeof(errmsg) - 1, msg, arg); |
||
443 |
errmsg[sizeof(errmsg) - 1] = 0; /* ensure NULL termination */ |
||
444 |
flexfatal(errmsg); |
||
445 |
} |
||
446 |
|||
447 |
|||
448 |
/* line_directive_out - spit out a "#line" statement */ |
||
449 |
|||
450 |
void |
||
451 |
line_directive_out(output_file, do_infile) |
||
452 |
FILE *output_file; |
||
453 |
int do_infile; |
||
454 |
{ |
||
455 |
1416 |
char directive[MAXLINE], filename[MAXLINE]; |
|
456 |
char *s1, *s2, *s3; |
||
457 |
static const char *line_fmt = "#line %d \"%s\"\n"; |
||
458 |
|||
459 |
✗✓ | 708 |
if (!gen_line_dirs) |
460 |
return; |
||
461 |
|||
462 |
708 |
s1 = do_infile ? infilename : "M4_YY_OUTFILE_NAME"; |
|
463 |
|||
464 |
708 |
if (do_infile && !s1) |
|
465 |
s1 = "<stdin>"; |
||
466 |
|||
467 |
708 |
s2 = filename; |
|
468 |
708 |
s3 = &filename[sizeof(filename) - 2]; |
|
469 |
|||
470 |
✓✗✓✓ |
31047 |
while (s2 < s3 && *s1) { |
471 |
✗✓ | 9641 |
if (*s1 == '\\') |
472 |
/* Escape the '\' */ |
||
473 |
*s2++ = '\\'; |
||
474 |
|||
475 |
9641 |
*s2++ = *s1++; |
|
476 |
} |
||
477 |
|||
478 |
708 |
*s2 = '\0'; |
|
479 |
|||
480 |
✓✓ | 708 |
if (do_infile) |
481 |
674 |
snprintf(directive, sizeof(directive), line_fmt, linenum, filename); |
|
482 |
else { |
||
483 |
34 |
snprintf(directive, sizeof(directive), line_fmt, 0, filename); |
|
484 |
} |
||
485 |
|||
486 |
/* |
||
487 |
* If output_file is nil then we should put the directive in the |
||
488 |
* accumulated actions. |
||
489 |
*/ |
||
490 |
✓✓ | 708 |
if (output_file) { |
491 |
44 |
fputs(directive, output_file); |
|
492 |
44 |
} else |
|
493 |
664 |
add_action(directive); |
|
494 |
1416 |
} |
|
495 |
|||
496 |
|||
497 |
/* mark_defs1 - mark the current position in the action array as |
||
498 |
* representing where the user's section 1 definitions end |
||
499 |
* and the prolog begins |
||
500 |
*/ |
||
501 |
void |
||
502 |
mark_defs1() |
||
503 |
{ |
||
504 |
60 |
defs1_offset = 0; |
|
505 |
30 |
action_array[action_index++] = '\0'; |
|
506 |
30 |
action_offset = prolog_offset = action_index; |
|
507 |
30 |
action_array[action_index] = '\0'; |
|
508 |
30 |
} |
|
509 |
|||
510 |
|||
511 |
/* mark_prolog - mark the current position in the action array as |
||
512 |
* representing the end of the action prolog |
||
513 |
*/ |
||
514 |
void |
||
515 |
mark_prolog() |
||
516 |
{ |
||
517 |
20 |
action_array[action_index++] = '\0'; |
|
518 |
10 |
action_offset = action_index; |
|
519 |
10 |
action_array[action_index] = '\0'; |
|
520 |
10 |
} |
|
521 |
|||
522 |
|||
523 |
/* mk2data - generate a data statement for a two-dimensional array |
||
524 |
* |
||
525 |
* Generates a data statement initializing the current 2-D array to "value". |
||
526 |
*/ |
||
527 |
void |
||
528 |
mk2data(value) |
||
529 |
int value; |
||
530 |
{ |
||
531 |
/* short circuit any output */ |
||
532 |
if (!gentables) |
||
533 |
return; |
||
534 |
|||
535 |
if (datapos >= NUMDATAITEMS) { |
||
536 |
outc(','); |
||
537 |
dataflush(); |
||
538 |
} |
||
539 |
if (datapos == 0) |
||
540 |
/* Indent. */ |
||
541 |
out(" "); |
||
542 |
|||
543 |
else |
||
544 |
outc(','); |
||
545 |
|||
546 |
++datapos; |
||
547 |
|||
548 |
out_dec("%5d", value); |
||
549 |
} |
||
550 |
|||
551 |
|||
552 |
/* mkdata - generate a data statement |
||
553 |
* |
||
554 |
* Generates a data statement initializing the current array element to |
||
555 |
* "value". |
||
556 |
*/ |
||
557 |
void |
||
558 |
mkdata(value) |
||
559 |
int value; |
||
560 |
{ |
||
561 |
/* short circuit any output */ |
||
562 |
✓✗ | 107604 |
if (!gentables) |
563 |
return; |
||
564 |
|||
565 |
✓✓ | 53802 |
if (datapos >= NUMDATAITEMS) { |
566 |
5346 |
outc(','); |
|
567 |
5346 |
dataflush(); |
|
568 |
5346 |
} |
|
569 |
✓✓ | 53802 |
if (datapos == 0) |
570 |
/* Indent. */ |
||
571 |
5417 |
out(" "); |
|
572 |
else |
||
573 |
48385 |
outc(','); |
|
574 |
|||
575 |
53802 |
++datapos; |
|
576 |
|||
577 |
53802 |
out_dec("%5d", value); |
|
578 |
107604 |
} |
|
579 |
|||
580 |
|||
581 |
/* myctoi - return the integer represented by a string of digits */ |
||
582 |
|||
583 |
int |
||
584 |
myctoi(array) |
||
585 |
const char *array; |
||
586 |
{ |
||
587 |
int val = 0; |
||
588 |
|||
589 |
(void) sscanf(array, "%d", &val); |
||
590 |
|||
591 |
return val; |
||
592 |
} |
||
593 |
|||
594 |
|||
595 |
/* myesc - return character corresponding to escape sequence */ |
||
596 |
|||
597 |
u_char |
||
598 |
myesc(array) |
||
599 |
u_char array[]; |
||
600 |
{ |
||
601 |
u_char c, esc_char; |
||
602 |
|||
603 |
✗✗✓✓ ✓✗✗✗ ✗✗✗✗ ✗✗✗✗ ✓ |
796 |
switch (array[1]) { |
604 |
case 'b': |
||
605 |
return '\b'; |
||
606 |
case 'f': |
||
607 |
return '\f'; |
||
608 |
case 'n': |
||
609 |
48 |
return '\n'; |
|
610 |
case 'r': |
||
611 |
10 |
return '\r'; |
|
612 |
case 't': |
||
613 |
21 |
return '\t'; |
|
614 |
|||
615 |
#if defined (__STDC__) |
||
616 |
case 'a': |
||
617 |
return '\a'; |
||
618 |
case 'v': |
||
619 |
return '\v'; |
||
620 |
#else |
||
621 |
case 'a': |
||
622 |
return '\007'; |
||
623 |
case 'v': |
||
624 |
return '\013'; |
||
625 |
#endif |
||
626 |
|||
627 |
case '0': |
||
628 |
case '1': |
||
629 |
case '2': |
||
630 |
case '3': |
||
631 |
case '4': |
||
632 |
case '5': |
||
633 |
case '6': |
||
634 |
case '7': |
||
635 |
{ /* \<octal> */ |
||
636 |
int sptr = 1; |
||
637 |
|||
638 |
while (isascii(array[sptr]) && |
||
639 |
isdigit(array[sptr])) |
||
640 |
/* |
||
641 |
* Don't increment inside loop control |
||
642 |
* because if isdigit() is a macro it might |
||
643 |
* expand into multiple increments ... |
||
644 |
*/ |
||
645 |
++sptr; |
||
646 |
|||
647 |
c = array[sptr]; |
||
648 |
array[sptr] = '\0'; |
||
649 |
|||
650 |
esc_char = otoi(array + 1); |
||
651 |
|||
652 |
array[sptr] = c; |
||
653 |
|||
654 |
return esc_char; |
||
655 |
} |
||
656 |
|||
657 |
case 'x': |
||
658 |
{ /* \x<hex> */ |
||
659 |
int sptr = 2; |
||
660 |
|||
661 |
while (isascii(array[sptr]) && |
||
662 |
isxdigit(array[sptr])) |
||
663 |
/* |
||
664 |
* Don't increment inside loop control |
||
665 |
* because if isdigit() is a macro it might |
||
666 |
* expand into multiple increments ... |
||
667 |
*/ |
||
668 |
++sptr; |
||
669 |
|||
670 |
c = array[sptr]; |
||
671 |
array[sptr] = '\0'; |
||
672 |
|||
673 |
esc_char = htoi(array + 2); |
||
674 |
|||
675 |
array[sptr] = c; |
||
676 |
|||
677 |
return esc_char; |
||
678 |
} |
||
679 |
|||
680 |
default: |
||
681 |
319 |
return array[1]; |
|
682 |
} |
||
683 |
398 |
} |
|
684 |
|||
685 |
|||
686 |
/* otoi - convert an octal digit string to an integer value */ |
||
687 |
|||
688 |
int |
||
689 |
otoi(str) |
||
690 |
u_char str[]; |
||
691 |
{ |
||
692 |
unsigned int result; |
||
693 |
|||
694 |
(void) sscanf((char *) str, "%o", &result); |
||
695 |
return result; |
||
696 |
} |
||
697 |
|||
698 |
|||
699 |
/* out - various flavors of outputing a (possibly formatted) string for the |
||
700 |
* generated scanner, keeping track of the line count. |
||
701 |
*/ |
||
702 |
|||
703 |
void |
||
704 |
out(str) |
||
705 |
const char *str; |
||
706 |
{ |
||
707 |
10906 |
fputs(str, stdout); |
|
708 |
5453 |
} |
|
709 |
|||
710 |
void |
||
711 |
out_dec(fmt, n) |
||
712 |
const char *fmt; |
||
713 |
int n; |
||
714 |
{ |
||
715 |
107888 |
fprintf(stdout, fmt, n); |
|
716 |
53944 |
} |
|
717 |
|||
718 |
void |
||
719 |
out_dec2(fmt, n1, n2) |
||
720 |
const char *fmt; |
||
721 |
int n1, n2; |
||
722 |
{ |
||
723 |
fprintf(stdout, fmt, n1, n2); |
||
724 |
} |
||
725 |
|||
726 |
void |
||
727 |
out_hex(fmt, x) |
||
728 |
const char *fmt; |
||
729 |
unsigned int x; |
||
730 |
{ |
||
731 |
fprintf(stdout, fmt, x); |
||
732 |
} |
||
733 |
|||
734 |
void |
||
735 |
out_str(fmt, str) |
||
736 |
const char *fmt, str[]; |
||
737 |
{ |
||
738 |
148 |
fprintf(stdout, fmt, str); |
|
739 |
74 |
} |
|
740 |
|||
741 |
void |
||
742 |
out_str3(fmt, s1, s2, s3) |
||
743 |
const char *fmt, s1[], s2[], s3[]; |
||
744 |
{ |
||
745 |
fprintf(stdout, fmt, s1, s2, s3); |
||
746 |
} |
||
747 |
|||
748 |
void |
||
749 |
out_str_dec(fmt, str, n) |
||
750 |
const char *fmt, str[]; |
||
751 |
int n; |
||
752 |
{ |
||
753 |
146 |
fprintf(stdout, fmt, str, n); |
|
754 |
73 |
} |
|
755 |
|||
756 |
void |
||
757 |
outc(c) |
||
758 |
int c; |
||
759 |
{ |
||
760 |
123384 |
fputc(c, stdout); |
|
761 |
61692 |
} |
|
762 |
|||
763 |
void |
||
764 |
outn(str) |
||
765 |
const char *str; |
||
766 |
{ |
||
767 |
49418 |
fputs(str, stdout); |
|
768 |
24709 |
fputc('\n', stdout); |
|
769 |
24709 |
} |
|
770 |
|||
771 |
/** Print "m4_define( [[def]], [[val]])m4_dnl\n". |
||
772 |
* @param def The m4 symbol to define. |
||
773 |
* @param val The definition; may be NULL. |
||
774 |
* @return buf |
||
775 |
*/ |
||
776 |
void |
||
777 |
out_m4_define(const char *def, const char *val) |
||
778 |
{ |
||
779 |
const char *fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n"; |
||
780 |
6 |
fprintf(stdout, fmt, def, val ? val : ""); |
|
781 |
3 |
} |
|
782 |
|||
783 |
|||
784 |
/* readable_form - return the human-readable form of a character |
||
785 |
* |
||
786 |
* The returned string is in static storage. |
||
787 |
*/ |
||
788 |
|||
789 |
char * |
||
790 |
readable_form(c) |
||
791 |
int c; |
||
792 |
{ |
||
793 |
static char rform[10]; |
||
794 |
|||
795 |
if ((c >= 0 && c < 32) || c >= 127) { |
||
796 |
switch (c) { |
||
797 |
case '\b': |
||
798 |
return "\\b"; |
||
799 |
case '\f': |
||
800 |
return "\\f"; |
||
801 |
case '\n': |
||
802 |
return "\\n"; |
||
803 |
case '\r': |
||
804 |
return "\\r"; |
||
805 |
case '\t': |
||
806 |
return "\\t"; |
||
807 |
|||
808 |
#if defined (__STDC__) |
||
809 |
case '\a': |
||
810 |
return "\\a"; |
||
811 |
case '\v': |
||
812 |
return "\\v"; |
||
813 |
#endif |
||
814 |
|||
815 |
default: |
||
816 |
snprintf(rform, sizeof(rform), "\\%.3o", (unsigned int) c); |
||
817 |
return rform; |
||
818 |
} |
||
819 |
} else if (c == ' ') |
||
820 |
return "' '"; |
||
821 |
|||
822 |
else { |
||
823 |
rform[0] = c; |
||
824 |
rform[1] = '\0'; |
||
825 |
|||
826 |
return rform; |
||
827 |
} |
||
828 |
} |
||
829 |
|||
830 |
|||
831 |
/* reallocate_array - increase the size of a dynamic array */ |
||
832 |
|||
833 |
void * |
||
834 |
reallocate_array(array, size, element_size) |
||
835 |
void *array; |
||
836 |
int size; |
||
837 |
size_t element_size; |
||
838 |
{ |
||
839 |
void *new_array; |
||
840 |
950 |
size_t num_bytes = element_size * size; |
|
841 |
|||
842 |
475 |
new_array = realloc(array, num_bytes); |
|
843 |
✗✓ | 475 |
if (!new_array) |
844 |
flexfatal(_("attempt to increase array size failed")); |
||
845 |
|||
846 |
475 |
return new_array; |
|
847 |
} |
||
848 |
|||
849 |
|||
850 |
/* skelout - write out one section of the skeleton file |
||
851 |
* |
||
852 |
* Description |
||
853 |
* Copies skelfile or skel array to stdout until a line beginning with |
||
854 |
* "%%" or EOF is found. |
||
855 |
*/ |
||
856 |
void |
||
857 |
skelout() |
||
858 |
{ |
||
859 |
420 |
char buf_storage[MAXLINE]; |
|
860 |
210 |
char *buf = buf_storage; |
|
861 |
210 |
bool do_copy = true; |
|
862 |
|||
863 |
/* "reset" the state by clearing the buffer and pushing a '1' */ |
||
864 |
✓✓ | 210 |
if (sko_len > 0) |
865 |
180 |
sko_peek(&do_copy); |
|
866 |
210 |
sko_len = 0; |
|
867 |
210 |
sko_push(do_copy = true); |
|
868 |
|||
869 |
|||
870 |
/* |
||
871 |
* Loop pulling lines either from the skelfile, if we're using one, |
||
872 |
* or from the skel[] array. |
||
873 |
*/ |
||
874 |
✗✓✓✓ |
112170 |
while (skelfile ? |
875 |
(fgets(buf, MAXLINE, skelfile) != NULL) : |
||
876 |
37320 |
((buf = (char *) skel[skel_ind++]) != 0)) { |
|
877 |
|||
878 |
✗✓ | 37310 |
if (skelfile) |
879 |
chomp(buf); |
||
880 |
|||
881 |
/* copy from skel array */ |
||
882 |
✓✓ | 37310 |
if (buf[0] == '%') { /* control line */ |
883 |
/* print the control line as a comment. */ |
||
884 |
✗✓✗✗ |
3390 |
if (ddebug && buf[1] != '#') { |
885 |
if (buf[strlen(buf) - 1] == '\\') |
||
886 |
out_str("/* %s */\\\n", buf); |
||
887 |
else |
||
888 |
out_str("/* %s */\n", buf); |
||
889 |
} |
||
890 |
/* |
||
891 |
* We've been accused of using cryptic markers in the |
||
892 |
* skel. So we'll use |
||
893 |
* emacs-style-hyphenated-commands. We might consider |
||
894 |
* a hash if this if-else-if-else chain gets too |
||
895 |
* large. |
||
896 |
*/ |
||
897 |
#define cmd_match(s) (strncmp(buf,(s),strlen(s))==0) |
||
898 |
|||
899 |
✓✓ | 3390 |
if (buf[1] == '%') { |
900 |
/* %% is a break point for skelout() */ |
||
901 |
200 |
return; |
|
902 |
✗✓ | 3190 |
} else if (cmd_match(CMD_PUSH)) { |
903 |
sko_push(do_copy); |
||
904 |
if (ddebug) { |
||
905 |
out_str("/*(state = (%s) */", do_copy ? "true" : "false"); |
||
906 |
} |
||
907 |
out_str("%s\n", buf[strlen(buf) - 1] == '\\' ? "\\" : ""); |
||
908 |
✗✓ | 3190 |
} else if (cmd_match(CMD_POP)) { |
909 |
sko_pop(&do_copy); |
||
910 |
if (ddebug) { |
||
911 |
out_str("/*(state = (%s) */", do_copy ? "true" : "false"); |
||
912 |
} |
||
913 |
out_str("%s\n", buf[strlen(buf) - 1] == '\\' ? "\\" : ""); |
||
914 |
✓✓ | 3190 |
} else if (cmd_match(CMD_IF_REENTRANT)) { |
915 |
80 |
sko_push(do_copy); |
|
916 |
80 |
do_copy = reentrant && do_copy; |
|
917 |
✓✓ | 3190 |
} else if (cmd_match(CMD_IF_NOT_REENTRANT)) { |
918 |
70 |
sko_push(do_copy); |
|
919 |
70 |
do_copy = !reentrant && do_copy; |
|
920 |
✓✓ | 3110 |
} else if (cmd_match(CMD_IF_BISON_BRIDGE)) { |
921 |
20 |
sko_push(do_copy); |
|
922 |
20 |
do_copy = bison_bridge_lval && do_copy; |
|
923 |
✗✓ | 3040 |
} else if (cmd_match(CMD_IF_NOT_BISON_BRIDGE)) { |
924 |
sko_push(do_copy); |
||
925 |
do_copy = !bison_bridge_lval && do_copy; |
||
926 |
✓✓ | 3020 |
} else if (cmd_match(CMD_ENDIF)) { |
927 |
1020 |
sko_pop(&do_copy); |
|
928 |
✓✓ | 3020 |
} else if (cmd_match(CMD_IF_TABLES_SER)) { |
929 |
30 |
do_copy = do_copy && tablesext; |
|
930 |
✓✓ | 2000 |
} else if (cmd_match(CMD_TABLES_YYDMAP)) { |
931 |
✓✗ | 10 |
if (tablesext && yydmap_buf.elts) |
932 |
outn((char *) (yydmap_buf.elts)); |
||
933 |
✓✓ | 1960 |
} else if (cmd_match(CMD_DEFINE_YYTABLES)) { |
934 |
10 |
out_str("#define YYTABLES_NAME \"%s\"\n", |
|
935 |
10 |
tablesname ? tablesname : "yytables"); |
|
936 |
✓✓ | 1960 |
} else if (cmd_match(CMD_IF_CPP_ONLY)) { |
937 |
/* only for C++ */ |
||
938 |
310 |
sko_push(do_copy); |
|
939 |
310 |
do_copy = C_plus_plus; |
|
940 |
✓✓ | 1950 |
} else if (cmd_match(CMD_IF_C_ONLY)) { |
941 |
/* %- only for C */ |
||
942 |
470 |
sko_push(do_copy); |
|
943 |
470 |
do_copy = !C_plus_plus; |
|
944 |
✓✓ | 1640 |
} else if (cmd_match(CMD_IF_C_OR_CPP)) { |
945 |
/* %* for C and C++ */ |
||
946 |
40 |
sko_push(do_copy); |
|
947 |
40 |
do_copy = true; |
|
948 |
✓✓ | 1170 |
} else if (cmd_match(CMD_NOT_FOR_HEADER)) { |
949 |
/* %c begin linkage-only (non-header) code. */ |
||
950 |
120 |
OUT_BEGIN_CODE(); |
|
951 |
✓✓ | 1130 |
} else if (cmd_match(CMD_OK_FOR_HEADER)) { |
952 |
/* %e end linkage-only code. */ |
||
953 |
120 |
OUT_END_CODE(); |
|
954 |
✓✗ | 1010 |
} else if (buf[1] == '#') { |
955 |
/* %# a comment in the skel. ignore. */ |
||
956 |
} else { |
||
957 |
flexfatal(_("bad line in skeleton file")); |
||
958 |
} |
||
959 |
✓✓ | 33920 |
} else if (do_copy) |
960 |
23020 |
outn(buf); |
|
961 |
} /* end while */ |
||
962 |
220 |
} |
|
963 |
|||
964 |
|||
965 |
/* transition_struct_out - output a yy_trans_info structure |
||
966 |
* |
||
967 |
* outputs the yy_trans_info structure with the two elements, element_v and |
||
968 |
* element_n. Formats the output with spaces and carriage returns. |
||
969 |
*/ |
||
970 |
|||
971 |
void |
||
972 |
transition_struct_out(element_v, element_n) |
||
973 |
int element_v, element_n; |
||
974 |
{ |
||
975 |
|||
976 |
/* short circuit any output */ |
||
977 |
if (!gentables) |
||
978 |
return; |
||
979 |
|||
980 |
out_dec2(" {%4d,%4d },", element_v, element_n); |
||
981 |
|||
982 |
datapos += TRANS_STRUCT_PRINT_LENGTH; |
||
983 |
|||
984 |
if (datapos >= 79 - TRANS_STRUCT_PRINT_LENGTH) { |
||
985 |
outc('\n'); |
||
986 |
|||
987 |
if (++dataline % 10 == 0) |
||
988 |
outc('\n'); |
||
989 |
|||
990 |
datapos = 0; |
||
991 |
} |
||
992 |
} |
||
993 |
|||
994 |
|||
995 |
/* The following is only needed when building flex's parser using certain |
||
996 |
* broken versions of bison. |
||
997 |
*/ |
||
998 |
void * |
||
999 |
yy_flex_xmalloc(size) |
||
1000 |
int size; |
||
1001 |
{ |
||
1002 |
void *result = malloc((size_t) size); |
||
1003 |
|||
1004 |
if (!result) |
||
1005 |
flexfatal(_ |
||
1006 |
("memory allocation failed in yy_flex_xmalloc()")); |
||
1007 |
|||
1008 |
return result; |
||
1009 |
} |
||
1010 |
|||
1011 |
|||
1012 |
/* Remove all '\n' and '\r' characters, if any, from the end of str. |
||
1013 |
* str can be any null-terminated string, or NULL. |
||
1014 |
* returns str. */ |
||
1015 |
char * |
||
1016 |
chomp(str) |
||
1017 |
char *str; |
||
1018 |
{ |
||
1019 |
char *p = str; |
||
1020 |
|||
1021 |
if (!str || !*str) /* s is null or empty string */ |
||
1022 |
return str; |
||
1023 |
|||
1024 |
/* find end of string minus one */ |
||
1025 |
while (*p) |
||
1026 |
++p; |
||
1027 |
--p; |
||
1028 |
|||
1029 |
/* eat newlines */ |
||
1030 |
while (p >= str && (*p == '\r' || *p == '\n')) |
||
1031 |
*p-- = 0; |
||
1032 |
return str; |
||
1033 |
} |
Generated by: GCOVR (Version 3.3) |