* Copyright (c) 1990 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Vern Paxson of Lawrence Berkeley Laboratory.
* 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
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. 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 BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)misc.c 5.3 (Berkeley) 2/26/91";
/* misc - miscellaneous flex routines */
/* ANSI C does not guarantee that isascii() is defined */
#define isascii(c) ((c) <= 0177)
/* declare functions that have forward references */
void dataflush
PROTO(());
int otoi
PROTO((Char
[]));
/* action_out - write the actions from the temporary file to lex.yy.c
* Copies the action file up to %% (or end-of-file) to lex.yy.c
while ( fgets( buf
, MAXLINE
, temp_action_file
) != NULL
)
if ( buf
[0] == '%' && buf
[1] == '%' )
/* allocate_array - allocate memory for an integer array of the given size */
void *allocate_array( size
, element_size
)
/* on 16-bit int machines (e.g., 80286) we might be trying to
* allocate more than a signed int can hold, and that won't
if ( element_size
* size
<= 0 )
flexfatal( "request for < 1 byte in allocate_array()" );
mem
= (void *) malloc( (unsigned) (element_size
* size
) );
flexfatal( "memory allocation failed in allocate_array()" );
/* all_lower - true if a string is all lower-case
* true/false = all_lower( str );
if ( ! isascii( *str
) || ! islower( *str
) )
/* all_upper - true if a string is all upper-case
* true/false = all_upper( str );
if ( ! isascii( *str
) || ! isupper( (char) *str
) )
/* bubble - bubble sort an integer array in increasing order
* sorts the first n elements of array v and replaces them in
* v - the array to be sorted
* n - the number of elements of 'v' to be sorted */
for ( i
= n
; i
> 1; --i
)
for ( j
= 1; j
< i
; ++j
)
if ( v
[j
] > v
[j
+ 1] ) /* compare */
/* clower - replace upper-case letter to lower-case
return ( (isascii( c
) && isupper( c
)) ? tolower( c
) : c
);
/* copy_string - returns a dynamically allocated copy of a string
* char *str, *copy, *copy_string();
* copy = copy_string( str );
copy
= malloc( (unsigned) ((c
- str
+ 1) * sizeof( char )) );
flexfatal( "dynamic memory failure in copy_string()" );
for ( c
= copy
; (*c
++ = *str
++); )
/* copy_unsigned_string -
* returns a dynamically allocated copy of a (potentially) unsigned string
* Char *str, *copy, *copy_unsigned_string();
* copy = copy_unsigned_string( str );
Char
*copy_unsigned_string( str
)
copy
= (Char
*) malloc( (unsigned) ((c
- str
+ 1) * sizeof( Char
)) );
flexfatal( "dynamic memory failure in copy_unsigned_string()" );
for ( c
= copy
; (*c
++ = *str
++); )
/* cshell - shell sort a character array in increasing order
* cshell( v, n, special_case_0 );
* 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.
* n - number of elements of v to be sorted
void cshell( v
, n
, special_case_0
)
for ( gap
= n
/ 2; gap
> 0; gap
= gap
/ 2 )
for ( i
= gap
; i
< n
; ++i
)
for ( j
= i
- gap
; j
>= 0; j
= j
- gap
)
else if ( v
[j
] != 0 && v
[j
] <= v
[jg
] )
else if ( v
[j
] <= v
[jg
] )
/* dataend - finish up a block of data declarations
/* add terminator for initialization */
/* dataflush - flush generated data statements
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
/* reset the number of characters written on the current line */
/* flexerror - report an error message and terminate
fprintf( stderr
, "%s: %s\n", program_name
, msg
);
/* flexfatal - report a fatal error message and terminate
fprintf( stderr
, "%s: fatal internal error, %s\n", program_name
, msg
);
/* flex_gettime - return current time
* char *flex_gettime(), *time_str;
* time_str = flex_gettime();
* the routine name has the "flex_" prefix because of name clashes
/* include sys/types.h to use time_t and make lint happy */
char *result
, *ctime(), *copy_string();
result
= copy_string( ctime( &t
) );
/* get rid of trailing newline */
/* lerrif - report an error message formatted with one integer argument
(void) sprintf( errmsg
, msg
, arg
);
/* lerrsf - report an error message formatted with one string argument
(void) sprintf( errmsg
, msg
, arg
);
/* htoi - convert a hexadecimal digit string to an integer value
(void) sscanf( (char *) str
, "%x", &result
);
/* line_directive_out - spit out a "# line" statement */
void line_directive_out( output_file_name
)
if ( infilename
&& gen_line_dirs
)
fprintf( output_file_name
, "# line %d \"%s\"\n", linenum
, infilename
);
/* mk2data - generate a data statement for a two-dimensional array
* generates a data statement initializing the current 2-D array to "value"
if ( datapos
>= NUMDATAITEMS
)
/* mkdata - generate a data statement
* generates a data statement initializing the current array element to
if ( datapos
>= NUMDATAITEMS
)
/* myctoi - return the integer represented by a string of digits
(void) sscanf( (char *) array
, "%d", &val
);
/* myesc - return character corresponding to escape sequence
* Char array[], c, myesc();
case 'a': return ( '\a' );
case 'b': return ( '\b' );
case 'f': return ( '\f' );
case 'n': return ( '\n' );
case 'r': return ( '\r' );
case 't': return ( '\t' );
case 'v': return ( '\v' );
{ /* \<octal> or \x<hex> */
while ( isascii( array
[sptr
] ) && isdigit( array
[sptr
] ) )
/* don't increment inside loop control because if
* isdigit() is a macro it will expand it to two
esc_char
= htoi( array
+ 2 );
esc_char
= otoi( array
+ 1 );
/* otoi - convert an octal digit string to an integer value
(void) sscanf( (char *) str
, "%o", &result
);
/* readable_form - return the the human-readable form of a character
* <string> = readable_form( c );
* The returned string is in static storage.
if ( (c
>= 0 && c
< 32) || c
>= 127 )
case '\n': return ( "\\n" );
case '\t': return ( "\\t" );
case '\f': return ( "\\f" );
case '\r': return ( "\\r" );
case '\b': return ( "\\b" );
(void) sprintf( rform
, "\\%.3o", c
);
/* reallocate_array - increase the size of a dynamic array */
void *reallocate_array( array
, size
, element_size
)
register void *new_array
;
/* same worry as in allocate_array(): */
if ( size
* element_size
<= 0 )
flexfatal( "attempt to increase array size by less than 1 byte" );
(void *) realloc( (char *)array
, (unsigned) (size
* element_size
));
flexfatal( "attempt to increase array size failed" );
/* skelout - write out one section of the skeleton file
* Copies from skelfile to stdout until a line beginning with "%%" or
while ( fgets( buf
, MAXLINE
, skelfile
) != NULL
)
if ( buf
[0] == '%' && buf
[1] == '%' )
/* transition_struct_out - output a yy_trans_info structure
* int element_v, element_n;
* transition_struct_out( element_v, element_n );
* outputs the yy_trans_info structure with the two elements, element_v and
* element_n. Formats the output with spaces and carriage returns.
void transition_struct_out( element_v
, element_n
)
int element_v
, element_n
;
printf( "%7d, %5d,", element_v
, element_n
);
datapos
+= TRANS_STRUCT_PRINT_LENGTH
;
if ( ++dataline
% 10 == 0 )