home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / FORTH / FLEX.ARC / MISC.C < prev    next >
Text File  |  1988-10-09  |  11KB  |  585 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. /* get_time - return current time
  215.  *
  216.  * synopsis
  217.  *    char *get_time(), *time_str;
  218.  *    time_str = get_time();
  219.  */
  220.  
  221. /* include sys/types.h to use time_t and make lint happy */
  222.  
  223. #ifndef MSDOS
  224. # include <sys/types.h>
  225. #else
  226. # include <time.h>
  227. #endif
  228.  
  229. char *get_time()
  230.  
  231.     {
  232.     time_t t, time();
  233.     char *result, *ctime(), *copy_string();
  234.  
  235.     t = time( (long *) 0 );
  236.  
  237.     result = copy_string( ctime( &t ) );
  238.  
  239.     /* get rid of trailing newline */
  240.     result[24] = '\0';
  241.  
  242.     return ( result );
  243.     }
  244.  
  245.  
  246. /* lerrif - report an error message formatted with one integer argument
  247.  *
  248.  * synopsis
  249.  *    char msg[];
  250.  *    int arg;
  251.  *    lerrif( msg, arg );
  252.  */
  253.  
  254. lerrif( msg, arg )
  255. char msg[];
  256. int arg;
  257.  
  258.     {
  259.     char errmsg[MAXLINE];
  260.     (void) sprintf( errmsg, msg, arg );
  261.     flexerror( errmsg );
  262.     }
  263.  
  264.  
  265. /* lerrsf - report an error message formatted with one string argument
  266.  *
  267.  * synopsis
  268.  *    char msg[], arg[];
  269.  *    lerrsf( msg, arg );
  270.  */
  271.  
  272. lerrsf( msg, arg )
  273. char msg[], arg[];
  274.  
  275.     {
  276.     char errmsg[MAXLINE];
  277.  
  278.     (void) sprintf( errmsg, msg, arg );
  279.     flexerror( errmsg );
  280.     }
  281.  
  282.  
  283. /* flexerror - report an error message and terminate
  284.  *
  285.  * synopsis
  286.  *    char msg[];
  287.  *    flexerror( msg );
  288.  */
  289.  
  290. flexerror( msg )
  291. char msg[];
  292.  
  293.     {
  294.     fprintf( stderr, "flex: %s\n", msg );
  295.     flexend( 1 );
  296.     }
  297.  
  298.  
  299. /* flexfatal - report a fatal error message and terminate
  300.  *
  301.  * synopsis
  302.  *    char msg[];
  303.  *    flexfatal( msg );
  304.  */
  305.  
  306. flexfatal( msg )
  307. char msg[];
  308.  
  309.     {
  310.     fprintf( stderr, "flex: fatal internal error %s\n", msg );
  311.     flexend( 1 );
  312.     }
  313.  
  314.  
  315. /* line_directive_out - spit out a "# line" statement */
  316.  
  317. line_directive_out( output_file_name )
  318. FILE *output_file_name;
  319.  
  320.     {
  321.     if ( infilename && gen_line_dirs )
  322.     fprintf( output_file_name, "# line %d \"%s\"\n", linenum, infilename );
  323.     }
  324.  
  325.  
  326. /* mk2data - generate a data statement for a two-dimensional array
  327.  *
  328.  * synopsis
  329.  *    int value;
  330.  *    mk2data( value );
  331.  *
  332.  *  generates a data statement initializing the current 2-D array to "value"
  333.  */
  334. mk2data( value )
  335. int value;
  336.  
  337.     {
  338.     if ( datapos >= NUMDATAITEMS )
  339.     {
  340.     putchar( ',' );
  341.     dataflush();
  342.     }
  343.  
  344.     if ( datapos == 0 )
  345.     /* indent */
  346.     fputs( "    ", stdout );
  347.  
  348.     else
  349.     putchar( ',' );
  350.  
  351.     ++datapos;
  352.  
  353.     printf( "%5d", value );
  354.     }
  355.  
  356.  
  357. /* mkdata - generate a data statement
  358.  *
  359.  * synopsis
  360.  *    int value;
  361.  *    mkdata( value );
  362.  *
  363.  *  generates a data statement initializing the current array element to
  364.  *  "value"
  365.  */
  366. mkdata( value )
  367. int value;
  368.  
  369.     {
  370.     if ( datapos >= NUMDATAITEMS )
  371.     {
  372.     putchar( ',' );
  373.     dataflush();
  374.     }
  375.  
  376.     if ( datapos == 0 )
  377.     /* indent */
  378.     fputs( "    ", stdout );
  379.  
  380.     else
  381.     putchar( ',' );
  382.  
  383.     ++datapos;
  384.  
  385.     printf( "%5d", value );
  386.     }
  387.  
  388.  
  389. /* myctoi - return the integer represented by a string of digits
  390.  *
  391.  * synopsis
  392.  *    char array[];
  393.  *    int val, myctoi();
  394.  *    val = myctoi( array );
  395.  *
  396.  */
  397.  
  398. int myctoi( array )
  399. char array[];
  400.  
  401.     {
  402.     int val = 0;
  403.  
  404.     (void) sscanf( array, "%d", &val );
  405.  
  406.     return ( val );
  407.     }
  408.  
  409.  
  410. /* myesc - return character corresponding to escape sequence
  411.  *
  412.  * synopsis
  413.  *    char array[], c, myesc();
  414.  *    c = myesc( array );
  415.  *
  416.  */
  417.  
  418. char myesc( array )
  419. char array[];
  420.  
  421.     {
  422.     switch ( array[1] )
  423.     {
  424.     case 'n': return ( '\n' );
  425.     case 't': return ( '\t' );
  426.     case 'f': return ( '\f' );
  427.     case 'r': return ( '\r' );
  428.     case 'b': return ( '\b' );
  429.  
  430.     case '0':
  431.         if ( isdigit(array[2]) )
  432.         { /* \0<octal> */
  433.         char c, esc_char;
  434.         register int sptr = 2;
  435.  
  436.         while ( isdigit(array[sptr]) )
  437.             /* don't increment inside loop control because the
  438.              * macro will expand it to two increments!    (Not a
  439.              * problem with the C version of the macro)
  440.              */
  441.             ++sptr;
  442.  
  443.         c = array[sptr];
  444.         array[sptr] = '\0';
  445.  
  446.         esc_char = otoi( array + 2 );
  447.         array[sptr] = c;
  448.  
  449.         if ( esc_char == '\0' )
  450.             {
  451.             synerr( "escape sequence for null not allowed" );
  452.             return ( 1 );
  453.             }
  454.  
  455.         return ( esc_char );
  456.         }
  457.  
  458.         else
  459.         {
  460.         synerr( "escape sequence for null not allowed" );
  461.         return ( 1 );
  462.         }
  463.  
  464. #ifdef NOTDEF
  465.     case '^':
  466.         {
  467.         register char next_char = array[2];
  468.  
  469.         if ( next_char == '?' )
  470.         return ( 0x7f );
  471.  
  472.         else if ( next_char >= 'A' && next_char <= 'Z' )
  473.         return ( next_char - 'A' + 1 );
  474.  
  475.         else if ( next_char >= 'a' && next_char <= 'z' )
  476.         return ( next_char - 'z' + 1 );
  477.  
  478.         synerr( "illegal \\^ escape sequence" );
  479.  
  480.         return ( 1 );
  481.         }
  482. #endif
  483.     }
  484.  
  485.     return ( array[1] );
  486.     }
  487.  
  488.  
  489. /* otoi - convert an octal digit string to an integer value
  490.  *
  491.  * synopsis:
  492.  *    int val, otoi();
  493.  *    char str[];
  494.  *    val = otoi( str );
  495.  */
  496.  
  497. int otoi( str )
  498. char str[];
  499.  
  500.     {
  501. #ifdef FTLSOURCE
  502.     fortran int gctoi()
  503.     int dummy = 1;
  504.  
  505.     return ( gctoi( str, dummy, 8 ) );
  506. #else
  507.     int result;
  508.  
  509.     (void) sscanf( str, "%o", &result );
  510.  
  511.     return ( result );
  512. #endif
  513.     }
  514.  
  515.  
  516.  
  517.  
  518. /* reallocate_array - increase the size of a dynamic array */
  519.  
  520. char *reallocate_array( array, size, element_size )
  521. char *array;
  522. int size, element_size;
  523.  
  524.     {
  525.     register char *new_array = realloc( array,
  526.                     (unsigned) (size * element_size ));
  527.  
  528.     if ( new_array == NULL )
  529.     flexfatal( "attempt to increase array size failed" );
  530.  
  531.     return ( new_array );
  532.     }
  533.  
  534.  
  535. /* skelout - write out one section of the skeleton file
  536.  *
  537.  * synopsis
  538.  *    skelout();
  539.  *
  540.  * DESCRIPTION
  541.  *    Copies from skelfile to stdout until a line beginning with "%%" or
  542.  *    EOF is found.
  543.  */
  544. skelout()
  545.  
  546.     {
  547.     char buf[MAXLINE];
  548.  
  549.     while ( fgets( buf, MAXLINE, skelfile ) != NULL )
  550.     if ( buf[0] == '%' && buf[1] == '%' )
  551.         break;
  552.     else
  553.         fputs( buf, stdout );
  554.     }
  555.  
  556.  
  557. /* transition_struct_out - output a yy_trans_info structure
  558.  *
  559.  * synopsis
  560.  *     int element_v, element_n;
  561.  *     transition_struct_out( element_v, element_n );
  562.  *
  563.  * outputs the yy_trans_info structure with the two elements, element_v and
  564.  * element_n.  Formats the output with spaces and carriage returns.
  565.  */
  566.  
  567. transition_struct_out( element_v, element_n )
  568. int element_v, element_n;
  569.  
  570.     {
  571.     printf( "%7d, %5d,", element_v, element_n );
  572.  
  573.     datapos += TRANS_STRUCT_PRINT_LENGTH;
  574.  
  575.     if ( datapos >= 75 )
  576.     {
  577.     printf( "\n" );
  578.  
  579.     if ( ++dataline % 10 == 0 )
  580.         printf( "\n" );
  581.  
  582.     datapos = 0;
  583.     }
  584.     }
  585.