xref: /freebsd-src/contrib/flex/src/misc.c (revision 7e38239042df09edbbdc443ccb4825f9155c6bb7)
1*7e382390SJung-uk Kim /* misc - miscellaneous flex routines */
2*7e382390SJung-uk Kim 
3*7e382390SJung-uk Kim /*  Copyright (c) 1990 The Regents of the University of California. */
4*7e382390SJung-uk Kim /*  All rights reserved. */
5*7e382390SJung-uk Kim 
6*7e382390SJung-uk Kim /*  This code is derived from software contributed to Berkeley by */
7*7e382390SJung-uk Kim /*  Vern Paxson. */
8*7e382390SJung-uk Kim 
9*7e382390SJung-uk Kim /*  The United States Government has rights in this work pursuant */
10*7e382390SJung-uk Kim /*  to contract no. DE-AC03-76SF00098 between the United States */
11*7e382390SJung-uk Kim /*  Department of Energy and the University of California. */
12*7e382390SJung-uk Kim 
13*7e382390SJung-uk Kim /*  This file is part of flex. */
14*7e382390SJung-uk Kim 
15*7e382390SJung-uk Kim /*  Redistribution and use in source and binary forms, with or without */
16*7e382390SJung-uk Kim /*  modification, are permitted provided that the following conditions */
17*7e382390SJung-uk Kim /*  are met: */
18*7e382390SJung-uk Kim 
19*7e382390SJung-uk Kim /*  1. Redistributions of source code must retain the above copyright */
20*7e382390SJung-uk Kim /*     notice, this list of conditions and the following disclaimer. */
21*7e382390SJung-uk Kim /*  2. Redistributions in binary form must reproduce the above copyright */
22*7e382390SJung-uk Kim /*     notice, this list of conditions and the following disclaimer in the */
23*7e382390SJung-uk Kim /*     documentation and/or other materials provided with the distribution. */
24*7e382390SJung-uk Kim 
25*7e382390SJung-uk Kim /*  Neither the name of the University nor the names of its contributors */
26*7e382390SJung-uk Kim /*  may be used to endorse or promote products derived from this software */
27*7e382390SJung-uk Kim /*  without specific prior written permission. */
28*7e382390SJung-uk Kim 
29*7e382390SJung-uk Kim /*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
30*7e382390SJung-uk Kim /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
31*7e382390SJung-uk Kim /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
32*7e382390SJung-uk Kim /*  PURPOSE. */
33*7e382390SJung-uk Kim #include "flexdef.h"
34*7e382390SJung-uk Kim #include "tables.h"
35*7e382390SJung-uk Kim 
36*7e382390SJung-uk Kim #define CMD_IF_TABLES_SER    "%if-tables-serialization"
37*7e382390SJung-uk Kim #define CMD_TABLES_YYDMAP    "%tables-yydmap"
38*7e382390SJung-uk Kim #define CMD_DEFINE_YYTABLES  "%define-yytables"
39*7e382390SJung-uk Kim #define CMD_IF_CPP_ONLY      "%if-c++-only"
40*7e382390SJung-uk Kim #define CMD_IF_C_ONLY        "%if-c-only"
41*7e382390SJung-uk Kim #define CMD_IF_C_OR_CPP      "%if-c-or-c++"
42*7e382390SJung-uk Kim #define CMD_NOT_FOR_HEADER   "%not-for-header"
43*7e382390SJung-uk Kim #define CMD_OK_FOR_HEADER    "%ok-for-header"
44*7e382390SJung-uk Kim #define CMD_PUSH             "%push"
45*7e382390SJung-uk Kim #define CMD_POP              "%pop"
46*7e382390SJung-uk Kim #define CMD_IF_REENTRANT     "%if-reentrant"
47*7e382390SJung-uk Kim #define CMD_IF_NOT_REENTRANT "%if-not-reentrant"
48*7e382390SJung-uk Kim #define CMD_IF_BISON_BRIDGE  "%if-bison-bridge"
49*7e382390SJung-uk Kim #define CMD_IF_NOT_BISON_BRIDGE  "%if-not-bison-bridge"
50*7e382390SJung-uk Kim #define CMD_ENDIF            "%endif"
51*7e382390SJung-uk Kim 
52*7e382390SJung-uk Kim /* we allow the skeleton to push and pop. */
53*7e382390SJung-uk Kim struct sko_state {
54*7e382390SJung-uk Kim     bool dc; /**< do_copy */
55*7e382390SJung-uk Kim };
56*7e382390SJung-uk Kim static struct sko_state *sko_stack=0;
57*7e382390SJung-uk Kim static int sko_len=0,sko_sz=0;
sko_push(bool dc)58*7e382390SJung-uk Kim static void sko_push(bool dc)
59*7e382390SJung-uk Kim {
60*7e382390SJung-uk Kim     if(!sko_stack){
61*7e382390SJung-uk Kim         sko_sz = 1;
62*7e382390SJung-uk Kim         sko_stack = malloc(sizeof(struct sko_state) * (size_t) sko_sz);
63*7e382390SJung-uk Kim         if (!sko_stack)
64*7e382390SJung-uk Kim             flexfatal(_("allocation of sko_stack failed"));
65*7e382390SJung-uk Kim         sko_len = 0;
66*7e382390SJung-uk Kim     }
67*7e382390SJung-uk Kim     if(sko_len >= sko_sz){
68*7e382390SJung-uk Kim         sko_sz *= 2;
69*7e382390SJung-uk Kim         sko_stack = realloc(sko_stack,
70*7e382390SJung-uk Kim 			sizeof(struct sko_state) * (size_t) sko_sz);
71*7e382390SJung-uk Kim     }
72*7e382390SJung-uk Kim 
73*7e382390SJung-uk Kim     /* initialize to zero and push */
74*7e382390SJung-uk Kim     sko_stack[sko_len].dc = dc;
75*7e382390SJung-uk Kim     sko_len++;
76*7e382390SJung-uk Kim }
sko_peek(bool * dc)77*7e382390SJung-uk Kim static void sko_peek(bool *dc)
78*7e382390SJung-uk Kim {
79*7e382390SJung-uk Kim     if(sko_len <= 0)
80*7e382390SJung-uk Kim         flex_die("peek attempt when sko stack is empty");
81*7e382390SJung-uk Kim     if(dc)
82*7e382390SJung-uk Kim         *dc = sko_stack[sko_len-1].dc;
83*7e382390SJung-uk Kim }
sko_pop(bool * dc)84*7e382390SJung-uk Kim static void sko_pop(bool* dc)
85*7e382390SJung-uk Kim {
86*7e382390SJung-uk Kim     sko_peek(dc);
87*7e382390SJung-uk Kim     sko_len--;
88*7e382390SJung-uk Kim     if(sko_len < 0)
89*7e382390SJung-uk Kim         flex_die("popped too many times in skeleton.");
90*7e382390SJung-uk Kim }
91*7e382390SJung-uk Kim 
92*7e382390SJung-uk Kim /* Append "#define defname value\n" to the running buffer. */
action_define(const char * defname,int value)93*7e382390SJung-uk Kim void action_define (const char *defname, int value)
94*7e382390SJung-uk Kim {
95*7e382390SJung-uk Kim 	char    buf[MAXLINE];
96*7e382390SJung-uk Kim 	char   *cpy;
97*7e382390SJung-uk Kim 
98*7e382390SJung-uk Kim 	if ((int) strlen (defname) > MAXLINE / 2) {
99*7e382390SJung-uk Kim 		format_pinpoint_message (_
100*7e382390SJung-uk Kim 					 ("name \"%s\" ridiculously long"),
101*7e382390SJung-uk Kim 					 defname);
102*7e382390SJung-uk Kim 		return;
103*7e382390SJung-uk Kim 	}
104*7e382390SJung-uk Kim 
105*7e382390SJung-uk Kim 	snprintf (buf, sizeof(buf), "#define %s %d\n", defname, value);
106*7e382390SJung-uk Kim 	add_action (buf);
107*7e382390SJung-uk Kim 
108*7e382390SJung-uk Kim 	/* track #defines so we can undef them when we're done. */
109*7e382390SJung-uk Kim 	cpy = xstrdup(defname);
110*7e382390SJung-uk Kim 	buf_append (&defs_buf, &cpy, 1);
111*7e382390SJung-uk Kim }
112*7e382390SJung-uk Kim 
113*7e382390SJung-uk Kim /* Append "new_text" to the running buffer. */
add_action(const char * new_text)114*7e382390SJung-uk Kim void add_action (const char *new_text)
115*7e382390SJung-uk Kim {
116*7e382390SJung-uk Kim 	int     len = (int) strlen (new_text);
117*7e382390SJung-uk Kim 
118*7e382390SJung-uk Kim 	while (len + action_index >= action_size - 10 /* slop */ ) {
119*7e382390SJung-uk Kim 		int     new_size = action_size * 2;
120*7e382390SJung-uk Kim 
121*7e382390SJung-uk Kim 		if (new_size <= 0)
122*7e382390SJung-uk Kim 			/* Increase just a little, to try to avoid overflow
123*7e382390SJung-uk Kim 			 * on 16-bit machines.
124*7e382390SJung-uk Kim 			 */
125*7e382390SJung-uk Kim 			action_size += action_size / 8;
126*7e382390SJung-uk Kim 		else
127*7e382390SJung-uk Kim 			action_size = new_size;
128*7e382390SJung-uk Kim 
129*7e382390SJung-uk Kim 		action_array =
130*7e382390SJung-uk Kim 			reallocate_character_array (action_array,
131*7e382390SJung-uk Kim 						    action_size);
132*7e382390SJung-uk Kim 	}
133*7e382390SJung-uk Kim 
134*7e382390SJung-uk Kim 	strcpy (&action_array[action_index], new_text);
135*7e382390SJung-uk Kim 
136*7e382390SJung-uk Kim 	action_index += len;
137*7e382390SJung-uk Kim }
138*7e382390SJung-uk Kim 
139*7e382390SJung-uk Kim 
140*7e382390SJung-uk Kim /* allocate_array - allocate memory for an integer array of the given size */
141*7e382390SJung-uk Kim 
allocate_array(int size,size_t element_size)142*7e382390SJung-uk Kim void   *allocate_array (int size, size_t element_size)
143*7e382390SJung-uk Kim {
144*7e382390SJung-uk Kim 	void *mem;
145*7e382390SJung-uk Kim #if HAVE_REALLOCARRAY
146*7e382390SJung-uk Kim 	/* reallocarray has built-in overflow detection */
147*7e382390SJung-uk Kim 	mem = reallocarray(NULL, (size_t) size, element_size);
148*7e382390SJung-uk Kim #else
149*7e382390SJung-uk Kim 	size_t num_bytes = (size_t) size * element_size;
150*7e382390SJung-uk Kim 	mem = (size && SIZE_MAX / (size_t) size < element_size) ? NULL :
151*7e382390SJung-uk Kim 		malloc(num_bytes);
152*7e382390SJung-uk Kim #endif
153*7e382390SJung-uk Kim 	if (!mem)
154*7e382390SJung-uk Kim 		flexfatal (_
155*7e382390SJung-uk Kim 			   ("memory allocation failed in allocate_array()"));
156*7e382390SJung-uk Kim 
157*7e382390SJung-uk Kim 	return mem;
158*7e382390SJung-uk Kim }
159*7e382390SJung-uk Kim 
160*7e382390SJung-uk Kim 
161*7e382390SJung-uk Kim /* all_lower - true if a string is all lower-case */
162*7e382390SJung-uk Kim 
all_lower(char * str)163*7e382390SJung-uk Kim int all_lower (char *str)
164*7e382390SJung-uk Kim {
165*7e382390SJung-uk Kim 	while (*str) {
166*7e382390SJung-uk Kim 		if (!isascii ((unsigned char) * str) || !islower ((unsigned char) * str))
167*7e382390SJung-uk Kim 			return 0;
168*7e382390SJung-uk Kim 		++str;
169*7e382390SJung-uk Kim 	}
170*7e382390SJung-uk Kim 
171*7e382390SJung-uk Kim 	return 1;
172*7e382390SJung-uk Kim }
173*7e382390SJung-uk Kim 
174*7e382390SJung-uk Kim 
175*7e382390SJung-uk Kim /* all_upper - true if a string is all upper-case */
176*7e382390SJung-uk Kim 
all_upper(char * str)177*7e382390SJung-uk Kim int all_upper (char *str)
178*7e382390SJung-uk Kim {
179*7e382390SJung-uk Kim 	while (*str) {
180*7e382390SJung-uk Kim 		if (!isascii ((unsigned char) * str) || !isupper ((unsigned char) * str))
181*7e382390SJung-uk Kim 			return 0;
182*7e382390SJung-uk Kim 		++str;
183*7e382390SJung-uk Kim 	}
184*7e382390SJung-uk Kim 
185*7e382390SJung-uk Kim 	return 1;
186*7e382390SJung-uk Kim }
187*7e382390SJung-uk Kim 
188*7e382390SJung-uk Kim 
189*7e382390SJung-uk Kim /* intcmp - compares two integers for use by qsort. */
190*7e382390SJung-uk Kim 
intcmp(const void * a,const void * b)191*7e382390SJung-uk Kim int intcmp (const void *a, const void *b)
192*7e382390SJung-uk Kim {
193*7e382390SJung-uk Kim   return *(const int *) a - *(const int *) b;
194*7e382390SJung-uk Kim }
195*7e382390SJung-uk Kim 
196*7e382390SJung-uk Kim 
197*7e382390SJung-uk Kim /* check_char - checks a character to make sure it's within the range
198*7e382390SJung-uk Kim  *		we're expecting.  If not, generates fatal error message
199*7e382390SJung-uk Kim  *		and exits.
200*7e382390SJung-uk Kim  */
201*7e382390SJung-uk Kim 
check_char(int c)202*7e382390SJung-uk Kim void check_char (int c)
203*7e382390SJung-uk Kim {
204*7e382390SJung-uk Kim 	if (c >= CSIZE)
205*7e382390SJung-uk Kim 		lerr (_("bad character '%s' detected in check_char()"),
206*7e382390SJung-uk Kim 			readable_form (c));
207*7e382390SJung-uk Kim 
208*7e382390SJung-uk Kim 	if (c >= csize)
209*7e382390SJung-uk Kim 		lerr (_
210*7e382390SJung-uk Kim 			("scanner requires -8 flag to use the character %s"),
211*7e382390SJung-uk Kim 			readable_form (c));
212*7e382390SJung-uk Kim }
213*7e382390SJung-uk Kim 
214*7e382390SJung-uk Kim 
215*7e382390SJung-uk Kim 
216*7e382390SJung-uk Kim /* clower - replace upper-case letter to lower-case */
217*7e382390SJung-uk Kim 
clower(int c)218*7e382390SJung-uk Kim unsigned char clower (int c)
219*7e382390SJung-uk Kim {
220*7e382390SJung-uk Kim 	return (unsigned char) ((isascii (c) && isupper (c)) ? tolower (c) : c);
221*7e382390SJung-uk Kim }
222*7e382390SJung-uk Kim 
223*7e382390SJung-uk Kim 
xstrdup(const char * s)224*7e382390SJung-uk Kim char *xstrdup(const char *s)
225*7e382390SJung-uk Kim {
226*7e382390SJung-uk Kim 	char *s2;
227*7e382390SJung-uk Kim 
228*7e382390SJung-uk Kim 	if ((s2 = strdup(s)) == NULL)
229*7e382390SJung-uk Kim 		flexfatal (_("memory allocation failure in xstrdup()"));
230*7e382390SJung-uk Kim 
231*7e382390SJung-uk Kim 	return s2;
232*7e382390SJung-uk Kim }
233*7e382390SJung-uk Kim 
234*7e382390SJung-uk Kim 
235*7e382390SJung-uk Kim /* cclcmp - compares two characters for use by qsort with '\0' sorting last. */
236*7e382390SJung-uk Kim 
cclcmp(const void * a,const void * b)237*7e382390SJung-uk Kim int cclcmp (const void *a, const void *b)
238*7e382390SJung-uk Kim {
239*7e382390SJung-uk Kim   if (!*(const unsigned char *) a)
240*7e382390SJung-uk Kim 	return 1;
241*7e382390SJung-uk Kim   else
242*7e382390SJung-uk Kim 	if (!*(const unsigned char *) b)
243*7e382390SJung-uk Kim 	  return - 1;
244*7e382390SJung-uk Kim 	else
245*7e382390SJung-uk Kim 	  return *(const unsigned char *) a - *(const unsigned char *) b;
246*7e382390SJung-uk Kim }
247*7e382390SJung-uk Kim 
248*7e382390SJung-uk Kim 
249*7e382390SJung-uk Kim /* dataend - finish up a block of data declarations */
250*7e382390SJung-uk Kim 
dataend(void)251*7e382390SJung-uk Kim void dataend (void)
252*7e382390SJung-uk Kim {
253*7e382390SJung-uk Kim 	/* short circuit any output */
254*7e382390SJung-uk Kim 	if (gentables) {
255*7e382390SJung-uk Kim 
256*7e382390SJung-uk Kim 		if (datapos > 0)
257*7e382390SJung-uk Kim 			dataflush ();
258*7e382390SJung-uk Kim 
259*7e382390SJung-uk Kim 		/* add terminator for initialization; { for vi */
260*7e382390SJung-uk Kim 		outn ("    } ;\n");
261*7e382390SJung-uk Kim 	}
262*7e382390SJung-uk Kim 	dataline = 0;
263*7e382390SJung-uk Kim 	datapos = 0;
264*7e382390SJung-uk Kim }
265*7e382390SJung-uk Kim 
266*7e382390SJung-uk Kim 
267*7e382390SJung-uk Kim /* dataflush - flush generated data statements */
268*7e382390SJung-uk Kim 
dataflush(void)269*7e382390SJung-uk Kim void dataflush (void)
270*7e382390SJung-uk Kim {
271*7e382390SJung-uk Kim 	/* short circuit any output */
272*7e382390SJung-uk Kim 	if (!gentables)
273*7e382390SJung-uk Kim 		return;
274*7e382390SJung-uk Kim 
275*7e382390SJung-uk Kim 	outc ('\n');
276*7e382390SJung-uk Kim 
277*7e382390SJung-uk Kim 	if (++dataline >= NUMDATALINES) {
278*7e382390SJung-uk Kim 		/* Put out a blank line so that the table is grouped into
279*7e382390SJung-uk Kim 		 * large blocks that enable the user to find elements easily.
280*7e382390SJung-uk Kim 		 */
281*7e382390SJung-uk Kim 		outc ('\n');
282*7e382390SJung-uk Kim 		dataline = 0;
283*7e382390SJung-uk Kim 	}
284*7e382390SJung-uk Kim 
285*7e382390SJung-uk Kim 	/* Reset the number of characters written on the current line. */
286*7e382390SJung-uk Kim 	datapos = 0;
287*7e382390SJung-uk Kim }
288*7e382390SJung-uk Kim 
289*7e382390SJung-uk Kim 
290*7e382390SJung-uk Kim /* flexerror - report an error message and terminate */
291*7e382390SJung-uk Kim 
flexerror(const char * msg)292*7e382390SJung-uk Kim void flexerror (const char *msg)
293*7e382390SJung-uk Kim {
294*7e382390SJung-uk Kim 	fprintf (stderr, "%s: %s\n", program_name, msg);
295*7e382390SJung-uk Kim 	flexend (1);
296*7e382390SJung-uk Kim }
297*7e382390SJung-uk Kim 
298*7e382390SJung-uk Kim 
299*7e382390SJung-uk Kim /* flexfatal - report a fatal error message and terminate */
300*7e382390SJung-uk Kim 
flexfatal(const char * msg)301*7e382390SJung-uk Kim void flexfatal (const char *msg)
302*7e382390SJung-uk Kim {
303*7e382390SJung-uk Kim 	fprintf (stderr, _("%s: fatal internal error, %s\n"),
304*7e382390SJung-uk Kim 		 program_name, msg);
305*7e382390SJung-uk Kim 	FLEX_EXIT (1);
306*7e382390SJung-uk Kim }
307*7e382390SJung-uk Kim 
308*7e382390SJung-uk Kim 
309*7e382390SJung-uk Kim /* lerr - report an error message */
310*7e382390SJung-uk Kim 
lerr(const char * msg,...)311*7e382390SJung-uk Kim void lerr (const char *msg, ...)
312*7e382390SJung-uk Kim {
313*7e382390SJung-uk Kim 	char    errmsg[MAXLINE];
314*7e382390SJung-uk Kim 	va_list args;
315*7e382390SJung-uk Kim 
316*7e382390SJung-uk Kim 	va_start(args, msg);
317*7e382390SJung-uk Kim 	vsnprintf (errmsg, sizeof(errmsg), msg, args);
318*7e382390SJung-uk Kim 	va_end(args);
319*7e382390SJung-uk Kim 	flexerror (errmsg);
320*7e382390SJung-uk Kim }
321*7e382390SJung-uk Kim 
322*7e382390SJung-uk Kim 
323*7e382390SJung-uk Kim /* lerr_fatal - as lerr, but call flexfatal */
324*7e382390SJung-uk Kim 
lerr_fatal(const char * msg,...)325*7e382390SJung-uk Kim void lerr_fatal (const char *msg, ...)
326*7e382390SJung-uk Kim {
327*7e382390SJung-uk Kim 	char    errmsg[MAXLINE];
328*7e382390SJung-uk Kim 	va_list args;
329*7e382390SJung-uk Kim 	va_start(args, msg);
330*7e382390SJung-uk Kim 
331*7e382390SJung-uk Kim 	vsnprintf (errmsg, sizeof(errmsg), msg, args);
332*7e382390SJung-uk Kim 	va_end(args);
333*7e382390SJung-uk Kim 	flexfatal (errmsg);
334*7e382390SJung-uk Kim }
335*7e382390SJung-uk Kim 
336*7e382390SJung-uk Kim 
337*7e382390SJung-uk Kim /* line_directive_out - spit out a "#line" statement */
338*7e382390SJung-uk Kim 
line_directive_out(FILE * output_file,int do_infile)339*7e382390SJung-uk Kim void line_directive_out (FILE *output_file, int do_infile)
340*7e382390SJung-uk Kim {
341*7e382390SJung-uk Kim 	char    directive[MAXLINE], filename[MAXLINE];
342*7e382390SJung-uk Kim 	char   *s1, *s2, *s3;
343*7e382390SJung-uk Kim 	static const char line_fmt[] = "#line %d \"%s\"\n";
344*7e382390SJung-uk Kim 
345*7e382390SJung-uk Kim 	if (!gen_line_dirs)
346*7e382390SJung-uk Kim 		return;
347*7e382390SJung-uk Kim 
348*7e382390SJung-uk Kim 	s1 = do_infile ? infilename : "M4_YY_OUTFILE_NAME";
349*7e382390SJung-uk Kim 
350*7e382390SJung-uk Kim 	if (do_infile && !s1)
351*7e382390SJung-uk Kim         s1 = "<stdin>";
352*7e382390SJung-uk Kim 
353*7e382390SJung-uk Kim 	s2 = filename;
354*7e382390SJung-uk Kim 	s3 = &filename[sizeof (filename) - 2];
355*7e382390SJung-uk Kim 
356*7e382390SJung-uk Kim 	while (s2 < s3 && *s1) {
357*7e382390SJung-uk Kim 		if (*s1 == '\\' || *s1 == '"')
358*7e382390SJung-uk Kim 			/* Escape the '\' or '"' */
359*7e382390SJung-uk Kim 			*s2++ = '\\';
360*7e382390SJung-uk Kim 
361*7e382390SJung-uk Kim 		*s2++ = *s1++;
362*7e382390SJung-uk Kim 	}
363*7e382390SJung-uk Kim 
364*7e382390SJung-uk Kim 	*s2 = '\0';
365*7e382390SJung-uk Kim 
366*7e382390SJung-uk Kim 	if (do_infile)
367*7e382390SJung-uk Kim 		snprintf (directive, sizeof(directive), line_fmt, linenum, filename);
368*7e382390SJung-uk Kim 	else {
369*7e382390SJung-uk Kim 		snprintf (directive, sizeof(directive), line_fmt, 0, filename);
370*7e382390SJung-uk Kim 	}
371*7e382390SJung-uk Kim 
372*7e382390SJung-uk Kim 	/* If output_file is nil then we should put the directive in
373*7e382390SJung-uk Kim 	 * the accumulated actions.
374*7e382390SJung-uk Kim 	 */
375*7e382390SJung-uk Kim 	if (output_file) {
376*7e382390SJung-uk Kim 		fputs (directive, output_file);
377*7e382390SJung-uk Kim 	}
378*7e382390SJung-uk Kim 	else
379*7e382390SJung-uk Kim 		add_action (directive);
380*7e382390SJung-uk Kim }
381*7e382390SJung-uk Kim 
382*7e382390SJung-uk Kim 
383*7e382390SJung-uk Kim /* mark_defs1 - mark the current position in the action array as
384*7e382390SJung-uk Kim  *               representing where the user's section 1 definitions end
385*7e382390SJung-uk Kim  *		 and the prolog begins
386*7e382390SJung-uk Kim  */
mark_defs1(void)387*7e382390SJung-uk Kim void mark_defs1 (void)
388*7e382390SJung-uk Kim {
389*7e382390SJung-uk Kim 	defs1_offset = 0;
390*7e382390SJung-uk Kim 	action_array[action_index++] = '\0';
391*7e382390SJung-uk Kim 	action_offset = prolog_offset = action_index;
392*7e382390SJung-uk Kim 	action_array[action_index] = '\0';
393*7e382390SJung-uk Kim }
394*7e382390SJung-uk Kim 
395*7e382390SJung-uk Kim 
396*7e382390SJung-uk Kim /* mark_prolog - mark the current position in the action array as
397*7e382390SJung-uk Kim  *               representing the end of the action prolog
398*7e382390SJung-uk Kim  */
mark_prolog(void)399*7e382390SJung-uk Kim void mark_prolog (void)
400*7e382390SJung-uk Kim {
401*7e382390SJung-uk Kim 	action_array[action_index++] = '\0';
402*7e382390SJung-uk Kim 	action_offset = action_index;
403*7e382390SJung-uk Kim 	action_array[action_index] = '\0';
404*7e382390SJung-uk Kim }
405*7e382390SJung-uk Kim 
406*7e382390SJung-uk Kim 
407*7e382390SJung-uk Kim /* mk2data - generate a data statement for a two-dimensional array
408*7e382390SJung-uk Kim  *
409*7e382390SJung-uk Kim  * Generates a data statement initializing the current 2-D array to "value".
410*7e382390SJung-uk Kim  */
mk2data(int value)411*7e382390SJung-uk Kim void mk2data (int value)
412*7e382390SJung-uk Kim {
413*7e382390SJung-uk Kim 	/* short circuit any output */
414*7e382390SJung-uk Kim 	if (!gentables)
415*7e382390SJung-uk Kim 		return;
416*7e382390SJung-uk Kim 
417*7e382390SJung-uk Kim 	if (datapos >= NUMDATAITEMS) {
418*7e382390SJung-uk Kim 		outc (',');
419*7e382390SJung-uk Kim 		dataflush ();
420*7e382390SJung-uk Kim 	}
421*7e382390SJung-uk Kim 
422*7e382390SJung-uk Kim 	if (datapos == 0)
423*7e382390SJung-uk Kim 		/* Indent. */
424*7e382390SJung-uk Kim 		out ("    ");
425*7e382390SJung-uk Kim 
426*7e382390SJung-uk Kim 	else
427*7e382390SJung-uk Kim 		outc (',');
428*7e382390SJung-uk Kim 
429*7e382390SJung-uk Kim 	++datapos;
430*7e382390SJung-uk Kim 
431*7e382390SJung-uk Kim 	out_dec ("%5d", value);
432*7e382390SJung-uk Kim }
433*7e382390SJung-uk Kim 
434*7e382390SJung-uk Kim 
435*7e382390SJung-uk Kim /* mkdata - generate a data statement
436*7e382390SJung-uk Kim  *
437*7e382390SJung-uk Kim  * Generates a data statement initializing the current array element to
438*7e382390SJung-uk Kim  * "value".
439*7e382390SJung-uk Kim  */
mkdata(int value)440*7e382390SJung-uk Kim void mkdata (int value)
441*7e382390SJung-uk Kim {
442*7e382390SJung-uk Kim 	/* short circuit any output */
443*7e382390SJung-uk Kim 	if (!gentables)
444*7e382390SJung-uk Kim 		return;
445*7e382390SJung-uk Kim 
446*7e382390SJung-uk Kim 	if (datapos >= NUMDATAITEMS) {
447*7e382390SJung-uk Kim 		outc (',');
448*7e382390SJung-uk Kim 		dataflush ();
449*7e382390SJung-uk Kim 	}
450*7e382390SJung-uk Kim 
451*7e382390SJung-uk Kim 	if (datapos == 0)
452*7e382390SJung-uk Kim 		/* Indent. */
453*7e382390SJung-uk Kim 		out ("    ");
454*7e382390SJung-uk Kim 	else
455*7e382390SJung-uk Kim 		outc (',');
456*7e382390SJung-uk Kim 
457*7e382390SJung-uk Kim 	++datapos;
458*7e382390SJung-uk Kim 
459*7e382390SJung-uk Kim 	out_dec ("%5d", value);
460*7e382390SJung-uk Kim }
461*7e382390SJung-uk Kim 
462*7e382390SJung-uk Kim 
463*7e382390SJung-uk Kim /* myctoi - return the integer represented by a string of digits */
464*7e382390SJung-uk Kim 
myctoi(const char * array)465*7e382390SJung-uk Kim int myctoi (const char *array)
466*7e382390SJung-uk Kim {
467*7e382390SJung-uk Kim 	int     val = 0;
468*7e382390SJung-uk Kim 
469*7e382390SJung-uk Kim 	(void) sscanf (array, "%d", &val);
470*7e382390SJung-uk Kim 
471*7e382390SJung-uk Kim 	return val;
472*7e382390SJung-uk Kim }
473*7e382390SJung-uk Kim 
474*7e382390SJung-uk Kim 
475*7e382390SJung-uk Kim /* myesc - return character corresponding to escape sequence */
476*7e382390SJung-uk Kim 
myesc(unsigned char array[])477*7e382390SJung-uk Kim unsigned char myesc (unsigned char array[])
478*7e382390SJung-uk Kim {
479*7e382390SJung-uk Kim 	unsigned char    c, esc_char;
480*7e382390SJung-uk Kim 
481*7e382390SJung-uk Kim 	switch (array[1]) {
482*7e382390SJung-uk Kim 	case 'b':
483*7e382390SJung-uk Kim 		return '\b';
484*7e382390SJung-uk Kim 	case 'f':
485*7e382390SJung-uk Kim 		return '\f';
486*7e382390SJung-uk Kim 	case 'n':
487*7e382390SJung-uk Kim 		return '\n';
488*7e382390SJung-uk Kim 	case 'r':
489*7e382390SJung-uk Kim 		return '\r';
490*7e382390SJung-uk Kim 	case 't':
491*7e382390SJung-uk Kim 		return '\t';
492*7e382390SJung-uk Kim 	case 'a':
493*7e382390SJung-uk Kim 		return '\a';
494*7e382390SJung-uk Kim 	case 'v':
495*7e382390SJung-uk Kim 		return '\v';
496*7e382390SJung-uk Kim 	case '0':
497*7e382390SJung-uk Kim 	case '1':
498*7e382390SJung-uk Kim 	case '2':
499*7e382390SJung-uk Kim 	case '3':
500*7e382390SJung-uk Kim 	case '4':
501*7e382390SJung-uk Kim 	case '5':
502*7e382390SJung-uk Kim 	case '6':
503*7e382390SJung-uk Kim 	case '7':
504*7e382390SJung-uk Kim 		{		/* \<octal> */
505*7e382390SJung-uk Kim 			int     sptr = 1;
506*7e382390SJung-uk Kim 
507*7e382390SJung-uk Kim 			while (sptr <= 3 &&
508*7e382390SJung-uk Kim                                array[sptr] >= '0' && array[sptr] <= '7') {
509*7e382390SJung-uk Kim 				++sptr;
510*7e382390SJung-uk Kim 			}
511*7e382390SJung-uk Kim 
512*7e382390SJung-uk Kim 			c = array[sptr];
513*7e382390SJung-uk Kim 			array[sptr] = '\0';
514*7e382390SJung-uk Kim 
515*7e382390SJung-uk Kim 			esc_char = (unsigned char) strtoul (array + 1, NULL, 8);
516*7e382390SJung-uk Kim 
517*7e382390SJung-uk Kim 			array[sptr] = c;
518*7e382390SJung-uk Kim 
519*7e382390SJung-uk Kim 			return esc_char;
520*7e382390SJung-uk Kim 		}
521*7e382390SJung-uk Kim 
522*7e382390SJung-uk Kim 	case 'x':
523*7e382390SJung-uk Kim 		{		/* \x<hex> */
524*7e382390SJung-uk Kim 			int     sptr = 2;
525*7e382390SJung-uk Kim 
526*7e382390SJung-uk Kim 			while (sptr <= 3 && isxdigit (array[sptr])) {
527*7e382390SJung-uk Kim 				/* Don't increment inside loop control
528*7e382390SJung-uk Kim 				 * because if isxdigit() is a macro it might
529*7e382390SJung-uk Kim 				 * expand into multiple increments ...
530*7e382390SJung-uk Kim 				 */
531*7e382390SJung-uk Kim 				++sptr;
532*7e382390SJung-uk Kim 			}
533*7e382390SJung-uk Kim 
534*7e382390SJung-uk Kim 			c = array[sptr];
535*7e382390SJung-uk Kim 			array[sptr] = '\0';
536*7e382390SJung-uk Kim 
537*7e382390SJung-uk Kim 			esc_char = (unsigned char) strtoul (array + 2, NULL, 16);
538*7e382390SJung-uk Kim 
539*7e382390SJung-uk Kim 			array[sptr] = c;
540*7e382390SJung-uk Kim 
541*7e382390SJung-uk Kim 			return esc_char;
542*7e382390SJung-uk Kim 		}
543*7e382390SJung-uk Kim 
544*7e382390SJung-uk Kim 	default:
545*7e382390SJung-uk Kim 		return array[1];
546*7e382390SJung-uk Kim 	}
547*7e382390SJung-uk Kim }
548*7e382390SJung-uk Kim 
549*7e382390SJung-uk Kim 
550*7e382390SJung-uk Kim /* out - various flavors of outputing a (possibly formatted) string for the
551*7e382390SJung-uk Kim  *	 generated scanner, keeping track of the line count.
552*7e382390SJung-uk Kim  */
553*7e382390SJung-uk Kim 
out(const char * str)554*7e382390SJung-uk Kim void out (const char *str)
555*7e382390SJung-uk Kim {
556*7e382390SJung-uk Kim 	fputs (str, stdout);
557*7e382390SJung-uk Kim }
558*7e382390SJung-uk Kim 
out_dec(const char * fmt,int n)559*7e382390SJung-uk Kim void out_dec (const char *fmt, int n)
560*7e382390SJung-uk Kim {
561*7e382390SJung-uk Kim 	fprintf (stdout, fmt, n);
562*7e382390SJung-uk Kim }
563*7e382390SJung-uk Kim 
out_dec2(const char * fmt,int n1,int n2)564*7e382390SJung-uk Kim void out_dec2 (const char *fmt, int n1, int n2)
565*7e382390SJung-uk Kim {
566*7e382390SJung-uk Kim 	fprintf (stdout, fmt, n1, n2);
567*7e382390SJung-uk Kim }
568*7e382390SJung-uk Kim 
out_hex(const char * fmt,unsigned int x)569*7e382390SJung-uk Kim void out_hex (const char *fmt, unsigned int x)
570*7e382390SJung-uk Kim {
571*7e382390SJung-uk Kim 	fprintf (stdout, fmt, x);
572*7e382390SJung-uk Kim }
573*7e382390SJung-uk Kim 
out_str(const char * fmt,const char str[])574*7e382390SJung-uk Kim void out_str (const char *fmt, const char str[])
575*7e382390SJung-uk Kim {
576*7e382390SJung-uk Kim 	fprintf (stdout,fmt, str);
577*7e382390SJung-uk Kim }
578*7e382390SJung-uk Kim 
out_str3(const char * fmt,const char s1[],const char s2[],const char s3[])579*7e382390SJung-uk Kim void out_str3 (const char *fmt, const char s1[], const char s2[], const char s3[])
580*7e382390SJung-uk Kim {
581*7e382390SJung-uk Kim 	fprintf (stdout,fmt, s1, s2, s3);
582*7e382390SJung-uk Kim }
583*7e382390SJung-uk Kim 
out_str_dec(const char * fmt,const char str[],int n)584*7e382390SJung-uk Kim void out_str_dec (const char *fmt, const char str[], int n)
585*7e382390SJung-uk Kim {
586*7e382390SJung-uk Kim 	fprintf (stdout,fmt, str, n);
587*7e382390SJung-uk Kim }
588*7e382390SJung-uk Kim 
outc(int c)589*7e382390SJung-uk Kim void outc (int c)
590*7e382390SJung-uk Kim {
591*7e382390SJung-uk Kim 	fputc (c, stdout);
592*7e382390SJung-uk Kim }
593*7e382390SJung-uk Kim 
outn(const char * str)594*7e382390SJung-uk Kim void outn (const char *str)
595*7e382390SJung-uk Kim {
596*7e382390SJung-uk Kim 	fputs (str,stdout);
597*7e382390SJung-uk Kim     fputc('\n',stdout);
598*7e382390SJung-uk Kim }
599*7e382390SJung-uk Kim 
600*7e382390SJung-uk Kim /** Print "m4_define( [[def]], [[val]])m4_dnl\n".
601*7e382390SJung-uk Kim  * @param def The m4 symbol to define.
602*7e382390SJung-uk Kim  * @param val The definition; may be NULL.
603*7e382390SJung-uk Kim  */
out_m4_define(const char * def,const char * val)604*7e382390SJung-uk Kim void out_m4_define (const char* def, const char* val)
605*7e382390SJung-uk Kim {
606*7e382390SJung-uk Kim     const char * fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n";
607*7e382390SJung-uk Kim     fprintf(stdout, fmt, def, val?val:"");
608*7e382390SJung-uk Kim }
609*7e382390SJung-uk Kim 
610*7e382390SJung-uk Kim 
611*7e382390SJung-uk Kim /* readable_form - return the the human-readable form of a character
612*7e382390SJung-uk Kim  *
613*7e382390SJung-uk Kim  * The returned string is in static storage.
614*7e382390SJung-uk Kim  */
615*7e382390SJung-uk Kim 
readable_form(int c)616*7e382390SJung-uk Kim char   *readable_form (int c)
617*7e382390SJung-uk Kim {
618*7e382390SJung-uk Kim 	static char rform[20];
619*7e382390SJung-uk Kim 
620*7e382390SJung-uk Kim 	if ((c >= 0 && c < 32) || c >= 127) {
621*7e382390SJung-uk Kim 		switch (c) {
622*7e382390SJung-uk Kim 		case '\b':
623*7e382390SJung-uk Kim 			return "\\b";
624*7e382390SJung-uk Kim 		case '\f':
625*7e382390SJung-uk Kim 			return "\\f";
626*7e382390SJung-uk Kim 		case '\n':
627*7e382390SJung-uk Kim 			return "\\n";
628*7e382390SJung-uk Kim 		case '\r':
629*7e382390SJung-uk Kim 			return "\\r";
630*7e382390SJung-uk Kim 		case '\t':
631*7e382390SJung-uk Kim 			return "\\t";
632*7e382390SJung-uk Kim 		case '\a':
633*7e382390SJung-uk Kim 			return "\\a";
634*7e382390SJung-uk Kim 		case '\v':
635*7e382390SJung-uk Kim 			return "\\v";
636*7e382390SJung-uk Kim 		default:
637*7e382390SJung-uk Kim 			if(trace_hex)
638*7e382390SJung-uk Kim 				snprintf (rform, sizeof(rform), "\\x%.2x", (unsigned int) c);
639*7e382390SJung-uk Kim 			else
640*7e382390SJung-uk Kim 				snprintf (rform, sizeof(rform), "\\%.3o", (unsigned int) c);
641*7e382390SJung-uk Kim 			return rform;
642*7e382390SJung-uk Kim 		}
643*7e382390SJung-uk Kim 	}
644*7e382390SJung-uk Kim 
645*7e382390SJung-uk Kim 	else if (c == ' ')
646*7e382390SJung-uk Kim 		return "' '";
647*7e382390SJung-uk Kim 
648*7e382390SJung-uk Kim 	else {
649*7e382390SJung-uk Kim 		rform[0] = (char) c;
650*7e382390SJung-uk Kim 		rform[1] = '\0';
651*7e382390SJung-uk Kim 
652*7e382390SJung-uk Kim 		return rform;
653*7e382390SJung-uk Kim 	}
654*7e382390SJung-uk Kim }
655*7e382390SJung-uk Kim 
656*7e382390SJung-uk Kim 
657*7e382390SJung-uk Kim /* reallocate_array - increase the size of a dynamic array */
658*7e382390SJung-uk Kim 
reallocate_array(void * array,int size,size_t element_size)659*7e382390SJung-uk Kim void   *reallocate_array (void *array, int size, size_t element_size)
660*7e382390SJung-uk Kim {
661*7e382390SJung-uk Kim 	void *new_array;
662*7e382390SJung-uk Kim #if HAVE_REALLOCARRAY
663*7e382390SJung-uk Kim 	/* reallocarray has built-in overflow detection */
664*7e382390SJung-uk Kim 	new_array = reallocarray(array, (size_t) size, element_size);
665*7e382390SJung-uk Kim #else
666*7e382390SJung-uk Kim 	size_t num_bytes = (size_t) size * element_size;
667*7e382390SJung-uk Kim 	new_array = (size && SIZE_MAX / (size_t) size < element_size) ? NULL :
668*7e382390SJung-uk Kim 		realloc(array, num_bytes);
669*7e382390SJung-uk Kim #endif
670*7e382390SJung-uk Kim 	if (!new_array)
671*7e382390SJung-uk Kim 		flexfatal (_("attempt to increase array size failed"));
672*7e382390SJung-uk Kim 
673*7e382390SJung-uk Kim 	return new_array;
674*7e382390SJung-uk Kim }
675*7e382390SJung-uk Kim 
676*7e382390SJung-uk Kim 
677*7e382390SJung-uk Kim /* skelout - write out one section of the skeleton file
678*7e382390SJung-uk Kim  *
679*7e382390SJung-uk Kim  * Description
680*7e382390SJung-uk Kim  *    Copies skelfile or skel array to stdout until a line beginning with
681*7e382390SJung-uk Kim  *    "%%" or EOF is found.
682*7e382390SJung-uk Kim  */
skelout(void)683*7e382390SJung-uk Kim void skelout (void)
684*7e382390SJung-uk Kim {
685*7e382390SJung-uk Kim 	char    buf_storage[MAXLINE];
686*7e382390SJung-uk Kim 	char   *buf = buf_storage;
687*7e382390SJung-uk Kim 	bool   do_copy = true;
688*7e382390SJung-uk Kim 
689*7e382390SJung-uk Kim     /* "reset" the state by clearing the buffer and pushing a '1' */
690*7e382390SJung-uk Kim     if(sko_len > 0)
691*7e382390SJung-uk Kim         sko_peek(&do_copy);
692*7e382390SJung-uk Kim     sko_len = 0;
693*7e382390SJung-uk Kim     sko_push(do_copy=true);
694*7e382390SJung-uk Kim 
695*7e382390SJung-uk Kim 
696*7e382390SJung-uk Kim 	/* Loop pulling lines either from the skelfile, if we're using
697*7e382390SJung-uk Kim 	 * one, or from the skel[] array.
698*7e382390SJung-uk Kim 	 */
699*7e382390SJung-uk Kim 	while (skelfile ?
700*7e382390SJung-uk Kim 	       (fgets (buf, MAXLINE, skelfile) != NULL) :
701*7e382390SJung-uk Kim 	       ((buf = (char *) skel[skel_ind++]) != 0)) {
702*7e382390SJung-uk Kim 
703*7e382390SJung-uk Kim 		if (skelfile)
704*7e382390SJung-uk Kim 			chomp (buf);
705*7e382390SJung-uk Kim 
706*7e382390SJung-uk Kim 		/* copy from skel array */
707*7e382390SJung-uk Kim 		if (buf[0] == '%') {	/* control line */
708*7e382390SJung-uk Kim 			/* print the control line as a comment. */
709*7e382390SJung-uk Kim 			if (ddebug && buf[1] != '#') {
710*7e382390SJung-uk Kim 				if (buf[strlen (buf) - 1] == '\\')
711*7e382390SJung-uk Kim 					out_str ("/* %s */\\\n", buf);
712*7e382390SJung-uk Kim 				else
713*7e382390SJung-uk Kim 					out_str ("/* %s */\n", buf);
714*7e382390SJung-uk Kim 			}
715*7e382390SJung-uk Kim 
716*7e382390SJung-uk Kim 			/* We've been accused of using cryptic markers in the skel.
717*7e382390SJung-uk Kim 			 * So we'll use emacs-style-hyphenated-commands.
718*7e382390SJung-uk Kim              * We might consider a hash if this if-else-if-else
719*7e382390SJung-uk Kim              * chain gets too large.
720*7e382390SJung-uk Kim 			 */
721*7e382390SJung-uk Kim #define cmd_match(s) (strncmp(buf,(s),strlen(s))==0)
722*7e382390SJung-uk Kim 
723*7e382390SJung-uk Kim 			if (buf[1] == '%') {
724*7e382390SJung-uk Kim 				/* %% is a break point for skelout() */
725*7e382390SJung-uk Kim 				return;
726*7e382390SJung-uk Kim 			}
727*7e382390SJung-uk Kim             else if (cmd_match (CMD_PUSH)){
728*7e382390SJung-uk Kim                 sko_push(do_copy);
729*7e382390SJung-uk Kim                 if(ddebug){
730*7e382390SJung-uk Kim                     out_str("/*(state = (%s) */",do_copy?"true":"false");
731*7e382390SJung-uk Kim                 }
732*7e382390SJung-uk Kim                 out_str("%s\n", buf[strlen (buf) - 1] =='\\' ? "\\" : "");
733*7e382390SJung-uk Kim             }
734*7e382390SJung-uk Kim             else if (cmd_match (CMD_POP)){
735*7e382390SJung-uk Kim                 sko_pop(&do_copy);
736*7e382390SJung-uk Kim                 if(ddebug){
737*7e382390SJung-uk Kim                     out_str("/*(state = (%s) */",do_copy?"true":"false");
738*7e382390SJung-uk Kim                 }
739*7e382390SJung-uk Kim                 out_str("%s\n", buf[strlen (buf) - 1] =='\\' ? "\\" : "");
740*7e382390SJung-uk Kim             }
741*7e382390SJung-uk Kim             else if (cmd_match (CMD_IF_REENTRANT)){
742*7e382390SJung-uk Kim                 sko_push(do_copy);
743*7e382390SJung-uk Kim                 do_copy = reentrant && do_copy;
744*7e382390SJung-uk Kim             }
745*7e382390SJung-uk Kim             else if (cmd_match (CMD_IF_NOT_REENTRANT)){
746*7e382390SJung-uk Kim                 sko_push(do_copy);
747*7e382390SJung-uk Kim                 do_copy = !reentrant && do_copy;
748*7e382390SJung-uk Kim             }
749*7e382390SJung-uk Kim             else if (cmd_match(CMD_IF_BISON_BRIDGE)){
750*7e382390SJung-uk Kim                 sko_push(do_copy);
751*7e382390SJung-uk Kim                 do_copy = bison_bridge_lval && do_copy;
752*7e382390SJung-uk Kim             }
753*7e382390SJung-uk Kim             else if (cmd_match(CMD_IF_NOT_BISON_BRIDGE)){
754*7e382390SJung-uk Kim                 sko_push(do_copy);
755*7e382390SJung-uk Kim                 do_copy = !bison_bridge_lval && do_copy;
756*7e382390SJung-uk Kim             }
757*7e382390SJung-uk Kim             else if (cmd_match (CMD_ENDIF)){
758*7e382390SJung-uk Kim                 sko_pop(&do_copy);
759*7e382390SJung-uk Kim             }
760*7e382390SJung-uk Kim 			else if (cmd_match (CMD_IF_TABLES_SER)) {
761*7e382390SJung-uk Kim                 do_copy = do_copy && tablesext;
762*7e382390SJung-uk Kim 			}
763*7e382390SJung-uk Kim 			else if (cmd_match (CMD_TABLES_YYDMAP)) {
764*7e382390SJung-uk Kim 				if (tablesext && yydmap_buf.elts)
765*7e382390SJung-uk Kim 					outn ((char *) (yydmap_buf.elts));
766*7e382390SJung-uk Kim 			}
767*7e382390SJung-uk Kim             else if (cmd_match (CMD_DEFINE_YYTABLES)) {
768*7e382390SJung-uk Kim                 out_str("#define YYTABLES_NAME \"%s\"\n",
769*7e382390SJung-uk Kim                         tablesname?tablesname:"yytables");
770*7e382390SJung-uk Kim             }
771*7e382390SJung-uk Kim 			else if (cmd_match (CMD_IF_CPP_ONLY)) {
772*7e382390SJung-uk Kim 				/* only for C++ */
773*7e382390SJung-uk Kim                 sko_push(do_copy);
774*7e382390SJung-uk Kim 				do_copy = C_plus_plus;
775*7e382390SJung-uk Kim 			}
776*7e382390SJung-uk Kim 			else if (cmd_match (CMD_IF_C_ONLY)) {
777*7e382390SJung-uk Kim 				/* %- only for C */
778*7e382390SJung-uk Kim                 sko_push(do_copy);
779*7e382390SJung-uk Kim 				do_copy = !C_plus_plus;
780*7e382390SJung-uk Kim 			}
781*7e382390SJung-uk Kim 			else if (cmd_match (CMD_IF_C_OR_CPP)) {
782*7e382390SJung-uk Kim 				/* %* for C and C++ */
783*7e382390SJung-uk Kim                 sko_push(do_copy);
784*7e382390SJung-uk Kim 				do_copy = true;
785*7e382390SJung-uk Kim 			}
786*7e382390SJung-uk Kim 			else if (cmd_match (CMD_NOT_FOR_HEADER)) {
787*7e382390SJung-uk Kim 				/* %c begin linkage-only (non-header) code. */
788*7e382390SJung-uk Kim 				OUT_BEGIN_CODE ();
789*7e382390SJung-uk Kim 			}
790*7e382390SJung-uk Kim 			else if (cmd_match (CMD_OK_FOR_HEADER)) {
791*7e382390SJung-uk Kim 				/* %e end linkage-only code. */
792*7e382390SJung-uk Kim 				OUT_END_CODE ();
793*7e382390SJung-uk Kim 			}
794*7e382390SJung-uk Kim 			else {
795*7e382390SJung-uk Kim 				flexfatal (_("bad line in skeleton file"));
796*7e382390SJung-uk Kim 			}
797*7e382390SJung-uk Kim 		}
798*7e382390SJung-uk Kim 
799*7e382390SJung-uk Kim 		else if (do_copy)
800*7e382390SJung-uk Kim             outn (buf);
801*7e382390SJung-uk Kim 	}			/* end while */
802*7e382390SJung-uk Kim }
803*7e382390SJung-uk Kim 
804*7e382390SJung-uk Kim 
805*7e382390SJung-uk Kim /* transition_struct_out - output a yy_trans_info structure
806*7e382390SJung-uk Kim  *
807*7e382390SJung-uk Kim  * outputs the yy_trans_info structure with the two elements, element_v and
808*7e382390SJung-uk Kim  * element_n.  Formats the output with spaces and carriage returns.
809*7e382390SJung-uk Kim  */
810*7e382390SJung-uk Kim 
transition_struct_out(int element_v,int element_n)811*7e382390SJung-uk Kim void transition_struct_out (int element_v, int element_n)
812*7e382390SJung-uk Kim {
813*7e382390SJung-uk Kim 
814*7e382390SJung-uk Kim 	/* short circuit any output */
815*7e382390SJung-uk Kim 	if (!gentables)
816*7e382390SJung-uk Kim 		return;
817*7e382390SJung-uk Kim 
818*7e382390SJung-uk Kim 	out_dec2 (" {%4d,%4d },", element_v, element_n);
819*7e382390SJung-uk Kim 
820*7e382390SJung-uk Kim 	datapos += TRANS_STRUCT_PRINT_LENGTH;
821*7e382390SJung-uk Kim 
822*7e382390SJung-uk Kim 	if (datapos >= 79 - TRANS_STRUCT_PRINT_LENGTH) {
823*7e382390SJung-uk Kim 		outc ('\n');
824*7e382390SJung-uk Kim 
825*7e382390SJung-uk Kim 		if (++dataline % 10 == 0)
826*7e382390SJung-uk Kim 			outc ('\n');
827*7e382390SJung-uk Kim 
828*7e382390SJung-uk Kim 		datapos = 0;
829*7e382390SJung-uk Kim 	}
830*7e382390SJung-uk Kim }
831*7e382390SJung-uk Kim 
832*7e382390SJung-uk Kim 
833*7e382390SJung-uk Kim /* The following is only needed when building flex's parser using certain
834*7e382390SJung-uk Kim  * broken versions of bison.
835*7e382390SJung-uk Kim  *
836*7e382390SJung-uk Kim  * XXX: this is should go soon
837*7e382390SJung-uk Kim  */
yy_flex_xmalloc(int size)838*7e382390SJung-uk Kim void   *yy_flex_xmalloc (int size)
839*7e382390SJung-uk Kim {
840*7e382390SJung-uk Kim 	void   *result;
841*7e382390SJung-uk Kim 
842*7e382390SJung-uk Kim 	result = malloc((size_t) size);
843*7e382390SJung-uk Kim 	if (!result)
844*7e382390SJung-uk Kim 		flexfatal (_
845*7e382390SJung-uk Kim 			   ("memory allocation failed in yy_flex_xmalloc()"));
846*7e382390SJung-uk Kim 
847*7e382390SJung-uk Kim 	return result;
848*7e382390SJung-uk Kim }
849*7e382390SJung-uk Kim 
850*7e382390SJung-uk Kim 
851*7e382390SJung-uk Kim /* Remove all '\n' and '\r' characters, if any, from the end of str.
852*7e382390SJung-uk Kim  * str can be any null-terminated string, or NULL.
853*7e382390SJung-uk Kim  * returns str. */
chomp(char * str)854*7e382390SJung-uk Kim char   *chomp (char *str)
855*7e382390SJung-uk Kim {
856*7e382390SJung-uk Kim 	char   *p = str;
857*7e382390SJung-uk Kim 
858*7e382390SJung-uk Kim 	if (!str || !*str)	/* s is null or empty string */
859*7e382390SJung-uk Kim 		return str;
860*7e382390SJung-uk Kim 
861*7e382390SJung-uk Kim 	/* find end of string minus one */
862*7e382390SJung-uk Kim 	while (*p)
863*7e382390SJung-uk Kim 		++p;
864*7e382390SJung-uk Kim 	--p;
865*7e382390SJung-uk Kim 
866*7e382390SJung-uk Kim 	/* eat newlines */
867*7e382390SJung-uk Kim 	while (p >= str && (*p == '\r' || *p == '\n'))
868*7e382390SJung-uk Kim 		*p-- = 0;
869*7e382390SJung-uk Kim 	return str;
870*7e382390SJung-uk Kim }
871