[BACK]Return to misc.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / lex

Diff for /src/usr.bin/lex/misc.c between version 1.14 and 1.15

version 1.14, 2015/10/15 05:57:09 version 1.15, 2015/11/19 19:43:40
Line 2 
Line 2 
   
 /* misc - miscellaneous flex routines */  /* misc - miscellaneous flex routines */
   
 /*-  /*  Copyright (c) 1990 The Regents of the University of California. */
  * Copyright (c) 1990 The Regents of the University of California.  /*  All rights reserved. */
  * All rights reserved.  
  *  
  * This code is derived from software contributed to Berkeley by  
  * Vern Paxson.  
  *  
  * The United States Government has rights in this work pursuant  
  * to contract no. DE-AC03-76SF00098 between the United States  
  * Department of Energy and the University of California.  
  *  
  * Redistribution and use in source and binary forms, with or without  
  * modification, are permitted provided that the following conditions  
  * are met:  
  *  
  * 1. Redistributions of source code must retain the above copyright  
  *    notice, this list of conditions and the following disclaimer.  
  * 2. Redistributions in binary form must reproduce the above copyright  
  *    notice, this list of conditions and the following disclaimer in the  
  *    documentation and/or other materials provided with the distribution.  
  *  
  * Neither the name of the University nor the names of its contributors  
  * may be used to endorse or promote products derived from this software  
  * without specific prior written permission.  
  *  
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR  
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED  
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  
  * PURPOSE.  
  */  
   
 /* $Header$ */  /*  This code is derived from software contributed to Berkeley by */
   /*  Vern Paxson. */
   
   /*  The United States Government has rights in this work pursuant */
   /*  to contract no. DE-AC03-76SF00098 between the United States */
   /*  Department of Energy and the University of California. */
   
   /*  This file is part of flex. */
   
   /*  Redistribution and use in source and binary forms, with or without */
   /*  modification, are permitted provided that the following conditions */
   /*  are met: */
   
   /*  1. Redistributions of source code must retain the above copyright */
   /*     notice, this list of conditions and the following disclaimer. */
   /*  2. Redistributions in binary form must reproduce the above copyright */
   /*     notice, this list of conditions and the following disclaimer in the */
   /*     documentation and/or other materials provided with the distribution. */
   
   /*  Neither the name of the University nor the names of its contributors */
   /*  may be used to endorse or promote products derived from this software */
   /*  without specific prior written permission. */
   
   /*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
   /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
   /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
   /*  PURPOSE. */
   
 #include "flexdef.h"  #include "flexdef.h"
   #include "tables.h"
   
   #define CMD_IF_TABLES_SER    "%if-tables-serialization"
   #define CMD_TABLES_YYDMAP    "%tables-yydmap"
   #define CMD_DEFINE_YYTABLES  "%define-yytables"
   #define CMD_IF_CPP_ONLY      "%if-c++-only"
   #define CMD_IF_C_ONLY        "%if-c-only"
   #define CMD_IF_C_OR_CPP      "%if-c-or-c++"
   #define CMD_NOT_FOR_HEADER   "%not-for-header"
   #define CMD_OK_FOR_HEADER    "%ok-for-header"
   #define CMD_PUSH             "%push"
   #define CMD_POP              "%pop"
   #define CMD_IF_REENTRANT     "%if-reentrant"
   #define CMD_IF_NOT_REENTRANT "%if-not-reentrant"
   #define CMD_IF_BISON_BRIDGE  "%if-bison-bridge"
   #define CMD_IF_NOT_BISON_BRIDGE  "%if-not-bison-bridge"
   #define CMD_ENDIF            "%endif"
   
 void action_define( defname, value )  /* we allow the skeleton to push and pop. */
 char *defname;  struct sko_state {
 int value;      bool dc; /**< do_copy */
         {  };
         char buf[MAXLINE];  static struct sko_state *sko_stack=0;
   static int sko_len=0,sko_sz=0;
   static void sko_push(bool dc)
   {
       if(!sko_stack){
           sko_sz = 1;
           sko_stack = (struct sko_state*)flex_alloc(sizeof(struct sko_state)*sko_sz);
           if (!sko_stack)
               flexfatal(_("allocation of sko_stack failed"));
           sko_len = 0;
       }
       if(sko_len >= sko_sz){
           sko_sz *= 2;
           sko_stack = (struct sko_state*)flex_realloc(sko_stack,sizeof(struct sko_state)*sko_sz);
       }
   
       /* initialize to zero and push */
       sko_stack[sko_len].dc = dc;
       sko_len++;
   }
   static void sko_peek(bool *dc)
   {
       if(sko_len <= 0)
           flex_die("peek attempt when sko stack is empty");
       if(dc)
           *dc = sko_stack[sko_len-1].dc;
   }
   static void sko_pop(bool* dc)
   {
       sko_peek(dc);
       sko_len--;
       if(sko_len < 0)
           flex_die("popped too many times in skeleton.");
   }
   
         if ( (int) strlen( defname ) > MAXLINE / 2 )  /* Append "#define defname value\n" to the running buffer. */
                 {  void action_define (defname, value)
                 format_pinpoint_message( _( "name \"%s\" ridiculously long" ),       const char *defname;
                         defname );       int value;
   {
           char    buf[MAXLINE];
           char   *cpy;
   
           if ((int) strlen (defname) > MAXLINE / 2) {
                   format_pinpoint_message (_
                                            ("name \"%s\" ridiculously long"),
                                            defname);
                 return;                  return;
                 }          }
   
         snprintf( buf, sizeof buf, "#define %s %d\n", defname, value );          snprintf (buf, sizeof(buf), "#define %s %d\n", defname, value);
         add_action( buf );          add_action (buf);
   
           /* track #defines so we can undef them when we're done. */
           cpy = copy_string (defname);
           buf_append (&defs_buf, &cpy, 1);
   }
   
   
   /** Append "m4_define([[defname]],[[value]])m4_dnl\n" to the running buffer.
    *  @param defname The macro name.
    *  @param value The macro value, can be NULL, which is the same as the empty string.
    */
   void action_m4_define (const char *defname, const char * value)
   {
           char    buf[MAXLINE];
   
       flexfatal ("DO NOT USE THIS FUNCTION!");
   
           if ((int) strlen (defname) > MAXLINE / 2) {
                   format_pinpoint_message (_
                                            ("name \"%s\" ridiculously long"),
                                            defname);
                   return;
         }          }
   
           snprintf (buf, sizeof(buf), "m4_define([[%s]],[[%s]])m4_dnl\n", defname, value?value:"");
           add_action (buf);
   }
   
 void add_action( new_text )  /* Append "new_text" to the running buffer. */
 char *new_text;  void add_action (new_text)
         {       const char   *new_text;
         int len = strlen( new_text );  {
           int     len = strlen (new_text);
   
         while ( len + action_index >= action_size - 10 /* slop */ )          while (len + action_index >= action_size - 10 /* slop */ ) {
                 {                  int     new_size = action_size * 2;
                 int new_size = action_size * 2;  
   
                 if ( new_size <= 0 )                  if (new_size <= 0)
                         /* Increase just a little, to try to avoid overflow                          /* Increase just a little, to try to avoid overflow
                          * on 16-bit machines.                           * on 16-bit machines.
                          */                           */
Line 74 
Line 154 
                         action_size = new_size;                          action_size = new_size;
   
                 action_array =                  action_array =
                         reallocate_character_array( action_array, action_size );                          reallocate_character_array (action_array,
                 }                                                      action_size);
           }
   
         strlcpy( &action_array[action_index], new_text,          strlcpy ( &action_array[action_index], new_text,
                 action_size - action_index );                  action_size - action_index );
   
         action_index += len;          action_index += len;
         }  }
   
   
 /* allocate_array - allocate memory for an integer array of the given size */  /* allocate_array - allocate memory for an integer array of the given size */
   
 void *allocate_array( size, element_size )  void   *allocate_array (size, element_size)
 int size;       int size;
 size_t element_size;       size_t element_size;
         {  {
         void *mem;          void *mem;
         size_t num_bytes = element_size * size;          size_t  num_bytes = element_size * size;
   
         mem = flex_alloc( num_bytes );          mem = flex_alloc (num_bytes);
         if ( ! mem )          if (!mem)
                 flexfatal(                  flexfatal (_
                         _( "memory allocation failed in allocate_array()" ) );                             ("memory allocation failed in allocate_array()"));
   
         return mem;          return mem;
         }  }
   
   
 /* all_lower - true if a string is all lower-case */  /* all_lower - true if a string is all lower-case */
   
 int all_lower( str )  int all_lower (str)
 char *str;       char *str;
         {  {
         while ( *str )          while (*str) {
                 {                  if (!isascii ((Char) * str) || !islower ((Char) * str))
                 if ( ! isascii( (Char) *str ) || ! islower( (Char) *str ) )  
                         return 0;                          return 0;
                 ++str;                  ++str;
                 }          }
   
         return 1;          return 1;
         }  }
   
   
 /* all_upper - true if a string is all upper-case */  /* all_upper - true if a string is all upper-case */
   
 int all_upper( str )  int all_upper (str)
 char *str;       char *str;
         {  {
         while ( *str )          while (*str) {
                 {                  if (!isascii ((Char) * str) || !isupper ((Char) * str))
                 if ( ! isascii( (Char) *str ) || ! isupper( (Char) *str ) )  
                         return 0;                          return 0;
                 ++str;                  ++str;
                 }          }
   
         return 1;          return 1;
         }  }
   
   
 /* bubble - bubble sort an integer array in increasing order  /* intcmp - compares two integers for use by qsort. */
  *  
  * synopsis  
  *   int v[n], n;  
  *   void bubble( v, n );  
  *  
  * description  
  *   sorts the first n elements of array v and replaces them in  
  *   increasing order.  
  *  
  * passed  
  *   v - the array to be sorted  
  *   n - the number of elements of 'v' to be sorted  
  */  
   
 void bubble( v, n )  int intcmp (const void *a, const void *b)
 int v[], n;  {
         {    return *(const int *) a - *(const int *) b;
         int i, j, k;  }
   
         for ( i = n; i > 1; --i )  
                 for ( j = 1; j < i; ++j )  
                         if ( v[j] > v[j + 1] )  /* compare */  
                                 {  
                                 k = v[j];       /* exchange */  
                                 v[j] = v[j + 1];  
                                 v[j + 1] = k;  
                                 }  
         }  
   
   
 /* check_char - checks a character to make sure it's within the range  /* check_char - checks a character to make sure it's within the range
  *              we're expecting.  If not, generates fatal error message   *              we're expecting.  If not, generates fatal error message
  *              and exits.   *              and exits.
  */   */
   
 void check_char( c )  void check_char (c)
 int c;       int c;
         {  {
         if ( c >= CSIZE )          if (c >= CSIZE)
                 lerrsf( _( "bad character '%s' detected in check_char()" ),                  lerrsf (_("bad character '%s' detected in check_char()"),
                         readable_form( c ) );                          readable_form (c));
   
         if ( c >= csize )          if (c >= csize)
                 lerrsf(                  lerrsf (_
                 _( "scanner requires -8 flag to use the character %s" ),                          ("scanner requires -8 flag to use the character %s"),
                         readable_form( c ) );                          readable_form (c));
         }  }
   
   
   
 /* clower - replace upper-case letter to lower-case */  /* clower - replace upper-case letter to lower-case */
   
 Char clower( c )  Char clower (c)
 int c;       int c;
         {  {
         return (Char) ((isascii( c ) && isupper( c )) ? tolower( c ) : c);          return (Char) ((isascii (c) && isupper (c)) ? tolower (c) : c);
         }  }
   
   
 /* copy_string - returns a dynamically allocated copy of a string */  /* copy_string - returns a dynamically allocated copy of a string */
   
 char *copy_string( str )  char   *copy_string (str)
 const char *str;       const char *str;
         {  {
         const char *c1;          const char *c1;
         char *c2;          char *c2;
         char *copy;          char   *copy;
         unsigned int size;          unsigned int size;
   
         /* find length */          /* find length */
         for ( c1 = str; *c1; ++c1 )          for (c1 = str; *c1; ++c1) ;
                 ;  
   
         size = (c1 - str + 1) * sizeof( char );          size = (c1 - str + 1) * sizeof (char);
         copy = (char *) flex_alloc( size );  
   
         if ( copy == NULL )          copy = (char *) flex_alloc (size);
                 flexfatal( _( "dynamic memory failure in copy_string()" ) );  
   
         for ( c2 = copy; (*c2++ = *str++) != 0; )          if (copy == NULL)
                 ;                  flexfatal (_("dynamic memory failure in copy_string()"));
   
           for (c2 = copy; (*c2++ = *str++) != 0;) ;
   
         return copy;          return copy;
         }  }
   
   
 /* copy_unsigned_string -  /* copy_unsigned_string -
  *    returns a dynamically allocated copy of a (potentially) unsigned string   *    returns a dynamically allocated copy of a (potentially) unsigned string
  */   */
   
 Char *copy_unsigned_string( str )  Char   *copy_unsigned_string (str)
 Char *str;       Char *str;
         {  {
         Char *c;          Char *c;
         Char *copy;          Char   *copy;
   
         /* find length */          /* find length */
         for ( c = str; *c; ++c )          for (c = str; *c; ++c) ;
                 ;  
   
         copy = allocate_Character_array( c - str + 1 );          copy = allocate_Character_array (c - str + 1);
   
         for ( c = copy; (*c++ = *str++) != 0; )          for (c = copy; (*c++ = *str++) != 0;) ;
                 ;  
   
         return copy;          return copy;
         }  }
   
   
 /* cshell - shell sort a character array in increasing order  /* cclcmp - compares two characters for use by qsort with '\0' sorting last. */
  *  
  * synopsis  
  *  
  *   Char v[n];  
  *   int n, special_case_0;  
  *   cshell( v, n, special_case_0 );  
  *  
  * description  
  *   Does a shell sort of the first n elements of array v.  
  *   If special_case_0 is true, then any element equal to 0  
  *   is instead assumed to have infinite weight.  
  *  
  * passed  
  *   v - array to be sorted  
  *   n - number of elements of v to be sorted  
  */  
   
 void cshell( v, n, special_case_0 )  int cclcmp (const void *a, const void *b)
 Char v[];  {
 int n, special_case_0;    if (!*(const Char *) a)
         {          return 1;
         int gap, i, j, jg;    else
         Char k;          if (!*(const Char *) b)
             return - 1;
           else
             return *(const Char *) a - *(const Char *) b;
   }
   
         for ( gap = n / 2; gap > 0; gap = gap / 2 )  
                 for ( i = gap; i < n; ++i )  
                         for ( j = i - gap; j >= 0; j = j - gap )  
                                 {  
                                 jg = j + gap;  
   
                                 if ( special_case_0 )  
                                         {  
                                         if ( v[jg] == 0 )  
                                                 break;  
   
                                         else if ( v[j] != 0 && v[j] <= v[jg] )  
                                                 break;  
                                         }  
   
                                 else if ( v[j] <= v[jg] )  
                                         break;  
   
                                 k = v[j];  
                                 v[j] = v[jg];  
                                 v[jg] = k;  
                                 }  
         }  
   
   
 /* dataend - finish up a block of data declarations */  /* dataend - finish up a block of data declarations */
   
 void dataend()  void dataend ()
         {  {
         if ( datapos > 0 )          /* short circuit any output */
                 dataflush();          if (gentables) {
   
         /* add terminator for initialization; { for vi */                  if (datapos > 0)
         outn( "    } ;\n" );                          dataflush ();
   
                   /* add terminator for initialization; { for vi */
                   outn ("    } ;\n");
           }
         dataline = 0;          dataline = 0;
         datapos = 0;          datapos = 0;
         }  }
   
   
 /* dataflush - flush generated data statements */  /* dataflush - flush generated data statements */
   
 void dataflush()  void dataflush ()
         {  {
         outc( '\n' );          /* short circuit any output */
           if (!gentables)
                   return;
   
         if ( ++dataline >= NUMDATALINES )          outc ('\n');
                 {  
           if (++dataline >= NUMDATALINES) {
                 /* Put out a blank line so that the table is grouped into                  /* Put out a blank line so that the table is grouped into
                  * large blocks that enable the user to find elements easily.                   * large blocks that enable the user to find elements easily.
                  */                   */
                 outc( '\n' );                  outc ('\n');
                 dataline = 0;                  dataline = 0;
                 }          }
   
         /* Reset the number of characters written on the current line. */          /* Reset the number of characters written on the current line. */
         datapos = 0;          datapos = 0;
         }  }
   
   
 /* flexerror - report an error message and terminate */  /* flexerror - report an error message and terminate */
   
 void flexerror( msg )  void flexerror (msg)
 const char msg[];       const char *msg;
         {  {
         fprintf( stderr, "%s: %s\n", program_name, msg );          fprintf (stderr, "%s: %s\n", program_name, msg);
         flexend( 1 );          flexend (1);
         }  }
   
   
 /* flexfatal - report a fatal error message and terminate */  /* flexfatal - report a fatal error message and terminate */
   
 void flexfatal( msg )  void flexfatal (msg)
 const char msg[];       const char *msg;
         {  {
         fprintf( stderr, _( "%s: fatal internal error, %s\n" ),          fprintf (stderr, _("%s: fatal internal error, %s\n"),
                 program_name, msg );                   program_name, msg);
         exit( 1 );          FLEX_EXIT (1);
         }  }
   
   
 /* htoi - convert a hexadecimal digit string to an integer value */  /* htoi - convert a hexadecimal digit string to an integer value */
   
 int htoi( str )  int htoi (str)
 Char str[];       Char str[];
         {  {
         unsigned int result;          unsigned int result;
   
         (void) sscanf( (char *) str, "%x", &result );          (void) sscanf ((char *) str, "%x", &result);
   
         return result;          return result;
         }  }
   
   
 /* lerrif - report an error message formatted with one integer argument */  /* lerrif - report an error message formatted with one integer argument */
   
 void lerrif( msg, arg )  void lerrif (msg, arg)
 const char msg[];       const char *msg;
 int arg;       int arg;
         {  {
         char errmsg[MAXLINE];          char    errmsg[MAXLINE];
         (void) snprintf( errmsg, sizeof errmsg, msg, arg );  
         flexerror( errmsg );  
         }  
   
           snprintf (errmsg, sizeof(errmsg), msg, arg);
           flexerror (errmsg);
   }
   
   
 /* lerrsf - report an error message formatted with one string argument */  /* lerrsf - report an error message formatted with one string argument */
   
 void lerrsf( msg, arg )  void lerrsf (msg, arg)
 const char msg[], arg[];          const char *msg, arg[];
         {  {
         char errmsg[MAXLINE];          char    errmsg[MAXLINE];
   
         (void) snprintf( errmsg, sizeof errmsg, msg, arg );          snprintf (errmsg, sizeof(errmsg)-1, msg, arg);
         flexerror( errmsg );          errmsg[sizeof(errmsg)-1] = 0; /* ensure NULL termination */
         }          flexerror (errmsg);
   }
   
   
   /* lerrsf_fatal - as lerrsf, but call flexfatal */
   
   void lerrsf_fatal (msg, arg)
           const char *msg, arg[];
   {
           char    errmsg[MAXLINE];
   
           snprintf (errmsg, sizeof(errmsg)-1, msg, arg);
           errmsg[sizeof(errmsg)-1] = 0; /* ensure NULL termination */
           flexfatal (errmsg);
   }
   
   
 /* line_directive_out - spit out a "#line" statement */  /* line_directive_out - spit out a "#line" statement */
   
 void line_directive_out( output_file, do_infile )  void line_directive_out (output_file, do_infile)
 FILE *output_file;       FILE   *output_file;
 int do_infile;       int do_infile;
         {  {
         char directive[MAXLINE], filename[MAXLINE];          char    directive[MAXLINE], filename[MAXLINE];
         char *s1, *s2, *s3;          char   *s1, *s2, *s3;
         static const char line_fmt[] = "#line %d \"%s\"\n";          static const char *line_fmt = "#line %d \"%s\"\n";
   
         if ( ! gen_line_dirs )          if (!gen_line_dirs)
                 return;                  return;
   
         if ( (do_infile && ! infilename) || (! do_infile && ! outfilename) )          s1 = do_infile ? infilename : "M4_YY_OUTFILE_NAME";
                 /* don't know the filename to use, skip */  
                 return;  
   
         s1 = do_infile ? infilename : outfilename;          if (do_infile && !s1)
           s1 = "<stdin>";
   
         s2 = filename;          s2 = filename;
         s3 = &filename[sizeof( filename ) - 2];          s3 = &filename[sizeof (filename) - 2];
   
         while ( s2 < s3 && *s1 )          while (s2 < s3 && *s1) {
                 {                  if (*s1 == '\\')
                 if ( *s1 == '\\' )  
                         /* Escape the '\' */                          /* Escape the '\' */
                         *s2++ = '\\';                          *s2++ = '\\';
   
                 *s2++ = *s1++;                  *s2++ = *s1++;
                 }          }
   
         *s2 = '\0';          *s2 = '\0';
   
         if ( do_infile )          if (do_infile)
                 snprintf( directive, sizeof directive, line_fmt,                  snprintf (directive, sizeof(directive), line_fmt, linenum, filename);
                         linenum, filename );          else {
         else                  snprintf (directive, sizeof(directive), line_fmt, 0, filename);
                 {          }
                 if ( output_file == stdout )  
                         /* Account for the line directive itself. */  
                         ++out_linenum;  
   
                 snprintf( directive, sizeof directive, line_fmt,  
                         out_linenum, filename );  
                 }  
   
         /* If output_file is nil then we should put the directive in          /* If output_file is nil then we should put the directive in
          * the accumulated actions.           * the accumulated actions.
          */           */
         if ( output_file )          if (output_file) {
                 {                  fputs (directive, output_file);
                 fputs( directive, output_file );  
                 }  
         else  
                 add_action( directive );  
         }          }
           else
                   add_action (directive);
   }
   
   
 /* mark_defs1 - mark the current position in the action array as  /* mark_defs1 - mark the current position in the action array as
  *               representing where the user's section 1 definitions end   *               representing where the user's section 1 definitions end
  *               and the prolog begins   *               and the prolog begins
  */   */
 void mark_defs1()  void mark_defs1 ()
         {  {
         defs1_offset = 0;          defs1_offset = 0;
         action_array[action_index++] = '\0';          action_array[action_index++] = '\0';
         action_offset = prolog_offset = action_index;          action_offset = prolog_offset = action_index;
         action_array[action_index] = '\0';          action_array[action_index] = '\0';
         }  }
   
   
 /* mark_prolog - mark the current position in the action array as  /* mark_prolog - mark the current position in the action array as
  *               representing the end of the action prolog   *               representing the end of the action prolog
  */   */
 void mark_prolog()  void mark_prolog ()
         {  {
         action_array[action_index++] = '\0';          action_array[action_index++] = '\0';
         action_offset = action_index;          action_offset = action_index;
         action_array[action_index] = '\0';          action_array[action_index] = '\0';
         }  }
   
   
 /* mk2data - generate a data statement for a two-dimensional array  /* mk2data - generate a data statement for a two-dimensional array
  *   *
  * Generates a data statement initializing the current 2-D array to "value".   * Generates a data statement initializing the current 2-D array to "value".
  */   */
 void mk2data( value )  void mk2data (value)
 int value;       int value;
         {  {
         if ( datapos >= NUMDATAITEMS )          /* short circuit any output */
                 {          if (!gentables)
                 outc( ',' );                  return;
                 dataflush();  
                 }  
   
         if ( datapos == 0 )          if (datapos >= NUMDATAITEMS) {
                   outc (',');
                   dataflush ();
           }
   
           if (datapos == 0)
                 /* Indent. */                  /* Indent. */
                 out( "    " );                  out ("    ");
   
         else          else
                 outc( ',' );                  outc (',');
   
         ++datapos;          ++datapos;
   
         out_dec( "%5d", value );          out_dec ("%5d", value);
         }  }
   
   
 /* mkdata - generate a data statement  /* mkdata - generate a data statement
Line 499 
Line 531 
  * Generates a data statement initializing the current array element to   * Generates a data statement initializing the current array element to
  * "value".   * "value".
  */   */
 void mkdata( value )  void mkdata (value)
 int value;       int value;
         {  {
         if ( datapos >= NUMDATAITEMS )          /* short circuit any output */
                 {          if (!gentables)
                 outc( ',' );                  return;
                 dataflush();  
                 }  
   
         if ( datapos == 0 )          if (datapos >= NUMDATAITEMS) {
                   outc (',');
                   dataflush ();
           }
   
           if (datapos == 0)
                 /* Indent. */                  /* Indent. */
                 out( "    " );                  out ("    ");
         else          else
                 outc( ',' );                  outc (',');
   
         ++datapos;          ++datapos;
   
         out_dec( "%5d", value );          out_dec ("%5d", value);
         }  }
   
   
 /* myctoi - return the integer represented by a string of digits */  /* myctoi - return the integer represented by a string of digits */
   
 int myctoi( array )  int myctoi (array)
 char array[];       const char *array;
         {  {
         int val = 0;          int     val = 0;
   
         (void) sscanf( array, "%d", &val );          (void) sscanf (array, "%d", &val);
   
         return val;          return val;
         }  }
   
   
 /* myesc - return character corresponding to escape sequence */  /* myesc - return character corresponding to escape sequence */
   
 Char myesc( array )  Char myesc (array)
 Char array[];       Char array[];
         {  {
         Char c, esc_char;          Char    c, esc_char;
   
         switch ( array[1] )          switch (array[1]) {
                 {          case 'b':
                 case 'b': return '\b';                  return '\b';
                 case 'f': return '\f';          case 'f':
                 case 'n': return '\n';                  return '\f';
                 case 'r': return '\r';          case 'n':
                 case 't': return '\t';                  return '\n';
           case 'r':
                   return '\r';
           case 't':
                   return '\t';
   
 #ifdef __STDC__  #if defined (__STDC__)
                 case 'a': return '\a';          case 'a':
                 case 'v': return '\v';                  return '\a';
           case 'v':
                   return '\v';
 #else  #else
                 case 'a': return '\007';          case 'a':
                 case 'v': return '\013';                  return '\007';
           case 'v':
                   return '\013';
 #endif  #endif
   
                 case '0':          case '0':
                 case '1':          case '1':
                 case '2':          case '2':
                 case '3':          case '3':
                 case '4':          case '4':
                 case '5':          case '5':
                 case '6':          case '6':
                 case '7':          case '7':
                         { /* \<octal> */                  {               /* \<octal> */
                         int sptr = 1;                          int     sptr = 1;
   
                         while ( isascii( array[sptr] ) &&                          while (isascii (array[sptr]) &&
                                 isdigit( array[sptr] ) )                                 isdigit (array[sptr]))
                                 /* Don't increment inside loop control                                  /* Don't increment inside loop control
                                  * because if isdigit() is a macro it might                                   * because if isdigit() is a macro it might
                                  * expand into multiple increments ...                                   * expand into multiple increments ...
Line 578 
Line 621 
                         c = array[sptr];                          c = array[sptr];
                         array[sptr] = '\0';                          array[sptr] = '\0';
   
                         esc_char = otoi( array + 1 );                          esc_char = otoi (array + 1);
   
                         array[sptr] = c;                          array[sptr] = c;
   
                         return esc_char;                          return esc_char;
                         }                  }
   
                 case 'x':          case 'x':
                         { /* \x<hex> */                  {               /* \x<hex> */
                         int sptr = 2;                          int     sptr = 2;
   
                         while ( isascii( array[sptr] ) &&                          while (isascii (array[sptr]) &&
                                 isxdigit( array[sptr] ) )                                 isxdigit (array[sptr]))
                                 /* Don't increment inside loop control                                  /* Don't increment inside loop control
                                  * because if isdigit() is a macro it might                                   * because if isdigit() is a macro it might
                                  * expand into multiple increments ...                                   * expand into multiple increments ...
Line 600 
Line 643 
                         c = array[sptr];                          c = array[sptr];
                         array[sptr] = '\0';                          array[sptr] = '\0';
   
                         esc_char = htoi( array + 2 );                          esc_char = htoi (array + 2);
   
                         array[sptr] = c;                          array[sptr] = c;
   
                         return esc_char;                          return esc_char;
                         }  
   
                 default:  
                         return array[1];  
                 }                  }
   
           default:
                   return array[1];
         }          }
   }
   
   
 /* otoi - convert an octal digit string to an integer value */  /* otoi - convert an octal digit string to an integer value */
   
 int otoi( str )  int otoi (str)
 Char str[];       Char str[];
         {  {
         unsigned int result;          unsigned int result;
   
         (void) sscanf( (char *) str, "%o", &result );          (void) sscanf ((char *) str, "%o", &result);
         return result;          return result;
         }  }
   
   
 /* out - various flavors of outputing a (possibly formatted) string for the  /* out - various flavors of outputing a (possibly formatted) string for the
  *       generated scanner, keeping track of the line count.   *       generated scanner, keeping track of the line count.
  */   */
   
 void out( str )  void out (str)
 const char str[];       const char *str;
         {  {
         fputs( str, stdout );          fputs (str, stdout);
         out_line_count( str );  }
         }  
   
 void out_dec( fmt, n )  void out_dec (fmt, n)
 const char fmt[];       const char *fmt;
 int n;       int n;
         {  {
         printf( fmt, n );          fprintf (stdout, fmt, n);
         out_line_count( fmt );  }
         }  
   
 void out_dec2( fmt, n1, n2 )  void out_dec2 (fmt, n1, n2)
 const char fmt[];       const char *fmt;
 int n1, n2;       int n1, n2;
         {  {
         printf( fmt, n1, n2 );          fprintf (stdout, fmt, n1, n2);
         out_line_count( fmt );  }
         }  
   
 void out_hex( fmt, x )  void out_hex (fmt, x)
 const char fmt[];       const char *fmt;
 unsigned int x;       unsigned int x;
         {  {
         printf( fmt, x );          fprintf (stdout, fmt, x);
         out_line_count( fmt );  }
         }  
   
 void out_line_count( str )  void out_str (fmt, str)
 const char str[];       const char *fmt, str[];
         {  {
         int i;          fprintf (stdout,fmt, str);
   }
   
         for ( i = 0; str[i]; ++i )  void out_str3 (fmt, s1, s2, s3)
                 if ( str[i] == '\n' )       const char *fmt, s1[], s2[], s3[];
                         ++out_linenum;  {
         }          fprintf (stdout,fmt, s1, s2, s3);
   }
   
 void out_str( fmt, str )  void out_str_dec (fmt, str, n)
 const char fmt[], str[];       const char *fmt, str[];
         {       int n;
         printf( fmt, str );  {
         out_line_count( fmt );          fprintf (stdout,fmt, str, n);
         out_line_count( str );  }
         }  
   
 void out_str3( fmt, s1, s2, s3 )  void outc (c)
 const char fmt[], s1[], s2[], s3[];       int c;
         {  {
         printf( fmt, s1, s2, s3 );          fputc (c, stdout);
         out_line_count( fmt );  }
         out_line_count( s1 );  
         out_line_count( s2 );  
         out_line_count( s3 );  
         }  
   
 void out_str_dec( fmt, str, n )  void outn (str)
 const char fmt[], str[];       const char *str;
 int n;  {
         {          fputs (str,stdout);
         printf( fmt, str, n );      fputc('\n',stdout);
         out_line_count( fmt );  }
         out_line_count( str );  
         }  
   
 void outc( c )  /** Print "m4_define( [[def]], [[val]])m4_dnl\n".
 int c;   * @param def The m4 symbol to define.
         {   * @param val The definition; may be NULL.
         putc( c, stdout );   * @return buf
    */
   void out_m4_define (const char* def, const char* val)
   {
       const char * fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n";
       fprintf(stdout, fmt, def, val?val:"");
   }
   
         if ( c == '\n' )  
                 ++out_linenum;  
         }  
   
 void outn( str )  
 const char str[];  
         {  
         puts( str );  
         out_line_count( str );  
         ++out_linenum;  
         }  
   
   
 /* readable_form - return the human-readable form of a character  /* readable_form - return the human-readable form of a character
  *   *
  * The returned string is in static storage.   * The returned string is in static storage.
  */   */
   
 char *readable_form( c )  char   *readable_form (c)
 int c;       int c;
         {  {
         static char rform[10];          static char rform[10];
   
         if ( (c >= 0 && c < 32) || c >= 127 )          if ((c >= 0 && c < 32) || c >= 127) {
                 {                  switch (c) {
                 switch ( c )                  case '\b':
                         {                          return "\\b";
                         case '\b': return "\\b";                  case '\f':
                         case '\f': return "\\f";                          return "\\f";
                         case '\n': return "\\n";                  case '\n':
                         case '\r': return "\\r";                          return "\\n";
                         case '\t': return "\\t";                  case '\r':
                           return "\\r";
                   case '\t':
                           return "\\t";
   
 #ifdef __STDC__  #if defined (__STDC__)
                         case '\a': return "\\a";                  case '\a':
                         case '\v': return "\\v";                          return "\\a";
                   case '\v':
                           return "\\v";
 #endif  #endif
   
                         default:                  default:
                                 (void) snprintf( rform, sizeof rform,                          snprintf (rform, sizeof(rform), "\\%.3o", (unsigned int) c);
                                         "\\%.3o", (unsigned int) c );                          return rform;
                                 return rform;  
                         }  
                 }                  }
           }
   
         else if ( c == ' ' )          else if (c == ' ')
                 return "' '";                  return "' '";
   
         else          else {
                 {  
                 rform[0] = c;                  rform[0] = c;
                 rform[1] = '\0';                  rform[1] = '\0';
   
                 return rform;                  return rform;
                 }  
         }          }
   }
   
   
 /* reallocate_array - increase the size of a dynamic array */  /* reallocate_array - increase the size of a dynamic array */
   
 void *reallocate_array( array, size, element_size )  void   *reallocate_array (array, size, element_size)
 void *array;       void   *array;
 int size;       int size;
 size_t element_size;       size_t element_size;
         {  {
         void *new_array;          void *new_array;
         size_t num_bytes = element_size * size;          size_t  num_bytes = element_size * size;
   
         new_array = flex_realloc( array, num_bytes );          new_array = flex_realloc (array, num_bytes);
         if ( ! new_array )          if (!new_array)
                 flexfatal( _( "attempt to increase array size failed" ) );                  flexfatal (_("attempt to increase array size failed"));
   
         return new_array;          return new_array;
         }  }
   
   
 /* skelout - write out one section of the skeleton file  /* skelout - write out one section of the skeleton file
Line 784 
Line 815 
  *    Copies skelfile or skel array to stdout until a line beginning with   *    Copies skelfile or skel array to stdout until a line beginning with
  *    "%%" or EOF is found.   *    "%%" or EOF is found.
  */   */
 void skelout()  void skelout ()
         {  {
         char buf_storage[MAXLINE];          char    buf_storage[MAXLINE];
         char *buf = buf_storage;          char   *buf = buf_storage;
         int do_copy = 1;          bool   do_copy = true;
   
       /* "reset" the state by clearing the buffer and pushing a '1' */
       if(sko_len > 0)
           sko_peek(&do_copy);
       sko_len = 0;
       sko_push(do_copy=true);
   
   
         /* Loop pulling lines either from the skelfile, if we're using          /* Loop pulling lines either from the skelfile, if we're using
          * one, or from the skel[] array.           * one, or from the skel[] array.
          */           */
         while ( skelfile ?          while (skelfile ?
                 (fgets( buf, MAXLINE, skelfile ) != NULL) :                 (fgets (buf, MAXLINE, skelfile) != NULL) :
                 ((buf = (char *) skel[skel_ind++]) != 0) )                 ((buf = (char *) skel[skel_ind++]) != 0)) {
                 { /* copy from skel array */  
                 if ( buf[0] == '%' )  
                         { /* control line */  
                         switch ( buf[1] )  
                                 {  
                                 case '%':  
                                         return;  
   
                                 case '+':                  if (skelfile)
                                         do_copy = C_plus_plus;                          chomp (buf);
                                         break;  
   
                                 case '-':                  /* copy from skel array */
                                         do_copy = ! C_plus_plus;                  if (buf[0] == '%') {    /* control line */
                                         break;                          /* print the control line as a comment. */
                           if (ddebug && buf[1] != '#') {
                                   if (buf[strlen (buf) - 1] == '\\')
                                           out_str ("/* %s */\\\n", buf);
                                   else
                                           out_str ("/* %s */\n", buf);
                           }
   
                                 case '*':                          /* We've been accused of using cryptic markers in the skel.
                                         do_copy = 1;                           * So we'll use emacs-style-hyphenated-commands.
                                         break;               * We might consider a hash if this if-else-if-else
                * chain gets too large.
                            */
   #define cmd_match(s) (strncmp(buf,(s),strlen(s))==0)
   
                                 default:                          if (buf[1] == '%') {
                                         flexfatal(                                  /* %% is a break point for skelout() */
                                         _( "bad line in skeleton file" ) );                                  return;
                                 }  
                         }                          }
               else if (cmd_match (CMD_PUSH)){
                 else if ( do_copy )                  sko_push(do_copy);
                         {                  if(ddebug){
                         if ( skelfile )                      out_str("/*(state = (%s) */",do_copy?"true":"false");
                                 /* Skeleton file reads include final                  }
                                  * newline, skel[] array does not.                  out_str("%s\n", buf[strlen (buf) - 1] =='\\' ? "\\" : "");
                                  */              }
                                 out( buf );              else if (cmd_match (CMD_POP)){
                         else                  sko_pop(&do_copy);
                                 outn( buf );                  if(ddebug){
                       out_str("/*(state = (%s) */",do_copy?"true":"false");
                   }
                   out_str("%s\n", buf[strlen (buf) - 1] =='\\' ? "\\" : "");
               }
               else if (cmd_match (CMD_IF_REENTRANT)){
                   sko_push(do_copy);
                   do_copy = reentrant && do_copy;
               }
               else if (cmd_match (CMD_IF_NOT_REENTRANT)){
                   sko_push(do_copy);
                   do_copy = !reentrant && do_copy;
               }
               else if (cmd_match(CMD_IF_BISON_BRIDGE)){
                   sko_push(do_copy);
                   do_copy = bison_bridge_lval && do_copy;
               }
               else if (cmd_match(CMD_IF_NOT_BISON_BRIDGE)){
                   sko_push(do_copy);
                   do_copy = !bison_bridge_lval && do_copy;
               }
               else if (cmd_match (CMD_ENDIF)){
                   sko_pop(&do_copy);
               }
                           else if (cmd_match (CMD_IF_TABLES_SER)) {
                   do_copy = do_copy && tablesext;
                         }                          }
                           else if (cmd_match (CMD_TABLES_YYDMAP)) {
                                   if (tablesext && yydmap_buf.elts)
                                           outn ((char *) (yydmap_buf.elts));
                           }
               else if (cmd_match (CMD_DEFINE_YYTABLES)) {
                   out_str("#define YYTABLES_NAME \"%s\"\n",
                           tablesname?tablesname:"yytables");
               }
                           else if (cmd_match (CMD_IF_CPP_ONLY)) {
                                   /* only for C++ */
                   sko_push(do_copy);
                                   do_copy = C_plus_plus;
                           }
                           else if (cmd_match (CMD_IF_C_ONLY)) {
                                   /* %- only for C */
                   sko_push(do_copy);
                                   do_copy = !C_plus_plus;
                           }
                           else if (cmd_match (CMD_IF_C_OR_CPP)) {
                                   /* %* for C and C++ */
                   sko_push(do_copy);
                                   do_copy = true;
                           }
                           else if (cmd_match (CMD_NOT_FOR_HEADER)) {
                                   /* %c begin linkage-only (non-header) code. */
                                   OUT_BEGIN_CODE ();
                           }
                           else if (cmd_match (CMD_OK_FOR_HEADER)) {
                                   /* %e end linkage-only code. */
                                   OUT_END_CODE ();
                           }
                           else if (buf[1] == '#') {
                                   /* %# a comment in the skel. ignore. */
                           }
                           else {
                                   flexfatal (_("bad line in skeleton file"));
                           }
                 }                  }
         }  
   
                   else if (do_copy)
               outn (buf);
           }                       /* end while */
   }
   
   
 /* transition_struct_out - output a yy_trans_info structure  /* transition_struct_out - output a yy_trans_info structure
  *   *
  * outputs the yy_trans_info structure with the two elements, element_v and   * outputs the yy_trans_info structure with the two elements, element_v and
  * element_n.  Formats the output with spaces and carriage returns.   * element_n.  Formats the output with spaces and carriage returns.
  */   */
   
 void transition_struct_out( element_v, element_n )  void transition_struct_out (element_v, element_n)
 int element_v, element_n;       int element_v, element_n;
         {  {
         out_dec2( " {%4d,%4d },", element_v, element_n );  
   
           /* short circuit any output */
           if (!gentables)
                   return;
   
           out_dec2 (" {%4d,%4d },", element_v, element_n);
   
         datapos += TRANS_STRUCT_PRINT_LENGTH;          datapos += TRANS_STRUCT_PRINT_LENGTH;
   
         if ( datapos >= 79 - TRANS_STRUCT_PRINT_LENGTH )          if (datapos >= 79 - TRANS_STRUCT_PRINT_LENGTH) {
                 {                  outc ('\n');
                 outc( '\n' );  
   
                 if ( ++dataline % 10 == 0 )                  if (++dataline % 10 == 0)
                         outc( '\n' );                          outc ('\n');
   
                 datapos = 0;                  datapos = 0;
                 }  
         }          }
   }
   
   
 /* The following is only needed when building flex's parser using certain  /* The following is only needed when building flex's parser using certain
  * broken versions of bison.   * broken versions of bison.
  */   */
 void *yy_flex_xmalloc( size )  void   *yy_flex_xmalloc (size)
 int size;       int size;
         {  {
         void *result = flex_alloc( (size_t) size );          void   *result = flex_alloc ((size_t) size);
   
         if ( ! result  )          if (!result)
                 flexfatal(                  flexfatal (_
                         _( "memory allocation failed in yy_flex_xmalloc()" ) );                             ("memory allocation failed in yy_flex_xmalloc()"));
   
         return result;          return result;
         }  }
   
   
 /* zero_out - set a region of memory to 0  /* zero_out - set a region of memory to 0
Line 882 
Line 990 
  * Sets region_ptr[0] through region_ptr[size_in_bytes - 1] to zero.   * Sets region_ptr[0] through region_ptr[size_in_bytes - 1] to zero.
  */   */
   
 void zero_out( region_ptr, size_in_bytes )  void zero_out (region_ptr, size_in_bytes)
 char *region_ptr;       char   *region_ptr;
 size_t size_in_bytes;       size_t size_in_bytes;
         {  {
         char *rp, *rp_end;          char *rp, *rp_end;
   
         rp = region_ptr;          rp = region_ptr;
         rp_end = region_ptr + size_in_bytes;          rp_end = region_ptr + size_in_bytes;
   
         while ( rp < rp_end )          while (rp < rp_end)
                 *rp++ = 0;                  *rp++ = 0;
         }  }
   
   /* Remove all '\n' and '\r' characters, if any, from the end of str.
    * str can be any null-terminated string, or NULL.
    * returns str. */
   char   *chomp (str)
        char   *str;
   {
           char   *p = str;
   
           if (!str || !*str)      /* s is null or empty string */
                   return str;
   
           /* find end of string minus one */
           while (*p)
                   ++p;
           --p;
   
           /* eat newlines */
           while (p >= str && (*p == '\r' || *p == '\n'))
                   *p-- = 0;
           return str;
   }

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15