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