home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 213b.lha / Flex / Flex1 / misc.c < prev    next >
C/C++ Source or Header  |  1996-02-14  |  11KB  |  581 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.  
  221. /* include sys/types.h to use time_t and make lint happy */
  222.  
  223. #include <time.h>
  224.  
  225. char *gettime()
  226.  
  227.     {
  228.     time_t t, time();
  229.     char *result, *ctime(), *copy_string();
  230.  
  231.     t = time( (long *) 0 );
  232.  
  233.     result = copy_string( ctime( &t ) );
  234.  
  235.     /* get rid of trailing newline */
  236.     result[24] = '\0';
  237.  
  238.     return ( result );
  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. 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. 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. 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. 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. 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. 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. 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.     {
  418.     switch ( array[1] )
  419.         {
  420.         case 'n': return ( '\n' );
  421.         case 't': return ( '\t' );
  422.         case 'f': return ( '\f' );
  423.         case 'r': return ( '\r' );
  424.         case 'b': return ( '\b' );
  425.  
  426.         case '0':
  427.             if ( isdigit(array[2]) )
  428.                 { /* \0<octal> */
  429.                 char c, esc_char;
  430.                 register int sptr = 2;
  431.  
  432.                 while ( isdigit(array[sptr]) )
  433.                     /* don't increment inside loop control because the
  434.                      * macro will expand it to two increments!  (Not a
  435.                      * problem with the C version of the macro)
  436.                      */
  437.                     ++sptr;
  438.  
  439.                 c = array[sptr];
  440.                 array[sptr] = '\0';
  441.  
  442.                 esc_char = otoi( array + 2 );
  443.                 array[sptr] = c;
  444.  
  445.                 if ( esc_char == '\0' )
  446.                     {
  447.                     synerr( "escape sequence for null not allowed" );
  448.                     return ( 1 );
  449.                     }
  450.  
  451.                 return ( esc_char );
  452.                 }
  453.  
  454.             else
  455.                 {
  456.                 synerr( "escape sequence for null not allowed" );
  457.                 return ( 1 );
  458.                 }
  459.  
  460. #ifdef NOTDEF
  461.         case '^':
  462.             {
  463.             register char next_char = array[2];
  464.  
  465.             if ( next_char == '?' )
  466.                 return ( 0x7f );
  467.  
  468.             else if ( next_char >= 'A' && next_char <= 'Z' )
  469.                 return ( next_char - 'A' + 1 );
  470.  
  471.             else if ( next_char >= 'a' && next_char <= 'z' )
  472.                 return ( next_char - 'z' + 1 );
  473.  
  474.             synerr( "illegal \\^ escape sequence" );
  475.  
  476.             return ( 1 );
  477.             }
  478. #endif
  479.         }
  480.  
  481.     return ( array[1] );
  482.     }
  483.  
  484.  
  485. /* otoi - convert an octal digit string to an integer value
  486.  *
  487.  * synopsis:
  488.  *    int val, otoi();
  489.  *    char str[];
  490.  *    val = otoi( str );
  491.  */
  492.  
  493. int otoi( str )
  494. char str[];
  495.  
  496.     {
  497. #ifdef FTLSOURCE
  498.     fortran int gctoi()
  499.     int dummy = 1;
  500.  
  501.     return ( gctoi( str, dummy, 8 ) );
  502. #else
  503.     int result;
  504.  
  505.     (void) sscanf( str, "%o", &result );
  506.  
  507.     return ( result );
  508. #endif
  509.     }
  510.  
  511.  
  512.  
  513.  
  514. /* reallocate_array - increase the size of a dynamic array */
  515.  
  516. char *reallocate_array( array, size, element_size )
  517. char *array;
  518. int size, element_size;
  519.  
  520.     {
  521.     register char *new_array = realloc( array,
  522.                                         (unsigned) (size * element_size ));
  523.  
  524.     if ( new_array == NULL )
  525.         flexfatal( "attempt to increase array size failed" );
  526.  
  527.     return ( new_array );
  528.     }
  529.  
  530.  
  531. /* skelout - write out one section of the skeleton file
  532.  *
  533.  * synopsis
  534.  *    skelout();
  535.  *
  536.  * DESCRIPTION
  537.  *    Copies from skelfile to stdout until a line beginning with "%%" or
  538.  *    EOF is found.
  539.  */
  540. skelout()
  541.  
  542.     {
  543.     char buf[MAXLINE];
  544.  
  545.     while ( fgets( buf, MAXLINE, skelfile ) != NULL )
  546.         if ( buf[0] == '%' && buf[1] == '%' )
  547.             break;
  548.         else
  549.             fputs( buf, stdout );
  550.     }
  551.  
  552.  
  553. /* transition_struct_out - output a yy_trans_info structure
  554.  *
  555.  * synopsis
  556.  *     int element_v, element_n;
  557.  *     transition_struct_out( element_v, element_n );
  558.  *
  559.  * outputs the yy_trans_info structure with the two elements, element_v and
  560.  * element_n.  Formats the output with spaces and carriage returns.
  561.  */
  562.  
  563. transition_struct_out( element_v, element_n )
  564. int element_v, element_n;
  565.  
  566.     {
  567.     printf( "%7d, %5d,", element_v, element_n );
  568.  
  569.     datapos += TRANS_STRUCT_PRINT_LENGTH;
  570.  
  571.     if ( datapos >= 75 )
  572.         {
  573.         printf( "\n" );
  574.  
  575.         if ( ++dataline % 10 == 0 )
  576.             printf( "\n" );
  577.  
  578.         datapos = 0;
  579.         }
  580.     }
  581.