1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1986-2012 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                                                                      *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman /*
22*b30d1939SAndy Fiddaman  * Glenn Fowler
23*b30d1939SAndy Fiddaman  * AT&T Research
24*b30d1939SAndy Fiddaman  *
25*b30d1939SAndy Fiddaman  * convert C prototypes to ANSI, K&R and C++ styles or K&R to ANSI
26*b30d1939SAndy Fiddaman  * slips into the pp block read
27*b30d1939SAndy Fiddaman  *
28*b30d1939SAndy Fiddaman  * define PROTOMAIN for standalone proto
29*b30d1939SAndy Fiddaman  * PROTOMAIN is coded for minimal library support
30*b30d1939SAndy Fiddaman  */
31*b30d1939SAndy Fiddaman 
32*b30d1939SAndy Fiddaman #if PROTOMAIN
33*b30d1939SAndy Fiddaman 
34*b30d1939SAndy Fiddaman #include "ppfsm.c"
35*b30d1939SAndy Fiddaman 
36*b30d1939SAndy Fiddaman #include <hashkey.h>
37*b30d1939SAndy Fiddaman 
38*b30d1939SAndy Fiddaman #if PROTO_STANDALONE
39*b30d1939SAndy Fiddaman #undef	O_RDONLY
40*b30d1939SAndy Fiddaman #endif
41*b30d1939SAndy Fiddaman 
42*b30d1939SAndy Fiddaman #else
43*b30d1939SAndy Fiddaman 
44*b30d1939SAndy Fiddaman #include "pplib.h"
45*b30d1939SAndy Fiddaman #include "ppfsm.h"
46*b30d1939SAndy Fiddaman 
47*b30d1939SAndy Fiddaman #endif
48*b30d1939SAndy Fiddaman 
49*b30d1939SAndy Fiddaman #define GENERATED	"/* : : generated by proto : : */\n"
50*b30d1939SAndy Fiddaman 
51*b30d1939SAndy Fiddaman #define PRAGMADIR	"pragma"	/* pragma directive		*/
52*b30d1939SAndy Fiddaman #define MAGICTOP	80		/* must be in these top lines	*/
53*b30d1939SAndy Fiddaman 
54*b30d1939SAndy Fiddaman #ifndef elementsof
55*b30d1939SAndy Fiddaman #define elementsof(x)	(sizeof(x)/sizeof(x[0]))
56*b30d1939SAndy Fiddaman #endif
57*b30d1939SAndy Fiddaman 
58*b30d1939SAndy Fiddaman typedef struct Key_s
59*b30d1939SAndy Fiddaman {
60*b30d1939SAndy Fiddaman 	const char*	name;
61*b30d1939SAndy Fiddaman 	size_t		size;
62*b30d1939SAndy Fiddaman 	int		hit;
63*b30d1939SAndy Fiddaman 	int		val;
64*b30d1939SAndy Fiddaman } Key_t;
65*b30d1939SAndy Fiddaman 
66*b30d1939SAndy Fiddaman typedef struct Proto_s			/* proto buffer state		*/
67*b30d1939SAndy Fiddaman {
68*b30d1939SAndy Fiddaman 	int		brace;		/* {..} level			*/
69*b30d1939SAndy Fiddaman 	int		call;		/* call level			*/
70*b30d1939SAndy Fiddaman 	int		fd;		/* input file descriptor	*/
71*b30d1939SAndy Fiddaman 	char*		file;		/* input file name		*/
72*b30d1939SAndy Fiddaman 	long		flags;		/* coupled flags		*/
73*b30d1939SAndy Fiddaman 	long		options;	/* uncoupled flags		*/
74*b30d1939SAndy Fiddaman 	char*		package;	/* header package		*/
75*b30d1939SAndy Fiddaman 	int		line;		/* input line count		*/
76*b30d1939SAndy Fiddaman 	int		test;		/* testing			*/
77*b30d1939SAndy Fiddaman 
78*b30d1939SAndy Fiddaman 	char*		tp;		/* input token base		*/
79*b30d1939SAndy Fiddaman 
80*b30d1939SAndy Fiddaman 	int		iz;		/* input buffer size		*/
81*b30d1939SAndy Fiddaman 	char*		ib;		/* input buffer base		*/
82*b30d1939SAndy Fiddaman 	char*		ip;		/* input buffer pointer		*/
83*b30d1939SAndy Fiddaman 
84*b30d1939SAndy Fiddaman 	int		oz;		/* output buffer size		*/
85*b30d1939SAndy Fiddaman 	char*		ob;		/* output buffer base		*/
86*b30d1939SAndy Fiddaman 	char*		op;		/* output buffer pointer	*/
87*b30d1939SAndy Fiddaman 	char*		ox;		/* output buffer externalize	*/
88*b30d1939SAndy Fiddaman 
89*b30d1939SAndy Fiddaman 	char		cc[3];		/* beg mid end comment char	*/
90*b30d1939SAndy Fiddaman 	char		pushback[4];	/* pushback area for caller	*/
91*b30d1939SAndy Fiddaman 
92*b30d1939SAndy Fiddaman 	char		variadic[256];	/* variadic args buffer		*/
93*b30d1939SAndy Fiddaman 
94*b30d1939SAndy Fiddaman 	/* output buffer */
95*b30d1939SAndy Fiddaman 	/* slide buffer */
96*b30d1939SAndy Fiddaman 	/* input buffer */
97*b30d1939SAndy Fiddaman } Proto_t;
98*b30d1939SAndy Fiddaman 
99*b30d1939SAndy Fiddaman /*
100*b30d1939SAndy Fiddaman  * proto is separate from pp so these undef's are ok
101*b30d1939SAndy Fiddaman  */
102*b30d1939SAndy Fiddaman 
103*b30d1939SAndy Fiddaman #undef	CLASSIC
104*b30d1939SAndy Fiddaman #define CLASSIC		(1L<<0)
105*b30d1939SAndy Fiddaman #undef	DECLARE
106*b30d1939SAndy Fiddaman #define DECLARE		(1L<<1)
107*b30d1939SAndy Fiddaman #undef	DEFINE
108*b30d1939SAndy Fiddaman #define DEFINE		(1L<<2)
109*b30d1939SAndy Fiddaman #undef	DIRECTIVE
110*b30d1939SAndy Fiddaman #define DIRECTIVE	(1L<<3)
111*b30d1939SAndy Fiddaman #undef	ERROR
112*b30d1939SAndy Fiddaman #define ERROR		(1L<<4)
113*b30d1939SAndy Fiddaman #undef	EXTERN
114*b30d1939SAndy Fiddaman #define EXTERN		(1L<<5)
115*b30d1939SAndy Fiddaman #undef	EXTERNALIZE
116*b30d1939SAndy Fiddaman #define EXTERNALIZE	(1L<<6)
117*b30d1939SAndy Fiddaman #undef	IDID
118*b30d1939SAndy Fiddaman #define IDID		(1L<<7)
119*b30d1939SAndy Fiddaman #undef	INDIRECT
120*b30d1939SAndy Fiddaman #define INDIRECT	(1L<<8)
121*b30d1939SAndy Fiddaman #undef	INIT
122*b30d1939SAndy Fiddaman #define INIT		(1L<<9)
123*b30d1939SAndy Fiddaman #undef	INIT_DEFINE
124*b30d1939SAndy Fiddaman #define INIT_DEFINE	(1L<<10)
125*b30d1939SAndy Fiddaman #undef	INIT_INCLUDE
126*b30d1939SAndy Fiddaman #define INIT_INCLUDE	(1L<<11)
127*b30d1939SAndy Fiddaman #undef	JUNK
128*b30d1939SAndy Fiddaman #define JUNK		(1L<<12)
129*b30d1939SAndy Fiddaman #undef	LINESYNC
130*b30d1939SAndy Fiddaman #define LINESYNC	(1L<<13)
131*b30d1939SAndy Fiddaman #undef	MANGLE
132*b30d1939SAndy Fiddaman #define MANGLE		(1L<<14)
133*b30d1939SAndy Fiddaman #undef	MATCH
134*b30d1939SAndy Fiddaman #define MATCH		(1L<<15)
135*b30d1939SAndy Fiddaman #undef	MORE
136*b30d1939SAndy Fiddaman #define MORE		(1L<<16)
137*b30d1939SAndy Fiddaman #undef	OTHER
138*b30d1939SAndy Fiddaman #define OTHER		(1L<<17)
139*b30d1939SAndy Fiddaman #undef	PASS
140*b30d1939SAndy Fiddaman #define PASS		(1L<<18)
141*b30d1939SAndy Fiddaman #undef	PLUSONLY
142*b30d1939SAndy Fiddaman #define PLUSONLY	(1L<<19)
143*b30d1939SAndy Fiddaman #undef	PLUSPLUS
144*b30d1939SAndy Fiddaman #define PLUSPLUS	(1L<<20)
145*b30d1939SAndy Fiddaman #undef	RECURSIVE
146*b30d1939SAndy Fiddaman #define RECURSIVE	(1L<<21)
147*b30d1939SAndy Fiddaman #undef	SHARP
148*b30d1939SAndy Fiddaman #define SHARP		(1L<<22)
149*b30d1939SAndy Fiddaman #undef	SKIP
150*b30d1939SAndy Fiddaman #define SKIP		(1L<<23)
151*b30d1939SAndy Fiddaman #undef	SLIDE
152*b30d1939SAndy Fiddaman #define SLIDE		(1L<<24)
153*b30d1939SAndy Fiddaman #undef	TOKENS
154*b30d1939SAndy Fiddaman #define TOKENS		(1L<<25)
155*b30d1939SAndy Fiddaman #undef	TYPEDEF
156*b30d1939SAndy Fiddaman #define TYPEDEF		(1L<<26)
157*b30d1939SAndy Fiddaman #undef	VARIADIC
158*b30d1939SAndy Fiddaman #define VARIADIC	(1L<<27)
159*b30d1939SAndy Fiddaman #undef	VARIADIC2
160*b30d1939SAndy Fiddaman #define VARIADIC2	(1L<<28)
161*b30d1939SAndy Fiddaman #undef	YACC
162*b30d1939SAndy Fiddaman #define YACC		(1L<<29)
163*b30d1939SAndy Fiddaman #undef	YACCSPLIT
164*b30d1939SAndy Fiddaman #define YACCSPLIT	(1L<<30)
165*b30d1939SAndy Fiddaman #undef	YACC2
166*b30d1939SAndy Fiddaman #define YACC2		(1L<<31)
167*b30d1939SAndy Fiddaman 
168*b30d1939SAndy Fiddaman #undef	GLOBAL
169*b30d1939SAndy Fiddaman #define GLOBAL		(MORE)
170*b30d1939SAndy Fiddaman 
171*b30d1939SAndy Fiddaman #undef	REGULAR
172*b30d1939SAndy Fiddaman #define REGULAR		(1L<<0)
173*b30d1939SAndy Fiddaman 
174*b30d1939SAndy Fiddaman #ifndef CHUNK
175*b30d1939SAndy Fiddaman #define CHUNK		1024
176*b30d1939SAndy Fiddaman #endif
177*b30d1939SAndy Fiddaman #define BLOCK		(16*CHUNK)
178*b30d1939SAndy Fiddaman 
179*b30d1939SAndy Fiddaman #define T_VA_START	(N_TOKEN+1)
180*b30d1939SAndy Fiddaman 
181*b30d1939SAndy Fiddaman #define RESERVED(b,e,n)	((((long)(b))<<16)|(((long)(e))<<8)|((long)(n)))
182*b30d1939SAndy Fiddaman 
183*b30d1939SAndy Fiddaman #define KEYENT(s,m,v)	{s,sizeof(s)-1,m,v}
184*b30d1939SAndy Fiddaman 
185*b30d1939SAndy Fiddaman #define HIT_prototyped	0x01
186*b30d1939SAndy Fiddaman #define HIT_noticed	0x02
187*b30d1939SAndy Fiddaman 
188*b30d1939SAndy Fiddaman static const Key_t	pragmas[] =
189*b30d1939SAndy Fiddaman {
190*b30d1939SAndy Fiddaman 	KEYENT("prototyped",	HIT_prototyped,	1),	/* NOTE: first entry */
191*b30d1939SAndy Fiddaman 	KEYENT("noprototyped",	HIT_prototyped,	0),
192*b30d1939SAndy Fiddaman 	KEYENT("noticed",	HIT_noticed,	1),
193*b30d1939SAndy Fiddaman 	KEYENT("nonoticed",	HIT_noticed,	0),
194*b30d1939SAndy Fiddaman };
195*b30d1939SAndy Fiddaman 
196*b30d1939SAndy Fiddaman #if PROTOMAIN
197*b30d1939SAndy Fiddaman static const Key_t	notices[] =
198*b30d1939SAndy Fiddaman {
199*b30d1939SAndy Fiddaman 	KEYENT("Copyright",	HIT_noticed,	1),
200*b30d1939SAndy Fiddaman 	KEYENT("COPYRIGHT",	HIT_noticed,	1),
201*b30d1939SAndy Fiddaman 	KEYENT("copyright",	HIT_noticed,	1),
202*b30d1939SAndy Fiddaman 	KEYENT("Public Domain",	HIT_noticed,	0),
203*b30d1939SAndy Fiddaman 	KEYENT("PUBLIC DOMAIN",	HIT_noticed,	0),
204*b30d1939SAndy Fiddaman };
205*b30d1939SAndy Fiddaman #endif
206*b30d1939SAndy Fiddaman 
207*b30d1939SAndy Fiddaman /*
208*b30d1939SAndy Fiddaman  * generate integer
209*b30d1939SAndy Fiddaman  * pointer to end returned
210*b30d1939SAndy Fiddaman  */
211*b30d1939SAndy Fiddaman 
212*b30d1939SAndy Fiddaman static char*
number(register char * p,register long n)213*b30d1939SAndy Fiddaman number(register char* p, register long n)
214*b30d1939SAndy Fiddaman {
215*b30d1939SAndy Fiddaman 	register long	d;
216*b30d1939SAndy Fiddaman 
217*b30d1939SAndy Fiddaman 	for (d = 1000000; d > 1; d /= 10)
218*b30d1939SAndy Fiddaman 		if (n >= d) *p++ = '0' + (n / d) % 10;
219*b30d1939SAndy Fiddaman 	*p++ = '0' + n % 10;
220*b30d1939SAndy Fiddaman 	return p;
221*b30d1939SAndy Fiddaman }
222*b30d1939SAndy Fiddaman 
223*b30d1939SAndy Fiddaman #if PROTOMAIN
224*b30d1939SAndy Fiddaman 
225*b30d1939SAndy Fiddaman static int		errors;
226*b30d1939SAndy Fiddaman 
227*b30d1939SAndy Fiddaman #if PROTO_STANDALONE
228*b30d1939SAndy Fiddaman 
229*b30d1939SAndy Fiddaman /*
230*b30d1939SAndy Fiddaman  * namespace pollution forces us to claim parts of libc
231*b30d1939SAndy Fiddaman  */
232*b30d1939SAndy Fiddaman 
233*b30d1939SAndy Fiddaman #undef	memcpy
234*b30d1939SAndy Fiddaman #define memcpy(t,f,n)	memcopy(t,f,n)
235*b30d1939SAndy Fiddaman #undef	strcpy
236*b30d1939SAndy Fiddaman #define strcpy(t,f)	strcopy(t,f)
237*b30d1939SAndy Fiddaman #undef	strlen
238*b30d1939SAndy Fiddaman #define strlen(s)	sstrlen(s)
239*b30d1939SAndy Fiddaman #undef	strncmp
240*b30d1939SAndy Fiddaman #define strncmp(s,t,n)	sstrncmp(s,t,n)
241*b30d1939SAndy Fiddaman 
242*b30d1939SAndy Fiddaman /*
243*b30d1939SAndy Fiddaman  * environmentally safe strlen()
244*b30d1939SAndy Fiddaman  */
245*b30d1939SAndy Fiddaman 
246*b30d1939SAndy Fiddaman static int
sstrlen(register const char * s)247*b30d1939SAndy Fiddaman sstrlen(register const char* s)
248*b30d1939SAndy Fiddaman {
249*b30d1939SAndy Fiddaman 	register const char*	b;
250*b30d1939SAndy Fiddaman 
251*b30d1939SAndy Fiddaman 	for (b = s; *s; s++);
252*b30d1939SAndy Fiddaman 	return s - b;
253*b30d1939SAndy Fiddaman }
254*b30d1939SAndy Fiddaman 
255*b30d1939SAndy Fiddaman /*
256*b30d1939SAndy Fiddaman  * environmentally safe strncmp()
257*b30d1939SAndy Fiddaman  */
258*b30d1939SAndy Fiddaman 
259*b30d1939SAndy Fiddaman static int
sstrncmp(register const char * s,register const char * t,register int n)260*b30d1939SAndy Fiddaman sstrncmp(register const char* s, register const char* t, register int n)
261*b30d1939SAndy Fiddaman {
262*b30d1939SAndy Fiddaman 	register const char*	e = s + n;
263*b30d1939SAndy Fiddaman 
264*b30d1939SAndy Fiddaman 	while (s < e)
265*b30d1939SAndy Fiddaman 	{
266*b30d1939SAndy Fiddaman 		if (*s != *t || !*s)
267*b30d1939SAndy Fiddaman 			return *s - *t;
268*b30d1939SAndy Fiddaman 		s++;
269*b30d1939SAndy Fiddaman 		t++;
270*b30d1939SAndy Fiddaman 	}
271*b30d1939SAndy Fiddaman 	return 0;
272*b30d1939SAndy Fiddaman }
273*b30d1939SAndy Fiddaman 
274*b30d1939SAndy Fiddaman /*
275*b30d1939SAndy Fiddaman  * strcpy() except pointer to end returned
276*b30d1939SAndy Fiddaman  */
277*b30d1939SAndy Fiddaman 
278*b30d1939SAndy Fiddaman static char*
strcopy(register char * s,register const char * t)279*b30d1939SAndy Fiddaman strcopy(register char* s, register const char* t)
280*b30d1939SAndy Fiddaman {
281*b30d1939SAndy Fiddaman 	while (*s++ = *t++);
282*b30d1939SAndy Fiddaman 	return s - 1;
283*b30d1939SAndy Fiddaman }
284*b30d1939SAndy Fiddaman 
285*b30d1939SAndy Fiddaman #endif
286*b30d1939SAndy Fiddaman 
287*b30d1939SAndy Fiddaman static void
proto_error(char * iob,int level,char * msg,char * arg)288*b30d1939SAndy Fiddaman proto_error(char* iob, int level, char* msg, char* arg)
289*b30d1939SAndy Fiddaman {
290*b30d1939SAndy Fiddaman 	register char*	p;
291*b30d1939SAndy Fiddaman 	char		buf[1024];
292*b30d1939SAndy Fiddaman 
293*b30d1939SAndy Fiddaman 	p = strcopy(buf, "proto: ");
294*b30d1939SAndy Fiddaman 	if (iob)
295*b30d1939SAndy Fiddaman 	{
296*b30d1939SAndy Fiddaman 		register Proto_t*	proto = (Proto_t*)(iob - sizeof(Proto_t));
297*b30d1939SAndy Fiddaman 
298*b30d1939SAndy Fiddaman 		if (proto->line)
299*b30d1939SAndy Fiddaman 		{
300*b30d1939SAndy Fiddaman 			if (proto->file)
301*b30d1939SAndy Fiddaman 			{
302*b30d1939SAndy Fiddaman 				*p++ = '"';
303*b30d1939SAndy Fiddaman 				p = strcopy(p, proto->file);
304*b30d1939SAndy Fiddaman 				*p++ = '"';
305*b30d1939SAndy Fiddaman 				*p++ = ',';
306*b30d1939SAndy Fiddaman 				*p++ = ' ';
307*b30d1939SAndy Fiddaman 			}
308*b30d1939SAndy Fiddaman 			p = strcopy(p, "line ");
309*b30d1939SAndy Fiddaman 			p = number(p, proto->line);
310*b30d1939SAndy Fiddaman 		}
311*b30d1939SAndy Fiddaman 		else if (proto->file)
312*b30d1939SAndy Fiddaman 			p = strcopy(p, proto->file);
313*b30d1939SAndy Fiddaman 	}
314*b30d1939SAndy Fiddaman 	else
315*b30d1939SAndy Fiddaman 	{
316*b30d1939SAndy Fiddaman 		p = strcopy(p, msg);
317*b30d1939SAndy Fiddaman 		msg = arg;
318*b30d1939SAndy Fiddaman 		arg = 0;
319*b30d1939SAndy Fiddaman 	}
320*b30d1939SAndy Fiddaman 	if (*(p - 1) != ' ')
321*b30d1939SAndy Fiddaman 	{
322*b30d1939SAndy Fiddaman 		*p++ = ':';
323*b30d1939SAndy Fiddaman 		*p++ = ' ';
324*b30d1939SAndy Fiddaman 	}
325*b30d1939SAndy Fiddaman 	if (level == 1)
326*b30d1939SAndy Fiddaman 		p = strcopy(p, "warning: ");
327*b30d1939SAndy Fiddaman 	p = strcopy(p, msg);
328*b30d1939SAndy Fiddaman 	if (arg)
329*b30d1939SAndy Fiddaman 	{
330*b30d1939SAndy Fiddaman 		*p++ = ' ';
331*b30d1939SAndy Fiddaman 		p = strcopy(p, arg);
332*b30d1939SAndy Fiddaman 	}
333*b30d1939SAndy Fiddaman 	*p++ = '\n';
334*b30d1939SAndy Fiddaman 	write(2, buf, p - buf);
335*b30d1939SAndy Fiddaman 	if (level >= 3)
336*b30d1939SAndy Fiddaman 		exit(level - 2);
337*b30d1939SAndy Fiddaman 	if (level >= 2)
338*b30d1939SAndy Fiddaman 		errors++;
339*b30d1939SAndy Fiddaman }
340*b30d1939SAndy Fiddaman 
341*b30d1939SAndy Fiddaman /*
342*b30d1939SAndy Fiddaman  * memcpy() but pointer to end returned
343*b30d1939SAndy Fiddaman  */
344*b30d1939SAndy Fiddaman 
345*b30d1939SAndy Fiddaman static char*
memcopy(register char * s,register char * t,int n)346*b30d1939SAndy Fiddaman memcopy(register char* s, register char* t, int n)
347*b30d1939SAndy Fiddaman {
348*b30d1939SAndy Fiddaman 	register char*	e = t + n;
349*b30d1939SAndy Fiddaman 
350*b30d1939SAndy Fiddaman 	while (t < e) *s++ = *t++;
351*b30d1939SAndy Fiddaman 	return s;
352*b30d1939SAndy Fiddaman }
353*b30d1939SAndy Fiddaman 
354*b30d1939SAndy Fiddaman #include "../libast/port/astlicense.c"
355*b30d1939SAndy Fiddaman 
356*b30d1939SAndy Fiddaman #else
357*b30d1939SAndy Fiddaman 
358*b30d1939SAndy Fiddaman #define memcopy(s,t,n)	(((char*)memcpy(s,t,n))+(n))
359*b30d1939SAndy Fiddaman 
360*b30d1939SAndy Fiddaman #endif
361*b30d1939SAndy Fiddaman 
362*b30d1939SAndy Fiddaman /*
363*b30d1939SAndy Fiddaman  * generate line sync
364*b30d1939SAndy Fiddaman  * pointer to end returned
365*b30d1939SAndy Fiddaman  */
366*b30d1939SAndy Fiddaman 
367*b30d1939SAndy Fiddaman static char*
linesync(register Proto_t * proto,register char * p,register long n)368*b30d1939SAndy Fiddaman linesync(register Proto_t* proto, register char* p, register long n)
369*b30d1939SAndy Fiddaman {
370*b30d1939SAndy Fiddaman #if PROTOMAIN
371*b30d1939SAndy Fiddaman 	if (proto->flags & LINESYNC)
372*b30d1939SAndy Fiddaman #endif
373*b30d1939SAndy Fiddaman 	{
374*b30d1939SAndy Fiddaman #if PROTOMAIN
375*b30d1939SAndy Fiddaman 		p = strcopy(p, "\n#line ");
376*b30d1939SAndy Fiddaman #else
377*b30d1939SAndy Fiddaman 		p = strcopy(p, "\n# ");
378*b30d1939SAndy Fiddaman #endif
379*b30d1939SAndy Fiddaman 		p = number(p, n);
380*b30d1939SAndy Fiddaman 		*p++ = '\n';
381*b30d1939SAndy Fiddaman 	}
382*b30d1939SAndy Fiddaman 	return p;
383*b30d1939SAndy Fiddaman }
384*b30d1939SAndy Fiddaman 
385*b30d1939SAndy Fiddaman /*
386*b30d1939SAndy Fiddaman  * output init header
387*b30d1939SAndy Fiddaman  * pointer to end returned
388*b30d1939SAndy Fiddaman  */
389*b30d1939SAndy Fiddaman 
390*b30d1939SAndy Fiddaman static char*
init(Proto_t * proto,char * op,int flags)391*b30d1939SAndy Fiddaman init(Proto_t* proto, char* op, int flags)
392*b30d1939SAndy Fiddaman {
393*b30d1939SAndy Fiddaman 	register char*	s;
394*b30d1939SAndy Fiddaman 
395*b30d1939SAndy Fiddaman 	if (flags & INIT_DEFINE)
396*b30d1939SAndy Fiddaman 	{
397*b30d1939SAndy Fiddaman 		op = strcopy(op, "\
398*b30d1939SAndy Fiddaman \n\
399*b30d1939SAndy Fiddaman #if !defined(__PROTO__)\n\
400*b30d1939SAndy Fiddaman #  if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)\n\
401*b30d1939SAndy Fiddaman #    if defined(__cplusplus)\n\
402*b30d1939SAndy Fiddaman #      define __LINKAGE__	\"C\"\n\
403*b30d1939SAndy Fiddaman #    else\n\
404*b30d1939SAndy Fiddaman #      define __LINKAGE__\n\
405*b30d1939SAndy Fiddaman #    endif\n\
406*b30d1939SAndy Fiddaman #    define __STDARG__\n\
407*b30d1939SAndy Fiddaman #    define __PROTO__(x)	x\n\
408*b30d1939SAndy Fiddaman #    define __OTORP__(x)\n\
409*b30d1939SAndy Fiddaman #    define __PARAM__(n,o)	n\n\
410*b30d1939SAndy Fiddaman #    if !defined(__STDC__) && !defined(__cplusplus)\n\
411*b30d1939SAndy Fiddaman #      if !defined(c_plusplus)\n\
412*b30d1939SAndy Fiddaman #      	define const\n\
413*b30d1939SAndy Fiddaman #      endif\n\
414*b30d1939SAndy Fiddaman #      define signed\n\
415*b30d1939SAndy Fiddaman #      define void		int\n\
416*b30d1939SAndy Fiddaman #      define volatile\n\
417*b30d1939SAndy Fiddaman #      define __V_		char\n\
418*b30d1939SAndy Fiddaman #    else\n\
419*b30d1939SAndy Fiddaman #      define __V_		void\n\
420*b30d1939SAndy Fiddaman #    endif\n\
421*b30d1939SAndy Fiddaman #  else\n\
422*b30d1939SAndy Fiddaman #    define __PROTO__(x)	()\n\
423*b30d1939SAndy Fiddaman #    define __OTORP__(x)	x\n\
424*b30d1939SAndy Fiddaman #    define __PARAM__(n,o)	o\n\
425*b30d1939SAndy Fiddaman #    define __LINKAGE__\n\
426*b30d1939SAndy Fiddaman #    define __V_		char\n\
427*b30d1939SAndy Fiddaman #    define const\n\
428*b30d1939SAndy Fiddaman #    define signed\n\
429*b30d1939SAndy Fiddaman #    define void		int\n\
430*b30d1939SAndy Fiddaman #    define volatile\n\
431*b30d1939SAndy Fiddaman #  endif\n\
432*b30d1939SAndy Fiddaman #  define __MANGLE__	__LINKAGE__\n\
433*b30d1939SAndy Fiddaman #  if defined(__cplusplus) || defined(c_plusplus)\n\
434*b30d1939SAndy Fiddaman #    define __VARARG__	...\n\
435*b30d1939SAndy Fiddaman #  else\n\
436*b30d1939SAndy Fiddaman #    define __VARARG__\n\
437*b30d1939SAndy Fiddaman #  endif\n\
438*b30d1939SAndy Fiddaman #  if defined(__STDARG__)\n\
439*b30d1939SAndy Fiddaman #    define __VA_START__(p,a)	va_start(p,a)\n\
440*b30d1939SAndy Fiddaman #  else\n\
441*b30d1939SAndy Fiddaman #    define __VA_START__(p,a)	va_start(p)\n\
442*b30d1939SAndy Fiddaman #  endif\n\
443*b30d1939SAndy Fiddaman #  if !defined(__INLINE__)\n\
444*b30d1939SAndy Fiddaman #    if defined(__cplusplus)\n\
445*b30d1939SAndy Fiddaman #      define __INLINE__	extern __MANGLE__ inline\n\
446*b30d1939SAndy Fiddaman #    else\n\
447*b30d1939SAndy Fiddaman #      if defined(_WIN32) && !defined(__GNUC__)\n\
448*b30d1939SAndy Fiddaman #      	define __INLINE__	__inline\n\
449*b30d1939SAndy Fiddaman #      endif\n\
450*b30d1939SAndy Fiddaman #    endif\n\
451*b30d1939SAndy Fiddaman #  endif\n\
452*b30d1939SAndy Fiddaman #endif\n\
453*b30d1939SAndy Fiddaman #if !defined(__LINKAGE__)\n\
454*b30d1939SAndy Fiddaman #define __LINKAGE__		/* 2004-08-11 transition */\n\
455*b30d1939SAndy Fiddaman #endif\n\
456*b30d1939SAndy Fiddaman ");
457*b30d1939SAndy Fiddaman 	}
458*b30d1939SAndy Fiddaman 	else
459*b30d1939SAndy Fiddaman 		op = strcopy(op, "\
460*b30d1939SAndy Fiddaman \n\
461*b30d1939SAndy Fiddaman #if !defined(__PROTO__)\n\
462*b30d1939SAndy Fiddaman #include <prototyped.h>\n\
463*b30d1939SAndy Fiddaman #endif\n\
464*b30d1939SAndy Fiddaman #if !defined(__LINKAGE__)\n\
465*b30d1939SAndy Fiddaman #define __LINKAGE__		/* 2004-08-11 transition */\n\
466*b30d1939SAndy Fiddaman #endif\n\
467*b30d1939SAndy Fiddaman ");
468*b30d1939SAndy Fiddaman 	if (proto->package)
469*b30d1939SAndy Fiddaman 	{
470*b30d1939SAndy Fiddaman 		s = "\
471*b30d1939SAndy Fiddaman #ifndef	__MANGLE_%_DATA__\n\
472*b30d1939SAndy Fiddaman #  ifdef _BLD_%\n\
473*b30d1939SAndy Fiddaman #    ifdef __EXPORT__\n\
474*b30d1939SAndy Fiddaman #      define	__MANGLE_%_DATA__	__MANGLE__ __EXPORT__\n\
475*b30d1939SAndy Fiddaman #    else\n\
476*b30d1939SAndy Fiddaman #      define	__MANGLE_%_DATA__	__MANGLE__\n\
477*b30d1939SAndy Fiddaman #    endif\n\
478*b30d1939SAndy Fiddaman #    define	__MANGLE_%_FUNC__	__MANGLE__\n\
479*b30d1939SAndy Fiddaman #  else\n\
480*b30d1939SAndy Fiddaman #    ifdef __IMPORT__\n\
481*b30d1939SAndy Fiddaman #      define	__MANGLE_%_DATA__	__MANGLE__ __IMPORT__\n\
482*b30d1939SAndy Fiddaman #    else\n\
483*b30d1939SAndy Fiddaman #      define	__MANGLE_%_DATA__	__MANGLE__\n\
484*b30d1939SAndy Fiddaman #    endif\n\
485*b30d1939SAndy Fiddaman #    define	__MANGLE_%_FUNC__	__MANGLE__\n\
486*b30d1939SAndy Fiddaman #  endif\n\
487*b30d1939SAndy Fiddaman #endif\n\
488*b30d1939SAndy Fiddaman ";
489*b30d1939SAndy Fiddaman 		for (;;)
490*b30d1939SAndy Fiddaman 		{
491*b30d1939SAndy Fiddaman 			switch (*op++ = *s++)
492*b30d1939SAndy Fiddaman 			{
493*b30d1939SAndy Fiddaman 			case 0:
494*b30d1939SAndy Fiddaman 				op--;
495*b30d1939SAndy Fiddaman 				break;
496*b30d1939SAndy Fiddaman 			case '%':
497*b30d1939SAndy Fiddaman 				op = strcopy(op - 1, proto->package);
498*b30d1939SAndy Fiddaman 				continue;
499*b30d1939SAndy Fiddaman 			default:
500*b30d1939SAndy Fiddaman 				continue;
501*b30d1939SAndy Fiddaman 			}
502*b30d1939SAndy Fiddaman 			break;
503*b30d1939SAndy Fiddaman 		}
504*b30d1939SAndy Fiddaman 	}
505*b30d1939SAndy Fiddaman 	return op;
506*b30d1939SAndy Fiddaman }
507*b30d1939SAndy Fiddaman 
508*b30d1939SAndy Fiddaman #define BACKOUT()	(op=ko)
509*b30d1939SAndy Fiddaman #define CACHE()		do{CACHEIN();CACHEOUT();call=proto->call;}while(0)
510*b30d1939SAndy Fiddaman #define CACHEIN()	(ip=proto->ip)
511*b30d1939SAndy Fiddaman #define CACHEOUT()	(op=proto->op)
512*b30d1939SAndy Fiddaman #define GETCHR()	(*(unsigned char*)ip++)
513*b30d1939SAndy Fiddaman #define KEEPOUT()	(ko=op)
514*b30d1939SAndy Fiddaman #define LASTOUT()	(*(op-1))
515*b30d1939SAndy Fiddaman #define PUTCHR(c)	(*op++=(c))
516*b30d1939SAndy Fiddaman #define SYNC()		do{SYNCIN();SYNCOUT();proto->flags&=~(EXTERN|INIT|OTHER|VARIADIC|VARIADIC2);proto->flags|=flags&(EXTERN|INIT|OTHER|VARIADIC|VARIADIC2);proto->call=call;}while(0)
517*b30d1939SAndy Fiddaman #define SYNCIN()	(proto->ip=ip)
518*b30d1939SAndy Fiddaman #define SYNCOUT()	(proto->op=op)
519*b30d1939SAndy Fiddaman #define UNGETCHR()	(ip--)
520*b30d1939SAndy Fiddaman #define UNPUTCHR()	(op--)
521*b30d1939SAndy Fiddaman 
522*b30d1939SAndy Fiddaman /*
523*b30d1939SAndy Fiddaman  * advance to the next non-space character
524*b30d1939SAndy Fiddaman  */
525*b30d1939SAndy Fiddaman 
526*b30d1939SAndy Fiddaman static char*
nns(register char * s)527*b30d1939SAndy Fiddaman nns(register char* s)
528*b30d1939SAndy Fiddaman {
529*b30d1939SAndy Fiddaman 	while (*s == ' ' || *s == '\t' || *s == '\n')
530*b30d1939SAndy Fiddaman 		s++;
531*b30d1939SAndy Fiddaman 	return s;
532*b30d1939SAndy Fiddaman }
533*b30d1939SAndy Fiddaman 
534*b30d1939SAndy Fiddaman #define DIR_if	01
535*b30d1939SAndy Fiddaman #define DIR_el	02
536*b30d1939SAndy Fiddaman #define DIR_en	03
537*b30d1939SAndy Fiddaman #define DIR	03
538*b30d1939SAndy Fiddaman 
539*b30d1939SAndy Fiddaman /*
540*b30d1939SAndy Fiddaman  * update directive mask
541*b30d1939SAndy Fiddaman  */
542*b30d1939SAndy Fiddaman 
543*b30d1939SAndy Fiddaman static int
directive(register char * s,int dir)544*b30d1939SAndy Fiddaman directive(register char* s, int dir)
545*b30d1939SAndy Fiddaman {
546*b30d1939SAndy Fiddaman 	switch (*(s = nns(s)))
547*b30d1939SAndy Fiddaman 	{
548*b30d1939SAndy Fiddaman 	case 'e':
549*b30d1939SAndy Fiddaman 	case 'i':
550*b30d1939SAndy Fiddaman 		dir <<= 2;
551*b30d1939SAndy Fiddaman 		switch (*++s)
552*b30d1939SAndy Fiddaman 		{
553*b30d1939SAndy Fiddaman 		case 'f':
554*b30d1939SAndy Fiddaman 			dir |= DIR_if;
555*b30d1939SAndy Fiddaman 			break;
556*b30d1939SAndy Fiddaman 		case 'l':
557*b30d1939SAndy Fiddaman 			dir |= DIR_el;
558*b30d1939SAndy Fiddaman 			break;
559*b30d1939SAndy Fiddaman 		case 'n':
560*b30d1939SAndy Fiddaman 			dir |= DIR_en;
561*b30d1939SAndy Fiddaman 			break;
562*b30d1939SAndy Fiddaman 		}
563*b30d1939SAndy Fiddaman 		break;
564*b30d1939SAndy Fiddaman 	}
565*b30d1939SAndy Fiddaman 	return dir;
566*b30d1939SAndy Fiddaman }
567*b30d1939SAndy Fiddaman 
568*b30d1939SAndy Fiddaman /*
569*b30d1939SAndy Fiddaman  * the tokenizer
570*b30d1939SAndy Fiddaman  * top level calls loop until EOB
571*b30d1939SAndy Fiddaman  * recursive calls just return the next token
572*b30d1939SAndy Fiddaman  */
573*b30d1939SAndy Fiddaman 
574*b30d1939SAndy Fiddaman static int
lex(register Proto_t * proto,register long flags)575*b30d1939SAndy Fiddaman lex(register Proto_t* proto, register long flags)
576*b30d1939SAndy Fiddaman {
577*b30d1939SAndy Fiddaman 	register char*		ip;
578*b30d1939SAndy Fiddaman 	register char*		op;
579*b30d1939SAndy Fiddaman 	register int		c;
580*b30d1939SAndy Fiddaman 	register int		state;
581*b30d1939SAndy Fiddaman 	register short*		rp;
582*b30d1939SAndy Fiddaman 	char*			m;
583*b30d1939SAndy Fiddaman 	char*			e;
584*b30d1939SAndy Fiddaman 	char*			t;
585*b30d1939SAndy Fiddaman 	char*			bp;
586*b30d1939SAndy Fiddaman 	char*			v;
587*b30d1939SAndy Fiddaman 	char*			im;
588*b30d1939SAndy Fiddaman 	char*			ko;
589*b30d1939SAndy Fiddaman 	char*			aom;
590*b30d1939SAndy Fiddaman 	int			n;
591*b30d1939SAndy Fiddaman 	int			line;
592*b30d1939SAndy Fiddaman 	int			quot;
593*b30d1939SAndy Fiddaman 	int			brack;
594*b30d1939SAndy Fiddaman 	int			sub;
595*b30d1939SAndy Fiddaman 	int			x;
596*b30d1939SAndy Fiddaman 	int			vc;
597*b30d1939SAndy Fiddaman 
598*b30d1939SAndy Fiddaman 	char*			ie = 0;
599*b30d1939SAndy Fiddaman 	char*			om = 0;
600*b30d1939SAndy Fiddaman 	char*			aim = 0;
601*b30d1939SAndy Fiddaman 	char*			aie = 0;
602*b30d1939SAndy Fiddaman 	char*			func = 0;
603*b30d1939SAndy Fiddaman 	int			call = 0;
604*b30d1939SAndy Fiddaman 	int			dir = 0;
605*b30d1939SAndy Fiddaman 	int			group = 0;
606*b30d1939SAndy Fiddaman 	int			last = 0;
607*b30d1939SAndy Fiddaman 	int			paren = 0;
608*b30d1939SAndy Fiddaman #if PROTOMAIN
609*b30d1939SAndy Fiddaman 	char*			qe = 0;
610*b30d1939SAndy Fiddaman 	int			qn = 0;
611*b30d1939SAndy Fiddaman 	int			args = 0;
612*b30d1939SAndy Fiddaman #endif
613*b30d1939SAndy Fiddaman 
614*b30d1939SAndy Fiddaman 	CACHE();
615*b30d1939SAndy Fiddaman #if PROTOMAIN
616*b30d1939SAndy Fiddaman 	if (flags & EXTERN) KEEPOUT();
617*b30d1939SAndy Fiddaman #endif
618*b30d1939SAndy Fiddaman  fsm_start:
619*b30d1939SAndy Fiddaman 	proto->tp = ip;
620*b30d1939SAndy Fiddaman 	state = PROTO;
621*b30d1939SAndy Fiddaman 	bp = ip;
622*b30d1939SAndy Fiddaman 	do
623*b30d1939SAndy Fiddaman 	{
624*b30d1939SAndy Fiddaman 		rp = fsm[state];
625*b30d1939SAndy Fiddaman  fsm_get:
626*b30d1939SAndy Fiddaman 		while (!(state = rp[c = GETCHR()]));
627*b30d1939SAndy Fiddaman  fsm_next:
628*b30d1939SAndy Fiddaman 		;
629*b30d1939SAndy Fiddaman 	} while (state > 0);
630*b30d1939SAndy Fiddaman 	if ((n = ip - bp - 1) > 0)
631*b30d1939SAndy Fiddaman 	{
632*b30d1939SAndy Fiddaman 		ip = bp;
633*b30d1939SAndy Fiddaman 		MEMCPY(op, ip, n);
634*b30d1939SAndy Fiddaman 		ip++;
635*b30d1939SAndy Fiddaman 	}
636*b30d1939SAndy Fiddaman 	state = ~state;
637*b30d1939SAndy Fiddaman  fsm_terminal:
638*b30d1939SAndy Fiddaman 	switch (TERM(state))
639*b30d1939SAndy Fiddaman 	{
640*b30d1939SAndy Fiddaman 	case S_CHR:
641*b30d1939SAndy Fiddaman 		if (op > proto->ob && *(op - 1) == '=' && (op == proto->ob + 1 || *(op - 2) != '=')) switch (c)
642*b30d1939SAndy Fiddaman 		{
643*b30d1939SAndy Fiddaman 		case '+':
644*b30d1939SAndy Fiddaman 		case '-':
645*b30d1939SAndy Fiddaman 		case '*':
646*b30d1939SAndy Fiddaman 		case '&':
647*b30d1939SAndy Fiddaman 			PUTCHR(' ');
648*b30d1939SAndy Fiddaman 			break;
649*b30d1939SAndy Fiddaman 		}
650*b30d1939SAndy Fiddaman 		PUTCHR(c);
651*b30d1939SAndy Fiddaman 		break;
652*b30d1939SAndy Fiddaman 
653*b30d1939SAndy Fiddaman 	case S_CHRB:
654*b30d1939SAndy Fiddaman 		UNGETCHR();
655*b30d1939SAndy Fiddaman 		c = LASTOUT();
656*b30d1939SAndy Fiddaman 		break;
657*b30d1939SAndy Fiddaman 
658*b30d1939SAndy Fiddaman 	case S_COMMENT:
659*b30d1939SAndy Fiddaman 		switch (c)
660*b30d1939SAndy Fiddaman 		{
661*b30d1939SAndy Fiddaman 		case '\n':
662*b30d1939SAndy Fiddaman 			if (INCOMMENTXX(rp)) goto fsm_newline;
663*b30d1939SAndy Fiddaman 			PUTCHR(c);
664*b30d1939SAndy Fiddaman 			proto->line++;
665*b30d1939SAndy Fiddaman 			rp = fsm[COM2];
666*b30d1939SAndy Fiddaman 			break;
667*b30d1939SAndy Fiddaman 		case '/':
668*b30d1939SAndy Fiddaman #if PROTOMAIN
669*b30d1939SAndy Fiddaman 			if ((flags & (EXTERN|MATCH)) == EXTERN) BACKOUT();
670*b30d1939SAndy Fiddaman 			else
671*b30d1939SAndy Fiddaman #endif
672*b30d1939SAndy Fiddaman 			PUTCHR(c);
673*b30d1939SAndy Fiddaman 			if (INCOMMENTXX(rp))
674*b30d1939SAndy Fiddaman 			{
675*b30d1939SAndy Fiddaman 				rp = fsm[COM5];
676*b30d1939SAndy Fiddaman 				break;
677*b30d1939SAndy Fiddaman 			}
678*b30d1939SAndy Fiddaman 			goto fsm_start;
679*b30d1939SAndy Fiddaman 		case EOF:
680*b30d1939SAndy Fiddaman 			break;
681*b30d1939SAndy Fiddaman 		default:
682*b30d1939SAndy Fiddaman #if PROTOMAIN
683*b30d1939SAndy Fiddaman 			if ((flags & (EXTERN|MATCH)) == EXTERN) BACKOUT();
684*b30d1939SAndy Fiddaman 			else
685*b30d1939SAndy Fiddaman #endif
686*b30d1939SAndy Fiddaman 			PUTCHR(c);
687*b30d1939SAndy Fiddaman 			rp = fsm[INCOMMENTXX(rp) ? COM5 : COM3];
688*b30d1939SAndy Fiddaman 			break;
689*b30d1939SAndy Fiddaman 		}
690*b30d1939SAndy Fiddaman 		bp = ip;
691*b30d1939SAndy Fiddaman 		goto fsm_get;
692*b30d1939SAndy Fiddaman 
693*b30d1939SAndy Fiddaman 	case S_EOB:
694*b30d1939SAndy Fiddaman 		if (c)
695*b30d1939SAndy Fiddaman 		{
696*b30d1939SAndy Fiddaman 			if (state = fsm[TERMINAL][INDEX(rp)+1])
697*b30d1939SAndy Fiddaman 				goto fsm_terminal;
698*b30d1939SAndy Fiddaman 			SYNC();
699*b30d1939SAndy Fiddaman 			return 0;
700*b30d1939SAndy Fiddaman 		}
701*b30d1939SAndy Fiddaman 		UNGETCHR();
702*b30d1939SAndy Fiddaman  fsm_eob:
703*b30d1939SAndy Fiddaman 		if ((flags & (DECLARE|GLOBAL|RECURSIVE)) == GLOBAL && (proto->flags & MORE))
704*b30d1939SAndy Fiddaman 		{
705*b30d1939SAndy Fiddaman #if PROTOMAIN
706*b30d1939SAndy Fiddaman 			if (!(flags & EXTERN)) /* XXX */
707*b30d1939SAndy Fiddaman #endif
708*b30d1939SAndy Fiddaman 			flags |= SLIDE;
709*b30d1939SAndy Fiddaman 			c = ip - proto->ib;
710*b30d1939SAndy Fiddaman 			if (!(flags & MATCH))
711*b30d1939SAndy Fiddaman 				im = proto->tp;
712*b30d1939SAndy Fiddaman 			if (ip > proto->ib)
713*b30d1939SAndy Fiddaman 			{
714*b30d1939SAndy Fiddaman 				n = ip - im;
715*b30d1939SAndy Fiddaman 				if (ip - n < proto->ib)
716*b30d1939SAndy Fiddaman 					proto->flags |= ERROR;
717*b30d1939SAndy Fiddaman 				memcopy(proto->ib - n, ip - n, n);
718*b30d1939SAndy Fiddaman 				ip = proto->ib;
719*b30d1939SAndy Fiddaman 			}
720*b30d1939SAndy Fiddaman 			proto->tp -= c;
721*b30d1939SAndy Fiddaman 			if (flags & MATCH)
722*b30d1939SAndy Fiddaman 			{
723*b30d1939SAndy Fiddaman 				im -= c;
724*b30d1939SAndy Fiddaman 				ie -= c;
725*b30d1939SAndy Fiddaman 			}
726*b30d1939SAndy Fiddaman 			if (aim)
727*b30d1939SAndy Fiddaman 				aim -= c;
728*b30d1939SAndy Fiddaman 			if (aie)
729*b30d1939SAndy Fiddaman 				aie -= c;
730*b30d1939SAndy Fiddaman 			if ((n = read(proto->fd, ip, proto->iz)) > 0)
731*b30d1939SAndy Fiddaman 			{
732*b30d1939SAndy Fiddaman 				if ((proto->options & REGULAR) && n < proto->iz)
733*b30d1939SAndy Fiddaman 				{
734*b30d1939SAndy Fiddaman 					proto->flags &= ~MORE;
735*b30d1939SAndy Fiddaman 					close(proto->fd);
736*b30d1939SAndy Fiddaman 				}
737*b30d1939SAndy Fiddaman 				*(ip + n) = 0;
738*b30d1939SAndy Fiddaman 				if (state & SPLICE)
739*b30d1939SAndy Fiddaman 					goto fsm_splice;
740*b30d1939SAndy Fiddaman 				bp = ip;
741*b30d1939SAndy Fiddaman 				goto fsm_get;
742*b30d1939SAndy Fiddaman 			}
743*b30d1939SAndy Fiddaman 			*ip = 0;
744*b30d1939SAndy Fiddaman 			proto->flags &= ~MORE;
745*b30d1939SAndy Fiddaman 			close(proto->fd);
746*b30d1939SAndy Fiddaman 		}
747*b30d1939SAndy Fiddaman 		if (state & SPLICE)
748*b30d1939SAndy Fiddaman 			goto fsm_splice;
749*b30d1939SAndy Fiddaman 		/* NOTE: RECURSIVE lex() should really SLIDE too */
750*b30d1939SAndy Fiddaman 		if (!(flags & RECURSIVE) && (state = rp[c = EOF]))
751*b30d1939SAndy Fiddaman 		{
752*b30d1939SAndy Fiddaman 			bp = ip;
753*b30d1939SAndy Fiddaman 			goto fsm_next;
754*b30d1939SAndy Fiddaman 		}
755*b30d1939SAndy Fiddaman 		SYNC();
756*b30d1939SAndy Fiddaman 		return 0;
757*b30d1939SAndy Fiddaman 
758*b30d1939SAndy Fiddaman 	case S_LITBEG:
759*b30d1939SAndy Fiddaman 		quot = c;
760*b30d1939SAndy Fiddaman #if PROTOMAIN
761*b30d1939SAndy Fiddaman 		if (c == '"' && qe)
762*b30d1939SAndy Fiddaman 		{
763*b30d1939SAndy Fiddaman 			for (n = 0, t = qe + 1; t < op && (*t == ' ' || *t == '\t' || *t == '\n' && ++n || *t >= 'A' && *t <= 'Z' || *t == '_'); t++);
764*b30d1939SAndy Fiddaman 			if (t == op)
765*b30d1939SAndy Fiddaman 			{
766*b30d1939SAndy Fiddaman 				op = qe;
767*b30d1939SAndy Fiddaman 				qe = 0;
768*b30d1939SAndy Fiddaman 				qn = n;
769*b30d1939SAndy Fiddaman 			}
770*b30d1939SAndy Fiddaman 			else PUTCHR(c);
771*b30d1939SAndy Fiddaman 		}
772*b30d1939SAndy Fiddaman 		else
773*b30d1939SAndy Fiddaman #endif
774*b30d1939SAndy Fiddaman 		PUTCHR(c);
775*b30d1939SAndy Fiddaman 		rp = fsm[LIT1];
776*b30d1939SAndy Fiddaman 		bp = ip;
777*b30d1939SAndy Fiddaman 		goto fsm_get;
778*b30d1939SAndy Fiddaman 
779*b30d1939SAndy Fiddaman 	case S_LITEND:
780*b30d1939SAndy Fiddaman 		if (c == quot)
781*b30d1939SAndy Fiddaman 		{
782*b30d1939SAndy Fiddaman #if PROTOMAIN
783*b30d1939SAndy Fiddaman 			if (!(flags & DIRECTIVE))
784*b30d1939SAndy Fiddaman 				qe = (c == '"') ? op : (char*)0;
785*b30d1939SAndy Fiddaman #endif
786*b30d1939SAndy Fiddaman 			PUTCHR(c);
787*b30d1939SAndy Fiddaman #if PROTOMAIN
788*b30d1939SAndy Fiddaman 			while (qn > 0)
789*b30d1939SAndy Fiddaman 			{
790*b30d1939SAndy Fiddaman 				qn--;
791*b30d1939SAndy Fiddaman 				PUTCHR('\n');
792*b30d1939SAndy Fiddaman 			}
793*b30d1939SAndy Fiddaman #endif
794*b30d1939SAndy Fiddaman 		}
795*b30d1939SAndy Fiddaman 		else if (c != '\n' && c != EOF)
796*b30d1939SAndy Fiddaman 		{
797*b30d1939SAndy Fiddaman 			PUTCHR(c);
798*b30d1939SAndy Fiddaman 			bp = ip;
799*b30d1939SAndy Fiddaman 			goto fsm_get;
800*b30d1939SAndy Fiddaman 		}
801*b30d1939SAndy Fiddaman 		else
802*b30d1939SAndy Fiddaman 		{
803*b30d1939SAndy Fiddaman #if PROTOMAIN
804*b30d1939SAndy Fiddaman 			while (qn > 0)
805*b30d1939SAndy Fiddaman 			{
806*b30d1939SAndy Fiddaman 				qn--;
807*b30d1939SAndy Fiddaman 				PUTCHR('\n');
808*b30d1939SAndy Fiddaman 			}
809*b30d1939SAndy Fiddaman #endif
810*b30d1939SAndy Fiddaman 			UNGETCHR();
811*b30d1939SAndy Fiddaman 		}
812*b30d1939SAndy Fiddaman 		c = T_INVALID;
813*b30d1939SAndy Fiddaman 		break;
814*b30d1939SAndy Fiddaman 
815*b30d1939SAndy Fiddaman 	case S_LITESC:
816*b30d1939SAndy Fiddaman #if PROTOMAIN
817*b30d1939SAndy Fiddaman 		if (flags & CLASSIC) PUTCHR(c);
818*b30d1939SAndy Fiddaman 		else
819*b30d1939SAndy Fiddaman #endif
820*b30d1939SAndy Fiddaman 		switch (c)
821*b30d1939SAndy Fiddaman 		{
822*b30d1939SAndy Fiddaman 		case 'a':
823*b30d1939SAndy Fiddaman 			n = CC_bel;
824*b30d1939SAndy Fiddaman 			goto fsm_oct;
825*b30d1939SAndy Fiddaman 		case 'E':
826*b30d1939SAndy Fiddaman 			n = CC_esc;
827*b30d1939SAndy Fiddaman 			goto fsm_oct;
828*b30d1939SAndy Fiddaman 		case 'v':
829*b30d1939SAndy Fiddaman 			n = CC_vt;
830*b30d1939SAndy Fiddaman 			goto fsm_oct;
831*b30d1939SAndy Fiddaman 		case 'x':
832*b30d1939SAndy Fiddaman 			SYNC();
833*b30d1939SAndy Fiddaman 			lex(proto, (flags & GLOBAL) | RECURSIVE);
834*b30d1939SAndy Fiddaman 			for (n = x = 0; (c = GETCHR()), x < 3; x++) switch (c)
835*b30d1939SAndy Fiddaman 			{
836*b30d1939SAndy Fiddaman 			case '0': case '1': case '2': case '3':
837*b30d1939SAndy Fiddaman 			case '4': case '5': case '6': case '7':
838*b30d1939SAndy Fiddaman 			case '8': case '9':
839*b30d1939SAndy Fiddaman 				n = (n << 4) + c - '0';
840*b30d1939SAndy Fiddaman 				break;
841*b30d1939SAndy Fiddaman 			case 'a': case 'b': case 'c': case 'd':
842*b30d1939SAndy Fiddaman 			case 'e': case 'f':
843*b30d1939SAndy Fiddaman 				n = (n << 4) + c - 'a' + 10;
844*b30d1939SAndy Fiddaman 				break;
845*b30d1939SAndy Fiddaman 			case 'A': case 'B': case 'C': case 'D':
846*b30d1939SAndy Fiddaman 			case 'E': case 'F':
847*b30d1939SAndy Fiddaman 				n = (n << 4) + c - 'A' + 10;
848*b30d1939SAndy Fiddaman 				break;
849*b30d1939SAndy Fiddaman 			default:
850*b30d1939SAndy Fiddaman 				goto fsm_hex;
851*b30d1939SAndy Fiddaman 			}
852*b30d1939SAndy Fiddaman  fsm_hex:
853*b30d1939SAndy Fiddaman 			UNGETCHR();
854*b30d1939SAndy Fiddaman  fsm_oct:
855*b30d1939SAndy Fiddaman 			PUTCHR(((n >> 6) & 07) + '0');
856*b30d1939SAndy Fiddaman 			PUTCHR(((n >> 3) & 07) + '0');
857*b30d1939SAndy Fiddaman 			PUTCHR((n & 07) + '0');
858*b30d1939SAndy Fiddaman 			break;
859*b30d1939SAndy Fiddaman 		default:
860*b30d1939SAndy Fiddaman 			PUTCHR(c);
861*b30d1939SAndy Fiddaman 			break;
862*b30d1939SAndy Fiddaman 		}
863*b30d1939SAndy Fiddaman 		rp = fsm[LIT1];
864*b30d1939SAndy Fiddaman 		bp = ip;
865*b30d1939SAndy Fiddaman 		goto fsm_get;
866*b30d1939SAndy Fiddaman 
867*b30d1939SAndy Fiddaman 	case S_MACRO:
868*b30d1939SAndy Fiddaman 		UNGETCHR();
869*b30d1939SAndy Fiddaman #if PROTOMAIN
870*b30d1939SAndy Fiddaman 		if ((flags & EXTERN) && *proto->tp == 's' && !strncmp(proto->tp, "static", 6))
871*b30d1939SAndy Fiddaman 		{
872*b30d1939SAndy Fiddaman 			c = T_EXTERN;
873*b30d1939SAndy Fiddaman 			break;
874*b30d1939SAndy Fiddaman 		}
875*b30d1939SAndy Fiddaman #endif
876*b30d1939SAndy Fiddaman 		if (*proto->tp == '_' && !strncmp(proto->tp, "__STDPP__directive", 6)) c = '#';
877*b30d1939SAndy Fiddaman 		else c = T_ID;
878*b30d1939SAndy Fiddaman 
879*b30d1939SAndy Fiddaman 		break;
880*b30d1939SAndy Fiddaman 
881*b30d1939SAndy Fiddaman 	case S_NL:
882*b30d1939SAndy Fiddaman  fsm_newline:
883*b30d1939SAndy Fiddaman 		proto->line++;
884*b30d1939SAndy Fiddaman #if PROTOMAIN
885*b30d1939SAndy Fiddaman 		if (flags & EXTERN)
886*b30d1939SAndy Fiddaman 		{
887*b30d1939SAndy Fiddaman 			if (op != proto->ob && LASTOUT() != ' ' && LASTOUT() != '\n')
888*b30d1939SAndy Fiddaman 				PUTCHR(' ');
889*b30d1939SAndy Fiddaman 		}
890*b30d1939SAndy Fiddaman 		else
891*b30d1939SAndy Fiddaman #endif
892*b30d1939SAndy Fiddaman 		PUTCHR(c);
893*b30d1939SAndy Fiddaman 		if (flags & DIRECTIVE)
894*b30d1939SAndy Fiddaman 		{
895*b30d1939SAndy Fiddaman #if PROTOMAIN
896*b30d1939SAndy Fiddaman 			if (flags & CLASSIC)
897*b30d1939SAndy Fiddaman 			{
898*b30d1939SAndy Fiddaman 				if (flags & EXTERN) BACKOUT();
899*b30d1939SAndy Fiddaman 				if (flags & JUNK)
900*b30d1939SAndy Fiddaman 				{
901*b30d1939SAndy Fiddaman 					*(ip - 1) = 0;
902*b30d1939SAndy Fiddaman 					op = strcopy(om, "/* ");
903*b30d1939SAndy Fiddaman 					op = strcopy(op, im);
904*b30d1939SAndy Fiddaman 					op = strcopy(op, " */\n");
905*b30d1939SAndy Fiddaman 				}
906*b30d1939SAndy Fiddaman 				flags &= ~(DEFINE|DIRECTIVE|IDID|INDIRECT|JUNK|MATCH|SHARP|TYPEDEF);
907*b30d1939SAndy Fiddaman 			}
908*b30d1939SAndy Fiddaman 			else
909*b30d1939SAndy Fiddaman #endif
910*b30d1939SAndy Fiddaman 			{
911*b30d1939SAndy Fiddaman 				if ((flags & (DEFINE|SHARP)) == (DEFINE|SHARP))
912*b30d1939SAndy Fiddaman 				{
913*b30d1939SAndy Fiddaman 					*(ip - 1) = 0;
914*b30d1939SAndy Fiddaman 					op = strcopy(om, "#if defined(__STDC__) || defined(__STDPP__)\n");
915*b30d1939SAndy Fiddaman 					op = strcopy(op, im);
916*b30d1939SAndy Fiddaman 					op = strcopy(op, "\n#else\n");
917*b30d1939SAndy Fiddaman 					bp = ip;
918*b30d1939SAndy Fiddaman 					ip = im;
919*b30d1939SAndy Fiddaman 					*op++ = *ip++;
920*b30d1939SAndy Fiddaman 					while (*op = *ip++)
921*b30d1939SAndy Fiddaman 						if (*op++ == '#' && *ip != '(')
922*b30d1939SAndy Fiddaman 						{
923*b30d1939SAndy Fiddaman 							op--;
924*b30d1939SAndy Fiddaman 							while (*--op == ' ' || *op == '\t');
925*b30d1939SAndy Fiddaman 							if (*ip == '#')
926*b30d1939SAndy Fiddaman 							{
927*b30d1939SAndy Fiddaman 								op = strcopy(op + 1, "/**/");
928*b30d1939SAndy Fiddaman 								while (*++ip == ' ' || *ip == '\t');
929*b30d1939SAndy Fiddaman 							}
930*b30d1939SAndy Fiddaman 							else
931*b30d1939SAndy Fiddaman 							{
932*b30d1939SAndy Fiddaman 								if (*op != '"') *++op = '"';
933*b30d1939SAndy Fiddaman 								op++;
934*b30d1939SAndy Fiddaman 								while (*ip == ' ' || *ip == '\t') ip++;
935*b30d1939SAndy Fiddaman 								while ((c = *ip) >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '_') *op++ = *ip++;
936*b30d1939SAndy Fiddaman 								while (*ip == ' ' || *ip == '\t') ip++;
937*b30d1939SAndy Fiddaman 								if (*ip == '"') ip++;
938*b30d1939SAndy Fiddaman 								else *op++ = '"';
939*b30d1939SAndy Fiddaman 							}
940*b30d1939SAndy Fiddaman 						}
941*b30d1939SAndy Fiddaman 					ip = bp;
942*b30d1939SAndy Fiddaman 					op = strcopy(op, "\n#endif\n");
943*b30d1939SAndy Fiddaman 					op = linesync(proto, op, proto->line);
944*b30d1939SAndy Fiddaman 				}
945*b30d1939SAndy Fiddaman 				flags &= ~(DEFINE|DIRECTIVE|IDID|INDIRECT|MATCH|OTHER|SHARP|SKIP|TOKENS|TYPEDEF);
946*b30d1939SAndy Fiddaman 			}
947*b30d1939SAndy Fiddaman 			call = 0;
948*b30d1939SAndy Fiddaman 			group = 0;
949*b30d1939SAndy Fiddaman 			paren = 0;
950*b30d1939SAndy Fiddaman 			last = '\n';
951*b30d1939SAndy Fiddaman 		}
952*b30d1939SAndy Fiddaman 		if (paren == 0 && (flags & (MATCH|RECURSIVE|SKIP|SLIDE)) == SLIDE)
953*b30d1939SAndy Fiddaman 		{
954*b30d1939SAndy Fiddaman #if PROTOMAIN
955*b30d1939SAndy Fiddaman 			if (flags & EXTERN) BACKOUT();
956*b30d1939SAndy Fiddaman #endif
957*b30d1939SAndy Fiddaman 			SYNC();
958*b30d1939SAndy Fiddaman 			return 0;
959*b30d1939SAndy Fiddaman 		}
960*b30d1939SAndy Fiddaman 		goto fsm_start;
961*b30d1939SAndy Fiddaman 
962*b30d1939SAndy Fiddaman 	case S_QUAL:
963*b30d1939SAndy Fiddaman 		PUTCHR(c);
964*b30d1939SAndy Fiddaman 		rp = fsm[NEXT(state)];
965*b30d1939SAndy Fiddaman 		bp = ip;
966*b30d1939SAndy Fiddaman 		goto fsm_get;
967*b30d1939SAndy Fiddaman 
968*b30d1939SAndy Fiddaman 	case S_TOK:
969*b30d1939SAndy Fiddaman 		PUTCHR(c);
970*b30d1939SAndy Fiddaman 		c = TYPE(state);
971*b30d1939SAndy Fiddaman 		break;
972*b30d1939SAndy Fiddaman 
973*b30d1939SAndy Fiddaman 	case S_TOKB:
974*b30d1939SAndy Fiddaman 		UNGETCHR();
975*b30d1939SAndy Fiddaman 		c = TYPE(state);
976*b30d1939SAndy Fiddaman 		break;
977*b30d1939SAndy Fiddaman 
978*b30d1939SAndy Fiddaman 	case S_RESERVED:
979*b30d1939SAndy Fiddaman 		UNGETCHR();
980*b30d1939SAndy Fiddaman 		c = T_ID;
981*b30d1939SAndy Fiddaman 		if (!(flags & DECLARE)) switch (RESERVED(*proto->tp, *(ip - 1), ip - proto->tp))
982*b30d1939SAndy Fiddaman 		{
983*b30d1939SAndy Fiddaman 		case RESERVED('N', 'N', 3):
984*b30d1939SAndy Fiddaman 			if (proto->tp[1] == 'o')
985*b30d1939SAndy Fiddaman 				c = T_DO;
986*b30d1939SAndy Fiddaman 			break;
987*b30d1939SAndy Fiddaman 		case RESERVED('d', 'o', 2):
988*b30d1939SAndy Fiddaman 			c = T_DO;
989*b30d1939SAndy Fiddaman 			break;
990*b30d1939SAndy Fiddaman 		case RESERVED('e', 'e', 4):
991*b30d1939SAndy Fiddaman 			if (!(flags & RECURSIVE) && (flags & (DIRECTIVE|TOKENS)) != DIRECTIVE && !strncmp(proto->tp, "else", 4))
992*b30d1939SAndy Fiddaman 			{
993*b30d1939SAndy Fiddaman 				c = T_ELSE;
994*b30d1939SAndy Fiddaman 				goto fsm_id;
995*b30d1939SAndy Fiddaman 			}
996*b30d1939SAndy Fiddaman 			break;
997*b30d1939SAndy Fiddaman 		case RESERVED('e', 'n', 6):
998*b30d1939SAndy Fiddaman 			if (!strncmp(proto->tp, "extern", 6))
999*b30d1939SAndy Fiddaman 				c = T_EXTERN;
1000*b30d1939SAndy Fiddaman 			break;
1001*b30d1939SAndy Fiddaman 		case RESERVED('f', 'r', 3):
1002*b30d1939SAndy Fiddaman 			if (!(flags & RECURSIVE) && !strncmp(proto->tp, "for", 3))
1003*b30d1939SAndy Fiddaman 			{
1004*b30d1939SAndy Fiddaman 				c = T_FOR;
1005*b30d1939SAndy Fiddaman 				goto fsm_id;
1006*b30d1939SAndy Fiddaman 			}
1007*b30d1939SAndy Fiddaman 			break;
1008*b30d1939SAndy Fiddaman 		case RESERVED('i', 'f', 2):
1009*b30d1939SAndy Fiddaman 			c = T_IF;
1010*b30d1939SAndy Fiddaman 			break;
1011*b30d1939SAndy Fiddaman 		case RESERVED('i', 'e', 6):
1012*b30d1939SAndy Fiddaman 			if (!strncmp(proto->tp, "inline", 6) && !(flags & (MATCH|SKIP|TOKENS|TYPEDEF)) && proto->brace == 0 && paren == 0 && group == 0 && (last == ';' || last == '}' || last == '\n' || last == 0))
1013*b30d1939SAndy Fiddaman 			{
1014*b30d1939SAndy Fiddaman 				flags |= SKIP;
1015*b30d1939SAndy Fiddaman 				SYNC();
1016*b30d1939SAndy Fiddaman 				line = proto->line;
1017*b30d1939SAndy Fiddaman 				op = strcopy(op - 6, "__INLINE__");
1018*b30d1939SAndy Fiddaman 				SYNC();
1019*b30d1939SAndy Fiddaman 			}
1020*b30d1939SAndy Fiddaman 			break;
1021*b30d1939SAndy Fiddaman 		case RESERVED('r', 'n', 6):
1022*b30d1939SAndy Fiddaman 			if (!(flags & RECURSIVE) && !strncmp(proto->tp, "return", 6))
1023*b30d1939SAndy Fiddaman 			{
1024*b30d1939SAndy Fiddaman 				c = T_RETURN;
1025*b30d1939SAndy Fiddaman 				goto fsm_id;
1026*b30d1939SAndy Fiddaman 			}
1027*b30d1939SAndy Fiddaman 			break;
1028*b30d1939SAndy Fiddaman 		case RESERVED('s', 'c', 6):
1029*b30d1939SAndy Fiddaman 			if ((proto->options & EXTERNALIZE) && !strncmp(proto->tp, "static", 6))
1030*b30d1939SAndy Fiddaman 			{
1031*b30d1939SAndy Fiddaman 				proto->ox = op - 6;
1032*b30d1939SAndy Fiddaman 				flags |= EXTERNALIZE;
1033*b30d1939SAndy Fiddaman 			}
1034*b30d1939SAndy Fiddaman 			break;
1035*b30d1939SAndy Fiddaman 		case RESERVED('t', 'f', 7):
1036*b30d1939SAndy Fiddaman 			if (!(flags & RECURSIVE) && !strncmp(proto->tp, "typedef", 7))
1037*b30d1939SAndy Fiddaman 			{
1038*b30d1939SAndy Fiddaman 				flags |= TYPEDEF;
1039*b30d1939SAndy Fiddaman 				c = T_EXTERN;
1040*b30d1939SAndy Fiddaman 			}
1041*b30d1939SAndy Fiddaman 			break;
1042*b30d1939SAndy Fiddaman 		case RESERVED('v', 't', 8):
1043*b30d1939SAndy Fiddaman 			if (*ip == '(' && !strncmp(proto->tp, "va_start", 8)) c = T_VA_START;
1044*b30d1939SAndy Fiddaman 			break;
1045*b30d1939SAndy Fiddaman 		case RESERVED('v', 'd', 4):
1046*b30d1939SAndy Fiddaman 			if (!strncmp(proto->tp, "void", 4))
1047*b30d1939SAndy Fiddaman 			{
1048*b30d1939SAndy Fiddaman 				if (flags & (CLASSIC|PLUSONLY|INIT_DEFINE|INIT_INCLUDE)) c = T_VOID;
1049*b30d1939SAndy Fiddaman 				else
1050*b30d1939SAndy Fiddaman 				{
1051*b30d1939SAndy Fiddaman 					SYNC();
1052*b30d1939SAndy Fiddaman 					line = proto->line;
1053*b30d1939SAndy Fiddaman 					if (lex(proto, (flags & GLOBAL) | RECURSIVE) == '*')
1054*b30d1939SAndy Fiddaman 					{
1055*b30d1939SAndy Fiddaman 						memcopy(op - 4, "__V_", 4);
1056*b30d1939SAndy Fiddaman 						memcopy(ip - 4, "__V_", 4);
1057*b30d1939SAndy Fiddaman 					}
1058*b30d1939SAndy Fiddaman 					else c = T_VOID;
1059*b30d1939SAndy Fiddaman 					proto->line = line;
1060*b30d1939SAndy Fiddaman 					SYNC();
1061*b30d1939SAndy Fiddaman 					bp = ip;
1062*b30d1939SAndy Fiddaman 				}
1063*b30d1939SAndy Fiddaman 			}
1064*b30d1939SAndy Fiddaman 			break;
1065*b30d1939SAndy Fiddaman 		case RESERVED('w', 'e', 5):
1066*b30d1939SAndy Fiddaman 			if (!(flags & RECURSIVE) && !strncmp(proto->tp, "while", 5))
1067*b30d1939SAndy Fiddaman 			{
1068*b30d1939SAndy Fiddaman 				c = T_WHILE;
1069*b30d1939SAndy Fiddaman 				goto fsm_id;
1070*b30d1939SAndy Fiddaman 			}
1071*b30d1939SAndy Fiddaman 			break;
1072*b30d1939SAndy Fiddaman 		}
1073*b30d1939SAndy Fiddaman #if PROTOMAIN
1074*b30d1939SAndy Fiddaman 		if ((flags & CLASSIC) && c != T_EXTERN)
1075*b30d1939SAndy Fiddaman 			c = T_ID;
1076*b30d1939SAndy Fiddaman #endif
1077*b30d1939SAndy Fiddaman 		break;
1078*b30d1939SAndy Fiddaman 
1079*b30d1939SAndy Fiddaman 	case S_VS:
1080*b30d1939SAndy Fiddaman 		goto fsm_start;
1081*b30d1939SAndy Fiddaman 
1082*b30d1939SAndy Fiddaman 	case S_WS:
1083*b30d1939SAndy Fiddaman 		UNGETCHR();
1084*b30d1939SAndy Fiddaman #if PROTOMAIN
1085*b30d1939SAndy Fiddaman 		if ((flags & (EXTERN|MATCH)) == EXTERN)
1086*b30d1939SAndy Fiddaman 		{
1087*b30d1939SAndy Fiddaman 			while (op > proto->ob && (*(op - 1) == ' ' || *(op - 1) == '\t'))
1088*b30d1939SAndy Fiddaman 				op--;
1089*b30d1939SAndy Fiddaman 			if (op > proto->ob && *(op - 1) != '\n') *op++ = ' ';
1090*b30d1939SAndy Fiddaman 		}
1091*b30d1939SAndy Fiddaman #endif
1092*b30d1939SAndy Fiddaman 		goto fsm_start;
1093*b30d1939SAndy Fiddaman 
1094*b30d1939SAndy Fiddaman 	default:
1095*b30d1939SAndy Fiddaman 		if (state & SPLICE)
1096*b30d1939SAndy Fiddaman 		{
1097*b30d1939SAndy Fiddaman 			if (c == '\\')
1098*b30d1939SAndy Fiddaman 			{
1099*b30d1939SAndy Fiddaman 				if (!(n = GETCHR()))
1100*b30d1939SAndy Fiddaman 				{
1101*b30d1939SAndy Fiddaman 					goto fsm_eob;
1102*b30d1939SAndy Fiddaman  fsm_splice:
1103*b30d1939SAndy Fiddaman 					c = '\\';
1104*b30d1939SAndy Fiddaman 					n = GETCHR();
1105*b30d1939SAndy Fiddaman 				}
1106*b30d1939SAndy Fiddaman 				if (n == '\n')
1107*b30d1939SAndy Fiddaman 				{
1108*b30d1939SAndy Fiddaman 					proto->line++;
1109*b30d1939SAndy Fiddaman 					PUTCHR('\\');
1110*b30d1939SAndy Fiddaman 					PUTCHR('\n');
1111*b30d1939SAndy Fiddaman 					bp = ip;
1112*b30d1939SAndy Fiddaman 					goto fsm_get;
1113*b30d1939SAndy Fiddaman 				}
1114*b30d1939SAndy Fiddaman 				UNGETCHR();
1115*b30d1939SAndy Fiddaman 			}
1116*b30d1939SAndy Fiddaman 			state &= ~SPLICE;
1117*b30d1939SAndy Fiddaman 			if (state >= TERMINAL)
1118*b30d1939SAndy Fiddaman 				goto fsm_terminal;
1119*b30d1939SAndy Fiddaman 			rp = fsm[state];
1120*b30d1939SAndy Fiddaman 		}
1121*b30d1939SAndy Fiddaman 		PUTCHR(c);
1122*b30d1939SAndy Fiddaman 		bp = ip;
1123*b30d1939SAndy Fiddaman 		goto fsm_get;
1124*b30d1939SAndy Fiddaman 	}
1125*b30d1939SAndy Fiddaman 	if (!(flags & (INIT_DEFINE|INIT_INCLUDE|RECURSIVE)))
1126*b30d1939SAndy Fiddaman 	{
1127*b30d1939SAndy Fiddaman 		if (!(flags & DIRECTIVE)) switch (c)
1128*b30d1939SAndy Fiddaman 		{
1129*b30d1939SAndy Fiddaman 		case '(':
1130*b30d1939SAndy Fiddaman #if PROTOMAIN
1131*b30d1939SAndy Fiddaman 			if (!(flags & CLASSIC) || proto->brace == 0)
1132*b30d1939SAndy Fiddaman #endif
1133*b30d1939SAndy Fiddaman 			{
1134*b30d1939SAndy Fiddaman 				if (paren++ == 0)
1135*b30d1939SAndy Fiddaman 				{
1136*b30d1939SAndy Fiddaman #if PROTOMAIN
1137*b30d1939SAndy Fiddaman 					if (!(flags & CLASSIC) || group <= 1)
1138*b30d1939SAndy Fiddaman #endif
1139*b30d1939SAndy Fiddaman 					{
1140*b30d1939SAndy Fiddaman #if PROTOMAIN
1141*b30d1939SAndy Fiddaman 						args = 0;
1142*b30d1939SAndy Fiddaman #endif
1143*b30d1939SAndy Fiddaman 						if (group++ == 0) group++;
1144*b30d1939SAndy Fiddaman 						else if (flags & INDIRECT) call++;
1145*b30d1939SAndy Fiddaman 						flags |= MATCH;
1146*b30d1939SAndy Fiddaman 						im = ip - 1;
1147*b30d1939SAndy Fiddaman 						om = op - 1;
1148*b30d1939SAndy Fiddaman 					}
1149*b30d1939SAndy Fiddaman 					sub = 0;
1150*b30d1939SAndy Fiddaman 				}
1151*b30d1939SAndy Fiddaman 				else if (paren == 2 && !aim)
1152*b30d1939SAndy Fiddaman 				{
1153*b30d1939SAndy Fiddaman 					sub++;
1154*b30d1939SAndy Fiddaman 					if (last == '(')
1155*b30d1939SAndy Fiddaman 					{
1156*b30d1939SAndy Fiddaman 						flags &= ~MATCH;
1157*b30d1939SAndy Fiddaman 						om = 0;
1158*b30d1939SAndy Fiddaman 					}
1159*b30d1939SAndy Fiddaman 					else if (flags & INDIRECT)
1160*b30d1939SAndy Fiddaman 					{
1161*b30d1939SAndy Fiddaman 						aim = ip - 1;
1162*b30d1939SAndy Fiddaman 						aom = op - 1;
1163*b30d1939SAndy Fiddaman 					}
1164*b30d1939SAndy Fiddaman 					else if ((flags & (MATCH|TOKENS)) == MATCH)
1165*b30d1939SAndy Fiddaman 					{
1166*b30d1939SAndy Fiddaman 						for (m = ip - 2; m > im && (*m == ' ' || *m == '\t'); m--);
1167*b30d1939SAndy Fiddaman 						if (m != im && sub == 1)
1168*b30d1939SAndy Fiddaman 						{
1169*b30d1939SAndy Fiddaman 							m = im + (*nns(ip) == '*');
1170*b30d1939SAndy Fiddaman 						}
1171*b30d1939SAndy Fiddaman 						if (m == im)
1172*b30d1939SAndy Fiddaman 						{
1173*b30d1939SAndy Fiddaman 							flags &= ~MATCH;
1174*b30d1939SAndy Fiddaman 							om = 0;
1175*b30d1939SAndy Fiddaman 						}
1176*b30d1939SAndy Fiddaman 					}
1177*b30d1939SAndy Fiddaman 					else if ((flags & MATCH) && sub == 1 && *nns(ip) != '*')
1178*b30d1939SAndy Fiddaman 					{
1179*b30d1939SAndy Fiddaman 						flags &= ~MATCH;
1180*b30d1939SAndy Fiddaman 						om = 0;
1181*b30d1939SAndy Fiddaman 					}
1182*b30d1939SAndy Fiddaman 				}
1183*b30d1939SAndy Fiddaman 				flags &= ~TOKENS;
1184*b30d1939SAndy Fiddaman 			}
1185*b30d1939SAndy Fiddaman 			break;
1186*b30d1939SAndy Fiddaman 		case ')':
1187*b30d1939SAndy Fiddaman #if PROTOMAIN
1188*b30d1939SAndy Fiddaman 			if (!(flags & CLASSIC) || proto->brace == 0)
1189*b30d1939SAndy Fiddaman #endif
1190*b30d1939SAndy Fiddaman 			if (--paren == 0)
1191*b30d1939SAndy Fiddaman 			{
1192*b30d1939SAndy Fiddaman #if PROTOMAIN
1193*b30d1939SAndy Fiddaman 				if (flags & CLASSIC)
1194*b30d1939SAndy Fiddaman 				{
1195*b30d1939SAndy Fiddaman 					if (group != 2)
1196*b30d1939SAndy Fiddaman 					{
1197*b30d1939SAndy Fiddaman 						c = T_ID;
1198*b30d1939SAndy Fiddaman 						break;
1199*b30d1939SAndy Fiddaman 					}
1200*b30d1939SAndy Fiddaman 					group++;
1201*b30d1939SAndy Fiddaman 				}
1202*b30d1939SAndy Fiddaman #endif
1203*b30d1939SAndy Fiddaman 				ie = ip;
1204*b30d1939SAndy Fiddaman 			}
1205*b30d1939SAndy Fiddaman 			else if (paren == 1 && (flags & INDIRECT) && !aie)
1206*b30d1939SAndy Fiddaman 				aie = ip;
1207*b30d1939SAndy Fiddaman 			break;
1208*b30d1939SAndy Fiddaman 		case '*':
1209*b30d1939SAndy Fiddaman 			if (last == '(' && group == 2)
1210*b30d1939SAndy Fiddaman 			{
1211*b30d1939SAndy Fiddaman 				group--;
1212*b30d1939SAndy Fiddaman 				if (paren == 1)
1213*b30d1939SAndy Fiddaman 				{
1214*b30d1939SAndy Fiddaman 					flags |= INDIRECT;
1215*b30d1939SAndy Fiddaman 					aim = aie = 0;
1216*b30d1939SAndy Fiddaman 				}
1217*b30d1939SAndy Fiddaman 			}
1218*b30d1939SAndy Fiddaman 			break;
1219*b30d1939SAndy Fiddaman 		case '#':
1220*b30d1939SAndy Fiddaman 			dir = directive(ip, dir);
1221*b30d1939SAndy Fiddaman 			if (proto->brace == 0 && paren == 0 && last != '=' && (flags & (CLASSIC|DECLARE|DIRECTIVE|MATCH|PLUSONLY|SKIP|TOKENS)) == (MATCH|TOKENS) && ((dir & DIR) != DIR_en || ((dir>>2) & DIR) != DIR_if))
1222*b30d1939SAndy Fiddaman 				flags |= DIRECTIVE;
1223*b30d1939SAndy Fiddaman 			else if (!(flags & (DECLARE|DIRECTIVE)))
1224*b30d1939SAndy Fiddaman 			{
1225*b30d1939SAndy Fiddaman 				flags |= DIRECTIVE;
1226*b30d1939SAndy Fiddaman 				if (!(flags & PLUSONLY))
1227*b30d1939SAndy Fiddaman 				{
1228*b30d1939SAndy Fiddaman 					bp = ip;
1229*b30d1939SAndy Fiddaman 					while (*ip == ' ' || *ip == '\t') ip++;
1230*b30d1939SAndy Fiddaman 					if (*ip == 'l' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e')
1231*b30d1939SAndy Fiddaman 					{
1232*b30d1939SAndy Fiddaman 						if (*++ip == ' ' || *ip == '\t')
1233*b30d1939SAndy Fiddaman 						{
1234*b30d1939SAndy Fiddaman 							proto->line = 0;
1235*b30d1939SAndy Fiddaman 							while (*++ip >= '0' && *ip <= '9')
1236*b30d1939SAndy Fiddaman 								proto->line = proto->line * 10 + *ip - '0';
1237*b30d1939SAndy Fiddaman 							proto->line--;
1238*b30d1939SAndy Fiddaman 						}
1239*b30d1939SAndy Fiddaman 					}
1240*b30d1939SAndy Fiddaman #if PROTOMAIN
1241*b30d1939SAndy Fiddaman 					else if ((flags & (CLASSIC|EXTERN)) == CLASSIC)
1242*b30d1939SAndy Fiddaman 					{
1243*b30d1939SAndy Fiddaman 						n = 0;
1244*b30d1939SAndy Fiddaman 						t = ip + 6;
1245*b30d1939SAndy Fiddaman 						while (ip < t && *ip >= 'a' && *ip <= 'z')
1246*b30d1939SAndy Fiddaman 							n = HASHKEYPART(n, *ip++);
1247*b30d1939SAndy Fiddaman 						switch (n)
1248*b30d1939SAndy Fiddaman 						{
1249*b30d1939SAndy Fiddaman 						case HASHKEY4('e','l','s','e'):
1250*b30d1939SAndy Fiddaman 						case HASHKEY5('e','n','d','i','f'):
1251*b30d1939SAndy Fiddaman 							while (*ip == ' ' || *ip == '\t') ip++;
1252*b30d1939SAndy Fiddaman 							if (*ip != '\n' && *ip != '/' && *(ip + 1) != '*')
1253*b30d1939SAndy Fiddaman 							{
1254*b30d1939SAndy Fiddaman 								flags |= JUNK|MATCH;
1255*b30d1939SAndy Fiddaman 								im = ip;
1256*b30d1939SAndy Fiddaman 								om = op + (ip - bp);
1257*b30d1939SAndy Fiddaman 							}
1258*b30d1939SAndy Fiddaman 							break;
1259*b30d1939SAndy Fiddaman 						case HASHKEY4('e','l','i','f'):
1260*b30d1939SAndy Fiddaman 						case HASHKEY5('e','r','r','o','r'):
1261*b30d1939SAndy Fiddaman 						case HASHKEY2('i','f'):
1262*b30d1939SAndy Fiddaman 						case HASHKEY5('i','f','d','e','f'):
1263*b30d1939SAndy Fiddaman 						case HASHKEY6('i','f','n','d','e','f'):
1264*b30d1939SAndy Fiddaman 						case HASHKEY5('u','n','d','e','f'):
1265*b30d1939SAndy Fiddaman 							break;
1266*b30d1939SAndy Fiddaman 						case HASHKEY6('i','n','c','l','u','d'):
1267*b30d1939SAndy Fiddaman 							if (*ip == 'e') ip++;
1268*b30d1939SAndy Fiddaman 							/*FALLTHROUGH*/
1269*b30d1939SAndy Fiddaman 						case HASHKEY6('d','e','f','i','n','e'):
1270*b30d1939SAndy Fiddaman 						case HASHKEY6('p','r','a','g','m','a'):
1271*b30d1939SAndy Fiddaman 							if (*ip < 'a' || *ip > 'z') break;
1272*b30d1939SAndy Fiddaman 							/*FALLTHROUGH*/
1273*b30d1939SAndy Fiddaman 						default:
1274*b30d1939SAndy Fiddaman 							flags |= JUNK|MATCH;
1275*b30d1939SAndy Fiddaman 							im = bp - 1;
1276*b30d1939SAndy Fiddaman 							om = op - 1;
1277*b30d1939SAndy Fiddaman 							break;
1278*b30d1939SAndy Fiddaman 						}
1279*b30d1939SAndy Fiddaman 					}
1280*b30d1939SAndy Fiddaman 					else
1281*b30d1939SAndy Fiddaman #endif
1282*b30d1939SAndy Fiddaman 					{
1283*b30d1939SAndy Fiddaman 						if (*ip == 'i' && *++ip == 'n' && *++ip == 'c' && *++ip == 'l' && *++ip == 'u' && *++ip == 'd' && *++ip == 'e')
1284*b30d1939SAndy Fiddaman 						{
1285*b30d1939SAndy Fiddaman 							while (*++ip == ' ' || *ip == '\t');
1286*b30d1939SAndy Fiddaman 							if (*ip++ == '<' && *ip++ == 's' && *ip++ == 't' && *ip++ == 'd' && *ip++ == 'a' && *ip++ == 'r' && *ip++ == 'g' && *ip++ == '.' && *ip++ == 'h' && *ip++ == '>')
1287*b30d1939SAndy Fiddaman 							{
1288*b30d1939SAndy Fiddaman 								op = strcopy(op, "\
1289*b30d1939SAndy Fiddaman if !defined(va_start)\n\
1290*b30d1939SAndy Fiddaman #if defined(__STDARG__)\n\
1291*b30d1939SAndy Fiddaman #include <stdarg.h>\n\
1292*b30d1939SAndy Fiddaman #else\n\
1293*b30d1939SAndy Fiddaman #include <varargs.h>\n\
1294*b30d1939SAndy Fiddaman #endif\n\
1295*b30d1939SAndy Fiddaman #endif\n\
1296*b30d1939SAndy Fiddaman ");
1297*b30d1939SAndy Fiddaman 								op = linesync(proto, op, proto->line);
1298*b30d1939SAndy Fiddaman 								break;
1299*b30d1939SAndy Fiddaman 							}
1300*b30d1939SAndy Fiddaman 						}
1301*b30d1939SAndy Fiddaman 						else if (*ip == 'd' && *++ip == 'e' && *++ ip == 'f' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e' && (*++ip == ' ' || *ip == '\t'))
1302*b30d1939SAndy Fiddaman 						{
1303*b30d1939SAndy Fiddaman 							while (*++ip == ' ' || *ip == '\t');
1304*b30d1939SAndy Fiddaman 							if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t'))
1305*b30d1939SAndy Fiddaman 							{
1306*b30d1939SAndy Fiddaman 								t = ip;
1307*b30d1939SAndy Fiddaman 								while (*++t == ' ' || *t == '\t');
1308*b30d1939SAndy Fiddaman 								if (*t == 'e' && *++t == 'x' && *++ t == 't' && *++t == 'e' && *++t == 'r' && *++t == 'n' && (*++t == ' ' || *t == '\t' || *t == '\n' || *t == '\r'))
1309*b30d1939SAndy Fiddaman 									ip = t;
1310*b30d1939SAndy Fiddaman 								t = ip;
1311*b30d1939SAndy Fiddaman 								while (*++t == ' ' || *t == '\t');
1312*b30d1939SAndy Fiddaman 								if (*t == '_' && *(t + 1) == '_')
1313*b30d1939SAndy Fiddaman 								{
1314*b30d1939SAndy Fiddaman 									op = strcopy(op, "undef __MANGLE__\n");
1315*b30d1939SAndy Fiddaman 									op = linesync(proto, op, proto->line);
1316*b30d1939SAndy Fiddaman 									op = strcopy(op, "#define __MANGLE__ __LINKAGE__");
1317*b30d1939SAndy Fiddaman 									break;
1318*b30d1939SAndy Fiddaman 								}
1319*b30d1939SAndy Fiddaman 							}
1320*b30d1939SAndy Fiddaman 							flags |= DEFINE|MATCH;
1321*b30d1939SAndy Fiddaman 							im = bp - 1;
1322*b30d1939SAndy Fiddaman 							om = op - 1;
1323*b30d1939SAndy Fiddaman 						}
1324*b30d1939SAndy Fiddaman 						else if (*ip == 'u' && *++ip == 'n' && *++ ip == 'd' && *++ip == 'e' && *++ip == 'f' && (*++ip == ' ' || *ip == '\t'))
1325*b30d1939SAndy Fiddaman 						{
1326*b30d1939SAndy Fiddaman 							while (*++ip == ' ' || *ip == '\t');
1327*b30d1939SAndy Fiddaman 							if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t' || *ip == '\n' || *ip == '\r'))
1328*b30d1939SAndy Fiddaman 							{
1329*b30d1939SAndy Fiddaman 								op = strcopy(op, "undef __MANGLE__\n");
1330*b30d1939SAndy Fiddaman 								op = linesync(proto, op, proto->line);
1331*b30d1939SAndy Fiddaman 								op = strcopy(op, "#define __MANGLE__ __LINKAGE__");
1332*b30d1939SAndy Fiddaman 								break;
1333*b30d1939SAndy Fiddaman 							}
1334*b30d1939SAndy Fiddaman 							flags |= DEFINE|MATCH;
1335*b30d1939SAndy Fiddaman 							im = bp - 1;
1336*b30d1939SAndy Fiddaman 							om = op - 1;
1337*b30d1939SAndy Fiddaman 						}
1338*b30d1939SAndy Fiddaman 					}
1339*b30d1939SAndy Fiddaman 					ip = bp;
1340*b30d1939SAndy Fiddaman 				}
1341*b30d1939SAndy Fiddaman 				break;
1342*b30d1939SAndy Fiddaman 			}
1343*b30d1939SAndy Fiddaman 			else
1344*b30d1939SAndy Fiddaman 				break;
1345*b30d1939SAndy Fiddaman 			/*FALLTHROUGH*/
1346*b30d1939SAndy Fiddaman 		case '{':
1347*b30d1939SAndy Fiddaman 			if (proto->brace++ == 0 && paren == 0)
1348*b30d1939SAndy Fiddaman 			{
1349*b30d1939SAndy Fiddaman 				if (last == '=') flags |= INIT;
1350*b30d1939SAndy Fiddaman #if PROTOMAIN
1351*b30d1939SAndy Fiddaman 				else if (flags & CLASSIC)
1352*b30d1939SAndy Fiddaman 				{
1353*b30d1939SAndy Fiddaman 					if ((flags & (MATCH|OTHER|SKIP)) == MATCH)
1354*b30d1939SAndy Fiddaman 					{
1355*b30d1939SAndy Fiddaman 						if (args)
1356*b30d1939SAndy Fiddaman 						{
1357*b30d1939SAndy Fiddaman 							v = number(op, args < 0 ? -args : args);
1358*b30d1939SAndy Fiddaman 							v = strcopy(v, " argument actual/formal mismatch");
1359*b30d1939SAndy Fiddaman 							*v++ = ' ';
1360*b30d1939SAndy Fiddaman 							v = memcopy(v, im, ie - im);
1361*b30d1939SAndy Fiddaman 							*v = 0;
1362*b30d1939SAndy Fiddaman 							proto_error((char*)proto + sizeof(Proto_t), 2, op, NiL);
1363*b30d1939SAndy Fiddaman 						}
1364*b30d1939SAndy Fiddaman 						ip--;
1365*b30d1939SAndy Fiddaman 						/*UNDENT...*/
1366*b30d1939SAndy Fiddaman 	v = ie;
1367*b30d1939SAndy Fiddaman 	while (ie < ip)
1368*b30d1939SAndy Fiddaman 		if (*ie++ == '/' && *ie == '*')
1369*b30d1939SAndy Fiddaman 		{
1370*b30d1939SAndy Fiddaman 			e = ie - 1;
1371*b30d1939SAndy Fiddaman 			while (++ie < ip)
1372*b30d1939SAndy Fiddaman 			{
1373*b30d1939SAndy Fiddaman 				if (*ie == '*')
1374*b30d1939SAndy Fiddaman 				{
1375*b30d1939SAndy Fiddaman 					while (ie < ip && *ie == '*') ie++;
1376*b30d1939SAndy Fiddaman 					if (ie < ip && *ie == '/')
1377*b30d1939SAndy Fiddaman 					{
1378*b30d1939SAndy Fiddaman 						while (++ie < ip && (*ie == ' ' || *ie == '\t'));
1379*b30d1939SAndy Fiddaman 						while (e > v && (*(e - 1) == ' ' || *(e - 1) == '\t')) e--;
1380*b30d1939SAndy Fiddaman 						if (e > v && *e != '\n') *e++ = ' ';
1381*b30d1939SAndy Fiddaman 						t = ie;
1382*b30d1939SAndy Fiddaman 						while (--e >= v)
1383*b30d1939SAndy Fiddaman 							*--t = *e;
1384*b30d1939SAndy Fiddaman 						v = t;
1385*b30d1939SAndy Fiddaman 						break;
1386*b30d1939SAndy Fiddaman 					}
1387*b30d1939SAndy Fiddaman 				}
1388*b30d1939SAndy Fiddaman 			}
1389*b30d1939SAndy Fiddaman 		}
1390*b30d1939SAndy Fiddaman 	ie = v;
1391*b30d1939SAndy Fiddaman 						/*...INDENT*/
1392*b30d1939SAndy Fiddaman 						op = om++;
1393*b30d1939SAndy Fiddaman 						if (flags & EXTERN)
1394*b30d1939SAndy Fiddaman 						{
1395*b30d1939SAndy Fiddaman 							v = op;
1396*b30d1939SAndy Fiddaman 							while (v > ko && *--v != ' ');
1397*b30d1939SAndy Fiddaman 							if (*v != ' ')
1398*b30d1939SAndy Fiddaman 							{
1399*b30d1939SAndy Fiddaman 								om = (v = (op += 4)) + 1;
1400*b30d1939SAndy Fiddaman 								while (v >= ko + 4)
1401*b30d1939SAndy Fiddaman 								{
1402*b30d1939SAndy Fiddaman 									*v = *(v - 4);
1403*b30d1939SAndy Fiddaman 									v--;
1404*b30d1939SAndy Fiddaman 								}
1405*b30d1939SAndy Fiddaman 								memcopy(ko, "int ", 4);
1406*b30d1939SAndy Fiddaman 							}
1407*b30d1939SAndy Fiddaman 							if (*v == ' ')
1408*b30d1939SAndy Fiddaman 							{
1409*b30d1939SAndy Fiddaman 								while (*(v + 1) == '*')
1410*b30d1939SAndy Fiddaman 									*v++ = '*';
1411*b30d1939SAndy Fiddaman 								*v = '\t';
1412*b30d1939SAndy Fiddaman 								if ((v - ko) <= 8)
1413*b30d1939SAndy Fiddaman 								{
1414*b30d1939SAndy Fiddaman 									om = (e = ++op) + 1;
1415*b30d1939SAndy Fiddaman 									while (e > v)
1416*b30d1939SAndy Fiddaman 									{
1417*b30d1939SAndy Fiddaman 										*e = *(e - 1);
1418*b30d1939SAndy Fiddaman 										e--;
1419*b30d1939SAndy Fiddaman 									}
1420*b30d1939SAndy Fiddaman 								}
1421*b30d1939SAndy Fiddaman 							}
1422*b30d1939SAndy Fiddaman 							om = (v = (op += 7)) + 1;
1423*b30d1939SAndy Fiddaman 							while (v >= ko + 7)
1424*b30d1939SAndy Fiddaman 							{
1425*b30d1939SAndy Fiddaman 								*v = *(v - 7);
1426*b30d1939SAndy Fiddaman 								v--;
1427*b30d1939SAndy Fiddaman 							}
1428*b30d1939SAndy Fiddaman 							memcopy(ko, "extern ", 7);
1429*b30d1939SAndy Fiddaman 						}
1430*b30d1939SAndy Fiddaman 						PUTCHR('(');
1431*b30d1939SAndy Fiddaman 						t = op;
1432*b30d1939SAndy Fiddaman 						e = 0;
1433*b30d1939SAndy Fiddaman 						/*UNDENT...*/
1434*b30d1939SAndy Fiddaman 	while (ie < ip)
1435*b30d1939SAndy Fiddaman 	{
1436*b30d1939SAndy Fiddaman 		if ((c = *ie) == ' ' || c == '\t' || c == '\n')
1437*b30d1939SAndy Fiddaman 		{
1438*b30d1939SAndy Fiddaman 			while ((c = *++ie) == ' ' || c == '\t' || c == '\n');
1439*b30d1939SAndy Fiddaman 			if (ie >= ip) break;
1440*b30d1939SAndy Fiddaman 			if (c != '*' && op > om) PUTCHR(' ');
1441*b30d1939SAndy Fiddaman 		}
1442*b30d1939SAndy Fiddaman 		if ((n = ((c = *ie) == ',')) || c == ';')
1443*b30d1939SAndy Fiddaman 		{
1444*b30d1939SAndy Fiddaman 			if (flags & EXTERN)
1445*b30d1939SAndy Fiddaman 			{
1446*b30d1939SAndy Fiddaman 				m = op;
1447*b30d1939SAndy Fiddaman 				while (op > om && ((c = *(op - 1)) == '(' || c == ')' || c == '[' || c == ']'))
1448*b30d1939SAndy Fiddaman 					op--;
1449*b30d1939SAndy Fiddaman 				v = op;
1450*b30d1939SAndy Fiddaman 				while (op > om && (c = *(op - 1)) != ' ' && c != '*')
1451*b30d1939SAndy Fiddaman 					op--;
1452*b30d1939SAndy Fiddaman 				while (*(op - 1) == ' ')
1453*b30d1939SAndy Fiddaman 					op--;
1454*b30d1939SAndy Fiddaman 				if (!e)
1455*b30d1939SAndy Fiddaman 				{
1456*b30d1939SAndy Fiddaman 					e = op;
1457*b30d1939SAndy Fiddaman 					while (e > om && *(e - 1) == '*')
1458*b30d1939SAndy Fiddaman 						e--;
1459*b30d1939SAndy Fiddaman 				}
1460*b30d1939SAndy Fiddaman #if _s5r4_386_compiler_bug_fixed_
1461*b30d1939SAndy Fiddaman 				if (op <= om || *(op - 1) == ',' && (*op++ = ' '))
1462*b30d1939SAndy Fiddaman 					op = strcopy(op, "int");
1463*b30d1939SAndy Fiddaman #else
1464*b30d1939SAndy Fiddaman 				if (op <= om)
1465*b30d1939SAndy Fiddaman 					op = strcopy(op, "int");
1466*b30d1939SAndy Fiddaman 				else if (*(op - 1) == ',')
1467*b30d1939SAndy Fiddaman 					op = strcopy(op, " int");
1468*b30d1939SAndy Fiddaman #endif
1469*b30d1939SAndy Fiddaman 				while (v < m)
1470*b30d1939SAndy Fiddaman 					PUTCHR(*v++);
1471*b30d1939SAndy Fiddaman 			}
1472*b30d1939SAndy Fiddaman 			PUTCHR(',');
1473*b30d1939SAndy Fiddaman 			if (n)
1474*b30d1939SAndy Fiddaman 			{
1475*b30d1939SAndy Fiddaman 				if (x = !e) e = op - 1;
1476*b30d1939SAndy Fiddaman 				PUTCHR(' ');
1477*b30d1939SAndy Fiddaman 				m = t;
1478*b30d1939SAndy Fiddaman 				while (m < e)
1479*b30d1939SAndy Fiddaman 					PUTCHR(*m++);
1480*b30d1939SAndy Fiddaman 				if (x)
1481*b30d1939SAndy Fiddaman 				{
1482*b30d1939SAndy Fiddaman 					m = e;
1483*b30d1939SAndy Fiddaman 					while (*--e != ' ');
1484*b30d1939SAndy Fiddaman 					while (*(e - 1) == '*') e--;
1485*b30d1939SAndy Fiddaman 					op -= m - e;
1486*b30d1939SAndy Fiddaman 				}
1487*b30d1939SAndy Fiddaman 			}
1488*b30d1939SAndy Fiddaman 			while ((c = *++ie) == ' ' || c == '\t' || c == '\n');
1489*b30d1939SAndy Fiddaman 			if (ie >= ip) UNPUTCHR();
1490*b30d1939SAndy Fiddaman 			else PUTCHR(' ');
1491*b30d1939SAndy Fiddaman 			if (!n)
1492*b30d1939SAndy Fiddaman 			{
1493*b30d1939SAndy Fiddaman 				t = op;
1494*b30d1939SAndy Fiddaman 				e = 0;
1495*b30d1939SAndy Fiddaman 			}
1496*b30d1939SAndy Fiddaman 		}
1497*b30d1939SAndy Fiddaman 		else if (*ie == '*')
1498*b30d1939SAndy Fiddaman 		{
1499*b30d1939SAndy Fiddaman 			if (op > om && (c = *(op - 1)) == ' ') op--;
1500*b30d1939SAndy Fiddaman 			while (*ie == '*') PUTCHR(*ie++);
1501*b30d1939SAndy Fiddaman 			while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++;
1502*b30d1939SAndy Fiddaman 			if (c != '(') PUTCHR(' ');
1503*b30d1939SAndy Fiddaman 		}
1504*b30d1939SAndy Fiddaman 		else if (*ie == '(')
1505*b30d1939SAndy Fiddaman 		{
1506*b30d1939SAndy Fiddaman 			if (op > om && *(op - 1) == ' ') op--;
1507*b30d1939SAndy Fiddaman 			PUTCHR(*ie++);
1508*b30d1939SAndy Fiddaman 			while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++;
1509*b30d1939SAndy Fiddaman 		}
1510*b30d1939SAndy Fiddaman 		else if (*ie == ')')
1511*b30d1939SAndy Fiddaman 		{
1512*b30d1939SAndy Fiddaman 			if (op > om && *(op - 1) == '(')
1513*b30d1939SAndy Fiddaman 				proto_error((char*)proto + sizeof(Proto_t), 1, "function pointer argument prototype omitted", NiL);
1514*b30d1939SAndy Fiddaman 			PUTCHR(*ie++);
1515*b30d1939SAndy Fiddaman 			while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++;
1516*b30d1939SAndy Fiddaman 		}
1517*b30d1939SAndy Fiddaman 		else if ((flags & EXTERN) && (op == om || *(op - 1) == ' ') && *ie == 'r' && !strncmp(ie, "register", 8) && (*(ie + 8) == ' ' || *(ie + 8) == '\t' || *(ie + 8) == '\n'))
1518*b30d1939SAndy Fiddaman 		{
1519*b30d1939SAndy Fiddaman 			ie += 8;
1520*b30d1939SAndy Fiddaman 			if (op > om) UNPUTCHR();
1521*b30d1939SAndy Fiddaman 		}
1522*b30d1939SAndy Fiddaman 		else PUTCHR(*ie++);
1523*b30d1939SAndy Fiddaman 	}
1524*b30d1939SAndy Fiddaman 						/*...INDENT*/
1525*b30d1939SAndy Fiddaman 						if (op <= om) op = strcopy(op, "void");
1526*b30d1939SAndy Fiddaman 						PUTCHR(')');
1527*b30d1939SAndy Fiddaman 						if (flags & EXTERN)
1528*b30d1939SAndy Fiddaman 						{
1529*b30d1939SAndy Fiddaman 							PUTCHR(';');
1530*b30d1939SAndy Fiddaman 							PUTCHR('\n');
1531*b30d1939SAndy Fiddaman 							SYNCOUT();
1532*b30d1939SAndy Fiddaman 							KEEPOUT();
1533*b30d1939SAndy Fiddaman 						}
1534*b30d1939SAndy Fiddaman 						else
1535*b30d1939SAndy Fiddaman 						{
1536*b30d1939SAndy Fiddaman 							PUTCHR('\n');
1537*b30d1939SAndy Fiddaman 							PUTCHR(*ip);
1538*b30d1939SAndy Fiddaman 						}
1539*b30d1939SAndy Fiddaman 						ip++;
1540*b30d1939SAndy Fiddaman 						flags &= ~(MATCH|SKIP);
1541*b30d1939SAndy Fiddaman 					}
1542*b30d1939SAndy Fiddaman 				}
1543*b30d1939SAndy Fiddaman #endif
1544*b30d1939SAndy Fiddaman 				else if ((flags & (MATCH|PLUSONLY|SKIP|TOKENS)) == (MATCH|TOKENS))
1545*b30d1939SAndy Fiddaman 				{
1546*b30d1939SAndy Fiddaman 					line = proto->line;
1547*b30d1939SAndy Fiddaman 					op = strcopy(om, " __PARAM__(");
1548*b30d1939SAndy Fiddaman 					op = memcopy(op, im, ie - im);
1549*b30d1939SAndy Fiddaman 					PUTCHR(',');
1550*b30d1939SAndy Fiddaman 					PUTCHR(' ');
1551*b30d1939SAndy Fiddaman 					PUTCHR('(');
1552*b30d1939SAndy Fiddaman 					flags &= ~(MATCH|SKIP);
1553*b30d1939SAndy Fiddaman 					if (flags & VARIADIC)
1554*b30d1939SAndy Fiddaman 					{
1555*b30d1939SAndy Fiddaman 						if ((vc = ie - im + 1) > sizeof(proto->variadic)) vc = sizeof(proto->variadic);
1556*b30d1939SAndy Fiddaman 						memcopy(proto->variadic, im, vc);
1557*b30d1939SAndy Fiddaman 						op = strcopy(op, "va_alist)) __OTORP__(va_dcl)\n{");
1558*b30d1939SAndy Fiddaman 					}
1559*b30d1939SAndy Fiddaman 					else
1560*b30d1939SAndy Fiddaman 					{
1561*b30d1939SAndy Fiddaman 						flags |= SKIP;
1562*b30d1939SAndy Fiddaman 						proto->ip = im;
1563*b30d1939SAndy Fiddaman 						proto->op = op;
1564*b30d1939SAndy Fiddaman 						group = 0;
1565*b30d1939SAndy Fiddaman 						brack = 0;
1566*b30d1939SAndy Fiddaman 						for (;;)
1567*b30d1939SAndy Fiddaman 						{
1568*b30d1939SAndy Fiddaman 							switch (lex(proto, (flags & GLOBAL) | RECURSIVE))
1569*b30d1939SAndy Fiddaman 							{
1570*b30d1939SAndy Fiddaman 							case '[':
1571*b30d1939SAndy Fiddaman 								brack++;
1572*b30d1939SAndy Fiddaman 								continue;
1573*b30d1939SAndy Fiddaman 							case ']':
1574*b30d1939SAndy Fiddaman 								brack--;
1575*b30d1939SAndy Fiddaman 								continue;
1576*b30d1939SAndy Fiddaman 							case '(':
1577*b30d1939SAndy Fiddaman 								if (paren++) group++;
1578*b30d1939SAndy Fiddaman 								continue;
1579*b30d1939SAndy Fiddaman 							case ')':
1580*b30d1939SAndy Fiddaman 								if (--paren == 0)
1581*b30d1939SAndy Fiddaman 								{
1582*b30d1939SAndy Fiddaman 									group = 0;
1583*b30d1939SAndy Fiddaman 									if (flags & MATCH)
1584*b30d1939SAndy Fiddaman 									{
1585*b30d1939SAndy Fiddaman 										flags &= ~(MATCH|SKIP);
1586*b30d1939SAndy Fiddaman 										op = memcopy(op, m, e - m);
1587*b30d1939SAndy Fiddaman 									}
1588*b30d1939SAndy Fiddaman 									break;
1589*b30d1939SAndy Fiddaman 								}
1590*b30d1939SAndy Fiddaman 								continue;
1591*b30d1939SAndy Fiddaman 							case ',':
1592*b30d1939SAndy Fiddaman 								if (paren == 1)
1593*b30d1939SAndy Fiddaman 								{
1594*b30d1939SAndy Fiddaman 									group = 0;
1595*b30d1939SAndy Fiddaman 									if (flags & MATCH)
1596*b30d1939SAndy Fiddaman 									{
1597*b30d1939SAndy Fiddaman 										flags &= ~(MATCH|SKIP);
1598*b30d1939SAndy Fiddaman 										op = memcopy(op, m, e - m);
1599*b30d1939SAndy Fiddaman 									}
1600*b30d1939SAndy Fiddaman 									PUTCHR(',');
1601*b30d1939SAndy Fiddaman 									PUTCHR(' ');
1602*b30d1939SAndy Fiddaman 									proto->op = op;
1603*b30d1939SAndy Fiddaman 								}
1604*b30d1939SAndy Fiddaman 								continue;
1605*b30d1939SAndy Fiddaman 							case T_ID:
1606*b30d1939SAndy Fiddaman 								if (group <= 1 && !brack)
1607*b30d1939SAndy Fiddaman 								{
1608*b30d1939SAndy Fiddaman 									flags |= MATCH;
1609*b30d1939SAndy Fiddaman 									m = proto->tp;
1610*b30d1939SAndy Fiddaman 									e = proto->ip;
1611*b30d1939SAndy Fiddaman 								}
1612*b30d1939SAndy Fiddaman 								continue;
1613*b30d1939SAndy Fiddaman 							default:
1614*b30d1939SAndy Fiddaman 								continue;
1615*b30d1939SAndy Fiddaman 							}
1616*b30d1939SAndy Fiddaman 							break;
1617*b30d1939SAndy Fiddaman 						}
1618*b30d1939SAndy Fiddaman 						PUTCHR(')');
1619*b30d1939SAndy Fiddaman 						PUTCHR(')');
1620*b30d1939SAndy Fiddaman 					}
1621*b30d1939SAndy Fiddaman 					if (!(flags & SKIP))
1622*b30d1939SAndy Fiddaman 					{
1623*b30d1939SAndy Fiddaman 						flags |= SKIP;
1624*b30d1939SAndy Fiddaman 						proto->op = strcopy(op, " __OTORP__(");
1625*b30d1939SAndy Fiddaman 						proto->ip = im + 1;
1626*b30d1939SAndy Fiddaman 						n = *(ie - 1);
1627*b30d1939SAndy Fiddaman 						*(ie - 1) = ';';
1628*b30d1939SAndy Fiddaman 						c = *ie;
1629*b30d1939SAndy Fiddaman 						*ie = 0;
1630*b30d1939SAndy Fiddaman 						lex(proto, (flags & GLOBAL) | DECLARE);
1631*b30d1939SAndy Fiddaman 						*(ie - 1) = n;
1632*b30d1939SAndy Fiddaman 						*ie = c;
1633*b30d1939SAndy Fiddaman 						proto->ip = ie;
1634*b30d1939SAndy Fiddaman 						op = proto->op;
1635*b30d1939SAndy Fiddaman 						PUTCHR(')');
1636*b30d1939SAndy Fiddaman 					}
1637*b30d1939SAndy Fiddaman 					if (flags & EXTERNALIZE) memcpy(proto->ox, "extern", 6);
1638*b30d1939SAndy Fiddaman 					op = linesync(proto, op, proto->line = line);
1639*b30d1939SAndy Fiddaman 					if (flags & DIRECTIVE)
1640*b30d1939SAndy Fiddaman 					{
1641*b30d1939SAndy Fiddaman 						proto->brace = 0;
1642*b30d1939SAndy Fiddaman 						PUTCHR('\n');
1643*b30d1939SAndy Fiddaman 						PUTCHR('#');
1644*b30d1939SAndy Fiddaman 					}
1645*b30d1939SAndy Fiddaman 					else if (!(flags & VARIADIC)) PUTCHR('{');
1646*b30d1939SAndy Fiddaman 				}
1647*b30d1939SAndy Fiddaman 			}
1648*b30d1939SAndy Fiddaman 			flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP);
1649*b30d1939SAndy Fiddaman 			call = 0;
1650*b30d1939SAndy Fiddaman 			group = 0;
1651*b30d1939SAndy Fiddaman 			break;
1652*b30d1939SAndy Fiddaman 		case '}':
1653*b30d1939SAndy Fiddaman 			flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP|TOKENS);
1654*b30d1939SAndy Fiddaman 			if (--proto->brace == 0)
1655*b30d1939SAndy Fiddaman 			{
1656*b30d1939SAndy Fiddaman 				flags &= ~(INIT|VARIADIC|VARIADIC2);
1657*b30d1939SAndy Fiddaman #if PROTOMAIN
1658*b30d1939SAndy Fiddaman 				if (flags & EXTERN) BACKOUT();
1659*b30d1939SAndy Fiddaman #endif
1660*b30d1939SAndy Fiddaman 			}
1661*b30d1939SAndy Fiddaman 			call = 0;
1662*b30d1939SAndy Fiddaman 			group = 0;
1663*b30d1939SAndy Fiddaman 			paren = 0;
1664*b30d1939SAndy Fiddaman 			break;
1665*b30d1939SAndy Fiddaman 		case '=':
1666*b30d1939SAndy Fiddaman 			if (last == '?') flags |= DIRECTIVE;
1667*b30d1939SAndy Fiddaman 			else if (paren == 0 && (flags & (INIT|MATCH|SKIP)) == MATCH)
1668*b30d1939SAndy Fiddaman 			{
1669*b30d1939SAndy Fiddaman 				if (last == ')' && proto->brace && (group != 2 || call != 2)) flags |= SKIP;
1670*b30d1939SAndy Fiddaman 				else goto fsm_statement;
1671*b30d1939SAndy Fiddaman 			}
1672*b30d1939SAndy Fiddaman 			goto fsm_other;
1673*b30d1939SAndy Fiddaman 		case ',':
1674*b30d1939SAndy Fiddaman #if PROTOMAIN
1675*b30d1939SAndy Fiddaman 			if (flags & CLASSIC)
1676*b30d1939SAndy Fiddaman 			{
1677*b30d1939SAndy Fiddaman 				if (paren == 1) args++;
1678*b30d1939SAndy Fiddaman 				else
1679*b30d1939SAndy Fiddaman 				{
1680*b30d1939SAndy Fiddaman 					args--;
1681*b30d1939SAndy Fiddaman 					flags &= ~MATCH;
1682*b30d1939SAndy Fiddaman 				}
1683*b30d1939SAndy Fiddaman 				break;
1684*b30d1939SAndy Fiddaman 			}
1685*b30d1939SAndy Fiddaman #endif
1686*b30d1939SAndy Fiddaman 			if (paren == 0 && (flags & DECLARE)) *(op - 1) = c = ';';
1687*b30d1939SAndy Fiddaman 			/*FALLTHROUGH*/
1688*b30d1939SAndy Fiddaman 		case ';':
1689*b30d1939SAndy Fiddaman  fsm_statement:
1690*b30d1939SAndy Fiddaman 			if (flags & INIT) /* ignore */;
1691*b30d1939SAndy Fiddaman #if PROTOMAIN
1692*b30d1939SAndy Fiddaman 			else if (flags & CLASSIC)
1693*b30d1939SAndy Fiddaman 			{
1694*b30d1939SAndy Fiddaman 				if (paren == 0)
1695*b30d1939SAndy Fiddaman 				{
1696*b30d1939SAndy Fiddaman 					if ((flags & MATCH) && last == ')')
1697*b30d1939SAndy Fiddaman 						flags &= ~MATCH;
1698*b30d1939SAndy Fiddaman 					if (!(flags & MATCH))
1699*b30d1939SAndy Fiddaman 					{
1700*b30d1939SAndy Fiddaman 						call = 0;
1701*b30d1939SAndy Fiddaman 						group = 0;
1702*b30d1939SAndy Fiddaman 						flags &= ~SKIP;
1703*b30d1939SAndy Fiddaman 						if (flags & EXTERN) BACKOUT();
1704*b30d1939SAndy Fiddaman 						if (flags & SLIDE)
1705*b30d1939SAndy Fiddaman 						{
1706*b30d1939SAndy Fiddaman 							SYNC();
1707*b30d1939SAndy Fiddaman 							return 0;
1708*b30d1939SAndy Fiddaman 						}
1709*b30d1939SAndy Fiddaman 					}
1710*b30d1939SAndy Fiddaman 					else
1711*b30d1939SAndy Fiddaman 					{
1712*b30d1939SAndy Fiddaman 						args--;
1713*b30d1939SAndy Fiddaman 						if ((flags & (EXTERN|SKIP)) == (EXTERN|SKIP))
1714*b30d1939SAndy Fiddaman 							BACKOUT();
1715*b30d1939SAndy Fiddaman 					}
1716*b30d1939SAndy Fiddaman 				}
1717*b30d1939SAndy Fiddaman 			}
1718*b30d1939SAndy Fiddaman #endif
1719*b30d1939SAndy Fiddaman 			else if (paren == 0)
1720*b30d1939SAndy Fiddaman 			{
1721*b30d1939SAndy Fiddaman 				if ((flags & (MATCH|OTHER|SKIP)) == MATCH && call > 1)
1722*b30d1939SAndy Fiddaman 				{
1723*b30d1939SAndy Fiddaman 					if ((flags & MANGLE) && func)
1724*b30d1939SAndy Fiddaman 					{
1725*b30d1939SAndy Fiddaman 						func[0] = 'F';
1726*b30d1939SAndy Fiddaman 						func[1] = 'U';
1727*b30d1939SAndy Fiddaman 						func[2] = 'N';
1728*b30d1939SAndy Fiddaman 						func[3] = 'C';
1729*b30d1939SAndy Fiddaman 						func = 0;
1730*b30d1939SAndy Fiddaman 					}
1731*b30d1939SAndy Fiddaman 					if ((flags & (DECLARE|INDIRECT)) == INDIRECT && aim && aie < im)
1732*b30d1939SAndy Fiddaman 					{
1733*b30d1939SAndy Fiddaman 						while (aie < ip && (*aie == ' ' || *aie == '\t' || *aie == '\n')) aie++;
1734*b30d1939SAndy Fiddaman 						v = aim;
1735*b30d1939SAndy Fiddaman 						while (v < aie)
1736*b30d1939SAndy Fiddaman 							if (*v++ == ')') break;
1737*b30d1939SAndy Fiddaman 						while (v < aie && (*v == ' ' || *v == '\t' || *v == '\n')) v++;
1738*b30d1939SAndy Fiddaman 						if (v == aie || !(flags & PLUSPLUS))
1739*b30d1939SAndy Fiddaman 						{
1740*b30d1939SAndy Fiddaman 							if (flags & PLUSPLUS) n = 3;
1741*b30d1939SAndy Fiddaman 							else if (v == aie && *v == '(') n = 10;
1742*b30d1939SAndy Fiddaman 							else n = 11;
1743*b30d1939SAndy Fiddaman 							ko = op;
1744*b30d1939SAndy Fiddaman 							om += n;
1745*b30d1939SAndy Fiddaman 							v = op += n;
1746*b30d1939SAndy Fiddaman 							while (v >= ko + n)
1747*b30d1939SAndy Fiddaman 							{
1748*b30d1939SAndy Fiddaman 								*v = *(v - n);
1749*b30d1939SAndy Fiddaman 								v--;
1750*b30d1939SAndy Fiddaman 							}
1751*b30d1939SAndy Fiddaman 							if (flags & PLUSPLUS) memcopy(aom, "(...))", 6);
1752*b30d1939SAndy Fiddaman 							else if (n == 10) memcopy(aom, "(__VARARG__))", 13);
1753*b30d1939SAndy Fiddaman 							else
1754*b30d1939SAndy Fiddaman 							{
1755*b30d1939SAndy Fiddaman 								ko = strcopy(aom, " __PROTO__(");
1756*b30d1939SAndy Fiddaman 								ko = memcopy(ko, aim, aie - aim);
1757*b30d1939SAndy Fiddaman 								*ko = ')';
1758*b30d1939SAndy Fiddaman 								if (++ko >= om)
1759*b30d1939SAndy Fiddaman 								{
1760*b30d1939SAndy Fiddaman 									*ko++ = ')';
1761*b30d1939SAndy Fiddaman 									om = ko;
1762*b30d1939SAndy Fiddaman 								}
1763*b30d1939SAndy Fiddaman 							}
1764*b30d1939SAndy Fiddaman 						}
1765*b30d1939SAndy Fiddaman 					}
1766*b30d1939SAndy Fiddaman 					else if (flags & TYPEDEF)
1767*b30d1939SAndy Fiddaman 					{
1768*b30d1939SAndy Fiddaman 						op = om;
1769*b30d1939SAndy Fiddaman 						while (*--op == ' ' || *op == '\t' || *op == '\n');
1770*b30d1939SAndy Fiddaman 						if (*op != ')')
1771*b30d1939SAndy Fiddaman 						{
1772*b30d1939SAndy Fiddaman 							op = om += 14;
1773*b30d1939SAndy Fiddaman 							*--op = ')';
1774*b30d1939SAndy Fiddaman 							while ((x = *(op - 14)) >= 'A' && x <= 'Z' || x >= 'a' && x <= 'z' || x >= '0' && x <= '9' || x == '_')
1775*b30d1939SAndy Fiddaman 								*--op = x;
1776*b30d1939SAndy Fiddaman 							memcopy(op - 13, "(__OTORP__(*)", 13);
1777*b30d1939SAndy Fiddaman 						}
1778*b30d1939SAndy Fiddaman 					}
1779*b30d1939SAndy Fiddaman 					if (flags & OTHER)
1780*b30d1939SAndy Fiddaman 						;
1781*b30d1939SAndy Fiddaman 					else if (flags & PLUSPLUS)
1782*b30d1939SAndy Fiddaman 					{
1783*b30d1939SAndy Fiddaman 						op = om;
1784*b30d1939SAndy Fiddaman 						if (!(flags & TOKENS)) op = strcopy(op, "(...)");
1785*b30d1939SAndy Fiddaman 						else op = memcopy(op, im, ie - im);
1786*b30d1939SAndy Fiddaman 						PUTCHR(c);
1787*b30d1939SAndy Fiddaman 					}
1788*b30d1939SAndy Fiddaman 					else
1789*b30d1939SAndy Fiddaman 					{
1790*b30d1939SAndy Fiddaman 						if (flags & DECLARE) op = strcopy(om, "()");
1791*b30d1939SAndy Fiddaman 						else if (!(flags & TOKENS)) op = strcopy(om, "(__VARARG__)");
1792*b30d1939SAndy Fiddaman 						else
1793*b30d1939SAndy Fiddaman 						{
1794*b30d1939SAndy Fiddaman 							op = strcopy(om, " __PROTO__(");
1795*b30d1939SAndy Fiddaman 							op = memcopy(op, im, ie - im);
1796*b30d1939SAndy Fiddaman 							PUTCHR(')');
1797*b30d1939SAndy Fiddaman 						}
1798*b30d1939SAndy Fiddaman 						if (flags & EXTERNALIZE) memcpy(proto->ox, "extern", 6);
1799*b30d1939SAndy Fiddaman 						PUTCHR(c);
1800*b30d1939SAndy Fiddaman 					}
1801*b30d1939SAndy Fiddaman 					flags &= ~(MATCH|VARIADIC|VARIADIC2);
1802*b30d1939SAndy Fiddaman 					if (c == ',' && !(flags & INDIRECT))
1803*b30d1939SAndy Fiddaman 					{
1804*b30d1939SAndy Fiddaman 						call = 1;
1805*b30d1939SAndy Fiddaman 						group = 0;
1806*b30d1939SAndy Fiddaman 						break;
1807*b30d1939SAndy Fiddaman 					}
1808*b30d1939SAndy Fiddaman 				}
1809*b30d1939SAndy Fiddaman 				else if (flags & (OTHER|SKIP)) call = 0;
1810*b30d1939SAndy Fiddaman 				if (c == ';')
1811*b30d1939SAndy Fiddaman 				{
1812*b30d1939SAndy Fiddaman 					flags &= ~(EXTERNALIZE|MANGLE|TOKENS|TYPEDEF);
1813*b30d1939SAndy Fiddaman 					call = 0;
1814*b30d1939SAndy Fiddaman 					if (flags & SLIDE)
1815*b30d1939SAndy Fiddaman 					{
1816*b30d1939SAndy Fiddaman 						SYNC();
1817*b30d1939SAndy Fiddaman 						return 0;
1818*b30d1939SAndy Fiddaman 					}
1819*b30d1939SAndy Fiddaman 				}
1820*b30d1939SAndy Fiddaman 				else call = call > 1 && c == ',';
1821*b30d1939SAndy Fiddaman 				group = 0;
1822*b30d1939SAndy Fiddaman 				flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP);
1823*b30d1939SAndy Fiddaman 			}
1824*b30d1939SAndy Fiddaman 			else if (paren == 1 && group == 1 && !(flags & (IDID|MANGLE))) flags |= TOKENS|OTHER;
1825*b30d1939SAndy Fiddaman 			break;
1826*b30d1939SAndy Fiddaman 		case T_DO:
1827*b30d1939SAndy Fiddaman 		case T_IF:
1828*b30d1939SAndy Fiddaman 			flags |= TOKENS|SKIP;
1829*b30d1939SAndy Fiddaman 			break;
1830*b30d1939SAndy Fiddaman 		case T_EXTERN:
1831*b30d1939SAndy Fiddaman #if PROTOMAIN
1832*b30d1939SAndy Fiddaman 			if (flags & CLASSIC)
1833*b30d1939SAndy Fiddaman 			{
1834*b30d1939SAndy Fiddaman 				if (proto->brace == 0)
1835*b30d1939SAndy Fiddaman 					flags |= SKIP;
1836*b30d1939SAndy Fiddaman 			}
1837*b30d1939SAndy Fiddaman 			else
1838*b30d1939SAndy Fiddaman #endif
1839*b30d1939SAndy Fiddaman 			if (paren == 0 && !(flags & TYPEDEF))
1840*b30d1939SAndy Fiddaman 			{
1841*b30d1939SAndy Fiddaman 				flags |= MANGLE;
1842*b30d1939SAndy Fiddaman 				if (!(flags & PLUSONLY) || proto->package)
1843*b30d1939SAndy Fiddaman 				{
1844*b30d1939SAndy Fiddaman 					op = strcopy(op, " __MANGLE__");
1845*b30d1939SAndy Fiddaman 					if (proto->package)
1846*b30d1939SAndy Fiddaman 					{
1847*b30d1939SAndy Fiddaman 						op = strcopy(op - 1, proto->package);
1848*b30d1939SAndy Fiddaman 						func = op + 1;
1849*b30d1939SAndy Fiddaman 						op = strcopy(op, "_DATA__");
1850*b30d1939SAndy Fiddaman 					}
1851*b30d1939SAndy Fiddaman 				}
1852*b30d1939SAndy Fiddaman 				else
1853*b30d1939SAndy Fiddaman 					func = 0;
1854*b30d1939SAndy Fiddaman 			}
1855*b30d1939SAndy Fiddaman 			break;
1856*b30d1939SAndy Fiddaman 		case T_VARIADIC:
1857*b30d1939SAndy Fiddaman 			if (paren == 0 && (flags & (DECLARE|VARIADIC)) == DECLARE)
1858*b30d1939SAndy Fiddaman 			{
1859*b30d1939SAndy Fiddaman 				op -= 3;
1860*b30d1939SAndy Fiddaman 				SYNC();
1861*b30d1939SAndy Fiddaman 				return c;
1862*b30d1939SAndy Fiddaman 			}
1863*b30d1939SAndy Fiddaman 			if (paren == 1 && !(flags & SKIP))
1864*b30d1939SAndy Fiddaman 				flags |= VARIADIC;
1865*b30d1939SAndy Fiddaman 			flags |= TOKENS;
1866*b30d1939SAndy Fiddaman 			break;
1867*b30d1939SAndy Fiddaman 		case T_VOID:
1868*b30d1939SAndy Fiddaman 			goto fsm_id;
1869*b30d1939SAndy Fiddaman 		case T_VA_START:
1870*b30d1939SAndy Fiddaman 			if ((flags & (PLUSONLY|VARIADIC)) == VARIADIC)
1871*b30d1939SAndy Fiddaman 			{
1872*b30d1939SAndy Fiddaman 				flags &= ~MATCH;
1873*b30d1939SAndy Fiddaman 				line = proto->line;
1874*b30d1939SAndy Fiddaman 				op = strcopy(op - 8, "__VA_START__");
1875*b30d1939SAndy Fiddaman 				SYNC();
1876*b30d1939SAndy Fiddaman 				for (;;)
1877*b30d1939SAndy Fiddaman 				{
1878*b30d1939SAndy Fiddaman 					switch (lex(proto, (flags & GLOBAL) | RECURSIVE))
1879*b30d1939SAndy Fiddaman 					{
1880*b30d1939SAndy Fiddaman 					case 0:
1881*b30d1939SAndy Fiddaman 					case ';':
1882*b30d1939SAndy Fiddaman 						break;
1883*b30d1939SAndy Fiddaman 					case T_ID:
1884*b30d1939SAndy Fiddaman 						if (!(flags & MATCH))
1885*b30d1939SAndy Fiddaman 						{
1886*b30d1939SAndy Fiddaman 							flags |= MATCH;
1887*b30d1939SAndy Fiddaman 							m = proto->tp;
1888*b30d1939SAndy Fiddaman 							e = proto->ip;
1889*b30d1939SAndy Fiddaman 						}
1890*b30d1939SAndy Fiddaman 						continue;
1891*b30d1939SAndy Fiddaman 					default:
1892*b30d1939SAndy Fiddaman 						continue;
1893*b30d1939SAndy Fiddaman 					}
1894*b30d1939SAndy Fiddaman 					break;
1895*b30d1939SAndy Fiddaman 				}
1896*b30d1939SAndy Fiddaman 				CACHE();
1897*b30d1939SAndy Fiddaman 				if (flags & MATCH)
1898*b30d1939SAndy Fiddaman 				{
1899*b30d1939SAndy Fiddaman 					v = m;
1900*b30d1939SAndy Fiddaman 					n = e - m;
1901*b30d1939SAndy Fiddaman 				}
1902*b30d1939SAndy Fiddaman 				else
1903*b30d1939SAndy Fiddaman 				{
1904*b30d1939SAndy Fiddaman 					v = "ap";
1905*b30d1939SAndy Fiddaman 					n = 2;
1906*b30d1939SAndy Fiddaman 				}
1907*b30d1939SAndy Fiddaman 				op = strcopy(op, " __OTORP__(");
1908*b30d1939SAndy Fiddaman 				proto->ip = proto->variadic;
1909*b30d1939SAndy Fiddaman 				proto->op = op;
1910*b30d1939SAndy Fiddaman 				flags &= ~MATCH;
1911*b30d1939SAndy Fiddaman 				group = 0;
1912*b30d1939SAndy Fiddaman 				bp = proto->ip + 1;
1913*b30d1939SAndy Fiddaman 				if (*bp == 'r' && !strncmp(bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9;
1914*b30d1939SAndy Fiddaman 				for (;;)
1915*b30d1939SAndy Fiddaman 				{
1916*b30d1939SAndy Fiddaman 					switch (lex(proto, (flags & GLOBAL) | RECURSIVE))
1917*b30d1939SAndy Fiddaman 					{
1918*b30d1939SAndy Fiddaman 					case '(':
1919*b30d1939SAndy Fiddaman 						if (paren++) group++;
1920*b30d1939SAndy Fiddaman 						continue;
1921*b30d1939SAndy Fiddaman 					case ')':
1922*b30d1939SAndy Fiddaman 						if (--paren == 0)
1923*b30d1939SAndy Fiddaman 						{
1924*b30d1939SAndy Fiddaman 							if (flags & MATCH)
1925*b30d1939SAndy Fiddaman 							{
1926*b30d1939SAndy Fiddaman 								flags &= ~MATCH;
1927*b30d1939SAndy Fiddaman 								if (!(flags & VARIADIC2))
1928*b30d1939SAndy Fiddaman 								{
1929*b30d1939SAndy Fiddaman 									op = memcopy(op, m, e - m);
1930*b30d1939SAndy Fiddaman 									op = strcopy(op, " = ");
1931*b30d1939SAndy Fiddaman 								}
1932*b30d1939SAndy Fiddaman 								op = strcopy(op, "va_arg(");
1933*b30d1939SAndy Fiddaman 								op = memcopy(op, v, n);
1934*b30d1939SAndy Fiddaman 								PUTCHR(',');
1935*b30d1939SAndy Fiddaman 								PUTCHR(' ');
1936*b30d1939SAndy Fiddaman 								if (m > bp) op = memcopy(op, bp, m - bp);
1937*b30d1939SAndy Fiddaman 								else op = strcopy(op, "int ");
1938*b30d1939SAndy Fiddaman 								if (group > 1) op = strcopy(op, ")()");
1939*b30d1939SAndy Fiddaman 								else op = memcopy(op, e, proto->ip - e - 1);
1940*b30d1939SAndy Fiddaman 								PUTCHR(')');
1941*b30d1939SAndy Fiddaman 								PUTCHR(';');
1942*b30d1939SAndy Fiddaman 							}
1943*b30d1939SAndy Fiddaman 							group = 0;
1944*b30d1939SAndy Fiddaman 							break;
1945*b30d1939SAndy Fiddaman 						}
1946*b30d1939SAndy Fiddaman 						continue;
1947*b30d1939SAndy Fiddaman 					case ',':
1948*b30d1939SAndy Fiddaman 						if (paren == 1)
1949*b30d1939SAndy Fiddaman 						{
1950*b30d1939SAndy Fiddaman 							if (flags & MATCH)
1951*b30d1939SAndy Fiddaman 							{
1952*b30d1939SAndy Fiddaman 								flags &= ~MATCH;
1953*b30d1939SAndy Fiddaman 								if (!(flags & VARIADIC2))
1954*b30d1939SAndy Fiddaman 								{
1955*b30d1939SAndy Fiddaman 									op = memcopy(op, m, e - m);
1956*b30d1939SAndy Fiddaman 									op = strcopy(op, " = ");
1957*b30d1939SAndy Fiddaman 								}
1958*b30d1939SAndy Fiddaman 								op = strcopy(op, "va_arg(");
1959*b30d1939SAndy Fiddaman 								op = memcopy(op, v, n);
1960*b30d1939SAndy Fiddaman 								PUTCHR(',');
1961*b30d1939SAndy Fiddaman 								PUTCHR(' ');
1962*b30d1939SAndy Fiddaman 								if (m > bp) op = memcopy(op, bp, m - bp);
1963*b30d1939SAndy Fiddaman 								else op = strcopy(op, "int ");
1964*b30d1939SAndy Fiddaman 								if (group > 1) op = strcopy(op, ")()");
1965*b30d1939SAndy Fiddaman 								else op = memcopy(op, e, proto->ip - e - 1);
1966*b30d1939SAndy Fiddaman 								PUTCHR(')');
1967*b30d1939SAndy Fiddaman 								PUTCHR(';');
1968*b30d1939SAndy Fiddaman 								bp = proto->ip + 1;
1969*b30d1939SAndy Fiddaman 								if (*bp == 'r' && !strncmp(bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9;
1970*b30d1939SAndy Fiddaman 							}
1971*b30d1939SAndy Fiddaman 							group = 0;
1972*b30d1939SAndy Fiddaman 							proto->op = op;
1973*b30d1939SAndy Fiddaman 						}
1974*b30d1939SAndy Fiddaman 						continue;
1975*b30d1939SAndy Fiddaman 					case T_ID:
1976*b30d1939SAndy Fiddaman 						if (group <= 1)
1977*b30d1939SAndy Fiddaman 						{
1978*b30d1939SAndy Fiddaman 							flags |= MATCH;
1979*b30d1939SAndy Fiddaman 							m = proto->tp;
1980*b30d1939SAndy Fiddaman 							e = proto->ip;
1981*b30d1939SAndy Fiddaman 						}
1982*b30d1939SAndy Fiddaman 						continue;
1983*b30d1939SAndy Fiddaman 					default:
1984*b30d1939SAndy Fiddaman 						continue;
1985*b30d1939SAndy Fiddaman 					}
1986*b30d1939SAndy Fiddaman 					break;
1987*b30d1939SAndy Fiddaman 				}
1988*b30d1939SAndy Fiddaman 				op = strcopy(op, ")");
1989*b30d1939SAndy Fiddaman 				flags |= VARIADIC2;
1990*b30d1939SAndy Fiddaman 				proto->line = line;
1991*b30d1939SAndy Fiddaman 				call = 0;
1992*b30d1939SAndy Fiddaman 				break;
1993*b30d1939SAndy Fiddaman 			}
1994*b30d1939SAndy Fiddaman 			/*FALLTHROUGH*/
1995*b30d1939SAndy Fiddaman 		case T_ID:
1996*b30d1939SAndy Fiddaman  fsm_id:
1997*b30d1939SAndy Fiddaman #if PROTOMAIN
1998*b30d1939SAndy Fiddaman 			if (flags & CLASSIC)
1999*b30d1939SAndy Fiddaman 			{
2000*b30d1939SAndy Fiddaman 				if (!args && paren == 1) args++;
2001*b30d1939SAndy Fiddaman 				break;
2002*b30d1939SAndy Fiddaman 			}
2003*b30d1939SAndy Fiddaman #endif
2004*b30d1939SAndy Fiddaman 			if (paren == 0)
2005*b30d1939SAndy Fiddaman 			{
2006*b30d1939SAndy Fiddaman 				if (last == ')')
2007*b30d1939SAndy Fiddaman 				{
2008*b30d1939SAndy Fiddaman 					if (proto->brace == 0 && !(flags & DECLARE)) flags |= SKIP;
2009*b30d1939SAndy Fiddaman 					call = !call;
2010*b30d1939SAndy Fiddaman 				}
2011*b30d1939SAndy Fiddaman 				else if ((flags & SKIP) || c == T_ID || c == T_VOID) call++;
2012*b30d1939SAndy Fiddaman 				else flags |= SKIP;
2013*b30d1939SAndy Fiddaman 				if (last == T_ID) flags |= IDID;
2014*b30d1939SAndy Fiddaman 			}
2015*b30d1939SAndy Fiddaman 			c = T_ID;
2016*b30d1939SAndy Fiddaman 			flags |= TOKENS;
2017*b30d1939SAndy Fiddaman 			break;
2018*b30d1939SAndy Fiddaman 		case T_INVALID:
2019*b30d1939SAndy Fiddaman 			if (*proto->tp >= '0' && *proto->tp <= '9')
2020*b30d1939SAndy Fiddaman 			{
2021*b30d1939SAndy Fiddaman 				n = 0;
2022*b30d1939SAndy Fiddaman 				for (;; op--)
2023*b30d1939SAndy Fiddaman 				{
2024*b30d1939SAndy Fiddaman 					switch (*(op - 1))
2025*b30d1939SAndy Fiddaman 					{
2026*b30d1939SAndy Fiddaman 					case 'f':
2027*b30d1939SAndy Fiddaman 					case 'F':
2028*b30d1939SAndy Fiddaman 						t = op;
2029*b30d1939SAndy Fiddaman 						while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
2030*b30d1939SAndy Fiddaman 						if (*t == '.')
2031*b30d1939SAndy Fiddaman 							op--;
2032*b30d1939SAndy Fiddaman 						n = 0;
2033*b30d1939SAndy Fiddaman 						break;
2034*b30d1939SAndy Fiddaman 					case 'l':
2035*b30d1939SAndy Fiddaman 					case 'L':
2036*b30d1939SAndy Fiddaman 						if (!(n & 01))
2037*b30d1939SAndy Fiddaman 						{
2038*b30d1939SAndy Fiddaman 							n |= 01;
2039*b30d1939SAndy Fiddaman 							t = op;
2040*b30d1939SAndy Fiddaman 							while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
2041*b30d1939SAndy Fiddaman 							if (*t == '.')
2042*b30d1939SAndy Fiddaman 							{
2043*b30d1939SAndy Fiddaman 								n = 0;
2044*b30d1939SAndy Fiddaman 								op--;
2045*b30d1939SAndy Fiddaman 								break;
2046*b30d1939SAndy Fiddaman 							}
2047*b30d1939SAndy Fiddaman 						}
2048*b30d1939SAndy Fiddaman 						continue;
2049*b30d1939SAndy Fiddaman 					case 'u':
2050*b30d1939SAndy Fiddaman 					case 'U':
2051*b30d1939SAndy Fiddaman 						n |= 02;
2052*b30d1939SAndy Fiddaman 						continue;
2053*b30d1939SAndy Fiddaman 					}
2054*b30d1939SAndy Fiddaman 					break;
2055*b30d1939SAndy Fiddaman 				}
2056*b30d1939SAndy Fiddaman 				if (n & 01)
2057*b30d1939SAndy Fiddaman 					*op++ = 'L';
2058*b30d1939SAndy Fiddaman 				if (n & 02)
2059*b30d1939SAndy Fiddaman 				{
2060*b30d1939SAndy Fiddaman 					m = op;
2061*b30d1939SAndy Fiddaman 					t = op = m + 10;
2062*b30d1939SAndy Fiddaman 					while ((c = *--m) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
2063*b30d1939SAndy Fiddaman 						*--t = c;
2064*b30d1939SAndy Fiddaman 					c = *t;
2065*b30d1939SAndy Fiddaman 					strcopy(m + 1, "(unsigned)");
2066*b30d1939SAndy Fiddaman 					*t = c;
2067*b30d1939SAndy Fiddaman 					break;
2068*b30d1939SAndy Fiddaman 				}
2069*b30d1939SAndy Fiddaman 			}
2070*b30d1939SAndy Fiddaman 			goto fsm_other;
2071*b30d1939SAndy Fiddaman #if PROTOMAIN
2072*b30d1939SAndy Fiddaman 		case '[':
2073*b30d1939SAndy Fiddaman 			if ((flags & CLASSIC) && paren == 0 && group <= 2) flags |= SKIP;
2074*b30d1939SAndy Fiddaman 			/*FALLTHROUGH*/
2075*b30d1939SAndy Fiddaman #endif
2076*b30d1939SAndy Fiddaman 		default:
2077*b30d1939SAndy Fiddaman  fsm_other:
2078*b30d1939SAndy Fiddaman #if PROTOMAIN
2079*b30d1939SAndy Fiddaman 			if (flags & CLASSIC) break;
2080*b30d1939SAndy Fiddaman #endif
2081*b30d1939SAndy Fiddaman 			flags |= TOKENS;
2082*b30d1939SAndy Fiddaman 			if (paren == 0) flags |= OTHER;
2083*b30d1939SAndy Fiddaman 			break;
2084*b30d1939SAndy Fiddaman 		}
2085*b30d1939SAndy Fiddaman 		else if (c == '#' && *ip != '(') flags |= SHARP;
2086*b30d1939SAndy Fiddaman 		last = c;
2087*b30d1939SAndy Fiddaman #if PROTOMAIN
2088*b30d1939SAndy Fiddaman 		if ((flags & (EXTERN|MATCH)) == (EXTERN|MATCH) && ((flags & (DIRECTIVE|SKIP)) || proto->brace || c != '(' && c != ')' && c != '*' && c != T_ID))
2089*b30d1939SAndy Fiddaman 			CACHEOUT();
2090*b30d1939SAndy Fiddaman 		else
2091*b30d1939SAndy Fiddaman #endif
2092*b30d1939SAndy Fiddaman 		SYNCOUT();
2093*b30d1939SAndy Fiddaman 		goto fsm_start;
2094*b30d1939SAndy Fiddaman 	}
2095*b30d1939SAndy Fiddaman 	else if (flags & (INIT_DEFINE|INIT_INCLUDE))
2096*b30d1939SAndy Fiddaman 	{
2097*b30d1939SAndy Fiddaman #if PROTOMAIN
2098*b30d1939SAndy Fiddaman 		if ((flags & YACC) && c == '%' && *ip == '{')
2099*b30d1939SAndy Fiddaman 			t = 0;
2100*b30d1939SAndy Fiddaman 		else
2101*b30d1939SAndy Fiddaman #endif
2102*b30d1939SAndy Fiddaman 		{
2103*b30d1939SAndy Fiddaman 			if (c == '#')
2104*b30d1939SAndy Fiddaman 			{
2105*b30d1939SAndy Fiddaman 				for (t = ip; *t == ' ' || *t == '\t'; t++);
2106*b30d1939SAndy Fiddaman 				if (*t++ == 'i' && *t++ == 'f' && *t++ == 'n' && *t++ == 'd' && *t++ == 'e' && *t++ == 'f')
2107*b30d1939SAndy Fiddaman 				{
2108*b30d1939SAndy Fiddaman #if !PROTOMAIN
2109*b30d1939SAndy Fiddaman 					while (*t == ' ' || *t == '\t') t++;
2110*b30d1939SAndy Fiddaman 					if (*t != '_')
2111*b30d1939SAndy Fiddaman #endif
2112*b30d1939SAndy Fiddaman 						t = 0;
2113*b30d1939SAndy Fiddaman 				}
2114*b30d1939SAndy Fiddaman 			}
2115*b30d1939SAndy Fiddaman 			else
2116*b30d1939SAndy Fiddaman 				t = "";
2117*b30d1939SAndy Fiddaman 		}
2118*b30d1939SAndy Fiddaman 		if (t)
2119*b30d1939SAndy Fiddaman 		{
2120*b30d1939SAndy Fiddaman #if PROTOMAIN
2121*b30d1939SAndy Fiddaman 			n = ip - proto->tp;
2122*b30d1939SAndy Fiddaman 			ip -= n;
2123*b30d1939SAndy Fiddaman 			op -= n;
2124*b30d1939SAndy Fiddaman #else
2125*b30d1939SAndy Fiddaman 			ip = bp;
2126*b30d1939SAndy Fiddaman 			op = proto->op;
2127*b30d1939SAndy Fiddaman #endif
2128*b30d1939SAndy Fiddaman 		}
2129*b30d1939SAndy Fiddaman 		else
2130*b30d1939SAndy Fiddaman 			while (*ip != '\n')
2131*b30d1939SAndy Fiddaman 				*op++ = *ip++;
2132*b30d1939SAndy Fiddaman 		op = init(proto, op, flags);
2133*b30d1939SAndy Fiddaman 		op = linesync(proto, op, proto->line);
2134*b30d1939SAndy Fiddaman 		flags &= ~(INIT_DEFINE|INIT_INCLUDE);
2135*b30d1939SAndy Fiddaman 		proto->flags &= ~(INIT_DEFINE|INIT_INCLUDE);
2136*b30d1939SAndy Fiddaman 		goto fsm_start;
2137*b30d1939SAndy Fiddaman 	}
2138*b30d1939SAndy Fiddaman 	SYNC();
2139*b30d1939SAndy Fiddaman 	return c;
2140*b30d1939SAndy Fiddaman }
2141*b30d1939SAndy Fiddaman 
2142*b30d1939SAndy Fiddaman /*
2143*b30d1939SAndy Fiddaman  * close a proto buffer stream
2144*b30d1939SAndy Fiddaman  */
2145*b30d1939SAndy Fiddaman 
2146*b30d1939SAndy Fiddaman void
pppclose(char * iob)2147*b30d1939SAndy Fiddaman pppclose(char* iob)
2148*b30d1939SAndy Fiddaman {
2149*b30d1939SAndy Fiddaman 	register Proto_t*	proto = (Proto_t*)(iob - sizeof(Proto_t));
2150*b30d1939SAndy Fiddaman 
2151*b30d1939SAndy Fiddaman 	if (proto->flags & MORE) close(proto->fd);
2152*b30d1939SAndy Fiddaman 	free((char*)proto); /* some ANSI cc's botch the free() prototype */
2153*b30d1939SAndy Fiddaman }
2154*b30d1939SAndy Fiddaman 
2155*b30d1939SAndy Fiddaman /*
2156*b30d1939SAndy Fiddaman  * open a new proto buffer stream
2157*b30d1939SAndy Fiddaman  * read buffer pointer returned
2158*b30d1939SAndy Fiddaman  * 0 returned on error or if no magic
2159*b30d1939SAndy Fiddaman  *
2160*b30d1939SAndy Fiddaman  *	file	!=0	file path to open, otherwise use fd
2161*b30d1939SAndy Fiddaman  *	fd		open file fd if file==0
2162*b30d1939SAndy Fiddaman  *	notice	!=0	copyright notice info commented at the top
2163*b30d1939SAndy Fiddaman  *	options	!=0	additional notice name=value pairs, space or ; separated
2164*b30d1939SAndy Fiddaman  *	package	!=0	generate header for this package
2165*b30d1939SAndy Fiddaman  */
2166*b30d1939SAndy Fiddaman 
2167*b30d1939SAndy Fiddaman char*
pppopen(char * file,int fd,char * notice,char * options,char * package,char * comment,int flags)2168*b30d1939SAndy Fiddaman pppopen(char* file, int fd, char* notice, char* options, char* package, char* comment, int flags)
2169*b30d1939SAndy Fiddaman {
2170*b30d1939SAndy Fiddaman 	register Proto_t*	proto;
2171*b30d1939SAndy Fiddaman 	register char*		iob;
2172*b30d1939SAndy Fiddaman 	register long		n;
2173*b30d1939SAndy Fiddaman 	register char*		s;
2174*b30d1939SAndy Fiddaman 	char*			t;
2175*b30d1939SAndy Fiddaman 	int			pragma;
2176*b30d1939SAndy Fiddaman 	int			clr;
2177*b30d1939SAndy Fiddaman 	int			hit;
2178*b30d1939SAndy Fiddaman 	int			i;
2179*b30d1939SAndy Fiddaman 	int			z;
2180*b30d1939SAndy Fiddaman 	char*			b;
2181*b30d1939SAndy Fiddaman #if PROTOMAIN
2182*b30d1939SAndy Fiddaman 	int			comlen;
2183*b30d1939SAndy Fiddaman 	char			com[80];
2184*b30d1939SAndy Fiddaman #endif
2185*b30d1939SAndy Fiddaman 	int			m = 0;
2186*b30d1939SAndy Fiddaman 
2187*b30d1939SAndy Fiddaman 	static int		retain;
2188*b30d1939SAndy Fiddaman 
2189*b30d1939SAndy Fiddaman 	/*
2190*b30d1939SAndy Fiddaman 	 * initialize proto
2191*b30d1939SAndy Fiddaman 	 */
2192*b30d1939SAndy Fiddaman 
2193*b30d1939SAndy Fiddaman #if PROTOMAIN
2194*b30d1939SAndy Fiddaman 	if (flags & PROTO_CLASSIC) flags &= ~PROTO_INCLUDE;
2195*b30d1939SAndy Fiddaman #endif
2196*b30d1939SAndy Fiddaman 	if (flags & PROTO_RETAIN) flags &= ~retain;
2197*b30d1939SAndy Fiddaman 	else retain &= PROTO_INITIALIZED;
2198*b30d1939SAndy Fiddaman 	if (file && (fd = open(file, O_RDONLY)) < 0) return 0;
2199*b30d1939SAndy Fiddaman #if !PROTOMAIN
2200*b30d1939SAndy Fiddaman 	if ((n = lseek(fd, 0L, 2)) > 0)
2201*b30d1939SAndy Fiddaman 	{
2202*b30d1939SAndy Fiddaman 		if (lseek(fd, 0L, 0)) return 0;
2203*b30d1939SAndy Fiddaman 		if (n < CHUNK) n = CHUNK;
2204*b30d1939SAndy Fiddaman 		else if (n > 2 * BLOCK) n = 0;
2205*b30d1939SAndy Fiddaman 		m = 1;
2206*b30d1939SAndy Fiddaman 	}
2207*b30d1939SAndy Fiddaman 	if (n > 0)
2208*b30d1939SAndy Fiddaman 	{
2209*b30d1939SAndy Fiddaman 		/*
2210*b30d1939SAndy Fiddaman 		 * file read in one chunk
2211*b30d1939SAndy Fiddaman 		 */
2212*b30d1939SAndy Fiddaman 
2213*b30d1939SAndy Fiddaman 		if (!(proto = newof(0, Proto_t, 1, 4 * n + 2)))
2214*b30d1939SAndy Fiddaman 			return 0;
2215*b30d1939SAndy Fiddaman 		proto->iz = n;
2216*b30d1939SAndy Fiddaman 		proto->oz = 3 * n;
2217*b30d1939SAndy Fiddaman 		n = 0;
2218*b30d1939SAndy Fiddaman 	}
2219*b30d1939SAndy Fiddaman 	else
2220*b30d1939SAndy Fiddaman #endif
2221*b30d1939SAndy Fiddaman 	{
2222*b30d1939SAndy Fiddaman 		/*
2223*b30d1939SAndy Fiddaman 		 * file read in BLOCK chunks
2224*b30d1939SAndy Fiddaman 		 */
2225*b30d1939SAndy Fiddaman 
2226*b30d1939SAndy Fiddaman 		n = BLOCK;
2227*b30d1939SAndy Fiddaman 		if (!(proto = newof(0, Proto_t, 1, 5 * n + 2)))
2228*b30d1939SAndy Fiddaman 			return 0;
2229*b30d1939SAndy Fiddaman 		proto->iz = n;
2230*b30d1939SAndy Fiddaman 		proto->oz = 3 * n;
2231*b30d1939SAndy Fiddaman 		proto->flags |= MORE;
2232*b30d1939SAndy Fiddaman 	}
2233*b30d1939SAndy Fiddaman 	proto->fd = fd;
2234*b30d1939SAndy Fiddaman 	proto->package = package;
2235*b30d1939SAndy Fiddaman 	iob = (char*)proto + sizeof(Proto_t);
2236*b30d1939SAndy Fiddaman 	proto->op = proto->ob = iob;
2237*b30d1939SAndy Fiddaman 	proto->ip = proto->ib = iob + proto->oz + n;
2238*b30d1939SAndy Fiddaman 	if (m) proto->options |= REGULAR;
2239*b30d1939SAndy Fiddaman 	if (!comment)
2240*b30d1939SAndy Fiddaman 		comment = "/*";
2241*b30d1939SAndy Fiddaman 	if (!(proto->cc[0] = comment[0]))
2242*b30d1939SAndy Fiddaman 		notice = options = 0;
2243*b30d1939SAndy Fiddaman 	else if (comment[1])
2244*b30d1939SAndy Fiddaman 	{
2245*b30d1939SAndy Fiddaman 		proto->cc[1] = comment[1];
2246*b30d1939SAndy Fiddaman 		proto->cc[2] = comment[2] ? comment[2] : comment[0];
2247*b30d1939SAndy Fiddaman 	}
2248*b30d1939SAndy Fiddaman 	else
2249*b30d1939SAndy Fiddaman 		proto->cc[1] = proto->cc[2] = comment[0];
2250*b30d1939SAndy Fiddaman 
2251*b30d1939SAndy Fiddaman 	/*
2252*b30d1939SAndy Fiddaman 	 * read the first chunk
2253*b30d1939SAndy Fiddaman 	 */
2254*b30d1939SAndy Fiddaman 
2255*b30d1939SAndy Fiddaman 	n = read(fd, proto->ip, proto->iz);
2256*b30d1939SAndy Fiddaman 	if (!(proto->flags & MORE))
2257*b30d1939SAndy Fiddaman 		close(fd);
2258*b30d1939SAndy Fiddaman 	if (n < 0)
2259*b30d1939SAndy Fiddaman 	{
2260*b30d1939SAndy Fiddaman 		pppclose(iob);
2261*b30d1939SAndy Fiddaman 		return 0;
2262*b30d1939SAndy Fiddaman 	}
2263*b30d1939SAndy Fiddaman 	*(proto->ip + n) = 0;
2264*b30d1939SAndy Fiddaman 
2265*b30d1939SAndy Fiddaman 	/*
2266*b30d1939SAndy Fiddaman 	 * check for proto pragma in first block of lines
2267*b30d1939SAndy Fiddaman 	 * pragma blanked out if found
2268*b30d1939SAndy Fiddaman 	 *
2269*b30d1939SAndy Fiddaman 	 *	-1	no pragma
2270*b30d1939SAndy Fiddaman 	 *	 0	#pragma noprototyped
2271*b30d1939SAndy Fiddaman 	 *	 1	#pragma prototyped
2272*b30d1939SAndy Fiddaman 	 *
2273*b30d1939SAndy Fiddaman 	 * NOTE: matches may occur inside comments and quotes
2274*b30d1939SAndy Fiddaman 	 */
2275*b30d1939SAndy Fiddaman 
2276*b30d1939SAndy Fiddaman #if PROTOMAIN
2277*b30d1939SAndy Fiddaman 	if (!notice && !options || (comlen = astlicense(com, sizeof(com), NiL, "type=check", proto->cc[0], proto->cc[1], proto->cc[2])) <= 0)
2278*b30d1939SAndy Fiddaman 		*com = 0;
2279*b30d1939SAndy Fiddaman #endif
2280*b30d1939SAndy Fiddaman 	hit = (notice || options) ? 0 : HIT_noticed;
2281*b30d1939SAndy Fiddaman 	pragma = -1;
2282*b30d1939SAndy Fiddaman 	s = proto->ip;
2283*b30d1939SAndy Fiddaman 	m = MAGICTOP;
2284*b30d1939SAndy Fiddaman 	while (m-- > 0 && *s && hit != (HIT_prototyped|HIT_noticed))
2285*b30d1939SAndy Fiddaman 	{
2286*b30d1939SAndy Fiddaman 		while (*s == ' ' || *s == '\t')
2287*b30d1939SAndy Fiddaman 			s++;
2288*b30d1939SAndy Fiddaman 		if (*s == '#')
2289*b30d1939SAndy Fiddaman 		{
2290*b30d1939SAndy Fiddaman 			b = s++;
2291*b30d1939SAndy Fiddaman 			while (*s == ' ' || *s == '\t')
2292*b30d1939SAndy Fiddaman 				s++;
2293*b30d1939SAndy Fiddaman 			if (*s == *PRAGMADIR && !strncmp(s, PRAGMADIR, sizeof(PRAGMADIR) - 1) && (*(s += sizeof(PRAGMADIR) - 1) == ' ' || *s == '\t'))
2294*b30d1939SAndy Fiddaman 			{
2295*b30d1939SAndy Fiddaman 				clr = 0;
2296*b30d1939SAndy Fiddaman 				while (*s && *s != '\r' && *s != '\n')
2297*b30d1939SAndy Fiddaman 				{
2298*b30d1939SAndy Fiddaman 					for (; *s == ' ' || *s == '\t'; s++);
2299*b30d1939SAndy Fiddaman 					for (t = s; *s && *s != ' ' && *s != '\t' && *s != '\r' && *s != '\n'; s++);
2300*b30d1939SAndy Fiddaman 					z = s - t;
2301*b30d1939SAndy Fiddaman 					for (i = 0; i < elementsof(pragmas); i++)
2302*b30d1939SAndy Fiddaman 						if (pragmas[i].size == z && !strncmp(t, pragmas[i].name, z))
2303*b30d1939SAndy Fiddaman 						{
2304*b30d1939SAndy Fiddaman 							clr = 1;
2305*b30d1939SAndy Fiddaman 							hit |= pragmas[i].hit;
2306*b30d1939SAndy Fiddaman 							switch (pragmas[i].hit)
2307*b30d1939SAndy Fiddaman 							{
2308*b30d1939SAndy Fiddaman 							case HIT_noticed:
2309*b30d1939SAndy Fiddaman 								notice = options = 0;
2310*b30d1939SAndy Fiddaman 								break;
2311*b30d1939SAndy Fiddaman 							case HIT_prototyped:
2312*b30d1939SAndy Fiddaman 								pragma = pragmas[i].val;
2313*b30d1939SAndy Fiddaman 								break;
2314*b30d1939SAndy Fiddaman 							}
2315*b30d1939SAndy Fiddaman 						}
2316*b30d1939SAndy Fiddaman 				}
2317*b30d1939SAndy Fiddaman 				if (clr)
2318*b30d1939SAndy Fiddaman 				{
2319*b30d1939SAndy Fiddaman #if PROTOMAIN
2320*b30d1939SAndy Fiddaman 					if (!(flags & PROTO_DISABLE) || (flags & PROTO_NOPRAGMA))
2321*b30d1939SAndy Fiddaman #endif
2322*b30d1939SAndy Fiddaman 					for (; b < s; *b++ = ' ');
2323*b30d1939SAndy Fiddaman 				}
2324*b30d1939SAndy Fiddaman 			}
2325*b30d1939SAndy Fiddaman 		}
2326*b30d1939SAndy Fiddaman 		else if (*s == *GENERATED && !strncmp(s, GENERATED, sizeof(GENERATED) - 1))
2327*b30d1939SAndy Fiddaman 		{
2328*b30d1939SAndy Fiddaman 			pragma = 0;
2329*b30d1939SAndy Fiddaman 			break;
2330*b30d1939SAndy Fiddaman 		}
2331*b30d1939SAndy Fiddaman #if PROTOMAIN
2332*b30d1939SAndy Fiddaman 		else if (*s == '%' && *(s + 1) == '{')
2333*b30d1939SAndy Fiddaman 			proto->flags |= YACC;
2334*b30d1939SAndy Fiddaman 		else if (!(hit & HIT_noticed))
2335*b30d1939SAndy Fiddaman 		{
2336*b30d1939SAndy Fiddaman 			if (*s == *com && !strncmp(s, com, comlen))
2337*b30d1939SAndy Fiddaman 			{
2338*b30d1939SAndy Fiddaman 				hit |= HIT_noticed;
2339*b30d1939SAndy Fiddaman 				notice = options = 0;
2340*b30d1939SAndy Fiddaman 			}
2341*b30d1939SAndy Fiddaman 			else
2342*b30d1939SAndy Fiddaman 				for (; *s && *s != '\n' && !(hit & HIT_noticed); s++)
2343*b30d1939SAndy Fiddaman 					for (i = 0; i < elementsof(notices); i++)
2344*b30d1939SAndy Fiddaman 						if (*s == notices[i].name[0] && !strncmp(s, notices[i].name, notices[i].size))
2345*b30d1939SAndy Fiddaman 						{
2346*b30d1939SAndy Fiddaman 							s += notices[i].size;
2347*b30d1939SAndy Fiddaman 							if (notices[i].val)
2348*b30d1939SAndy Fiddaman 							{
2349*b30d1939SAndy Fiddaman 								while (*s == ' ' || *s == '\t')
2350*b30d1939SAndy Fiddaman 									s++;
2351*b30d1939SAndy Fiddaman 								if (*s == '(' && (*(s + 1) == 'c' || *(s + 1) == 'C') && *(s + 2) == ')' || *s >= '0' && *s <= '9' && *(s + 1) >= '0' && *(s + 1) <= '9')
2352*b30d1939SAndy Fiddaman 								{
2353*b30d1939SAndy Fiddaman 									hit |= notices[i].hit;
2354*b30d1939SAndy Fiddaman 									notice = options = 0;
2355*b30d1939SAndy Fiddaman 								}
2356*b30d1939SAndy Fiddaman 							}
2357*b30d1939SAndy Fiddaman 							else
2358*b30d1939SAndy Fiddaman 							{
2359*b30d1939SAndy Fiddaman 								hit |= notices[i].hit;
2360*b30d1939SAndy Fiddaman 								notice = options = 0;
2361*b30d1939SAndy Fiddaman 							}
2362*b30d1939SAndy Fiddaman 							break;
2363*b30d1939SAndy Fiddaman 						}
2364*b30d1939SAndy Fiddaman 		}
2365*b30d1939SAndy Fiddaman #endif
2366*b30d1939SAndy Fiddaman 		while (*s && *s++ != '\n');
2367*b30d1939SAndy Fiddaman 	}
2368*b30d1939SAndy Fiddaman 	if (flags & PROTO_PLUSPLUS) proto->flags |= PLUSPLUS;
2369*b30d1939SAndy Fiddaman 	if (flags & PROTO_TEST) proto->test = 1;
2370*b30d1939SAndy Fiddaman 	if (flags & PROTO_EXTERNALIZE) proto->options |= EXTERNALIZE;
2371*b30d1939SAndy Fiddaman #if PROTOMAIN
2372*b30d1939SAndy Fiddaman 	if (flags & PROTO_CLASSIC) pragma = -pragma;
2373*b30d1939SAndy Fiddaman 	if (flags & PROTO_DISABLE) pragma = 0;
2374*b30d1939SAndy Fiddaman 	if (flags & PROTO_LINESYNC) proto->flags |= LINESYNC;
2375*b30d1939SAndy Fiddaman 	if (!(proto->flags & YACC) && file && (m = strlen(file)) > 2 && file[--m] == 'y' && file[--m] == '.')
2376*b30d1939SAndy Fiddaman 		proto->flags |= YACC;
2377*b30d1939SAndy Fiddaman #endif
2378*b30d1939SAndy Fiddaman 	if (pragma <= 0)
2379*b30d1939SAndy Fiddaman 	{
2380*b30d1939SAndy Fiddaman 		if (flags & PROTO_PLUSPLUS)
2381*b30d1939SAndy Fiddaman 		{
2382*b30d1939SAndy Fiddaman 			flags &= ~(PROTO_HEADER|PROTO_INCLUDE);
2383*b30d1939SAndy Fiddaman 			proto->flags |= PLUSONLY;
2384*b30d1939SAndy Fiddaman 		}
2385*b30d1939SAndy Fiddaman 		else if (!(flags & (PROTO_FORCE|PROTO_PASS)))
2386*b30d1939SAndy Fiddaman 		{
2387*b30d1939SAndy Fiddaman 			pppclose(iob);
2388*b30d1939SAndy Fiddaman 			return 0;
2389*b30d1939SAndy Fiddaman 		}
2390*b30d1939SAndy Fiddaman 		else if ((flags & (PROTO_FORCE|PROTO_PASS)) == PROTO_PASS || !pragma)
2391*b30d1939SAndy Fiddaman 		{
2392*b30d1939SAndy Fiddaman 			proto->flags |= PASS;
2393*b30d1939SAndy Fiddaman 			if (proto->flags & MORE)
2394*b30d1939SAndy Fiddaman 				proto->oz += proto->iz;
2395*b30d1939SAndy Fiddaman 			proto->iz = n;
2396*b30d1939SAndy Fiddaman 			if (notice || options)
2397*b30d1939SAndy Fiddaman 			{
2398*b30d1939SAndy Fiddaman 				if (proto->cc[0] == '#' && proto->ip[0] == '#' && proto->ip[1] == '!')
2399*b30d1939SAndy Fiddaman 				{
2400*b30d1939SAndy Fiddaman 					s = proto->ip;
2401*b30d1939SAndy Fiddaman 					while (*s && *s++ != '\n');
2402*b30d1939SAndy Fiddaman 					m = s - proto->ip;
2403*b30d1939SAndy Fiddaman 					proto->op = memcopy(proto->op, proto->ip, m);
2404*b30d1939SAndy Fiddaman 					proto->ip = s;
2405*b30d1939SAndy Fiddaman 					proto->iz = n -= m;
2406*b30d1939SAndy Fiddaman 				}
2407*b30d1939SAndy Fiddaman #if PROTOMAIN
2408*b30d1939SAndy Fiddaman 				if (proto->cc[0])
2409*b30d1939SAndy Fiddaman 				{
2410*b30d1939SAndy Fiddaman 					if ((comlen = astlicense(proto->op, proto->oz, notice, options, proto->cc[0], proto->cc[1], proto->cc[2])) < 0)
2411*b30d1939SAndy Fiddaman 						proto_error((char*)proto + sizeof(Proto_t), 1, proto->op, NiL);
2412*b30d1939SAndy Fiddaman 					else
2413*b30d1939SAndy Fiddaman 						proto->op += comlen;
2414*b30d1939SAndy Fiddaman 				}
2415*b30d1939SAndy Fiddaman 				if (!(flags & PROTO_CLASSIC) && !(proto->flags & YACC))
2416*b30d1939SAndy Fiddaman #endif
2417*b30d1939SAndy Fiddaman 				proto->op = linesync(proto, proto->op, 1);
2418*b30d1939SAndy Fiddaman 				proto->iz += proto->op - proto->ob;
2419*b30d1939SAndy Fiddaman 			}
2420*b30d1939SAndy Fiddaman 			memcopy(proto->op, proto->ip, n);
2421*b30d1939SAndy Fiddaman 			return iob;
2422*b30d1939SAndy Fiddaman 		}
2423*b30d1939SAndy Fiddaman 	}
2424*b30d1939SAndy Fiddaman #if PROTOMAIN
2425*b30d1939SAndy Fiddaman 	if (!(retain & PROTO_INITIALIZED))
2426*b30d1939SAndy Fiddaman 	{
2427*b30d1939SAndy Fiddaman 		retain |= PROTO_INITIALIZED;
2428*b30d1939SAndy Fiddaman 		ppfsm(FSM_INIT, NiL);
2429*b30d1939SAndy Fiddaman 	}
2430*b30d1939SAndy Fiddaman #endif
2431*b30d1939SAndy Fiddaman 	proto->line = 1;
2432*b30d1939SAndy Fiddaman #if CHUNK >= 512
2433*b30d1939SAndy Fiddaman 	if (notice || options || (flags & (PROTO_HEADER|PROTO_INCLUDE)))
2434*b30d1939SAndy Fiddaman 	{
2435*b30d1939SAndy Fiddaman #if PROTOMAIN
2436*b30d1939SAndy Fiddaman 		if (notice || options)
2437*b30d1939SAndy Fiddaman 		{
2438*b30d1939SAndy Fiddaman 			if ((comlen = astlicense(proto->op, proto->oz, notice, options, proto->cc[0], proto->cc[1], proto->cc[2])) < 0)
2439*b30d1939SAndy Fiddaman 				proto_error((char*)proto + sizeof(Proto_t), 1, proto->op, NiL);
2440*b30d1939SAndy Fiddaman 			else
2441*b30d1939SAndy Fiddaman 				proto->op += comlen;
2442*b30d1939SAndy Fiddaman 		}
2443*b30d1939SAndy Fiddaman #endif
2444*b30d1939SAndy Fiddaman 		if (flags & PROTO_INCLUDE)
2445*b30d1939SAndy Fiddaman 		{
2446*b30d1939SAndy Fiddaman 			proto->flags |= INIT_INCLUDE;
2447*b30d1939SAndy Fiddaman 			if (flags & PROTO_RETAIN)
2448*b30d1939SAndy Fiddaman 				retain |= PROTO_INCLUDE;
2449*b30d1939SAndy Fiddaman 		}
2450*b30d1939SAndy Fiddaman 		else if (flags & PROTO_HEADER)
2451*b30d1939SAndy Fiddaman 		{
2452*b30d1939SAndy Fiddaman 			if (flags & PROTO_RETAIN) retain |= PROTO_HEADER;
2453*b30d1939SAndy Fiddaman #if PROTOMAIN
2454*b30d1939SAndy Fiddaman 			if (flags & PROTO_CLASSIC)
2455*b30d1939SAndy Fiddaman 			{
2456*b30d1939SAndy Fiddaman 				*proto->op++ = '#';
2457*b30d1939SAndy Fiddaman 				proto->op = strcopy(proto->op, PRAGMADIR);
2458*b30d1939SAndy Fiddaman 				*proto->op++ = ' ';
2459*b30d1939SAndy Fiddaman 				proto->op = strcopy(proto->op, pragmas[0].name);
2460*b30d1939SAndy Fiddaman 				*proto->op++ = '\n';
2461*b30d1939SAndy Fiddaman 			}
2462*b30d1939SAndy Fiddaman 			else
2463*b30d1939SAndy Fiddaman #endif
2464*b30d1939SAndy Fiddaman 			proto->flags |= INIT_DEFINE;
2465*b30d1939SAndy Fiddaman 		}
2466*b30d1939SAndy Fiddaman #if PROTOMAIN
2467*b30d1939SAndy Fiddaman 		if (!(flags & PROTO_CLASSIC))
2468*b30d1939SAndy Fiddaman 		{
2469*b30d1939SAndy Fiddaman 			if (proto->flags & YACC)
2470*b30d1939SAndy Fiddaman 			{
2471*b30d1939SAndy Fiddaman 				proto->op = strcopy(proto->op, "\n%{\n" + !notice);
2472*b30d1939SAndy Fiddaman 				proto->op = strcopy(proto->op, GENERATED);
2473*b30d1939SAndy Fiddaman 				proto->op = strcopy(proto->op, "%}\n");
2474*b30d1939SAndy Fiddaman 			}
2475*b30d1939SAndy Fiddaman 			else
2476*b30d1939SAndy Fiddaman 			{
2477*b30d1939SAndy Fiddaman 				if (n || notice || options)
2478*b30d1939SAndy Fiddaman 					*proto->op++ = '\n';
2479*b30d1939SAndy Fiddaman 				proto->op = strcopy(proto->op, GENERATED);
2480*b30d1939SAndy Fiddaman 				if (n)
2481*b30d1939SAndy Fiddaman 					proto->op = linesync(proto, proto->op, proto->line);
2482*b30d1939SAndy Fiddaman 				else if (proto->flags & (INIT_DEFINE|INIT_INCLUDE))
2483*b30d1939SAndy Fiddaman 					proto->op = init(proto, proto->op, proto->flags);
2484*b30d1939SAndy Fiddaman 			}
2485*b30d1939SAndy Fiddaman 		}
2486*b30d1939SAndy Fiddaman #endif
2487*b30d1939SAndy Fiddaman 	}
2488*b30d1939SAndy Fiddaman #endif
2489*b30d1939SAndy Fiddaman #if PROTOMAIN
2490*b30d1939SAndy Fiddaman 	proto->file = file;
2491*b30d1939SAndy Fiddaman 	if (flags & PROTO_CLASSIC)
2492*b30d1939SAndy Fiddaman 	{
2493*b30d1939SAndy Fiddaman 		proto->flags |= CLASSIC;
2494*b30d1939SAndy Fiddaman 		if (!(flags & PROTO_HEADER)) proto->flags |= EXTERN;
2495*b30d1939SAndy Fiddaman 	}
2496*b30d1939SAndy Fiddaman #endif
2497*b30d1939SAndy Fiddaman 	return iob;
2498*b30d1939SAndy Fiddaman }
2499*b30d1939SAndy Fiddaman 
2500*b30d1939SAndy Fiddaman /*
2501*b30d1939SAndy Fiddaman  * read next proto'd chunk into iob
2502*b30d1939SAndy Fiddaman  * the chunk is 0 terminated and its size is returned
2503*b30d1939SAndy Fiddaman  */
2504*b30d1939SAndy Fiddaman 
2505*b30d1939SAndy Fiddaman int
pppread(char * iob)2506*b30d1939SAndy Fiddaman pppread(char* iob)
2507*b30d1939SAndy Fiddaman {
2508*b30d1939SAndy Fiddaman 	register Proto_t*	proto = (Proto_t*)(iob - sizeof(Proto_t));
2509*b30d1939SAndy Fiddaman 	register int		n;
2510*b30d1939SAndy Fiddaman 
2511*b30d1939SAndy Fiddaman 	if (proto->flags & PASS)
2512*b30d1939SAndy Fiddaman 	{
2513*b30d1939SAndy Fiddaman 		if (proto->iz)
2514*b30d1939SAndy Fiddaman 		{
2515*b30d1939SAndy Fiddaman 			n = proto->iz;
2516*b30d1939SAndy Fiddaman 			proto->iz = 0;
2517*b30d1939SAndy Fiddaman 		}
2518*b30d1939SAndy Fiddaman 		else if (!(proto->flags & MORE)) n = 0;
2519*b30d1939SAndy Fiddaman 		else if ((n = read(proto->fd, proto->ob, proto->oz)) <= 0 || (proto->options & REGULAR) && n < proto->oz)
2520*b30d1939SAndy Fiddaman 		{
2521*b30d1939SAndy Fiddaman 			proto->flags &= ~MORE;
2522*b30d1939SAndy Fiddaman 			close(proto->fd);
2523*b30d1939SAndy Fiddaman 		}
2524*b30d1939SAndy Fiddaman 	}
2525*b30d1939SAndy Fiddaman 	else
2526*b30d1939SAndy Fiddaman 	{
2527*b30d1939SAndy Fiddaman 		if (proto->op == proto->ob)
2528*b30d1939SAndy Fiddaman 		{
2529*b30d1939SAndy Fiddaman 			if (proto->flags & ERROR) return -1;
2530*b30d1939SAndy Fiddaman #if PROTOMAIN
2531*b30d1939SAndy Fiddaman 			if (proto->flags & YACC)
2532*b30d1939SAndy Fiddaman 			{
2533*b30d1939SAndy Fiddaman 				register char*	ip = proto->ip;
2534*b30d1939SAndy Fiddaman 				register char*	op = proto->ob;
2535*b30d1939SAndy Fiddaman 				register char*	ep = proto->ob + proto->oz - 2;
2536*b30d1939SAndy Fiddaman 
2537*b30d1939SAndy Fiddaman 				if (!*ip)
2538*b30d1939SAndy Fiddaman 				{
2539*b30d1939SAndy Fiddaman 					ip = proto->ip = proto->ib;
2540*b30d1939SAndy Fiddaman 					if (!(proto->flags & MORE)) n = 0;
2541*b30d1939SAndy Fiddaman 					else if ((n = read(proto->fd, ip, proto->iz)) <= 0 || (proto->options & REGULAR) && n < proto->iz)
2542*b30d1939SAndy Fiddaman 					{
2543*b30d1939SAndy Fiddaman 						if (n < 0) n = 0;
2544*b30d1939SAndy Fiddaman 						proto->flags &= ~MORE;
2545*b30d1939SAndy Fiddaman 						close(proto->fd);
2546*b30d1939SAndy Fiddaman 					}
2547*b30d1939SAndy Fiddaman 					ip[n] = 0;
2548*b30d1939SAndy Fiddaman 				}
2549*b30d1939SAndy Fiddaman 				if (proto->flags & YACCSPLIT)
2550*b30d1939SAndy Fiddaman 				{
2551*b30d1939SAndy Fiddaman 					proto->flags &= ~YACCSPLIT;
2552*b30d1939SAndy Fiddaman 					if (*ip == '%')
2553*b30d1939SAndy Fiddaman 					{
2554*b30d1939SAndy Fiddaman 						*op++ = *ip++;
2555*b30d1939SAndy Fiddaman 						if (proto->flags & YACC2) proto->flags &= ~YACC;
2556*b30d1939SAndy Fiddaman 						else proto->flags |= YACC2;
2557*b30d1939SAndy Fiddaman 					}
2558*b30d1939SAndy Fiddaman 				}
2559*b30d1939SAndy Fiddaman 				if (proto->flags & YACC)
2560*b30d1939SAndy Fiddaman 					while (op < ep && (n = *op++ = *ip))
2561*b30d1939SAndy Fiddaman 					{
2562*b30d1939SAndy Fiddaman 						ip++;
2563*b30d1939SAndy Fiddaman 						if (n == '%')
2564*b30d1939SAndy Fiddaman 						{
2565*b30d1939SAndy Fiddaman 							if (*ip == '%' && (ip == proto->ip + 1 || *(ip - 2) == '\n'))
2566*b30d1939SAndy Fiddaman 							{
2567*b30d1939SAndy Fiddaman 								*op++ = *ip++;
2568*b30d1939SAndy Fiddaman 								if (proto->flags & YACC2) proto->flags &= ~YACC;
2569*b30d1939SAndy Fiddaman 								else proto->flags |= YACC2;
2570*b30d1939SAndy Fiddaman 								break;
2571*b30d1939SAndy Fiddaman 							}
2572*b30d1939SAndy Fiddaman 							if (!*ip)
2573*b30d1939SAndy Fiddaman 							{
2574*b30d1939SAndy Fiddaman 								*op++ = '%';
2575*b30d1939SAndy Fiddaman 								proto->flags |= YACCSPLIT;
2576*b30d1939SAndy Fiddaman 								break;
2577*b30d1939SAndy Fiddaman 							}
2578*b30d1939SAndy Fiddaman 						}
2579*b30d1939SAndy Fiddaman 						else if (n == '\n') proto->line++;
2580*b30d1939SAndy Fiddaman 					}
2581*b30d1939SAndy Fiddaman 				proto->op = memcopy(proto->ob, proto->ip, ip - proto->ip);
2582*b30d1939SAndy Fiddaman 				proto->ip = ip;
2583*b30d1939SAndy Fiddaman 			}
2584*b30d1939SAndy Fiddaman 			else
2585*b30d1939SAndy Fiddaman #endif
2586*b30d1939SAndy Fiddaman 			lex(proto, proto->flags);
2587*b30d1939SAndy Fiddaman 			if ((proto->flags & (ERROR|MORE)) == ERROR)
2588*b30d1939SAndy Fiddaman 				proto->op = strcopy(proto->op, "/* NOTE: some constructs may not have been converted */\n");
2589*b30d1939SAndy Fiddaman 		}
2590*b30d1939SAndy Fiddaman 		n = proto->op - proto->ob;
2591*b30d1939SAndy Fiddaman 		proto->op = proto->ob;
2592*b30d1939SAndy Fiddaman 	}
2593*b30d1939SAndy Fiddaman 	return n;
2594*b30d1939SAndy Fiddaman }
2595*b30d1939SAndy Fiddaman 
2596*b30d1939SAndy Fiddaman #if !PROTOMAIN
2597*b30d1939SAndy Fiddaman 
2598*b30d1939SAndy Fiddaman /*
2599*b30d1939SAndy Fiddaman  * drop control of iob after first pppread()
2600*b30d1939SAndy Fiddaman  * return value is input fd
2601*b30d1939SAndy Fiddaman  * if fd<0 then all data in iob
2602*b30d1939SAndy Fiddaman  */
2603*b30d1939SAndy Fiddaman 
2604*b30d1939SAndy Fiddaman int
pppdrop(char * iob)2605*b30d1939SAndy Fiddaman pppdrop(char* iob)
2606*b30d1939SAndy Fiddaman {
2607*b30d1939SAndy Fiddaman 	register Proto_t*	proto = (Proto_t*)(iob - sizeof(Proto_t));
2608*b30d1939SAndy Fiddaman 
2609*b30d1939SAndy Fiddaman 	if (proto->flags & MORE)
2610*b30d1939SAndy Fiddaman 	{
2611*b30d1939SAndy Fiddaman 		proto->flags &= ~MORE;
2612*b30d1939SAndy Fiddaman 		return proto->fd;
2613*b30d1939SAndy Fiddaman 	}
2614*b30d1939SAndy Fiddaman 	return -1;
2615*b30d1939SAndy Fiddaman }
2616*b30d1939SAndy Fiddaman 
2617*b30d1939SAndy Fiddaman #endif
2618