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