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