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