diff options
Diffstat (limited to 'usr.bin/lex/misc.c')
-rw-r--r-- | usr.bin/lex/misc.c | 1234 |
1 files changed, 682 insertions, 552 deletions
diff --git a/usr.bin/lex/misc.c b/usr.bin/lex/misc.c index 40797f57448..0dddc3aace7 100644 --- a/usr.bin/lex/misc.c +++ b/usr.bin/lex/misc.c @@ -1,71 +1,151 @@ -/* $OpenBSD: misc.c,v 1.14 2015/10/15 05:57:09 mmcc Exp $ */ +/* $OpenBSD: misc.c,v 1.15 2015/11/19 19:43:40 tedu Exp $ */ /* misc - miscellaneous flex routines */ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * 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. - */ +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ -/* $Header: /cvs/OpenBSD/src/usr.bin/lex/misc.c,v 1.14 2015/10/15 05:57:09 mmcc Exp $ */ +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ -#include "flexdef.h" +/* 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. */ -void action_define( defname, value ) -char *defname; -int value; - { - char buf[MAXLINE]; +/* 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. */ - if ( (int) strlen( defname ) > MAXLINE / 2 ) - { - format_pinpoint_message( _( "name \"%s\" ridiculously long" ), - defname ); +#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" + +/* we allow the skeleton to push and pop. */ +struct sko_state { + bool dc; /**< do_copy */ +}; +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."); +} + +/* Append "#define defname value\n" to the running buffer. */ +void action_define (defname, value) + const char *defname; + int value; +{ + char buf[MAXLINE]; + char *cpy; + + if ((int) strlen (defname) > MAXLINE / 2) { + format_pinpoint_message (_ + ("name \"%s\" ridiculously long"), + defname); return; - } + } + + snprintf (buf, sizeof(buf), "#define %s %d\n", defname, value); + 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!"); - snprintf( buf, sizeof buf, "#define %s %d\n", defname, value ); - add_action( buf ); + 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 ) -char *new_text; - { - int len = strlen( new_text ); +/* Append "new_text" to the running buffer. */ +void add_action (new_text) + const char *new_text; +{ + int len = strlen (new_text); - while ( len + action_index >= action_size - 10 /* slop */ ) - { - int new_size = action_size * 2; + while (len + action_index >= action_size - 10 /* slop */ ) { + int new_size = action_size * 2; - if ( new_size <= 0 ) + if (new_size <= 0) /* Increase just a little, to try to avoid overflow * on 16-bit machines. */ @@ -74,95 +154,71 @@ char *new_text; action_size = new_size; 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_index += len; - } +} /* allocate_array - allocate memory for an integer array of the given size */ -void *allocate_array( size, element_size ) -int size; -size_t element_size; - { +void *allocate_array (size, element_size) + int size; + size_t element_size; +{ void *mem; - size_t num_bytes = element_size * size; + size_t num_bytes = element_size * size; - mem = flex_alloc( num_bytes ); - if ( ! mem ) - flexfatal( - _( "memory allocation failed in allocate_array()" ) ); + mem = flex_alloc (num_bytes); + if (!mem) + flexfatal (_ + ("memory allocation failed in allocate_array()")); return mem; - } +} /* all_lower - true if a string is all lower-case */ -int all_lower( str ) -char *str; - { - while ( *str ) - { - if ( ! isascii( (Char) *str ) || ! islower( (Char) *str ) ) +int all_lower (str) + char *str; +{ + while (*str) { + if (!isascii ((Char) * str) || !islower ((Char) * str)) return 0; ++str; - } + } return 1; - } +} /* all_upper - true if a string is all upper-case */ -int all_upper( str ) -char *str; - { - while ( *str ) - { - if ( ! isascii( (Char) *str ) || ! isupper( (Char) *str ) ) +int all_upper (str) + char *str; +{ + while (*str) { + if (!isascii ((Char) * str) || !isupper ((Char) * str)) return 0; ++str; - } + } return 1; - } +} -/* bubble - bubble sort an integer array in increasing order - * - * 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 - */ +/* intcmp - compares two integers for use by qsort. */ -void bubble( v, n ) -int v[], n; - { - 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; - } - } +int intcmp (const void *a, const void *b) +{ + return *(const int *) a - *(const int *) b; +} /* check_char - checks a character to make sure it's within the range @@ -170,328 +226,304 @@ int v[], n; * and exits. */ -void check_char( c ) -int c; - { - if ( c >= CSIZE ) - lerrsf( _( "bad character '%s' detected in check_char()" ), - readable_form( c ) ); - - if ( c >= csize ) - lerrsf( - _( "scanner requires -8 flag to use the character %s" ), - readable_form( c ) ); - } +void check_char (c) + int c; +{ + if (c >= CSIZE) + lerrsf (_("bad character '%s' detected in check_char()"), + readable_form (c)); + + if (c >= csize) + lerrsf (_ + ("scanner requires -8 flag to use the character %s"), + readable_form (c)); +} /* clower - replace upper-case letter to lower-case */ -Char clower( c ) -int c; - { - return (Char) ((isascii( c ) && isupper( c )) ? tolower( c ) : c); - } +Char clower (c) + int c; +{ + return (Char) ((isascii (c) && isupper (c)) ? tolower (c) : c); +} /* copy_string - returns a dynamically allocated copy of a string */ -char *copy_string( str ) -const char *str; - { +char *copy_string (str) + const char *str; +{ const char *c1; char *c2; - char *copy; + char *copy; unsigned int size; /* 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 ); + copy = (char *) flex_alloc (size); - if ( copy == NULL ) - flexfatal( _( "dynamic memory failure in copy_string()" ) ); + if (copy == NULL) + flexfatal (_("dynamic memory failure in copy_string()")); - for ( c2 = copy; (*c2++ = *str++) != 0; ) - ; + for (c2 = copy; (*c2++ = *str++) != 0;) ; return copy; - } +} /* copy_unsigned_string - * returns a dynamically allocated copy of a (potentially) unsigned string */ -Char *copy_unsigned_string( str ) -Char *str; - { +Char *copy_unsigned_string (str) + Char *str; +{ Char *c; - Char *copy; + Char *copy; /* 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; - } +} -/* cshell - shell sort a character array in increasing order - * - * 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 - */ +/* cclcmp - compares two characters for use by qsort with '\0' sorting last. */ -void cshell( v, n, special_case_0 ) -Char v[]; -int n, special_case_0; - { - int gap, i, j, jg; - Char k; - - 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; - } - } +int cclcmp (const void *a, const void *b) +{ + if (!*(const Char *) a) + return 1; + else + if (!*(const Char *) b) + return - 1; + else + return *(const Char *) a - *(const Char *) b; +} /* dataend - finish up a block of data declarations */ -void dataend() - { - if ( datapos > 0 ) - dataflush(); +void dataend () +{ + /* short circuit any output */ + if (gentables) { - /* add terminator for initialization; { for vi */ - outn( " } ;\n" ); + if (datapos > 0) + dataflush (); + /* add terminator for initialization; { for vi */ + outn (" } ;\n"); + } dataline = 0; datapos = 0; - } +} /* dataflush - flush generated data statements */ -void dataflush() - { - outc( '\n' ); +void dataflush () +{ + /* short circuit any output */ + if (!gentables) + return; + + outc ('\n'); - if ( ++dataline >= NUMDATALINES ) - { + if (++dataline >= NUMDATALINES) { /* Put out a blank line so that the table is grouped into * large blocks that enable the user to find elements easily. */ - outc( '\n' ); + outc ('\n'); dataline = 0; - } + } /* Reset the number of characters written on the current line. */ datapos = 0; - } +} /* flexerror - report an error message and terminate */ -void flexerror( msg ) -const char msg[]; - { - fprintf( stderr, "%s: %s\n", program_name, msg ); - flexend( 1 ); - } +void flexerror (msg) + const char *msg; +{ + fprintf (stderr, "%s: %s\n", program_name, msg); + flexend (1); +} /* flexfatal - report a fatal error message and terminate */ -void flexfatal( msg ) -const char msg[]; - { - fprintf( stderr, _( "%s: fatal internal error, %s\n" ), - program_name, msg ); - exit( 1 ); - } +void flexfatal (msg) + const char *msg; +{ + fprintf (stderr, _("%s: fatal internal error, %s\n"), + program_name, msg); + FLEX_EXIT (1); +} /* htoi - convert a hexadecimal digit string to an integer value */ -int htoi( str ) -Char str[]; - { +int htoi (str) + Char str[]; +{ unsigned int result; - (void) sscanf( (char *) str, "%x", &result ); + (void) sscanf ((char *) str, "%x", &result); return result; - } +} /* lerrif - report an error message formatted with one integer argument */ -void lerrif( msg, arg ) -const char msg[]; -int arg; - { - char errmsg[MAXLINE]; - (void) snprintf( errmsg, sizeof errmsg, msg, arg ); - flexerror( errmsg ); - } +void lerrif (msg, arg) + const char *msg; + int arg; +{ + char errmsg[MAXLINE]; + + snprintf (errmsg, sizeof(errmsg), msg, arg); + flexerror (errmsg); +} /* lerrsf - report an error message formatted with one string argument */ -void lerrsf( msg, arg ) -const char msg[], arg[]; - { - char errmsg[MAXLINE]; +void lerrsf (msg, arg) + const char *msg, arg[]; +{ + char errmsg[MAXLINE]; - (void) snprintf( errmsg, sizeof errmsg, msg, arg ); - flexerror( errmsg ); - } + snprintf (errmsg, sizeof(errmsg)-1, msg, arg); + 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 */ -void line_directive_out( output_file, do_infile ) -FILE *output_file; -int do_infile; - { - char directive[MAXLINE], filename[MAXLINE]; - char *s1, *s2, *s3; - static const char line_fmt[] = "#line %d \"%s\"\n"; +void line_directive_out (output_file, do_infile) + FILE *output_file; + int do_infile; +{ + char directive[MAXLINE], filename[MAXLINE]; + char *s1, *s2, *s3; + static const char *line_fmt = "#line %d \"%s\"\n"; - if ( ! gen_line_dirs ) + if (!gen_line_dirs) return; - if ( (do_infile && ! infilename) || (! do_infile && ! outfilename) ) - /* don't know the filename to use, skip */ - return; + s1 = do_infile ? infilename : "M4_YY_OUTFILE_NAME"; - s1 = do_infile ? infilename : outfilename; + if (do_infile && !s1) + s1 = "<stdin>"; + s2 = filename; - s3 = &filename[sizeof( filename ) - 2]; + s3 = &filename[sizeof (filename) - 2]; - while ( s2 < s3 && *s1 ) - { - if ( *s1 == '\\' ) + while (s2 < s3 && *s1) { + if (*s1 == '\\') /* Escape the '\' */ *s2++ = '\\'; *s2++ = *s1++; - } + } *s2 = '\0'; - if ( do_infile ) - snprintf( directive, sizeof directive, line_fmt, - linenum, filename ); - else - { - if ( output_file == stdout ) - /* Account for the line directive itself. */ - ++out_linenum; - - snprintf( directive, sizeof directive, line_fmt, - out_linenum, filename ); - } + if (do_infile) + snprintf (directive, sizeof(directive), line_fmt, linenum, filename); + else { + snprintf (directive, sizeof(directive), line_fmt, 0, filename); + } /* If output_file is nil then we should put the directive in * the accumulated actions. */ - if ( output_file ) - { - fputs( directive, output_file ); - } - else - add_action( directive ); + if (output_file) { + fputs (directive, output_file); } + else + add_action (directive); +} /* mark_defs1 - mark the current position in the action array as * representing where the user's section 1 definitions end * and the prolog begins */ -void mark_defs1() - { +void mark_defs1 () +{ defs1_offset = 0; action_array[action_index++] = '\0'; action_offset = prolog_offset = action_index; action_array[action_index] = '\0'; - } +} /* mark_prolog - mark the current position in the action array as * representing the end of the action prolog */ -void mark_prolog() - { +void mark_prolog () +{ action_array[action_index++] = '\0'; action_offset = action_index; action_array[action_index] = '\0'; - } +} /* mk2data - generate a data statement for a two-dimensional array * * Generates a data statement initializing the current 2-D array to "value". */ -void mk2data( value ) -int value; - { - if ( datapos >= NUMDATAITEMS ) - { - outc( ',' ); - dataflush(); - } +void mk2data (value) + int value; +{ + /* short circuit any output */ + if (!gentables) + return; - if ( datapos == 0 ) + if (datapos >= NUMDATAITEMS) { + outc (','); + dataflush (); + } + + if (datapos == 0) /* Indent. */ - out( " " ); + out (" "); else - outc( ',' ); + outc (','); ++datapos; - out_dec( "%5d", value ); - } + out_dec ("%5d", value); +} /* mkdata - generate a data statement @@ -499,76 +531,87 @@ int value; * Generates a data statement initializing the current array element to * "value". */ -void mkdata( value ) -int value; - { - if ( datapos >= NUMDATAITEMS ) - { - outc( ',' ); - dataflush(); - } +void mkdata (value) + int value; +{ + /* short circuit any output */ + if (!gentables) + return; - if ( datapos == 0 ) + if (datapos >= NUMDATAITEMS) { + outc (','); + dataflush (); + } + + if (datapos == 0) /* Indent. */ - out( " " ); + out (" "); else - outc( ',' ); + outc (','); ++datapos; - out_dec( "%5d", value ); - } + out_dec ("%5d", value); +} /* myctoi - return the integer represented by a string of digits */ -int myctoi( array ) -char array[]; - { - int val = 0; +int myctoi (array) + const char *array; +{ + int val = 0; - (void) sscanf( array, "%d", &val ); + (void) sscanf (array, "%d", &val); return val; - } +} /* myesc - return character corresponding to escape sequence */ -Char myesc( array ) -Char array[]; - { - Char c, esc_char; - - switch ( array[1] ) - { - case 'b': return '\b'; - case 'f': return '\f'; - case 'n': return '\n'; - case 'r': return '\r'; - case 't': return '\t'; - -#ifdef __STDC__ - case 'a': return '\a'; - case 'v': return '\v'; +Char myesc (array) + Char array[]; +{ + Char c, esc_char; + + switch (array[1]) { + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + +#if defined (__STDC__) + case 'a': + return '\a'; + case 'v': + return '\v'; #else - case 'a': return '\007'; - case 'v': return '\013'; + case 'a': + return '\007'; + case 'v': + return '\013'; #endif - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { /* \<octal> */ - int sptr = 1; - - while ( isascii( array[sptr] ) && - isdigit( array[sptr] ) ) + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { /* \<octal> */ + int sptr = 1; + + while (isascii (array[sptr]) && + isdigit (array[sptr])) /* Don't increment inside loop control * because if isdigit() is a macro it might * expand into multiple increments ... @@ -578,19 +621,19 @@ Char array[]; c = array[sptr]; array[sptr] = '\0'; - esc_char = otoi( array + 1 ); + esc_char = otoi (array + 1); array[sptr] = c; return esc_char; - } + } - case 'x': - { /* \x<hex> */ - int sptr = 2; + case 'x': + { /* \x<hex> */ + int sptr = 2; - while ( isascii( array[sptr] ) && - isxdigit( array[sptr] ) ) + while (isascii (array[sptr]) && + isxdigit (array[sptr])) /* Don't increment inside loop control * because if isdigit() is a macro it might * expand into multiple increments ... @@ -600,119 +643,104 @@ Char array[]; c = array[sptr]; array[sptr] = '\0'; - esc_char = htoi( array + 2 ); + esc_char = htoi (array + 2); array[sptr] = c; return esc_char; - } - - default: - return array[1]; } + + default: + return array[1]; } +} /* otoi - convert an octal digit string to an integer value */ -int otoi( str ) -Char str[]; - { +int otoi (str) + Char str[]; +{ unsigned int result; - (void) sscanf( (char *) str, "%o", &result ); + (void) sscanf ((char *) str, "%o", &result); return result; - } +} /* out - various flavors of outputing a (possibly formatted) string for the * generated scanner, keeping track of the line count. */ -void out( str ) -const char str[]; - { - fputs( str, stdout ); - out_line_count( str ); - } - -void out_dec( fmt, n ) -const char fmt[]; -int n; - { - printf( fmt, n ); - out_line_count( fmt ); - } - -void out_dec2( fmt, n1, n2 ) -const char fmt[]; -int n1, n2; - { - printf( fmt, n1, n2 ); - out_line_count( fmt ); - } - -void out_hex( fmt, x ) -const char fmt[]; -unsigned int x; - { - printf( fmt, x ); - out_line_count( fmt ); - } - -void out_line_count( str ) -const char str[]; - { - int i; - - for ( i = 0; str[i]; ++i ) - if ( str[i] == '\n' ) - ++out_linenum; - } - -void out_str( fmt, str ) -const char fmt[], str[]; - { - printf( fmt, str ); - out_line_count( fmt ); - out_line_count( str ); - } - -void out_str3( fmt, s1, s2, s3 ) -const char fmt[], s1[], s2[], s3[]; - { - printf( fmt, s1, s2, s3 ); - out_line_count( fmt ); - out_line_count( s1 ); - out_line_count( s2 ); - out_line_count( s3 ); - } - -void out_str_dec( fmt, str, n ) -const char fmt[], str[]; -int n; - { - printf( fmt, str, n ); - out_line_count( fmt ); - out_line_count( str ); - } - -void outc( c ) -int c; - { - putc( c, stdout ); - - if ( c == '\n' ) - ++out_linenum; - } - -void outn( str ) -const char str[]; - { - puts( str ); - out_line_count( str ); - ++out_linenum; - } +void out (str) + const char *str; +{ + fputs (str, stdout); +} + +void out_dec (fmt, n) + const char *fmt; + int n; +{ + fprintf (stdout, fmt, n); +} + +void out_dec2 (fmt, n1, n2) + const char *fmt; + int n1, n2; +{ + fprintf (stdout, fmt, n1, n2); +} + +void out_hex (fmt, x) + const char *fmt; + unsigned int x; +{ + fprintf (stdout, fmt, x); +} + +void out_str (fmt, str) + const char *fmt, str[]; +{ + fprintf (stdout,fmt, str); +} + +void out_str3 (fmt, s1, s2, s3) + const char *fmt, s1[], s2[], s3[]; +{ + fprintf (stdout,fmt, s1, s2, s3); +} + +void out_str_dec (fmt, str, n) + const char *fmt, str[]; + int n; +{ + fprintf (stdout,fmt, str, n); +} + +void outc (c) + int c; +{ + fputc (c, stdout); +} + +void outn (str) + const char *str; +{ + fputs (str,stdout); + fputc('\n',stdout); +} + +/** Print "m4_define( [[def]], [[val]])m4_dnl\n". + * @param def The m4 symbol to define. + * @param val The definition; may be NULL. + * @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:""); +} /* readable_form - return the human-readable form of a character @@ -720,62 +748,65 @@ const char str[]; * The returned string is in static storage. */ -char *readable_form( c ) -int c; - { +char *readable_form (c) + int c; +{ static char rform[10]; - if ( (c >= 0 && c < 32) || c >= 127 ) - { - switch ( c ) - { - case '\b': return "\\b"; - case '\f': return "\\f"; - case '\n': return "\\n"; - case '\r': return "\\r"; - case '\t': return "\\t"; - -#ifdef __STDC__ - case '\a': return "\\a"; - case '\v': return "\\v"; + if ((c >= 0 && c < 32) || c >= 127) { + switch (c) { + case '\b': + return "\\b"; + case '\f': + return "\\f"; + case '\n': + return "\\n"; + case '\r': + return "\\r"; + case '\t': + return "\\t"; + +#if defined (__STDC__) + case '\a': + return "\\a"; + case '\v': + return "\\v"; #endif - default: - (void) snprintf( rform, sizeof rform, - "\\%.3o", (unsigned int) c ); - return rform; - } + default: + snprintf (rform, sizeof(rform), "\\%.3o", (unsigned int) c); + return rform; } + } - else if ( c == ' ' ) + else if (c == ' ') return "' '"; - else - { + else { rform[0] = c; rform[1] = '\0'; return rform; - } } +} /* reallocate_array - increase the size of a dynamic array */ -void *reallocate_array( array, size, element_size ) -void *array; -int size; -size_t element_size; - { +void *reallocate_array (array, size, element_size) + void *array; + int size; + size_t element_size; +{ void *new_array; - size_t num_bytes = element_size * size; + size_t num_bytes = element_size * size; - new_array = flex_realloc( array, num_bytes ); - if ( ! new_array ) - flexfatal( _( "attempt to increase array size failed" ) ); + new_array = flex_realloc (array, num_bytes); + if (!new_array) + flexfatal (_("attempt to increase array size failed")); return new_array; - } +} /* skelout - write out one section of the skeleton file @@ -784,56 +815,129 @@ size_t element_size; * Copies skelfile or skel array to stdout until a line beginning with * "%%" or EOF is found. */ -void skelout() - { - char buf_storage[MAXLINE]; - char *buf = buf_storage; - int do_copy = 1; +void skelout () +{ + char buf_storage[MAXLINE]; + char *buf = buf_storage; + 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 * one, or from the skel[] array. */ - while ( skelfile ? - (fgets( buf, MAXLINE, skelfile ) != NULL) : - ((buf = (char *) skel[skel_ind++]) != 0) ) - { /* copy from skel array */ - if ( buf[0] == '%' ) - { /* control line */ - switch ( buf[1] ) - { - case '%': - return; - - case '+': - do_copy = C_plus_plus; - break; - - case '-': - do_copy = ! C_plus_plus; - break; - - case '*': - do_copy = 1; - break; - - default: - flexfatal( - _( "bad line in skeleton file" ) ); - } + while (skelfile ? + (fgets (buf, MAXLINE, skelfile) != NULL) : + ((buf = (char *) skel[skel_ind++]) != 0)) { + + if (skelfile) + chomp (buf); + + /* copy from skel array */ + if (buf[0] == '%') { /* control line */ + /* 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); } - else if ( do_copy ) - { - if ( skelfile ) - /* Skeleton file reads include final - * newline, skel[] array does not. - */ - out( buf ); - else - outn( buf ); + /* We've been accused of using cryptic markers in the skel. + * So we'll use emacs-style-hyphenated-commands. + * 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) + + if (buf[1] == '%') { + /* %% is a break point for skelout() */ + return; + } + else if (cmd_match (CMD_PUSH)){ + sko_push(do_copy); + if(ddebug){ + out_str("/*(state = (%s) */",do_copy?"true":"false"); + } + out_str("%s\n", buf[strlen (buf) - 1] =='\\' ? "\\" : ""); + } + else if (cmd_match (CMD_POP)){ + sko_pop(&do_copy); + 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 @@ -842,39 +946,43 @@ void skelout() * element_n. Formats the output with spaces and carriage returns. */ -void transition_struct_out( element_v, element_n ) -int element_v, element_n; - { - out_dec2( " {%4d,%4d },", element_v, element_n ); +void transition_struct_out (element_v, element_n) + int element_v, element_n; +{ + + /* short circuit any output */ + if (!gentables) + return; + + out_dec2 (" {%4d,%4d },", element_v, element_n); datapos += TRANS_STRUCT_PRINT_LENGTH; - if ( datapos >= 79 - TRANS_STRUCT_PRINT_LENGTH ) - { - outc( '\n' ); + if (datapos >= 79 - TRANS_STRUCT_PRINT_LENGTH) { + outc ('\n'); - if ( ++dataline % 10 == 0 ) - outc( '\n' ); + if (++dataline % 10 == 0) + outc ('\n'); datapos = 0; - } } +} /* The following is only needed when building flex's parser using certain * broken versions of bison. */ -void *yy_flex_xmalloc( size ) -int size; - { - void *result = flex_alloc( (size_t) size ); +void *yy_flex_xmalloc (size) + int size; +{ + void *result = flex_alloc ((size_t) size); - if ( ! result ) - flexfatal( - _( "memory allocation failed in yy_flex_xmalloc()" ) ); + if (!result) + flexfatal (_ + ("memory allocation failed in yy_flex_xmalloc()")); return result; - } +} /* zero_out - set a region of memory to 0 @@ -882,15 +990,37 @@ int size; * Sets region_ptr[0] through region_ptr[size_in_bytes - 1] to zero. */ -void zero_out( region_ptr, size_in_bytes ) -char *region_ptr; -size_t size_in_bytes; - { +void zero_out (region_ptr, size_in_bytes) + char *region_ptr; + size_t size_in_bytes; +{ char *rp, *rp_end; rp = region_ptr; rp_end = region_ptr + size_in_bytes; - while ( rp < rp_end ) + while (rp < rp_end) *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; +} |