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