|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1990 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Vern Paxson. ! 7: * ! 8: * The United States Government has rights in this work pursuant ! 9: * to contract no. DE-AC03-76SF00098 between the United States ! 10: * Department of Energy and the University of California. ! 11: * ! 12: * Redistribution and use in source and binary forms are permitted provided ! 13: * that: (1) source distributions retain this entire copyright notice and ! 14: * comment, and (2) distributions including binaries display the following ! 15: * acknowledgement: ``This product includes software developed by the ! 16: * University of California, Berkeley and its contributors'' in the ! 17: * documentation or other materials provided with the distribution and in ! 18: * all advertising materials mentioning features or use of this software. ! 19: * Neither the name of the University nor the names of its contributors may ! 20: * be used to endorse or promote products derived from this software without ! 21: * specific prior written permission. ! 22: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 23: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 24: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 25: */ ! 26: ! 27: #ifndef lint ! 28: static char sccsid[] = "@(#)misc.c 5.2 (Berkeley) 6/18/90"; ! 29: #endif /* not lint */ ! 30: ! 31: /* misc - miscellaneous flex routines */ ! 32: ! 33: #include <ctype.h> ! 34: #include "flexdef.h" ! 35: ! 36: /* ANSI C does not guarantee that isascii() is defined */ ! 37: #ifndef isascii ! 38: #define isascii(c) ((c) <= 0177) ! 39: #endif ! 40: ! 41: ! 42: ! 43: /* declare functions that have forward references */ ! 44: ! 45: void dataflush PROTO(()); ! 46: int otoi PROTO((Char [])); ! 47: ! 48: ! 49: /* action_out - write the actions from the temporary file to lex.yy.c ! 50: * ! 51: * synopsis ! 52: * action_out(); ! 53: * ! 54: * Copies the action file up to %% (or end-of-file) to lex.yy.c ! 55: */ ! 56: ! 57: void action_out() ! 58: ! 59: { ! 60: char buf[MAXLINE]; ! 61: ! 62: while ( fgets( buf, MAXLINE, temp_action_file ) != NULL ) ! 63: if ( buf[0] == '%' && buf[1] == '%' ) ! 64: break; ! 65: else ! 66: fputs( buf, stdout ); ! 67: } ! 68: ! 69: ! 70: /* allocate_array - allocate memory for an integer array of the given size */ ! 71: ! 72: void *allocate_array( size, element_size ) ! 73: int size, element_size; ! 74: ! 75: { ! 76: register void *mem; ! 77: ! 78: /* on 16-bit int machines (e.g., 80286) we might be trying to ! 79: * allocate more than a signed int can hold, and that won't ! 80: * work. Cheap test: ! 81: */ ! 82: if ( element_size * size <= 0 ) ! 83: flexfatal( "request for < 1 byte in allocate_array()" ); ! 84: ! 85: mem = (void *) malloc( (unsigned) (element_size * size) ); ! 86: ! 87: if ( mem == NULL ) ! 88: flexfatal( "memory allocation failed in allocate_array()" ); ! 89: ! 90: return ( mem ); ! 91: } ! 92: ! 93: ! 94: /* all_lower - true if a string is all lower-case ! 95: * ! 96: * synopsis: ! 97: * Char *str; ! 98: * int all_lower(); ! 99: * true/false = all_lower( str ); ! 100: */ ! 101: ! 102: int all_lower( str ) ! 103: register Char *str; ! 104: ! 105: { ! 106: while ( *str ) ! 107: { ! 108: if ( ! isascii( *str ) || ! islower( *str ) ) ! 109: return ( 0 ); ! 110: ++str; ! 111: } ! 112: ! 113: return ( 1 ); ! 114: } ! 115: ! 116: ! 117: /* all_upper - true if a string is all upper-case ! 118: * ! 119: * synopsis: ! 120: * Char *str; ! 121: * int all_upper(); ! 122: * true/false = all_upper( str ); ! 123: */ ! 124: ! 125: int all_upper( str ) ! 126: register Char *str; ! 127: ! 128: { ! 129: while ( *str ) ! 130: { ! 131: if ( ! isascii( *str ) || ! isupper( (char) *str ) ) ! 132: return ( 0 ); ! 133: ++str; ! 134: } ! 135: ! 136: return ( 1 ); ! 137: } ! 138: ! 139: ! 140: /* bubble - bubble sort an integer array in increasing order ! 141: * ! 142: * synopsis ! 143: * int v[n], n; ! 144: * bubble( v, n ); ! 145: * ! 146: * description ! 147: * sorts the first n elements of array v and replaces them in ! 148: * increasing order. ! 149: * ! 150: * passed ! 151: * v - the array to be sorted ! 152: * n - the number of elements of 'v' to be sorted */ ! 153: ! 154: void bubble( v, n ) ! 155: int v[], n; ! 156: ! 157: { ! 158: register int i, j, k; ! 159: ! 160: for ( i = n; i > 1; --i ) ! 161: for ( j = 1; j < i; ++j ) ! 162: if ( v[j] > v[j + 1] ) /* compare */ ! 163: { ! 164: k = v[j]; /* exchange */ ! 165: v[j] = v[j + 1]; ! 166: v[j + 1] = k; ! 167: } ! 168: } ! 169: ! 170: ! 171: /* clower - replace upper-case letter to lower-case ! 172: * ! 173: * synopsis: ! 174: * Char clower(); ! 175: * int c; ! 176: * c = clower( c ); ! 177: */ ! 178: ! 179: Char clower( c ) ! 180: register int c; ! 181: ! 182: { ! 183: return ( (isascii( c ) && isupper( c )) ? tolower( c ) : c ); ! 184: } ! 185: ! 186: ! 187: /* copy_string - returns a dynamically allocated copy of a string ! 188: * ! 189: * synopsis ! 190: * char *str, *copy, *copy_string(); ! 191: * copy = copy_string( str ); ! 192: */ ! 193: ! 194: char *copy_string( str ) ! 195: register char *str; ! 196: ! 197: { ! 198: register char *c; ! 199: char *copy; ! 200: ! 201: /* find length */ ! 202: for ( c = str; *c; ++c ) ! 203: ; ! 204: ! 205: copy = malloc( (unsigned) ((c - str + 1) * sizeof( char )) ); ! 206: ! 207: if ( copy == NULL ) ! 208: flexfatal( "dynamic memory failure in copy_string()" ); ! 209: ! 210: for ( c = copy; (*c++ = *str++); ) ! 211: ; ! 212: ! 213: return ( copy ); ! 214: } ! 215: ! 216: ! 217: /* copy_unsigned_string - ! 218: * returns a dynamically allocated copy of a (potentially) unsigned string ! 219: * ! 220: * synopsis ! 221: * Char *str, *copy, *copy_unsigned_string(); ! 222: * copy = copy_unsigned_string( str ); ! 223: */ ! 224: ! 225: Char *copy_unsigned_string( str ) ! 226: register Char *str; ! 227: ! 228: { ! 229: register Char *c; ! 230: Char *copy; ! 231: ! 232: /* find length */ ! 233: for ( c = str; *c; ++c ) ! 234: ; ! 235: ! 236: copy = (Char *) malloc( (unsigned) ((c - str + 1) * sizeof( Char )) ); ! 237: ! 238: if ( copy == NULL ) ! 239: flexfatal( "dynamic memory failure in copy_unsigned_string()" ); ! 240: ! 241: for ( c = copy; (*c++ = *str++); ) ! 242: ; ! 243: ! 244: return ( copy ); ! 245: } ! 246: ! 247: ! 248: /* cshell - shell sort a character array in increasing order ! 249: * ! 250: * synopsis ! 251: * ! 252: * Char v[n]; ! 253: * int n, special_case_0; ! 254: * cshell( v, n, special_case_0 ); ! 255: * ! 256: * description ! 257: * does a shell sort of the first n elements of array v. ! 258: * If special_case_0 is true, then any element equal to 0 ! 259: * is instead assumed to have infinite weight. ! 260: * ! 261: * passed ! 262: * v - array to be sorted ! 263: * n - number of elements of v to be sorted ! 264: */ ! 265: ! 266: void cshell( v, n, special_case_0 ) ! 267: Char v[]; ! 268: int n, special_case_0; ! 269: ! 270: { ! 271: int gap, i, j, jg; ! 272: Char k; ! 273: ! 274: for ( gap = n / 2; gap > 0; gap = gap / 2 ) ! 275: for ( i = gap; i < n; ++i ) ! 276: for ( j = i - gap; j >= 0; j = j - gap ) ! 277: { ! 278: jg = j + gap; ! 279: ! 280: if ( special_case_0 ) ! 281: { ! 282: if ( v[jg] == 0 ) ! 283: break; ! 284: ! 285: else if ( v[j] != 0 && v[j] <= v[jg] ) ! 286: break; ! 287: } ! 288: ! 289: else if ( v[j] <= v[jg] ) ! 290: break; ! 291: ! 292: k = v[j]; ! 293: v[j] = v[jg]; ! 294: v[jg] = k; ! 295: } ! 296: } ! 297: ! 298: ! 299: /* dataend - finish up a block of data declarations ! 300: * ! 301: * synopsis ! 302: * dataend(); ! 303: */ ! 304: ! 305: void dataend() ! 306: ! 307: { ! 308: if ( datapos > 0 ) ! 309: dataflush(); ! 310: ! 311: /* add terminator for initialization */ ! 312: puts( " } ;\n" ); ! 313: ! 314: dataline = 0; ! 315: datapos = 0; ! 316: } ! 317: ! 318: ! 319: ! 320: /* dataflush - flush generated data statements ! 321: * ! 322: * synopsis ! 323: * dataflush(); ! 324: */ ! 325: ! 326: void dataflush() ! 327: ! 328: { ! 329: putchar( '\n' ); ! 330: ! 331: if ( ++dataline >= NUMDATALINES ) ! 332: { ! 333: /* put out a blank line so that the table is grouped into ! 334: * large blocks that enable the user to find elements easily ! 335: */ ! 336: putchar( '\n' ); ! 337: dataline = 0; ! 338: } ! 339: ! 340: /* reset the number of characters written on the current line */ ! 341: datapos = 0; ! 342: } ! 343: ! 344: ! 345: /* flexerror - report an error message and terminate ! 346: * ! 347: * synopsis ! 348: * char msg[]; ! 349: * flexerror( msg ); ! 350: */ ! 351: ! 352: void flexerror( msg ) ! 353: char msg[]; ! 354: ! 355: { ! 356: fprintf( stderr, "%s: %s\n", program_name, msg ); ! 357: ! 358: flexend( 1 ); ! 359: } ! 360: ! 361: ! 362: /* flexfatal - report a fatal error message and terminate ! 363: * ! 364: * synopsis ! 365: * char msg[]; ! 366: * flexfatal( msg ); ! 367: */ ! 368: ! 369: void flexfatal( msg ) ! 370: char msg[]; ! 371: ! 372: { ! 373: fprintf( stderr, "%s: fatal internal error, %s\n", program_name, msg ); ! 374: flexend( 1 ); ! 375: } ! 376: ! 377: ! 378: /* flex_gettime - return current time ! 379: * ! 380: * synopsis ! 381: * char *flex_gettime(), *time_str; ! 382: * time_str = flex_gettime(); ! 383: * ! 384: * note ! 385: * the routine name has the "flex_" prefix because of name clashes ! 386: * with Turbo-C ! 387: */ ! 388: ! 389: /* include sys/types.h to use time_t and make lint happy */ ! 390: ! 391: #ifndef MS_DOS ! 392: #ifndef VMS ! 393: #include <sys/types.h> ! 394: #else ! 395: #include <types.h> ! 396: #endif ! 397: #endif ! 398: ! 399: #ifdef MS_DOS ! 400: #include <time.h> ! 401: typedef long time_t; ! 402: #endif ! 403: ! 404: char *flex_gettime() ! 405: ! 406: { ! 407: time_t t, time(); ! 408: char *result, *ctime(), *copy_string(); ! 409: ! 410: t = time( (long *) 0 ); ! 411: ! 412: result = copy_string( ctime( &t ) ); ! 413: ! 414: /* get rid of trailing newline */ ! 415: result[24] = '\0'; ! 416: ! 417: return ( result ); ! 418: } ! 419: ! 420: ! 421: /* lerrif - report an error message formatted with one integer argument ! 422: * ! 423: * synopsis ! 424: * char msg[]; ! 425: * int arg; ! 426: * lerrif( msg, arg ); ! 427: */ ! 428: ! 429: void lerrif( msg, arg ) ! 430: char msg[]; ! 431: int arg; ! 432: ! 433: { ! 434: char errmsg[MAXLINE]; ! 435: (void) sprintf( errmsg, msg, arg ); ! 436: flexerror( errmsg ); ! 437: } ! 438: ! 439: ! 440: /* lerrsf - report an error message formatted with one string argument ! 441: * ! 442: * synopsis ! 443: * char msg[], arg[]; ! 444: * lerrsf( msg, arg ); ! 445: */ ! 446: ! 447: void lerrsf( msg, arg ) ! 448: char msg[], arg[]; ! 449: ! 450: { ! 451: char errmsg[MAXLINE]; ! 452: ! 453: (void) sprintf( errmsg, msg, arg ); ! 454: flexerror( errmsg ); ! 455: } ! 456: ! 457: ! 458: /* htoi - convert a hexadecimal digit string to an integer value ! 459: * ! 460: * synopsis: ! 461: * int val, htoi(); ! 462: * Char str[]; ! 463: * val = htoi( str ); ! 464: */ ! 465: ! 466: int htoi( str ) ! 467: Char str[]; ! 468: ! 469: { ! 470: int result; ! 471: ! 472: (void) sscanf( (char *) str, "%x", &result ); ! 473: ! 474: return ( result ); ! 475: } ! 476: ! 477: ! 478: /* line_directive_out - spit out a "# line" statement */ ! 479: ! 480: void line_directive_out( output_file_name ) ! 481: FILE *output_file_name; ! 482: ! 483: { ! 484: if ( infilename && gen_line_dirs ) ! 485: fprintf( output_file_name, "# line %d \"%s\"\n", linenum, infilename ); ! 486: } ! 487: ! 488: ! 489: /* mk2data - generate a data statement for a two-dimensional array ! 490: * ! 491: * synopsis ! 492: * int value; ! 493: * mk2data( value ); ! 494: * ! 495: * generates a data statement initializing the current 2-D array to "value" ! 496: */ ! 497: void mk2data( value ) ! 498: int value; ! 499: ! 500: { ! 501: if ( datapos >= NUMDATAITEMS ) ! 502: { ! 503: putchar( ',' ); ! 504: dataflush(); ! 505: } ! 506: ! 507: if ( datapos == 0 ) ! 508: /* indent */ ! 509: fputs( " ", stdout ); ! 510: ! 511: else ! 512: putchar( ',' ); ! 513: ! 514: ++datapos; ! 515: ! 516: printf( "%5d", value ); ! 517: } ! 518: ! 519: ! 520: /* mkdata - generate a data statement ! 521: * ! 522: * synopsis ! 523: * int value; ! 524: * mkdata( value ); ! 525: * ! 526: * generates a data statement initializing the current array element to ! 527: * "value" ! 528: */ ! 529: void mkdata( value ) ! 530: int value; ! 531: ! 532: { ! 533: if ( datapos >= NUMDATAITEMS ) ! 534: { ! 535: putchar( ',' ); ! 536: dataflush(); ! 537: } ! 538: ! 539: if ( datapos == 0 ) ! 540: /* indent */ ! 541: fputs( " ", stdout ); ! 542: ! 543: else ! 544: putchar( ',' ); ! 545: ! 546: ++datapos; ! 547: ! 548: printf( "%5d", value ); ! 549: } ! 550: ! 551: ! 552: /* myctoi - return the integer represented by a string of digits ! 553: * ! 554: * synopsis ! 555: * Char array[]; ! 556: * int val, myctoi(); ! 557: * val = myctoi( array ); ! 558: * ! 559: */ ! 560: ! 561: int myctoi( array ) ! 562: Char array[]; ! 563: ! 564: { ! 565: int val = 0; ! 566: ! 567: (void) sscanf( (char *) array, "%d", &val ); ! 568: ! 569: return ( val ); ! 570: } ! 571: ! 572: ! 573: /* myesc - return character corresponding to escape sequence ! 574: * ! 575: * synopsis ! 576: * Char array[], c, myesc(); ! 577: * c = myesc( array ); ! 578: * ! 579: */ ! 580: ! 581: Char myesc( array ) ! 582: Char array[]; ! 583: ! 584: { ! 585: switch ( array[1] ) ! 586: { ! 587: case 'a': return ( '\a' ); ! 588: case 'b': return ( '\b' ); ! 589: case 'f': return ( '\f' ); ! 590: case 'n': return ( '\n' ); ! 591: case 'r': return ( '\r' ); ! 592: case 't': return ( '\t' ); ! 593: case 'v': return ( '\v' ); ! 594: ! 595: case 'x': ! 596: /* fall through */ ! 597: ! 598: case '0': ! 599: case '1': ! 600: case '2': ! 601: case '3': ! 602: case '4': ! 603: case '5': ! 604: case '6': ! 605: case '7': ! 606: case '8': ! 607: case '9': ! 608: ! 609: { /* \<octal> or \x<hex> */ ! 610: Char c, esc_char; ! 611: register int sptr = 1; ! 612: ! 613: if ( array[1] == 'x' ) ! 614: ++sptr; ! 615: ! 616: while ( isascii( array[sptr] ) && isdigit( array[sptr] ) ) ! 617: /* don't increment inside loop control because if ! 618: * isdigit() is a macro it will expand it to two ! 619: * increments ... ! 620: */ ! 621: ++sptr; ! 622: ! 623: c = array[sptr]; ! 624: array[sptr] = '\0'; ! 625: ! 626: if ( array[1] == 'x' ) ! 627: esc_char = htoi( array + 2 ); ! 628: else ! 629: esc_char = otoi( array + 1 ); ! 630: ! 631: array[sptr] = c; ! 632: ! 633: return ( esc_char ); ! 634: } ! 635: ! 636: default: ! 637: return ( array[1] ); ! 638: } ! 639: } ! 640: ! 641: ! 642: /* otoi - convert an octal digit string to an integer value ! 643: * ! 644: * synopsis: ! 645: * int val, otoi(); ! 646: * Char str[]; ! 647: * val = otoi( str ); ! 648: */ ! 649: ! 650: int otoi( str ) ! 651: Char str[]; ! 652: ! 653: { ! 654: int result; ! 655: ! 656: (void) sscanf( (char *) str, "%o", &result ); ! 657: ! 658: return ( result ); ! 659: } ! 660: ! 661: ! 662: /* readable_form - return the the human-readable form of a character ! 663: * ! 664: * synopsis: ! 665: * int c; ! 666: * char *readable_form(); ! 667: * <string> = readable_form( c ); ! 668: * ! 669: * The returned string is in static storage. ! 670: */ ! 671: ! 672: char *readable_form( c ) ! 673: register int c; ! 674: ! 675: { ! 676: static char rform[10]; ! 677: ! 678: if ( (c >= 0 && c < 32) || c >= 127 ) ! 679: { ! 680: switch ( c ) ! 681: { ! 682: case '\n': return ( "\\n" ); ! 683: case '\t': return ( "\\t" ); ! 684: case '\f': return ( "\\f" ); ! 685: case '\r': return ( "\\r" ); ! 686: case '\b': return ( "\\b" ); ! 687: ! 688: default: ! 689: (void) sprintf( rform, "\\%.3o", c ); ! 690: return ( rform ); ! 691: } ! 692: } ! 693: ! 694: else if ( c == ' ' ) ! 695: return ( "' '" ); ! 696: ! 697: else ! 698: { ! 699: rform[0] = c; ! 700: rform[1] = '\0'; ! 701: ! 702: return ( rform ); ! 703: } ! 704: } ! 705: ! 706: ! 707: /* reallocate_array - increase the size of a dynamic array */ ! 708: ! 709: void *reallocate_array( array, size, element_size ) ! 710: void *array; ! 711: int size, element_size; ! 712: ! 713: { ! 714: register void *new_array; ! 715: ! 716: /* same worry as in allocate_array(): */ ! 717: if ( size * element_size <= 0 ) ! 718: flexfatal( "attempt to increase array size by less than 1 byte" ); ! 719: ! 720: new_array = ! 721: (void *) realloc( (char *)array, (unsigned) (size * element_size )); ! 722: ! 723: if ( new_array == NULL ) ! 724: flexfatal( "attempt to increase array size failed" ); ! 725: ! 726: return ( new_array ); ! 727: } ! 728: ! 729: ! 730: /* skelout - write out one section of the skeleton file ! 731: * ! 732: * synopsis ! 733: * skelout(); ! 734: * ! 735: * DESCRIPTION ! 736: * Copies from skelfile to stdout until a line beginning with "%%" or ! 737: * EOF is found. ! 738: */ ! 739: void skelout() ! 740: ! 741: { ! 742: char buf[MAXLINE]; ! 743: ! 744: while ( fgets( buf, MAXLINE, skelfile ) != NULL ) ! 745: if ( buf[0] == '%' && buf[1] == '%' ) ! 746: break; ! 747: else ! 748: fputs( buf, stdout ); ! 749: } ! 750: ! 751: ! 752: /* transition_struct_out - output a yy_trans_info structure ! 753: * ! 754: * synopsis ! 755: * int element_v, element_n; ! 756: * transition_struct_out( element_v, element_n ); ! 757: * ! 758: * outputs the yy_trans_info structure with the two elements, element_v and ! 759: * element_n. Formats the output with spaces and carriage returns. ! 760: */ ! 761: ! 762: void transition_struct_out( element_v, element_n ) ! 763: int element_v, element_n; ! 764: ! 765: { ! 766: printf( "%7d, %5d,", element_v, element_n ); ! 767: ! 768: datapos += TRANS_STRUCT_PRINT_LENGTH; ! 769: ! 770: if ( datapos >= 75 ) ! 771: { ! 772: putchar( '\n' ); ! 773: ! 774: if ( ++dataline % 10 == 0 ) ! 775: putchar( '\n' ); ! 776: ! 777: datapos = 0; ! 778: } ! 779: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.