version 1.15, 2015/11/19 19:43:40 |
version 1.16, 2015/11/19 22:52:40 |
|
|
|
|
/* we allow the skeleton to push and pop. */ |
/* we allow the skeleton to push and pop. */ |
struct sko_state { |
struct sko_state { |
bool dc; /**< do_copy */ |
bool dc; /**< do_copy */ |
}; |
}; |
static struct sko_state *sko_stack=0; |
static struct sko_state *sko_stack = 0; |
static int sko_len=0,sko_sz=0; |
static int sko_len = 0, sko_sz = 0; |
static void sko_push(bool dc) |
static void |
|
sko_push(bool dc) |
{ |
{ |
if(!sko_stack){ |
if (!sko_stack) { |
sko_sz = 1; |
sko_sz = 1; |
sko_stack = (struct sko_state*)flex_alloc(sizeof(struct sko_state)*sko_sz); |
sko_stack = (struct sko_state *) flex_alloc(sizeof(struct sko_state) * sko_sz); |
if (!sko_stack) |
if (!sko_stack) |
flexfatal(_("allocation of sko_stack failed")); |
flexfatal(_("allocation of sko_stack failed")); |
sko_len = 0; |
sko_len = 0; |
} |
} |
if(sko_len >= sko_sz){ |
if (sko_len >= sko_sz) { |
sko_sz *= 2; |
sko_sz *= 2; |
sko_stack = (struct sko_state*)flex_realloc(sko_stack,sizeof(struct sko_state)*sko_sz); |
sko_stack = (struct sko_state *) flex_realloc(sko_stack, sizeof(struct sko_state) * sko_sz); |
} |
} |
|
/* initialize to zero and push */ |
/* initialize to zero and push */ |
sko_stack[sko_len].dc = dc; |
sko_stack[sko_len].dc = dc; |
sko_len++; |
sko_len++; |
|
} |
} |
static void sko_peek(bool *dc) |
static void |
|
sko_peek(bool * dc) |
{ |
{ |
if(sko_len <= 0) |
if (sko_len <= 0) |
flex_die("peek attempt when sko stack is empty"); |
flex_die("peek attempt when sko stack is empty"); |
if(dc) |
if (dc) |
*dc = sko_stack[sko_len-1].dc; |
*dc = sko_stack[sko_len - 1].dc; |
} |
} |
static void sko_pop(bool* dc) |
static void |
|
sko_pop(bool * dc) |
{ |
{ |
sko_peek(dc); |
sko_peek(dc); |
sko_len--; |
sko_len--; |
if(sko_len < 0) |
if (sko_len < 0) |
flex_die("popped too many times in skeleton."); |
flex_die("popped too many times in skeleton."); |
} |
} |
|
|
/* Append "#define defname value\n" to the running buffer. */ |
/* Append "#define defname value\n" to the running buffer. */ |
void action_define (defname, value) |
void |
const char *defname; |
action_define(defname, value) |
int value; |
const char *defname; |
|
int value; |
{ |
{ |
char buf[MAXLINE]; |
char buf[MAXLINE]; |
char *cpy; |
char *cpy; |
|
|
if ((int) strlen (defname) > MAXLINE / 2) { |
if ((int) strlen(defname) > MAXLINE / 2) { |
format_pinpoint_message (_ |
format_pinpoint_message(_ |
("name \"%s\" ridiculously long"), |
("name \"%s\" ridiculously long"), |
defname); |
defname); |
return; |
return; |
} |
} |
|
snprintf(buf, sizeof(buf), "#define %s %d\n", defname, value); |
|
add_action(buf); |
|
|
snprintf (buf, sizeof(buf), "#define %s %d\n", defname, value); |
|
add_action (buf); |
|
|
|
/* track #defines so we can undef them when we're done. */ |
/* track #defines so we can undef them when we're done. */ |
cpy = copy_string (defname); |
cpy = copy_string(defname); |
buf_append (&defs_buf, &cpy, 1); |
buf_append(&defs_buf, &cpy, 1); |
} |
} |
|
|
|
|
|
|
* @param defname The macro name. |
* @param defname The macro name. |
* @param value The macro value, can be NULL, which is the same as the empty string. |
* @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) |
void |
|
action_m4_define(const char *defname, const char *value) |
{ |
{ |
char buf[MAXLINE]; |
char buf[MAXLINE]; |
|
|
flexfatal ("DO NOT USE THIS FUNCTION!"); |
flexfatal("DO NOT USE THIS FUNCTION!"); |
|
|
if ((int) strlen (defname) > MAXLINE / 2) { |
if ((int) strlen(defname) > MAXLINE / 2) { |
format_pinpoint_message (_ |
format_pinpoint_message(_ |
("name \"%s\" ridiculously long"), |
("name \"%s\" ridiculously long"), |
defname); |
defname); |
return; |
return; |
} |
} |
|
snprintf(buf, sizeof(buf), "m4_define([[%s]],[[%s]])m4_dnl\n", defname, value ? value : ""); |
snprintf (buf, sizeof(buf), "m4_define([[%s]],[[%s]])m4_dnl\n", defname, value?value:""); |
add_action(buf); |
add_action (buf); |
|
} |
} |
|
|
/* Append "new_text" to the running buffer. */ |
/* Append "new_text" to the running buffer. */ |
void add_action (new_text) |
void |
const char *new_text; |
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. |
*/ |
*/ |
action_size += action_size / 8; |
action_size += action_size / 8; |
|
|
action_size = new_size; |
action_size = new_size; |
|
|
action_array = |
action_array = |
reallocate_character_array (action_array, |
reallocate_character_array(action_array, |
action_size); |
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 * |
int size; |
allocate_array(size, element_size) |
size_t element_size; |
int 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 |
char *str; |
all_lower(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; |
} |
} |
|
|
|
|
/* 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 |
char *str; |
all_upper(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; |
} |
} |
|
|
|
|
/* intcmp - compares two integers for use by qsort. */ |
/* intcmp - compares two integers for use by qsort. */ |
|
|
int intcmp (const void *a, const void *b) |
int |
|
intcmp(const void *a, const void *b) |
{ |
{ |
return *(const int *) a - *(const int *) b; |
return *(const int *) a - *(const int *) b; |
} |
} |
|
|
|
|
|
|
* and exits. |
* and exits. |
*/ |
*/ |
|
|
void check_char (c) |
void |
int c; |
check_char(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 |
int c; |
clower(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 * |
const char *str; |
copy_string(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); |
copy = (char *) flex_alloc(size); |
|
|
if (copy == NULL) |
if (copy == NULL) |
flexfatal (_("dynamic memory failure in copy_string()")); |
flexfatal(_("dynamic memory failure in copy_string()")); |
|
|
for (c2 = copy; (*c2++ = *str++) != 0;) ; |
for (c2 = copy; (*c2++ = *str++) != 0;); |
|
|
return copy; |
return copy; |
} |
} |
|
|
* 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 * |
Char *str; |
copy_unsigned_string(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; |
} |
} |
|
|
|
|
/* cclcmp - compares two characters for use by qsort with '\0' sorting last. */ |
/* cclcmp - compares two characters for use by qsort with '\0' sorting last. */ |
|
|
int cclcmp (const void *a, const void *b) |
int |
|
cclcmp(const void *a, const void *b) |
{ |
{ |
if (!*(const Char *) a) |
if (!*(const Char *) a) |
return 1; |
return 1; |
else |
else if (!*(const Char *) b) |
if (!*(const Char *) b) |
return -1; |
return - 1; |
|
else |
else |
return *(const Char *) a - *(const Char *) b; |
return *(const Char *) a - *(const Char *) b; |
} |
} |
|
|
|
|
/* dataend - finish up a block of data declarations */ |
/* dataend - finish up a block of data declarations */ |
|
|
void dataend () |
void |
|
dataend() |
{ |
{ |
/* short circuit any output */ |
/* short circuit any output */ |
if (gentables) { |
if (gentables) { |
|
|
if (datapos > 0) |
if (datapos > 0) |
dataflush (); |
dataflush(); |
|
|
/* add terminator for initialization; { for vi */ |
/* add terminator for initialization; { for vi */ |
outn (" } ;\n"); |
outn(" } ;\n"); |
} |
} |
dataline = 0; |
dataline = 0; |
datapos = 0; |
datapos = 0; |
|
|
|
|
/* dataflush - flush generated data statements */ |
/* dataflush - flush generated data statements */ |
|
|
void dataflush () |
void |
|
dataflush() |
{ |
{ |
/* short circuit any output */ |
/* short circuit any output */ |
if (!gentables) |
if (!gentables) |
return; |
return; |
|
|
outc ('\n'); |
outc('\n'); |
|
|
if (++dataline >= NUMDATALINES) { |
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 |
const char *msg; |
flexerror(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 |
const char *msg; |
flexfatal(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); |
FLEX_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 |
Char str[]; |
htoi(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 |
const char *msg; |
lerrif(msg, arg) |
int arg; |
const char *msg; |
|
int arg; |
{ |
{ |
char errmsg[MAXLINE]; |
char errmsg[MAXLINE]; |
|
|
snprintf (errmsg, sizeof(errmsg), msg, arg); |
snprintf(errmsg, sizeof(errmsg), msg, arg); |
flexerror (errmsg); |
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]; |
|
|
snprintf (errmsg, sizeof(errmsg)-1, msg, arg); |
snprintf(errmsg, sizeof(errmsg) - 1, msg, arg); |
errmsg[sizeof(errmsg)-1] = 0; /* ensure NULL termination */ |
errmsg[sizeof(errmsg) - 1] = 0; /* ensure NULL termination */ |
flexerror (errmsg); |
flexerror(errmsg); |
} |
} |
|
|
|
|
/* lerrsf_fatal - as lerrsf, but call flexfatal */ |
/* lerrsf_fatal - as lerrsf, but call flexfatal */ |
|
|
void lerrsf_fatal (msg, arg) |
void |
|
lerrsf_fatal(msg, arg) |
const char *msg, arg[]; |
const char *msg, arg[]; |
{ |
{ |
char errmsg[MAXLINE]; |
char errmsg[MAXLINE]; |
|
|
snprintf (errmsg, sizeof(errmsg)-1, msg, arg); |
snprintf(errmsg, sizeof(errmsg) - 1, msg, arg); |
errmsg[sizeof(errmsg)-1] = 0; /* ensure NULL termination */ |
errmsg[sizeof(errmsg) - 1] = 0; /* ensure NULL termination */ |
flexfatal (errmsg); |
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 |
FILE *output_file; |
line_directive_out(output_file, do_infile) |
int do_infile; |
FILE *output_file; |
|
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) |
|
|
s1 = do_infile ? infilename : "M4_YY_OUTFILE_NAME"; |
s1 = do_infile ? infilename : "M4_YY_OUTFILE_NAME"; |
|
|
if (do_infile && !s1) |
if (do_infile && !s1) |
s1 = "<stdin>"; |
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 == '\\') |
|
|
*s2 = '\0'; |
*s2 = '\0'; |
|
|
if (do_infile) |
if (do_infile) |
snprintf (directive, sizeof(directive), line_fmt, linenum, filename); |
snprintf(directive, sizeof(directive), line_fmt, linenum, filename); |
else { |
else { |
snprintf (directive, sizeof(directive), line_fmt, 0, filename); |
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 is nil then we should put the directive in the |
|
* accumulated actions. |
*/ |
*/ |
if (output_file) { |
if (output_file) { |
fputs (directive, output_file); |
fputs(directive, output_file); |
} |
} else |
else |
add_action(directive); |
add_action (directive); |
|
} |
} |
|
|
|
|
|
|
* 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'; |
|
|
/* 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; |
|
|
* |
* |
* 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 |
int value; |
mk2data(value) |
|
int value; |
{ |
{ |
/* short circuit any output */ |
/* short circuit any output */ |
if (!gentables) |
if (!gentables) |
return; |
return; |
|
|
if (datapos >= NUMDATAITEMS) { |
if (datapos >= NUMDATAITEMS) { |
outc (','); |
outc(','); |
dataflush (); |
dataflush(); |
} |
} |
|
|
if (datapos == 0) |
if (datapos == 0) |
/* Indent. */ |
/* Indent. */ |
out (" "); |
out(" "); |
|
|
else |
else |
outc (','); |
outc(','); |
|
|
++datapos; |
++datapos; |
|
|
out_dec ("%5d", value); |
out_dec("%5d", value); |
} |
} |
|
|
|
|
|
|
* 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 |
int value; |
mkdata(value) |
|
int value; |
{ |
{ |
/* short circuit any output */ |
/* short circuit any output */ |
if (!gentables) |
if (!gentables) |
return; |
return; |
|
|
if (datapos >= NUMDATAITEMS) { |
if (datapos >= NUMDATAITEMS) { |
outc (','); |
outc(','); |
dataflush (); |
dataflush(); |
} |
} |
|
|
if (datapos == 0) |
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 |
const char *array; |
myctoi(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 |
Char array[]; |
myesc(array) |
|
Char array[]; |
{ |
{ |
Char c, esc_char; |
Char c, esc_char; |
|
|
switch (array[1]) { |
switch (array[1]) { |
case 'b': |
case 'b': |
|
|
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 ... |
*/ |
*/ |
|
|
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; |
|
|
|
|
|
|
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 ... |
*/ |
*/ |
|
|
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; |
|
|
|
|
|
|
/* otoi - convert an octal digit string to an integer value */ |
/* otoi - convert an octal digit string to an integer value */ |
|
|
int otoi (str) |
int |
Char str[]; |
otoi(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; |
} |
} |
|
|
|
|
* generated scanner, keeping track of the line count. |
* generated scanner, keeping track of the line count. |
*/ |
*/ |
|
|
void out (str) |
void |
const char *str; |
out(str) |
|
const char *str; |
{ |
{ |
fputs (str, stdout); |
fputs(str, stdout); |
} |
} |
|
|
void out_dec (fmt, n) |
void |
const char *fmt; |
out_dec(fmt, n) |
int n; |
const char *fmt; |
|
int n; |
{ |
{ |
fprintf (stdout, fmt, n); |
fprintf(stdout, fmt, n); |
} |
} |
|
|
void out_dec2 (fmt, n1, n2) |
void |
const char *fmt; |
out_dec2(fmt, n1, n2) |
int n1, n2; |
const char *fmt; |
|
int n1, n2; |
{ |
{ |
fprintf (stdout, fmt, n1, n2); |
fprintf(stdout, fmt, n1, n2); |
} |
} |
|
|
void out_hex (fmt, x) |
void |
const char *fmt; |
out_hex(fmt, x) |
unsigned int x; |
const char *fmt; |
|
unsigned int x; |
{ |
{ |
fprintf (stdout, fmt, x); |
fprintf(stdout, fmt, x); |
} |
} |
|
|
void out_str (fmt, str) |
void |
const char *fmt, str[]; |
out_str(fmt, str) |
|
const char *fmt, str[]; |
{ |
{ |
fprintf (stdout,fmt, str); |
fprintf(stdout, fmt, str); |
} |
} |
|
|
void out_str3 (fmt, s1, s2, s3) |
void |
const char *fmt, s1[], s2[], s3[]; |
out_str3(fmt, s1, s2, s3) |
|
const char *fmt, s1[], s2[], s3[]; |
{ |
{ |
fprintf (stdout,fmt, s1, s2, s3); |
fprintf(stdout, fmt, s1, s2, s3); |
} |
} |
|
|
void out_str_dec (fmt, str, n) |
void |
const char *fmt, str[]; |
out_str_dec(fmt, str, n) |
int n; |
const char *fmt, str[]; |
|
int n; |
{ |
{ |
fprintf (stdout,fmt, str, n); |
fprintf(stdout, fmt, str, n); |
} |
} |
|
|
void outc (c) |
void |
int c; |
outc(c) |
|
int c; |
{ |
{ |
fputc (c, stdout); |
fputc(c, stdout); |
} |
} |
|
|
void outn (str) |
void |
const char *str; |
outn(str) |
|
const char *str; |
{ |
{ |
fputs (str,stdout); |
fputs(str, stdout); |
fputc('\n',stdout); |
fputc('\n', stdout); |
} |
} |
|
|
/** Print "m4_define( [[def]], [[val]])m4_dnl\n". |
/** Print "m4_define( [[def]], [[val]])m4_dnl\n". |
|
|
* @param val The definition; may be NULL. |
* @param val The definition; may be NULL. |
* @return buf |
* @return buf |
*/ |
*/ |
void out_m4_define (const char* def, const char* val) |
void |
|
out_m4_define(const char *def, const char *val) |
{ |
{ |
const char * fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n"; |
const char *fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n"; |
fprintf(stdout, fmt, def, val?val:""); |
fprintf(stdout, fmt, def, val ? val : ""); |
} |
} |
|
|
|
|
|
|
* The returned string is in static storage. |
* The returned string is in static storage. |
*/ |
*/ |
|
|
char *readable_form (c) |
char * |
int c; |
readable_form(c) |
|
int c; |
{ |
{ |
static char rform[10]; |
static char rform[10]; |
|
|
|
|
#endif |
#endif |
|
|
default: |
default: |
snprintf (rform, sizeof(rform), "\\%.3o", (unsigned int) c); |
snprintf(rform, sizeof(rform), "\\%.3o", (unsigned int) c); |
return rform; |
return rform; |
} |
} |
} |
} else if (c == ' ') |
|
|
else if (c == ' ') |
|
return "' '"; |
return "' '"; |
|
|
else { |
else { |
|
|
|
|
/* 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 * |
void *array; |
reallocate_array(array, size, element_size) |
int size; |
void *array; |
size_t element_size; |
int 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; |
} |
} |
|
|
* 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; |
bool do_copy = true; |
bool do_copy = true; |
|
|
/* "reset" the state by clearing the buffer and pushing a '1' */ |
/* "reset" the state by clearing the buffer and pushing a '1' */ |
if(sko_len > 0) |
if (sko_len > 0) |
sko_peek(&do_copy); |
sko_peek(&do_copy); |
sko_len = 0; |
sko_len = 0; |
sko_push(do_copy=true); |
sko_push(do_copy = true); |
|
|
|
|
/* Loop pulling lines either from the skelfile, if we're using |
/* |
* one, or from the skel[] array. |
* Loop pulling lines either from the skelfile, if we're using 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)) { |
|
|
if (skelfile) |
if (skelfile) |
chomp (buf); |
chomp(buf); |
|
|
/* copy from skel array */ |
/* copy from skel array */ |
if (buf[0] == '%') { /* control line */ |
if (buf[0] == '%') { /* control line */ |
/* print the control line as a comment. */ |
/* print the control line as a comment. */ |
if (ddebug && buf[1] != '#') { |
if (ddebug && buf[1] != '#') { |
if (buf[strlen (buf) - 1] == '\\') |
if (buf[strlen(buf) - 1] == '\\') |
out_str ("/* %s */\\\n", buf); |
out_str("/* %s */\\\n", buf); |
else |
else |
out_str ("/* %s */\n", buf); |
out_str("/* %s */\n", buf); |
} |
} |
|
/* |
/* We've been accused of using cryptic markers in the skel. |
* We've been accused of using cryptic markers in the |
* So we'll use emacs-style-hyphenated-commands. |
* skel. So we'll use |
* We might consider a hash if this if-else-if-else |
* emacs-style-hyphenated-commands. We might consider |
* chain gets too large. |
* a hash if this if-else-if-else chain gets too |
|
* large. |
*/ |
*/ |
#define cmd_match(s) (strncmp(buf,(s),strlen(s))==0) |
#define cmd_match(s) (strncmp(buf,(s),strlen(s))==0) |
|
|
if (buf[1] == '%') { |
if (buf[1] == '%') { |
/* %% is a break point for skelout() */ |
/* %% is a break point for skelout() */ |
return; |
return; |
} |
} else if (cmd_match(CMD_PUSH)) { |
else if (cmd_match (CMD_PUSH)){ |
sko_push(do_copy); |
sko_push(do_copy); |
if (ddebug) { |
if(ddebug){ |
out_str("/*(state = (%s) */", do_copy ? "true" : "false"); |
out_str("/*(state = (%s) */",do_copy?"true":"false"); |
} |
} |
out_str("%s\n", buf[strlen(buf) - 1] == '\\' ? "\\" : ""); |
out_str("%s\n", buf[strlen (buf) - 1] =='\\' ? "\\" : ""); |
} else if (cmd_match(CMD_POP)) { |
} |
sko_pop(&do_copy); |
else if (cmd_match (CMD_POP)){ |
if (ddebug) { |
sko_pop(&do_copy); |
out_str("/*(state = (%s) */", do_copy ? "true" : "false"); |
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)) { |
out_str("%s\n", buf[strlen (buf) - 1] =='\\' ? "\\" : ""); |
sko_push(do_copy); |
} |
do_copy = reentrant && do_copy; |
else if (cmd_match (CMD_IF_REENTRANT)){ |
} else if (cmd_match(CMD_IF_NOT_REENTRANT)) { |
sko_push(do_copy); |
sko_push(do_copy); |
do_copy = reentrant && do_copy; |
do_copy = !reentrant && do_copy; |
} |
} else if (cmd_match(CMD_IF_BISON_BRIDGE)) { |
else if (cmd_match (CMD_IF_NOT_REENTRANT)){ |
sko_push(do_copy); |
sko_push(do_copy); |
do_copy = bison_bridge_lval && do_copy; |
do_copy = !reentrant && do_copy; |
} else if (cmd_match(CMD_IF_NOT_BISON_BRIDGE)) { |
} |
sko_push(do_copy); |
else if (cmd_match(CMD_IF_BISON_BRIDGE)){ |
do_copy = !bison_bridge_lval && do_copy; |
sko_push(do_copy); |
} else if (cmd_match(CMD_ENDIF)) { |
do_copy = bison_bridge_lval && do_copy; |
sko_pop(&do_copy); |
} |
} else if (cmd_match(CMD_IF_TABLES_SER)) { |
else if (cmd_match(CMD_IF_NOT_BISON_BRIDGE)){ |
do_copy = do_copy && tablesext; |
sko_push(do_copy); |
} else if (cmd_match(CMD_TABLES_YYDMAP)) { |
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) |
if (tablesext && yydmap_buf.elts) |
outn ((char *) (yydmap_buf.elts)); |
outn((char *) (yydmap_buf.elts)); |
} |
} else if (cmd_match(CMD_DEFINE_YYTABLES)) { |
else if (cmd_match (CMD_DEFINE_YYTABLES)) { |
out_str("#define YYTABLES_NAME \"%s\"\n", |
out_str("#define YYTABLES_NAME \"%s\"\n", |
tablesname ? tablesname : "yytables"); |
tablesname?tablesname:"yytables"); |
} else if (cmd_match(CMD_IF_CPP_ONLY)) { |
} |
|
else if (cmd_match (CMD_IF_CPP_ONLY)) { |
|
/* only for C++ */ |
/* only for C++ */ |
sko_push(do_copy); |
sko_push(do_copy); |
do_copy = C_plus_plus; |
do_copy = C_plus_plus; |
} |
} else if (cmd_match(CMD_IF_C_ONLY)) { |
else if (cmd_match (CMD_IF_C_ONLY)) { |
|
/* %- only for C */ |
/* %- only for C */ |
sko_push(do_copy); |
sko_push(do_copy); |
do_copy = !C_plus_plus; |
do_copy = !C_plus_plus; |
} |
} else if (cmd_match(CMD_IF_C_OR_CPP)) { |
else if (cmd_match (CMD_IF_C_OR_CPP)) { |
|
/* %* for C and C++ */ |
/* %* for C and C++ */ |
sko_push(do_copy); |
sko_push(do_copy); |
do_copy = true; |
do_copy = true; |
} |
} else if (cmd_match(CMD_NOT_FOR_HEADER)) { |
else if (cmd_match (CMD_NOT_FOR_HEADER)) { |
|
/* %c begin linkage-only (non-header) code. */ |
/* %c begin linkage-only (non-header) code. */ |
OUT_BEGIN_CODE (); |
OUT_BEGIN_CODE(); |
} |
} else if (cmd_match(CMD_OK_FOR_HEADER)) { |
else if (cmd_match (CMD_OK_FOR_HEADER)) { |
|
/* %e end linkage-only code. */ |
/* %e end linkage-only code. */ |
OUT_END_CODE (); |
OUT_END_CODE(); |
} |
} else if (buf[1] == '#') { |
else if (buf[1] == '#') { |
|
/* %# a comment in the skel. ignore. */ |
/* %# a comment in the skel. ignore. */ |
|
} else { |
|
flexfatal(_("bad line in skeleton file")); |
} |
} |
else { |
} else if (do_copy) |
flexfatal (_("bad line in skeleton file")); |
outn(buf); |
} |
|
} |
|
|
|
else if (do_copy) |
|
outn (buf); |
|
} /* end while */ |
} /* end while */ |
} |
} |
|
|
|
|
* 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 |
int element_v, element_n; |
transition_struct_out(element_v, element_n) |
|
int element_v, element_n; |
{ |
{ |
|
|
/* short circuit any output */ |
/* short circuit any output */ |
if (!gentables) |
if (!gentables) |
return; |
return; |
|
|
out_dec2 (" {%4d,%4d },", element_v, element_n); |
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 * |
int size; |
yy_flex_xmalloc(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; |
} |
} |
|
|
* 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 |
char *region_ptr; |
zero_out(region_ptr, size_in_bytes) |
size_t size_in_bytes; |
char *region_ptr; |
|
size_t size_in_bytes; |
{ |
{ |
char *rp, *rp_end; |
char *rp, *rp_end; |
|
|
|
|
/* Remove all '\n' and '\r' characters, if any, from the end of str. |
/* Remove all '\n' and '\r' characters, if any, from the end of str. |
* str can be any null-terminated string, or NULL. |
* str can be any null-terminated string, or NULL. |
* returns str. */ |
* returns str. */ |
char *chomp (str) |
char * |
char *str; |
chomp(str) |
|
char *str; |
{ |
{ |
char *p = str; |
char *p = str; |
|
|
if (!str || !*str) /* s is null or empty string */ |
if (!str || !*str) /* s is null or empty string */ |
return str; |
return str; |