home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 290_01 / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-12  |  11.1 KB  |  587 lines

  1. /* misc - miscellaneous flex routines */
  2.  
  3. /*
  4.  * Copyright (c) 1987, the University of California
  5.  * 
  6.  * The United States Government has rights in this work pursuant to
  7.  * contract no. DE-AC03-76SF00098 between the United States Department of
  8.  * Energy and the University of California.
  9.  * 
  10.  * This program may be redistributed.  Enhancements and derivative works
  11.  * may be created provided the new works, if made available to the general
  12.  * public, are made available for use by anyone.
  13.  */
  14.  
  15. #include <time.h>
  16. #include "flexdef.h"
  17.  
  18. #include "main.h"
  19. #include "misc.h"
  20. #include "main.h"
  21. #include "parse.h"
  22.  
  23. /* action_out - write the actions from the temporary file to lex.yy.c
  24.  *
  25.  * synopsis
  26.  *     action_out();
  27.  *
  28.  *     Copies the action file up to %% (or end-of-file) to lex.yy.c
  29.  */
  30.  
  31. void action_out()
  32.  
  33. {
  34.     char buf[MAXLINE];
  35.  
  36.     while ( fgets( buf, MAXLINE, temp_action_file ) != NULL )
  37.         if ( buf[0] == '%' && buf[1] == '%' )
  38.             break;
  39.         else
  40.             fputs( buf, stdout );
  41. }
  42.  
  43.  
  44. /* allocate_array - allocate memory for an integer array of the given size */
  45.  
  46. char *allocate_array( size, element_size )
  47. int size, element_size;
  48.  
  49. {
  50.     register char *mem = malloc( (unsigned) (element_size * size) );
  51.  
  52.     if ( mem == NULL )
  53.         flexfatal( "memory allocation failed in allocate_array()" );
  54.  
  55.     return ( mem );
  56. }
  57.  
  58.  
  59. /* bubble - bubble sort an integer array in increasing order
  60.  *
  61.  * synopsis
  62.  *   int v[n], n;
  63.  *   bubble( v, n );
  64.  *
  65.  * description
  66.  *   sorts the first n elements of array v and replaces them in
  67.  *   increasing order.
  68.  *
  69.  * passed
  70.  *   v - the array to be sorted
  71.  *   n - the number of elements of 'v' to be sorted */
  72.  
  73. void bubble( v, n )
  74. int v[], n;
  75.  
  76. {
  77.     register int i, j, k;
  78.  
  79.     for ( i = n; i > 1; --i )
  80.         for ( j = 1; j < i; ++j )
  81.             if ( v[j] > v[j + 1] )      /* compare */
  82.             {
  83.                 k = v[j];       /* exchange */
  84.                 v[j] = v[j + 1];
  85.                 v[j + 1] = k;
  86.             }
  87. }
  88.  
  89.  
  90. /* clower - replace upper-case letter to lower-case
  91.  *
  92.  * synopsis:
  93.  *    char clower(), c;
  94.  *    c = clower( c );
  95.  */
  96.  
  97. char clower( c )
  98. register char c;
  99.  
  100. {
  101.     return ( isupper(c) ? tolower(c) : c );
  102. }
  103.  
  104.  
  105. /* copy_string - returns a dynamically allocated copy of a string
  106.  *
  107.  * synopsis
  108.  *    char *str, *copy, *copy_string();
  109.  *    copy = copy_string( str );
  110.  */
  111.  
  112. char *copy_string( str )
  113. register char *str;
  114.  
  115. {
  116.     register char *c;
  117.     char *copy;
  118.  
  119.     /* find length */
  120.     for ( c = str; *c; ++c )
  121.         ;
  122.  
  123.     copy = malloc( (unsigned) ((c - str + 1) * sizeof( char )) );
  124.  
  125.     if ( copy == NULL )
  126.         flexfatal( "dynamic memory failure in copy_string()" );
  127.  
  128.     for ( c = copy; (*c++ = *str++); )
  129.         ;
  130.  
  131.     return ( copy );
  132. }
  133.  
  134.  
  135. /* cshell - shell sort a character array in increasing order
  136.  *
  137.  * synopsis
  138.  *
  139.  *   char v[n];
  140.  *   int n;
  141.  *   cshell( v, n );
  142.  *
  143.  * description
  144.  *   does a shell sort of the first n elements of array v.
  145.  *
  146.  * passed
  147.  *   v - array to be sorted
  148.  *   n - number of elements of v to be sorted
  149.  */
  150. void cshell( v, n )
  151. char v[];
  152. int n;
  153.  
  154. {
  155.     int gap, i, j, jg;
  156.     char k;
  157.  
  158.     for ( gap = n / 2; gap > 0; gap = gap / 2 )
  159.         for ( i = gap; i < n; ++i )
  160.             for ( j = i - gap; j >= 0; j = j - gap )
  161.             {
  162.                 jg = j + gap;
  163.  
  164.                 if ( v[j] <= v[jg] )
  165.                     break;
  166.  
  167.                 k = v[j];
  168.                 v[j] = v[jg];
  169.                 v[jg] = k;
  170.             }
  171. }
  172.  
  173.  
  174. /* dataend - finish up a block of data declarations
  175.  *
  176.  * synopsis
  177.  *    dataend();
  178.  */
  179. void dataend()
  180.  
  181. {
  182.     if ( datapos > 0 )
  183.         dataflush();
  184.  
  185.     /* add terminator for initialization */
  186.     puts( "    } ;\n" );
  187.  
  188.     dataline = 0;
  189. }
  190.  
  191.  
  192.  
  193. /* dataflush - flush generated data statements
  194.  *
  195.  * synopsis
  196.  *    dataflush();
  197.  */
  198. void dataflush()
  199.  
  200. {
  201.     putchar( '\n' );
  202.  
  203.     if ( ++dataline >= NUMDATALINES )
  204.     {
  205.         /* put out a blank line so that the table is grouped into
  206.          * large blocks that enable the user to find elements easily
  207.          */
  208.         putchar( '\n' );
  209.         dataline = 0;
  210.     }
  211.  
  212.     /* reset the number of characters written on the current line */
  213.     datapos = 0;
  214. }
  215.  
  216. /* gettimestr - return current time
  217.  *
  218.  * synopsis
  219.  *    char *gettimestr(), *time_str;
  220.  *    time_str = gettimestr();
  221.  */
  222.  
  223. char *gettimestr()
  224. {
  225.     time_t t ;
  226.     char *result, *s ;
  227.  
  228.     t = time( (time_t *) 0 );
  229.  
  230.     result = strdup( ctime( &t ) );
  231.  
  232.     s = result + strlen( result) - 1 ;      /* find last char in time string */
  233.  
  234.     while (*s && isspace(*s))               /* trim trailing  whitespace */
  235.         *s-- = '\0' ;
  236.  
  237.     return ( result );
  238. }
  239.  
  240.  
  241.  
  242. /* lerrif - report an error message formatted with one integer argument
  243.  *
  244.  * synopsis
  245.  *    char msg[];
  246.  *    int arg;
  247.  *    lerrif( msg, arg );
  248.  */
  249.  
  250. void lerrif( msg, arg )
  251. char msg[];
  252. int arg;
  253.  
  254. {
  255.     char errmsg[MAXLINE];
  256.     (void) sprintf( errmsg, msg, arg );
  257.     flexerror( errmsg );
  258. }
  259.  
  260.  
  261. /* lerrsf - report an error message formatted with one string argument
  262.  *
  263.  * synopsis
  264.  *    char msg[], arg[];
  265.  *    lerrsf( msg, arg );
  266.  */
  267.  
  268. void lerrsf( msg, arg )
  269. char msg[], arg[];
  270.  
  271. {
  272.     char errmsg[MAXLINE];
  273.  
  274.     (void) sprintf( errmsg, msg, arg );
  275.     flexerror( errmsg );
  276. }
  277.  
  278.  
  279. /* flexerror - report an error message and terminate
  280.  *
  281.  * synopsis
  282.  *    char msg[];
  283.  *    flexerror( msg );
  284.  */
  285.  
  286. void flexerror( msg )
  287. char msg[];
  288.  
  289. {
  290.     fprintf( stderr, "flex: %s\n", msg );
  291.     flexend( 1 );
  292. }
  293.  
  294.  
  295. /* flexfatal - report a fatal error message and terminate
  296.  *
  297.  * synopsis
  298.  *    char msg[];
  299.  *    flexfatal( msg );
  300.  */
  301.  
  302. void flexfatal( msg )
  303. char msg[];
  304.  
  305. {
  306.     fprintf( stderr, "flex: fatal internal error %s\n", msg );
  307.     flexend( 1 );
  308. }
  309.  
  310.  
  311. /* line_directive_out - spit out a "# line" statement */
  312.  
  313. void line_directive_out( output_file_name )
  314. FILE *output_file_name;
  315.  
  316. {
  317.     if ( infilename && gen_line_dirs )
  318.         fprintf( output_file_name, "# line %d \"%s\"\n", linenum, infilename );
  319. }
  320.  
  321.  
  322. /* mk2data - generate a data statement for a two-dimensional array
  323.  *
  324.  * synopsis
  325.  *    int value;
  326.  *    mk2data( value );
  327.  *
  328.  *  generates a data statement initializing the current 2-D array to "value"
  329.  */
  330. void mk2data( value )
  331. int value;
  332.  
  333. {
  334.     if ( datapos >= NUMDATAITEMS )
  335.     {
  336.         putchar( ',' );
  337.         dataflush();
  338.     }
  339.  
  340.     if ( datapos == 0 )
  341.         /* indent */
  342.         fputs( "    ", stdout );
  343.  
  344.     else
  345.         putchar( ',' );
  346.  
  347.     ++datapos;
  348.  
  349.     printf( "%5d", value );
  350. }
  351.  
  352.  
  353. /* mkdata - generate a data statement
  354.  *
  355.  * synopsis
  356.  *    int value;
  357.  *    mkdata( value );
  358.  *
  359.  *  generates a data statement initializing the current array element to
  360.  *  "value"
  361.  */
  362. void mkdata( value )
  363. int value;
  364.  
  365. {
  366.     if ( datapos >= NUMDATAITEMS )
  367.     {
  368.         putchar( ',' );
  369.         dataflush();
  370.     }
  371.  
  372.     if ( datapos == 0 )
  373.         /* indent */
  374.         fputs( "    ", stdout );
  375.  
  376.     else
  377.         putchar( ',' );
  378.  
  379.     ++datapos;
  380.  
  381.     printf( "%5d", value );
  382. }
  383.  
  384.  
  385. /* myctoi - return the integer represented by a string of digits
  386.  *
  387.  * synopsis
  388.  *    char array[];
  389.  *    int val, myctoi();
  390.  *    val = myctoi( array );
  391.  *
  392.  */
  393.  
  394. int myctoi( array )
  395. char array[];
  396.  
  397. {
  398.     int val = 0;
  399.  
  400.     (void) sscanf( array, "%d", &val );
  401.  
  402.     return ( val );
  403. }
  404.  
  405.  
  406. /* myesc - return character corresponding to escape sequence
  407.  *
  408.  * synopsis
  409.  *    char array[], c, myesc();
  410.  *    c = myesc( array );
  411.  *
  412.  */
  413.  
  414. char myesc( array )
  415. char array[];
  416. {
  417.     char c, esc_char;
  418.     register int sptr = 2;
  419.  
  420.     switch ( array[1] )
  421.     {
  422.     case 'n': 
  423.         return ( '\n' );
  424.     case 't': 
  425.         return ( '\t' );
  426.     case 'f': 
  427.         return ( '\f' );
  428.     case 'r': 
  429.         return ( '\r' );
  430.     case 'b': 
  431.         return ( '\b' );
  432.  
  433.     case '0':
  434.         if ( isdigit(array[2]) )
  435.         { /* \0<octal> */
  436.  
  437.             while ( isdigit(array[sptr]) )
  438.                 /* don't increment inside loop control because the
  439.                      * macro will expand it to two increments!  (Not a
  440.                      * problem with the C version of the macro)
  441.  
  442.                      */
  443.                 ++sptr;
  444.  
  445.             c = array[sptr];
  446.             array[sptr] = '\0';
  447.  
  448.             esc_char = (unsigned char) otoi( array + 2 );
  449.             array[sptr] = c;
  450.  
  451.             if ( esc_char == '\0' )
  452.             {
  453.                 synerr( "escape sequence for null not allowed" );
  454.                 return ( 1 );
  455.             }
  456.  
  457.             return ( esc_char );
  458.         }
  459.  
  460.         else
  461.         {
  462.             synerr( "escape sequence for null not allowed" );
  463.             return ( 1 );
  464.         }
  465.  
  466. #ifdef NOTDEF
  467.     case '^':
  468.         {
  469.             register char next_char = array[2];
  470.  
  471.             if ( next_char == '?' )
  472.                 return ( 0x7f );
  473.  
  474.             else if ( next_char >= 'A' && next_char <= 'Z' )
  475.                 return ( next_char - 'A' + 1 );
  476.  
  477.             else if ( next_char >= 'a' && next_char <= 'z' )
  478.                 return ( next_char - 'z' + 1 );
  479.  
  480.             synerr( "illegal \\^ escape sequence" );
  481.  
  482.             return ( 1 );
  483.         }
  484. #endif
  485.     }
  486.  
  487.     return ( array[1] );
  488. }
  489.  
  490.  
  491. /* otoi - convert an octal digit string to an integer value
  492.  *
  493.  * synopsis:
  494.  *    int val, otoi();
  495.  *    char str[];
  496.  *    val = otoi( str );
  497.  */
  498.  
  499. int otoi( str )
  500. char str[];
  501.  
  502. {
  503. #ifdef FTLSOURCE
  504.     fortran int gctoi()
  505.       int dummy = 1;
  506.  
  507.     return ( gctoi( str, dummy, 8 ) );
  508. #else
  509.     int result;
  510.  
  511.     (void) sscanf( str, "%o", &result );
  512.  
  513.     return ( result );
  514. #endif
  515. }
  516.  
  517.  
  518.  
  519.  
  520. /* reallocate_array - increase the size of a dynamic array */
  521.  
  522. char *reallocate_array( array, size, element_size )
  523. char *array;
  524. int size, element_size;
  525.  
  526. {
  527.     register char *new_array = realloc( array,
  528.       (unsigned) (size * element_size ));
  529.  
  530.     if ( new_array == NULL )
  531.         flexfatal( "attempt to increase array size failed" );
  532.  
  533.     return ( new_array );
  534. }
  535.  
  536.  
  537. /* skelout - write out one section of the skeleton file
  538.  *
  539.  * synopsis
  540.  *    skelout();
  541.  *
  542.  * DESCRIPTION
  543.  *    Copies from skelfile to stdout until a line beginning with "%%" or
  544.  *    EOF is found.
  545.  */
  546. void skelout()
  547.  
  548. {
  549.     char buf[MAXLINE];
  550.  
  551.     while ( fgets( buf, MAXLINE, skelfile ) != NULL )
  552.         if ( buf[0] == '%' && buf[1] == '%' )
  553.             break;
  554.         else
  555.             fputs( buf, stdout );
  556. }
  557.  
  558.  
  559. /* transition_struct_out - output a yy_trans_info structure
  560.  *
  561.  * synopsis
  562.  *     int element_v, element_n;
  563.  *     transition_struct_out( element_v, element_n );
  564.  *
  565.  * outputs the yy_trans_info structure with the two elements, element_v and
  566.  * element_n.  Formats the output with spaces and carriage returns.
  567.  */
  568.  
  569. void transition_struct_out( element_v, element_n )
  570. int element_v, element_n;
  571.  
  572. {
  573.     printf( "%7d, %5d,", element_v, element_n );
  574.  
  575.     datapos += TRANS_STRUCT_PRINT_LENGTH;
  576.  
  577.     if ( datapos >= 75 )
  578.     {
  579.         printf( "\n" );
  580.  
  581.         if ( ++dataline % 10 == 0 )
  582.             printf( "\n" );
  583.  
  584.         datapos = 0;
  585.     }
  586. }
  587.