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