14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*10898Sroland.mainz@nrubsig.org * Copyright (c) 1986-2009 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * *
194887Schin ***********************************************************************/
204887Schin #pragma prototyped
214887Schin /*
224887Schin * Glenn Fowler
234887Schin * AT&T Research
244887Schin *
254887Schin * convert C prototypes to ANSI, K&R and C++ styles or K&R to ANSI
264887Schin * slips into the pp block read
274887Schin *
284887Schin * define PROTOMAIN for standalone proto
294887Schin * PROTOMAIN is coded for minimal library support
304887Schin */
314887Schin
328462SApril.Chin@Sun.COM static const char id[] = "\n@(#)$Id: proto (AT&T Research) 2008-05-11 $\0\n";
334887Schin
344887Schin #if PROTOMAIN
354887Schin
364887Schin #include "ppfsm.c"
374887Schin
384887Schin #include <hashkey.h>
394887Schin
404887Schin #if PROTO_STANDALONE
414887Schin #undef O_RDONLY
424887Schin #endif
434887Schin
444887Schin #else
454887Schin
464887Schin #include "pplib.h"
474887Schin #include "ppfsm.h"
484887Schin
494887Schin #endif
504887Schin
514887Schin #define MAGICGEN "/* : : generated by proto : : */\n"
524887Schin
534887Schin #define MAGICDIR "pragma" /* proto magic directive */
544887Schin #define MAGICARG "prototyped" /* proto magic directive arg */
554887Schin #define MAGICOFF "noticed" /* no notice if found in pragma */
564887Schin #define MAGICTOP 64 /* must be in these top lines */
574887Schin #define NOTICED "Copyright" /* no notice if found in magic */
588462SApril.Chin@Sun.COM #define PUBLICDOMAIN "Public Domain" /* no notice if found in magic */
594887Schin
604887Schin struct proto /* proto buffer state */
614887Schin {
624887Schin int brace; /* {..} level */
634887Schin int call; /* call level */
644887Schin int fd; /* input file descriptor */
654887Schin char* file; /* input file name */
664887Schin long flags; /* coupled flags */
674887Schin long options; /* uncoupled flags */
684887Schin char* package; /* header package */
694887Schin int line; /* input line count */
704887Schin int test; /* testing */
714887Schin
724887Schin char* tp; /* input token base */
734887Schin
744887Schin int iz; /* input buffer size */
754887Schin char* ib; /* input buffer base */
764887Schin char* ip; /* input buffer pointer */
774887Schin
784887Schin int oz; /* output buffer size */
794887Schin char* ob; /* output buffer base */
804887Schin char* op; /* output buffer pointer */
814887Schin char* ox; /* output buffer externalize */
824887Schin
834887Schin char cc[3]; /* beg mid end comment char */
844887Schin char pushback[4]; /* pushback area for caller */
854887Schin
864887Schin char variadic[256]; /* variadic args buffer */
874887Schin
884887Schin /* output buffer */
894887Schin /* slide buffer */
904887Schin /* input buffer */
914887Schin };
924887Schin
934887Schin /*
944887Schin * proto is separate from pp so these undef's are ok
954887Schin */
964887Schin
974887Schin #undef CLASSIC
984887Schin #define CLASSIC (1L<<0)
994887Schin #undef DECLARE
1004887Schin #define DECLARE (1L<<1)
1014887Schin #undef DEFINE
1024887Schin #define DEFINE (1L<<2)
1034887Schin #undef DIRECTIVE
1044887Schin #define DIRECTIVE (1L<<3)
1054887Schin #undef ERROR
1064887Schin #define ERROR (1L<<4)
1074887Schin #undef EXTERN
1084887Schin #define EXTERN (1L<<5)
1094887Schin #undef EXTERNALIZE
1104887Schin #define EXTERNALIZE (1L<<6)
1114887Schin #undef IDID
1124887Schin #define IDID (1L<<7)
1134887Schin #undef INDIRECT
1144887Schin #define INDIRECT (1L<<8)
1154887Schin #undef INIT
1164887Schin #define INIT (1L<<9)
1174887Schin #undef INIT_DEFINE
1184887Schin #define INIT_DEFINE (1L<<10)
1194887Schin #undef INIT_INCLUDE
1204887Schin #define INIT_INCLUDE (1L<<11)
1214887Schin #undef JUNK
1224887Schin #define JUNK (1L<<12)
1234887Schin #undef LINESYNC
1244887Schin #define LINESYNC (1L<<13)
1254887Schin #undef MANGLE
1264887Schin #define MANGLE (1L<<14)
1274887Schin #undef MATCH
1284887Schin #define MATCH (1L<<15)
1294887Schin #undef MORE
1304887Schin #define MORE (1L<<16)
1314887Schin #undef OTHER
1324887Schin #define OTHER (1L<<17)
1334887Schin #undef PASS
1344887Schin #define PASS (1L<<18)
1354887Schin #undef PLUSONLY
1364887Schin #define PLUSONLY (1L<<19)
1374887Schin #undef PLUSPLUS
1384887Schin #define PLUSPLUS (1L<<20)
1394887Schin #undef RECURSIVE
1404887Schin #define RECURSIVE (1L<<21)
1414887Schin #undef SHARP
1424887Schin #define SHARP (1L<<22)
1434887Schin #undef SKIP
1444887Schin #define SKIP (1L<<23)
1454887Schin #undef SLIDE
1464887Schin #define SLIDE (1L<<24)
1474887Schin #undef TOKENS
1484887Schin #define TOKENS (1L<<25)
1494887Schin #undef TYPEDEF
1504887Schin #define TYPEDEF (1L<<26)
1514887Schin #undef VARIADIC
1524887Schin #define VARIADIC (1L<<27)
1534887Schin #undef VARIADIC2
1544887Schin #define VARIADIC2 (1L<<28)
1554887Schin #undef YACC
1564887Schin #define YACC (1L<<29)
1574887Schin #undef YACCSPLIT
1584887Schin #define YACCSPLIT (1L<<30)
1594887Schin #undef YACC2
1604887Schin #define YACC2 (1L<<31)
1614887Schin
1624887Schin #undef GLOBAL
1634887Schin #define GLOBAL (MORE)
1644887Schin
1654887Schin #undef REGULAR
1664887Schin #define REGULAR (1L<<0)
1674887Schin
1684887Schin #ifndef CHUNK
1694887Schin #define CHUNK 1024
1704887Schin #endif
1714887Schin #define BLOCK (8*CHUNK)
1724887Schin
1734887Schin #define T_VA_START (N_TOKEN+1)
1744887Schin
1754887Schin #define RESERVED(b,e,n) ((((long)(b))<<16)|(((long)(e))<<8)|((long)(n)))
1764887Schin
1774887Schin /*
1784887Schin * generate integer
1794887Schin * pointer to end returned
1804887Schin */
1814887Schin
1824887Schin static char*
number(register char * p,register long n)1834887Schin number(register char* p, register long n)
1844887Schin {
1854887Schin register long d;
1864887Schin
1874887Schin for (d = 1000000; d > 1; d /= 10)
1884887Schin if (n >= d) *p++ = '0' + (n / d) % 10;
1894887Schin *p++ = '0' + n % 10;
1904887Schin return p;
1914887Schin }
1924887Schin
1934887Schin #if PROTOMAIN
1944887Schin
1954887Schin static int errors;
1964887Schin
1974887Schin #if PROTO_STANDALONE
1984887Schin
1994887Schin /*
2004887Schin * namespace pollution forces us to claim parts of libc
2014887Schin */
2024887Schin
2034887Schin #undef memcpy
2044887Schin #define memcpy(t,f,n) memcopy(t,f,n)
2054887Schin #undef strcpy
2064887Schin #define strcpy(t,f) strcopy(t,f)
2074887Schin #undef strlen
2084887Schin #define strlen(s) sstrlen(s)
2094887Schin #undef strncmp
2104887Schin #define strncmp(s,t,n) sstrncmp(s,t,n)
2114887Schin
2124887Schin /*
2134887Schin * environmentally safe strlen()
2144887Schin */
2154887Schin
2164887Schin static int
sstrlen(register const char * s)2174887Schin sstrlen(register const char* s)
2184887Schin {
2194887Schin register const char* b;
2204887Schin
2214887Schin for (b = s; *s; s++);
2224887Schin return s - b;
2234887Schin }
2244887Schin
2254887Schin /*
2264887Schin * environmentally safe strncmp()
2274887Schin */
2284887Schin
2294887Schin static int
sstrncmp(register const char * s,register char * t,register int n)2304887Schin sstrncmp(register const char* s, register char* t, register int n)
2314887Schin {
2324887Schin register const char* e = s + n;
2334887Schin
2344887Schin while (s < e)
2354887Schin {
2364887Schin if (*s != *t || !*s)
2374887Schin return *s - *t;
2384887Schin s++;
2394887Schin t++;
2404887Schin }
2414887Schin return 0;
2424887Schin }
2434887Schin
2444887Schin /*
2454887Schin * strcpy() except pointer to end returned
2464887Schin */
2474887Schin
2484887Schin static char*
strcopy(register char * s,register const char * t)2494887Schin strcopy(register char* s, register const char* t)
2504887Schin {
2514887Schin while (*s++ = *t++);
2524887Schin return s - 1;
2534887Schin }
2544887Schin
2554887Schin #endif
2564887Schin
2574887Schin static void
proto_error(char * iob,int level,char * msg,char * arg)2584887Schin proto_error(char* iob, int level, char* msg, char* arg)
2594887Schin {
2604887Schin register char* p;
2614887Schin char buf[1024];
2624887Schin
2634887Schin p = strcopy(buf, "proto: ");
2644887Schin if (iob)
2654887Schin {
2664887Schin register struct proto* proto = (struct proto*)(iob - sizeof(struct proto));
2674887Schin
2684887Schin if (proto->line)
2694887Schin {
2704887Schin if (proto->file)
2714887Schin {
2724887Schin *p++ = '"';
2734887Schin p = strcopy(p, proto->file);
2744887Schin *p++ = '"';
2754887Schin *p++ = ',';
2764887Schin *p++ = ' ';
2774887Schin }
2784887Schin p = strcopy(p, "line ");
2794887Schin p = number(p, proto->line);
2804887Schin }
2814887Schin else if (proto->file)
2824887Schin p = strcopy(p, proto->file);
2834887Schin }
2844887Schin else
2854887Schin {
2864887Schin p = strcopy(p, msg);
2874887Schin msg = arg;
2884887Schin arg = 0;
2894887Schin }
2904887Schin if (*(p - 1) != ' ')
2914887Schin {
2924887Schin *p++ = ':';
2934887Schin *p++ = ' ';
2944887Schin }
2954887Schin if (level == 1)
2964887Schin p = strcopy(p, "warning: ");
2974887Schin p = strcopy(p, msg);
2984887Schin if (arg)
2994887Schin {
3004887Schin *p++ = ' ';
3014887Schin p = strcopy(p, arg);
3024887Schin }
3034887Schin *p++ = '\n';
3044887Schin write(2, buf, p - buf);
3054887Schin if (level >= 3)
3064887Schin exit(level - 2);
3074887Schin if (level >= 2)
3084887Schin errors++;
3094887Schin }
3104887Schin
3114887Schin /*
3124887Schin * memcpy() but pointer to end returned
3134887Schin */
3144887Schin
3154887Schin static char*
memcopy(register char * s,register char * t,int n)3164887Schin memcopy(register char* s, register char* t, int n)
3174887Schin {
3184887Schin register char* e = t + n;
3194887Schin
3204887Schin while (t < e) *s++ = *t++;
3214887Schin return s;
3224887Schin }
3234887Schin
3244887Schin #include "../libast/port/astlicense.c"
3254887Schin
3264887Schin #else
3274887Schin
3284887Schin #define memcopy(s,t,n) (((char*)memcpy(s,t,n))+(n))
3294887Schin
3304887Schin #endif
3314887Schin
3324887Schin /*
3334887Schin * generate line sync
3344887Schin * pointer to end returned
3354887Schin */
3364887Schin
3374887Schin static char*
linesync(register struct proto * proto,register char * p,register long n)3384887Schin linesync(register struct proto* proto, register char* p, register long n)
3394887Schin {
3404887Schin #if PROTOMAIN
3414887Schin if (proto->flags & LINESYNC)
3424887Schin #endif
3434887Schin {
3444887Schin #if PROTOMAIN
3454887Schin p = strcopy(p, "\n#line ");
3464887Schin #else
3474887Schin p = strcopy(p, "\n# ");
3484887Schin #endif
3494887Schin p = number(p, n);
3504887Schin *p++ = '\n';
3514887Schin }
3524887Schin return p;
3534887Schin }
3544887Schin
3554887Schin /*
3564887Schin * output init header
3574887Schin * pointer to end returned
3584887Schin */
3594887Schin
3604887Schin static char*
init(struct proto * proto,char * op,int flags)3614887Schin init(struct proto* proto, char* op, int flags)
3624887Schin {
3634887Schin register char* s;
3644887Schin
3654887Schin if (flags & INIT_DEFINE)
3664887Schin {
3674887Schin op = strcopy(op, "\
3684887Schin \n\
3694887Schin #if !defined(__PROTO__)\n\
3704887Schin # if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)\n\
3714887Schin # if defined(__cplusplus)\n\
3724887Schin # define __LINKAGE__ \"C\"\n\
3734887Schin # else\n\
3744887Schin # define __LINKAGE__\n\
3754887Schin # endif\n\
3764887Schin # define __STDARG__\n\
3774887Schin # define __PROTO__(x) x\n\
3784887Schin # define __OTORP__(x)\n\
3794887Schin # define __PARAM__(n,o) n\n\
3804887Schin # if !defined(__STDC__) && !defined(__cplusplus)\n\
3814887Schin # if !defined(c_plusplus)\n\
3824887Schin # define const\n\
3834887Schin # endif\n\
3844887Schin # define signed\n\
3854887Schin # define void int\n\
3864887Schin # define volatile\n\
3874887Schin # define __V_ char\n\
3884887Schin # else\n\
3894887Schin # define __V_ void\n\
3904887Schin # endif\n\
3914887Schin # else\n\
3924887Schin # define __PROTO__(x) ()\n\
3934887Schin # define __OTORP__(x) x\n\
3944887Schin # define __PARAM__(n,o) o\n\
3954887Schin # define __LINKAGE__\n\
3964887Schin # define __V_ char\n\
3974887Schin # define const\n\
3984887Schin # define signed\n\
3994887Schin # define void int\n\
4004887Schin # define volatile\n\
4014887Schin # endif\n\
4024887Schin # define __MANGLE__ __LINKAGE__\n\
4034887Schin # if defined(__cplusplus) || defined(c_plusplus)\n\
4044887Schin # define __VARARG__ ...\n\
4054887Schin # else\n\
4064887Schin # define __VARARG__\n\
4074887Schin # endif\n\
4084887Schin # if defined(__STDARG__)\n\
4094887Schin # define __VA_START__(p,a) va_start(p,a)\n\
4104887Schin # else\n\
4114887Schin # define __VA_START__(p,a) va_start(p)\n\
4124887Schin # endif\n\
4134887Schin # if !defined(__INLINE__)\n\
4144887Schin # if defined(__cplusplus)\n\
4154887Schin # define __INLINE__ extern __MANGLE__ inline\n\
4164887Schin # else\n\
4174887Schin # if defined(_WIN32) && !defined(__GNUC__)\n\
4184887Schin # define __INLINE__ __inline\n\
4194887Schin # endif\n\
4204887Schin # endif\n\
4214887Schin # endif\n\
4224887Schin #endif\n\
4234887Schin #if !defined(__LINKAGE__)\n\
4244887Schin #define __LINKAGE__ /* 2004-08-11 transition */\n\
4254887Schin #endif\n\
4264887Schin ");
4274887Schin }
4284887Schin else
4294887Schin op = strcopy(op, "\
4304887Schin \n\
4314887Schin #if !defined(__PROTO__)\n\
4324887Schin #include <prototyped.h>\n\
4334887Schin #endif\n\
4344887Schin #if !defined(__LINKAGE__)\n\
4354887Schin #define __LINKAGE__ /* 2004-08-11 transition */\n\
4364887Schin #endif\n\
4374887Schin ");
4384887Schin if (proto->package)
4394887Schin {
4404887Schin s = "\
4414887Schin #ifndef __MANGLE_%_DATA__\n\
4424887Schin # ifdef _BLD_%\n\
4434887Schin # ifdef __EXPORT__\n\
4444887Schin # define __MANGLE_%_DATA__ __MANGLE__ __EXPORT__\n\
4454887Schin # else\n\
4464887Schin # define __MANGLE_%_DATA__ __MANGLE__\n\
4474887Schin # endif\n\
4484887Schin # define __MANGLE_%_FUNC__ __MANGLE__\n\
4494887Schin # else\n\
4504887Schin # ifdef __IMPORT__\n\
4514887Schin # define __MANGLE_%_DATA__ __MANGLE__ __IMPORT__\n\
4524887Schin # else\n\
4534887Schin # define __MANGLE_%_DATA__ __MANGLE__\n\
4544887Schin # endif\n\
4554887Schin # define __MANGLE_%_FUNC__ __MANGLE__\n\
4564887Schin # endif\n\
4574887Schin #endif\n\
4584887Schin ";
4594887Schin for (;;)
4604887Schin {
4614887Schin switch (*op++ = *s++)
4624887Schin {
4634887Schin case 0:
4644887Schin op--;
4654887Schin break;
4664887Schin case '%':
4674887Schin op = strcopy(op - 1, proto->package);
4684887Schin continue;
4694887Schin default:
4704887Schin continue;
4714887Schin }
4724887Schin break;
4734887Schin }
4744887Schin }
4754887Schin return op;
4764887Schin }
4774887Schin
4784887Schin #define BACKOUT() (op=ko)
4794887Schin #define CACHE() do{CACHEIN();CACHEOUT();call=proto->call;}while(0)
4804887Schin #define CACHEIN() (ip=proto->ip)
4814887Schin #define CACHEOUT() (op=proto->op)
4824887Schin #define GETCHR() (*(unsigned char*)ip++)
4834887Schin #define KEEPOUT() (ko=op)
4844887Schin #define LASTOUT() (*(op-1))
4854887Schin #define PUTCHR(c) (*op++=(c))
4864887Schin #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)
4874887Schin #define SYNCIN() (proto->ip=ip)
4884887Schin #define SYNCOUT() (proto->op=op)
4894887Schin #define UNGETCHR() (ip--)
4904887Schin #define UNPUTCHR() (op--)
4914887Schin
4924887Schin /*
4934887Schin * advance to the next non-space character
4944887Schin */
4954887Schin
4964887Schin static char*
nns(register char * s)4974887Schin nns(register char* s)
4984887Schin {
4994887Schin while (*s == ' ' || *s == '\t' || *s == '\n')
5004887Schin s++;
5014887Schin return s;
5024887Schin }
5034887Schin
5044887Schin #define DIR_if 01
5054887Schin #define DIR_el 02
5064887Schin #define DIR_en 03
5074887Schin #define DIR 03
5084887Schin
5094887Schin /*
5104887Schin * update directive mask
5114887Schin */
5124887Schin
5134887Schin static int
directive(register char * s,int dir)5144887Schin directive(register char* s, int dir)
5154887Schin {
5164887Schin switch (*(s = nns(s)))
5174887Schin {
5184887Schin case 'e':
5194887Schin case 'i':
5204887Schin dir <<= 2;
5214887Schin switch (*++s)
5224887Schin {
5234887Schin case 'f':
5244887Schin dir |= DIR_if;
5254887Schin break;
5264887Schin case 'l':
5274887Schin dir |= DIR_el;
5284887Schin break;
5294887Schin case 'n':
5304887Schin dir |= DIR_en;
5314887Schin break;
5324887Schin }
5334887Schin break;
5344887Schin }
5354887Schin return dir;
5364887Schin }
5374887Schin
5384887Schin /*
5394887Schin * the tokenizer
5404887Schin * top level calls loop until EOB
5414887Schin * recursive calls just return the next token
5424887Schin */
5434887Schin
5444887Schin static int
lex(register struct proto * proto,register long flags)5454887Schin lex(register struct proto* proto, register long flags)
5464887Schin {
5474887Schin register char* ip;
5484887Schin register char* op;
5494887Schin register int c;
5504887Schin register int state;
5514887Schin register short* rp;
5524887Schin char* m;
5534887Schin char* e;
5544887Schin char* t;
5554887Schin char* bp;
5564887Schin char* v;
5574887Schin char* im;
5584887Schin char* ko;
5594887Schin char* aom;
5604887Schin int n;
5614887Schin int line;
5624887Schin int quot;
5634887Schin int brack;
5644887Schin int sub;
5654887Schin int x;
5664887Schin int vc;
5674887Schin
5684887Schin char* ie = 0;
5694887Schin char* om = 0;
5704887Schin char* aim = 0;
5714887Schin char* aie = 0;
5724887Schin char* func = 0;
5734887Schin int call = 0;
5744887Schin int dir = 0;
5754887Schin int group = 0;
5764887Schin int last = 0;
5774887Schin int paren = 0;
5784887Schin #if PROTOMAIN
5794887Schin char* qe = 0;
5804887Schin int qn = 0;
5814887Schin int args = 0;
5824887Schin #endif
5834887Schin
5844887Schin CACHE();
5854887Schin #if PROTOMAIN
5864887Schin if (flags & EXTERN) KEEPOUT();
5874887Schin #endif
5884887Schin fsm_start:
5894887Schin proto->tp = ip;
5904887Schin state = PROTO;
5914887Schin bp = ip;
5924887Schin do
5934887Schin {
5944887Schin rp = fsm[state];
5954887Schin fsm_get:
5964887Schin while (!(state = rp[c = GETCHR()]));
5974887Schin fsm_next:
5984887Schin ;
5994887Schin } while (state > 0);
6004887Schin if ((n = ip - bp - 1) > 0)
6014887Schin {
6024887Schin ip = bp;
6034887Schin MEMCPY(op, ip, n);
6044887Schin ip++;
6054887Schin }
6064887Schin state = ~state;
6074887Schin fsm_terminal:
6084887Schin switch (TERM(state))
6094887Schin {
6104887Schin case S_CHR:
6114887Schin if (op > proto->ob && *(op - 1) == '=' && (op == proto->ob + 1 || *(op - 2) != '=')) switch (c)
6124887Schin {
6134887Schin case '+':
6144887Schin case '-':
6154887Schin case '*':
6164887Schin case '&':
6174887Schin PUTCHR(' ');
6184887Schin break;
6194887Schin }
6204887Schin PUTCHR(c);
6214887Schin break;
6224887Schin
6234887Schin case S_CHRB:
6244887Schin UNGETCHR();
6254887Schin c = LASTOUT();
6264887Schin break;
6274887Schin
6284887Schin case S_COMMENT:
6294887Schin switch (c)
6304887Schin {
6314887Schin case '\n':
6324887Schin if (INCOMMENTXX(rp)) goto fsm_newline;
6334887Schin PUTCHR(c);
6344887Schin proto->line++;
6354887Schin rp = fsm[COM2];
6364887Schin break;
6374887Schin case '/':
6384887Schin #if PROTOMAIN
6394887Schin if ((flags & (EXTERN|MATCH)) == EXTERN) BACKOUT();
6404887Schin else
6414887Schin #endif
6424887Schin PUTCHR(c);
6434887Schin if (INCOMMENTXX(rp))
6444887Schin {
6454887Schin rp = fsm[COM5];
6464887Schin break;
6474887Schin }
6484887Schin goto fsm_start;
6494887Schin case EOF:
6504887Schin break;
6514887Schin default:
6524887Schin #if PROTOMAIN
6534887Schin if ((flags & (EXTERN|MATCH)) == EXTERN) BACKOUT();
6544887Schin else
6554887Schin #endif
6564887Schin PUTCHR(c);
6574887Schin rp = fsm[INCOMMENTXX(rp) ? COM5 : COM3];
6584887Schin break;
6594887Schin }
6604887Schin bp = ip;
6614887Schin goto fsm_get;
6624887Schin
6634887Schin case S_EOB:
6644887Schin if (c)
6654887Schin {
6664887Schin if (state = fsm[TERMINAL][INDEX(rp)+1])
6674887Schin goto fsm_terminal;
6684887Schin SYNC();
6694887Schin return 0;
6704887Schin }
6714887Schin UNGETCHR();
6724887Schin fsm_eob:
6734887Schin if ((flags & (DECLARE|GLOBAL|RECURSIVE)) == GLOBAL && (proto->flags & MORE))
6744887Schin {
6754887Schin #if PROTOMAIN
6764887Schin if (!(flags & EXTERN)) /* XXX */
6774887Schin #endif
6784887Schin flags |= SLIDE;
6794887Schin c = ip - proto->ib;
6804887Schin if (!(flags & MATCH))
6814887Schin im = proto->tp;
6824887Schin if (ip > proto->ib)
6834887Schin {
6844887Schin n = ip - im;
6854887Schin if (ip - n < proto->ib)
6864887Schin proto->flags |= ERROR;
6874887Schin memcopy(proto->ib - n, ip - n, n);
6884887Schin ip = proto->ib;
6894887Schin }
6904887Schin proto->tp -= c;
6914887Schin if (flags & MATCH)
6924887Schin {
6934887Schin im -= c;
6944887Schin ie -= c;
6954887Schin }
6964887Schin if (aim)
6974887Schin aim -= c;
6984887Schin if (aie)
6994887Schin aie -= c;
7004887Schin if ((n = read(proto->fd, ip, proto->iz)) > 0)
7014887Schin {
7024887Schin if ((proto->options & REGULAR) && n < proto->iz)
7034887Schin {
7044887Schin proto->flags &= ~MORE;
7054887Schin close(proto->fd);
7064887Schin }
7074887Schin *(ip + n) = 0;
7084887Schin if (state & SPLICE)
7094887Schin goto fsm_splice;
7104887Schin bp = ip;
7114887Schin goto fsm_get;
7124887Schin }
7134887Schin *ip = 0;
7144887Schin proto->flags &= ~MORE;
7154887Schin close(proto->fd);
7164887Schin }
7174887Schin if (state & SPLICE)
7184887Schin goto fsm_splice;
7194887Schin /* NOTE: RECURSIVE lex() should really SLIDE too */
7204887Schin if (!(flags & RECURSIVE) && (state = rp[c = EOF]))
7214887Schin {
7224887Schin bp = ip;
7234887Schin goto fsm_next;
7244887Schin }
7254887Schin SYNC();
7264887Schin return 0;
7274887Schin
7284887Schin case S_LITBEG:
7294887Schin quot = c;
7304887Schin #if PROTOMAIN
7314887Schin if (c == '"' && qe)
7324887Schin {
7334887Schin for (n = 0, t = qe + 1; t < op && (*t == ' ' || *t == '\t' || *t == '\n' && ++n || *t >= 'A' && *t <= 'Z' || *t == '_'); t++);
7344887Schin if (t == op)
7354887Schin {
7364887Schin op = qe;
7374887Schin qe = 0;
7384887Schin qn = n;
7394887Schin }
7404887Schin else PUTCHR(c);
7414887Schin }
7424887Schin else
7434887Schin #endif
7444887Schin PUTCHR(c);
7454887Schin rp = fsm[LIT1];
7464887Schin bp = ip;
7474887Schin goto fsm_get;
7484887Schin
7494887Schin case S_LITEND:
7504887Schin if (c == quot)
7514887Schin {
7524887Schin #if PROTOMAIN
7534887Schin if (!(flags & DIRECTIVE))
7544887Schin qe = (c == '"') ? op : (char*)0;
7554887Schin #endif
7564887Schin PUTCHR(c);
7574887Schin #if PROTOMAIN
7584887Schin while (qn > 0)
7594887Schin {
7604887Schin qn--;
7614887Schin PUTCHR('\n');
7624887Schin }
7634887Schin #endif
7644887Schin }
7654887Schin else if (c != '\n' && c != EOF)
7664887Schin {
7674887Schin PUTCHR(c);
7684887Schin bp = ip;
7694887Schin goto fsm_get;
7704887Schin }
7714887Schin else
7724887Schin {
7734887Schin #if PROTOMAIN
7744887Schin while (qn > 0)
7754887Schin {
7764887Schin qn--;
7774887Schin PUTCHR('\n');
7784887Schin }
7794887Schin #endif
7804887Schin UNGETCHR();
7814887Schin }
7824887Schin c = T_INVALID;
7834887Schin break;
7844887Schin
7854887Schin case S_LITESC:
7864887Schin #if PROTOMAIN
7874887Schin if (flags & CLASSIC) PUTCHR(c);
7884887Schin else
7894887Schin #endif
7904887Schin switch (c)
7914887Schin {
7924887Schin case 'a':
7934887Schin n = CC_bel;
7944887Schin goto fsm_oct;
7954887Schin case 'E':
7964887Schin n = CC_esc;
7974887Schin goto fsm_oct;
7984887Schin case 'v':
7994887Schin n = CC_vt;
8004887Schin goto fsm_oct;
8014887Schin case 'x':
8024887Schin SYNC();
8034887Schin lex(proto, (flags & GLOBAL) | RECURSIVE);
8044887Schin for (n = x = 0; (c = GETCHR()), x < 3; x++) switch (c)
8054887Schin {
8064887Schin case '0': case '1': case '2': case '3':
8074887Schin case '4': case '5': case '6': case '7':
8084887Schin case '8': case '9':
8094887Schin n = (n << 4) + c - '0';
8104887Schin break;
8114887Schin case 'a': case 'b': case 'c': case 'd':
8124887Schin case 'e': case 'f':
8134887Schin n = (n << 4) + c - 'a' + 10;
8144887Schin break;
8154887Schin case 'A': case 'B': case 'C': case 'D':
8164887Schin case 'E': case 'F':
8174887Schin n = (n << 4) + c - 'A' + 10;
8184887Schin break;
8194887Schin default:
8204887Schin goto fsm_hex;
8214887Schin }
8224887Schin fsm_hex:
8234887Schin UNGETCHR();
8244887Schin fsm_oct:
8254887Schin PUTCHR(((n >> 6) & 07) + '0');
8264887Schin PUTCHR(((n >> 3) & 07) + '0');
8274887Schin PUTCHR((n & 07) + '0');
8284887Schin break;
8294887Schin default:
8304887Schin PUTCHR(c);
8314887Schin break;
8324887Schin }
8334887Schin rp = fsm[LIT1];
8344887Schin bp = ip;
8354887Schin goto fsm_get;
8364887Schin
8374887Schin case S_MACRO:
8384887Schin UNGETCHR();
8394887Schin #if PROTOMAIN
8404887Schin if ((flags & EXTERN) && *proto->tp == 's' && !strncmp(proto->tp, "static", 6))
8414887Schin {
8424887Schin c = T_EXTERN;
8434887Schin break;
8444887Schin }
8454887Schin #endif
8464887Schin if (*proto->tp == '_' && !strncmp(proto->tp, "__STDPP__directive", 6)) c = '#';
8474887Schin else c = T_ID;
8484887Schin
8494887Schin break;
8504887Schin
8514887Schin case S_NL:
8524887Schin fsm_newline:
8534887Schin proto->line++;
8544887Schin #if PROTOMAIN
8554887Schin if (flags & EXTERN)
8564887Schin {
8574887Schin if (op != proto->ob && LASTOUT() != ' ' && LASTOUT() != '\n')
8584887Schin PUTCHR(' ');
8594887Schin }
8604887Schin else
8614887Schin #endif
8624887Schin PUTCHR(c);
8634887Schin if (flags & DIRECTIVE)
8644887Schin {
8654887Schin #if PROTOMAIN
8664887Schin if (flags & CLASSIC)
8674887Schin {
8684887Schin if (flags & EXTERN) BACKOUT();
8694887Schin if (flags & JUNK)
8704887Schin {
8714887Schin *(ip - 1) = 0;
8724887Schin op = strcopy(om, "/* ");
8734887Schin op = strcopy(op, im);
8744887Schin op = strcopy(op, " */\n");
8754887Schin }
8764887Schin flags &= ~(DEFINE|DIRECTIVE|IDID|INDIRECT|JUNK|MATCH|SHARP|TYPEDEF);
8774887Schin }
8784887Schin else
8794887Schin #endif
8804887Schin {
8814887Schin if ((flags & (DEFINE|SHARP)) == (DEFINE|SHARP))
8824887Schin {
8834887Schin *(ip - 1) = 0;
8844887Schin op = strcopy(om, "#if defined(__STDC__) || defined(__STDPP__)\n");
8854887Schin op = strcopy(op, im);
8864887Schin op = strcopy(op, "\n#else\n");
8874887Schin bp = ip;
8884887Schin ip = im;
8894887Schin *op++ = *ip++;
8904887Schin while (*op = *ip++)
8914887Schin if (*op++ == '#' && *ip != '(')
8924887Schin {
8934887Schin op--;
8944887Schin while (*--op == ' ' || *op == '\t');
8954887Schin if (*ip == '#')
8964887Schin {
8974887Schin op = strcopy(op + 1, "/**/");
8984887Schin while (*++ip == ' ' || *ip == '\t');
8994887Schin }
9004887Schin else
9014887Schin {
9024887Schin if (*op != '"') *++op = '"';
9034887Schin op++;
9044887Schin while (*ip == ' ' || *ip == '\t') ip++;
9054887Schin while ((c = *ip) >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '_') *op++ = *ip++;
9064887Schin while (*ip == ' ' || *ip == '\t') ip++;
9074887Schin if (*ip == '"') ip++;
9084887Schin else *op++ = '"';
9094887Schin }
9104887Schin }
9114887Schin ip = bp;
9124887Schin op = strcopy(op, "\n#endif\n");
9134887Schin op = linesync(proto, op, proto->line);
9144887Schin }
9154887Schin flags &= ~(DEFINE|DIRECTIVE|IDID|INDIRECT|MATCH|OTHER|SHARP|SKIP|TOKENS|TYPEDEF);
9164887Schin }
9174887Schin call = 0;
9184887Schin group = 0;
9194887Schin paren = 0;
9204887Schin last = '\n';
9214887Schin }
9224887Schin if (paren == 0 && (flags & (MATCH|RECURSIVE|SKIP|SLIDE)) == SLIDE)
9234887Schin {
9244887Schin #if PROTOMAIN
9254887Schin if (flags & EXTERN) BACKOUT();
9264887Schin #endif
9274887Schin SYNC();
9284887Schin return 0;
9294887Schin }
9304887Schin goto fsm_start;
9314887Schin
9324887Schin case S_QUAL:
9334887Schin PUTCHR(c);
9344887Schin rp = fsm[NEXT(state)];
9354887Schin bp = ip;
9364887Schin goto fsm_get;
9374887Schin
9384887Schin case S_TOK:
9394887Schin PUTCHR(c);
9404887Schin c = TYPE(state);
9414887Schin break;
9424887Schin
9434887Schin case S_TOKB:
9444887Schin UNGETCHR();
9454887Schin c = TYPE(state);
9464887Schin break;
9474887Schin
9484887Schin case S_RESERVED:
9494887Schin UNGETCHR();
9504887Schin c = T_ID;
9514887Schin if (!(flags & DECLARE)) switch (RESERVED(*proto->tp, *(ip - 1), ip - proto->tp))
9524887Schin {
9534887Schin case RESERVED('N', 'N', 3):
9544887Schin if (proto->tp[1] == 'o')
9554887Schin c = T_DO;
9564887Schin break;
9574887Schin case RESERVED('d', 'o', 2):
9584887Schin c = T_DO;
9594887Schin break;
9604887Schin case RESERVED('e', 'e', 4):
9614887Schin if (!(flags & RECURSIVE) && (flags & (DIRECTIVE|TOKENS)) != DIRECTIVE && !strncmp(proto->tp, "else", 4))
9624887Schin {
9634887Schin c = T_ELSE;
9644887Schin goto fsm_id;
9654887Schin }
9664887Schin break;
9674887Schin case RESERVED('e', 'n', 6):
9684887Schin if (!strncmp(proto->tp, "extern", 6))
9694887Schin c = T_EXTERN;
9704887Schin break;
9714887Schin case RESERVED('f', 'r', 3):
9724887Schin if (!(flags & RECURSIVE) && !strncmp(proto->tp, "for", 3))
9734887Schin {
9744887Schin c = T_FOR;
9754887Schin goto fsm_id;
9764887Schin }
9774887Schin break;
9784887Schin case RESERVED('i', 'f', 2):
9794887Schin c = T_IF;
9804887Schin break;
9814887Schin case RESERVED('i', 'e', 6):
9824887Schin if (!strncmp(proto->tp, "inline", 6) && !(flags & (MATCH|SKIP|TOKENS|TYPEDEF)) && proto->brace == 0 && paren == 0 && group == 0 && (last == ';' || last == '}' || last == '\n' || last == 0))
9834887Schin {
9844887Schin flags |= SKIP;
9854887Schin SYNC();
9864887Schin line = proto->line;
9874887Schin op = strcopy(op - 6, "__INLINE__");
9884887Schin SYNC();
9894887Schin }
9904887Schin break;
9914887Schin case RESERVED('r', 'n', 6):
9924887Schin if (!(flags & RECURSIVE) && !strncmp(proto->tp, "return", 6))
9934887Schin {
9944887Schin c = T_RETURN;
9954887Schin goto fsm_id;
9964887Schin }
9974887Schin break;
9984887Schin case RESERVED('s', 'c', 6):
9994887Schin if ((proto->options & EXTERNALIZE) && !strncmp(proto->tp, "static", 6))
10004887Schin {
10014887Schin proto->ox = op - 6;
10024887Schin flags |= EXTERNALIZE;
10034887Schin }
10044887Schin break;
10054887Schin case RESERVED('t', 'f', 7):
10064887Schin if (!(flags & RECURSIVE) && !strncmp(proto->tp, "typedef", 7))
10074887Schin {
10084887Schin flags |= TYPEDEF;
10094887Schin c = T_EXTERN;
10104887Schin }
10114887Schin break;
10124887Schin case RESERVED('v', 't', 8):
10134887Schin if (*ip == '(' && !strncmp(proto->tp, "va_start", 8)) c = T_VA_START;
10144887Schin break;
10154887Schin case RESERVED('v', 'd', 4):
10164887Schin if (!strncmp(proto->tp, "void", 4))
10174887Schin {
10184887Schin if (flags & (CLASSIC|PLUSONLY|INIT_DEFINE|INIT_INCLUDE)) c = T_VOID;
10194887Schin else
10204887Schin {
10214887Schin SYNC();
10224887Schin line = proto->line;
10234887Schin if (lex(proto, (flags & GLOBAL) | RECURSIVE) == '*')
10244887Schin {
10254887Schin memcopy(op - 4, "__V_", 4);
10264887Schin memcopy(ip - 4, "__V_", 4);
10274887Schin }
10284887Schin else c = T_VOID;
10294887Schin proto->line = line;
10304887Schin SYNC();
10314887Schin bp = ip;
10324887Schin }
10334887Schin }
10344887Schin break;
10354887Schin case RESERVED('w', 'e', 5):
10364887Schin if (!(flags & RECURSIVE) && !strncmp(proto->tp, "while", 5))
10374887Schin {
10384887Schin c = T_WHILE;
10394887Schin goto fsm_id;
10404887Schin }
10414887Schin break;
10424887Schin }
10434887Schin #if PROTOMAIN
10444887Schin if ((flags & CLASSIC) && c != T_EXTERN)
10454887Schin c = T_ID;
10464887Schin #endif
10474887Schin break;
10484887Schin
10494887Schin case S_VS:
10504887Schin goto fsm_start;
10514887Schin
10524887Schin case S_WS:
10534887Schin UNGETCHR();
10544887Schin #if PROTOMAIN
10554887Schin if ((flags & (EXTERN|MATCH)) == EXTERN)
10564887Schin {
10574887Schin while (op > proto->ob && (*(op - 1) == ' ' || *(op - 1) == '\t'))
10584887Schin op--;
10594887Schin if (op > proto->ob && *(op - 1) != '\n') *op++ = ' ';
10604887Schin }
10614887Schin #endif
10624887Schin goto fsm_start;
10634887Schin
10644887Schin default:
10654887Schin if (state & SPLICE)
10664887Schin {
10674887Schin if (c == '\\')
10684887Schin {
10694887Schin if (!(n = GETCHR()))
10704887Schin {
10714887Schin goto fsm_eob;
10724887Schin fsm_splice:
10734887Schin c = '\\';
10744887Schin n = GETCHR();
10754887Schin }
10764887Schin if (n == '\n')
10774887Schin {
10784887Schin proto->line++;
10794887Schin PUTCHR('\\');
10804887Schin PUTCHR('\n');
10814887Schin bp = ip;
10824887Schin goto fsm_get;
10834887Schin }
10844887Schin UNGETCHR();
10854887Schin }
10864887Schin state &= ~SPLICE;
10874887Schin if (state >= TERMINAL)
10884887Schin goto fsm_terminal;
10894887Schin rp = fsm[state];
10904887Schin }
10914887Schin PUTCHR(c);
10924887Schin bp = ip;
10934887Schin goto fsm_get;
10944887Schin }
10954887Schin if (!(flags & (INIT_DEFINE|INIT_INCLUDE|RECURSIVE)))
10964887Schin {
10974887Schin if (!(flags & DIRECTIVE)) switch (c)
10984887Schin {
10994887Schin case '(':
11004887Schin #if PROTOMAIN
11014887Schin if (!(flags & CLASSIC) || proto->brace == 0)
11024887Schin #endif
11034887Schin {
11044887Schin if (paren++ == 0)
11054887Schin {
11064887Schin #if PROTOMAIN
11074887Schin if (!(flags & CLASSIC) || group <= 1)
11084887Schin #endif
11094887Schin {
11104887Schin #if PROTOMAIN
11114887Schin args = 0;
11124887Schin #endif
11134887Schin if (group++ == 0) group++;
11144887Schin else if (flags & INDIRECT) call++;
11154887Schin flags |= MATCH;
11164887Schin im = ip - 1;
11174887Schin om = op - 1;
11184887Schin }
11194887Schin sub = 0;
11204887Schin }
11214887Schin else if (paren == 2 && !aim)
11224887Schin {
11234887Schin sub++;
11244887Schin if (last == '(')
11254887Schin {
11264887Schin flags &= ~MATCH;
11274887Schin om = 0;
11284887Schin }
11294887Schin else if (flags & INDIRECT)
11304887Schin {
11314887Schin aim = ip - 1;
11324887Schin aom = op - 1;
11334887Schin }
11344887Schin else if ((flags & (MATCH|TOKENS)) == MATCH)
11354887Schin {
11364887Schin for (m = ip - 2; m > im && (*m == ' ' || *m == '\t'); m--);
11374887Schin if (m != im && sub == 1)
11384887Schin {
11394887Schin m = im + (*nns(ip) == '*');
11404887Schin }
11414887Schin if (m == im)
11424887Schin {
11434887Schin flags &= ~MATCH;
11444887Schin om = 0;
11454887Schin }
11464887Schin }
11474887Schin else if ((flags & MATCH) && sub == 1 && *nns(ip) != '*')
11484887Schin {
11494887Schin flags &= ~MATCH;
11504887Schin om = 0;
11514887Schin }
11524887Schin }
11534887Schin flags &= ~TOKENS;
11544887Schin }
11554887Schin break;
11564887Schin case ')':
11574887Schin #if PROTOMAIN
11584887Schin if (!(flags & CLASSIC) || proto->brace == 0)
11594887Schin #endif
11604887Schin if (--paren == 0)
11614887Schin {
11624887Schin #if PROTOMAIN
11634887Schin if (flags & CLASSIC)
11644887Schin {
11654887Schin if (group != 2)
11664887Schin {
11674887Schin c = T_ID;
11684887Schin break;
11694887Schin }
11704887Schin group++;
11714887Schin }
11724887Schin #endif
11734887Schin ie = ip;
11744887Schin }
11754887Schin else if (paren == 1 && (flags & INDIRECT) && !aie)
11764887Schin aie = ip;
11774887Schin break;
11784887Schin case '*':
11794887Schin if (last == '(' && group == 2)
11804887Schin {
11814887Schin group--;
11824887Schin if (paren == 1)
11834887Schin {
11844887Schin flags |= INDIRECT;
11854887Schin aim = aie = 0;
11864887Schin }
11874887Schin }
11884887Schin break;
11894887Schin case '#':
11904887Schin dir = directive(ip, dir);
11914887Schin 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))
11924887Schin flags |= DIRECTIVE;
11934887Schin else if (!(flags & (DECLARE|DIRECTIVE)))
11944887Schin {
11954887Schin flags |= DIRECTIVE;
11964887Schin if (!(flags & PLUSONLY))
11974887Schin {
11984887Schin bp = ip;
11994887Schin while (*ip == ' ' || *ip == '\t') ip++;
12004887Schin if (*ip == 'l' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e')
12014887Schin {
12024887Schin if (*++ip == ' ' || *ip == '\t')
12034887Schin {
12044887Schin proto->line = 0;
12054887Schin while (*++ip >= '0' && *ip <= '9')
12064887Schin proto->line = proto->line * 10 + *ip - '0';
12074887Schin proto->line--;
12084887Schin }
12094887Schin }
12104887Schin #if PROTOMAIN
12114887Schin else if ((flags & (CLASSIC|EXTERN)) == CLASSIC)
12124887Schin {
12134887Schin n = 0;
12144887Schin t = ip + 6;
12154887Schin while (ip < t && *ip >= 'a' && *ip <= 'z')
12164887Schin n = HASHKEYPART(n, *ip++);
12174887Schin switch (n)
12184887Schin {
12194887Schin case HASHKEY4('e','l','s','e'):
12204887Schin case HASHKEY5('e','n','d','i','f'):
12214887Schin while (*ip == ' ' || *ip == '\t') ip++;
12224887Schin if (*ip != '\n' && *ip != '/' && *(ip + 1) != '*')
12234887Schin {
12244887Schin flags |= JUNK|MATCH;
12254887Schin im = ip;
12264887Schin om = op + (ip - bp);
12274887Schin }
12284887Schin break;
12294887Schin case HASHKEY4('e','l','i','f'):
12304887Schin case HASHKEY5('e','r','r','o','r'):
12314887Schin case HASHKEY2('i','f'):
12324887Schin case HASHKEY5('i','f','d','e','f'):
12334887Schin case HASHKEY6('i','f','n','d','e','f'):
12344887Schin case HASHKEY5('u','n','d','e','f'):
12354887Schin break;
12364887Schin case HASHKEY6('i','n','c','l','u','d'):
12374887Schin if (*ip == 'e') ip++;
12384887Schin /*FALLTHROUGH*/
12394887Schin case HASHKEY6('d','e','f','i','n','e'):
12404887Schin case HASHKEY6('p','r','a','g','m','a'):
12414887Schin if (*ip < 'a' || *ip > 'z') break;
12424887Schin /*FALLTHROUGH*/
12434887Schin default:
12444887Schin flags |= JUNK|MATCH;
12454887Schin im = bp - 1;
12464887Schin om = op - 1;
12474887Schin break;
12484887Schin }
12494887Schin }
12504887Schin else
12514887Schin #endif
12524887Schin {
12534887Schin if (*ip == 'i' && *++ip == 'n' && *++ip == 'c' && *++ip == 'l' && *++ip == 'u' && *++ip == 'd' && *++ip == 'e')
12544887Schin {
12554887Schin while (*++ip == ' ' || *ip == '\t');
12564887Schin if (*ip++ == '<' && *ip++ == 's' && *ip++ == 't' && *ip++ == 'd' && *ip++ == 'a' && *ip++ == 'r' && *ip++ == 'g' && *ip++ == '.' && *ip++ == 'h' && *ip++ == '>')
12574887Schin {
12584887Schin op = strcopy(op, "\
12594887Schin if !defined(va_start)\n\
12604887Schin #if defined(__STDARG__)\n\
12614887Schin #include <stdarg.h>\n\
12624887Schin #else\n\
12634887Schin #include <varargs.h>\n\
12644887Schin #endif\n\
12654887Schin #endif\n\
12664887Schin ");
12674887Schin op = linesync(proto, op, proto->line);
12684887Schin break;
12694887Schin }
12704887Schin }
12714887Schin else if (*ip == 'd' && *++ip == 'e' && *++ ip == 'f' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e' && (*++ip == ' ' || *ip == '\t'))
12724887Schin {
12734887Schin while (*++ip == ' ' || *ip == '\t');
12744887Schin if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t'))
12754887Schin {
12764887Schin t = ip;
12774887Schin while (*++t == ' ' || *t == '\t');
12784887Schin if (*t == 'e' && *++t == 'x' && *++ t == 't' && *++t == 'e' && *++t == 'r' && *++t == 'n' && (*++t == ' ' || *t == '\t' || *t == '\n' || *t == '\r'))
12794887Schin ip = t;
12804887Schin t = ip;
12814887Schin while (*++t == ' ' || *t == '\t');
12824887Schin if (*t == '_' && *(t + 1) == '_')
12834887Schin {
12844887Schin op = strcopy(op, "undef __MANGLE__\n");
12854887Schin op = linesync(proto, op, proto->line);
12864887Schin op = strcopy(op, "#define __MANGLE__ __LINKAGE__");
12874887Schin break;
12884887Schin }
12894887Schin }
12904887Schin flags |= DEFINE|MATCH;
12914887Schin im = bp - 1;
12924887Schin om = op - 1;
12934887Schin }
12944887Schin else if (*ip == 'u' && *++ip == 'n' && *++ ip == 'd' && *++ip == 'e' && *++ip == 'f' && (*++ip == ' ' || *ip == '\t'))
12954887Schin {
12964887Schin while (*++ip == ' ' || *ip == '\t');
12974887Schin if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t' || *ip == '\n' || *ip == '\r'))
12984887Schin {
12994887Schin op = strcopy(op, "undef __MANGLE__\n");
13004887Schin op = linesync(proto, op, proto->line);
13014887Schin op = strcopy(op, "#define __MANGLE__ __LINKAGE__");
13024887Schin break;
13034887Schin }
13044887Schin flags |= DEFINE|MATCH;
13054887Schin im = bp - 1;
13064887Schin om = op - 1;
13074887Schin }
13084887Schin }
13094887Schin ip = bp;
13104887Schin }
13114887Schin break;
13124887Schin }
13134887Schin else
13144887Schin break;
13154887Schin /*FALLTHROUGH*/
13164887Schin case '{':
13174887Schin if (proto->brace++ == 0 && paren == 0)
13184887Schin {
13194887Schin if (last == '=') flags |= INIT;
13204887Schin #if PROTOMAIN
13214887Schin else if (flags & CLASSIC)
13224887Schin {
13234887Schin if ((flags & (MATCH|OTHER|SKIP)) == MATCH)
13244887Schin {
13254887Schin if (args)
13264887Schin {
13274887Schin v = number(op, args < 0 ? -args : args);
13284887Schin v = strcopy(v, " argument actual/formal mismatch");
13294887Schin *v++ = ' ';
13304887Schin v = memcopy(v, im, ie - im);
13314887Schin *v = 0;
13324887Schin proto_error((char*)proto + sizeof(struct proto), 2, op, NiL);
13334887Schin }
13344887Schin ip--;
13354887Schin /*UNDENT...*/
13364887Schin v = ie;
13374887Schin while (ie < ip)
13384887Schin if (*ie++ == '/' && *ie == '*')
13394887Schin {
13404887Schin e = ie - 1;
13414887Schin while (++ie < ip)
13424887Schin {
13434887Schin if (*ie == '*')
13444887Schin {
13454887Schin while (ie < ip && *ie == '*') ie++;
13464887Schin if (ie < ip && *ie == '/')
13474887Schin {
13484887Schin while (++ie < ip && (*ie == ' ' || *ie == '\t'));
13494887Schin while (e > v && (*(e - 1) == ' ' || *(e - 1) == '\t')) e--;
13504887Schin if (e > v && *e != '\n') *e++ = ' ';
13514887Schin t = ie;
13524887Schin while (--e >= v)
13534887Schin *--t = *e;
13544887Schin v = t;
13554887Schin break;
13564887Schin }
13574887Schin }
13584887Schin }
13594887Schin }
13604887Schin ie = v;
13614887Schin /*...INDENT*/
13624887Schin op = om++;
13634887Schin if (flags & EXTERN)
13644887Schin {
13654887Schin v = op;
13664887Schin while (v > ko && *--v != ' ');
13674887Schin if (*v != ' ')
13684887Schin {
13694887Schin om = (v = (op += 4)) + 1;
13704887Schin while (v >= ko + 4)
13714887Schin {
13724887Schin *v = *(v - 4);
13734887Schin v--;
13744887Schin }
13754887Schin memcopy(ko, "int ", 4);
13764887Schin }
13774887Schin if (*v == ' ')
13784887Schin {
13794887Schin while (*(v + 1) == '*')
13804887Schin *v++ = '*';
13814887Schin *v = '\t';
13824887Schin if ((v - ko) <= 8)
13834887Schin {
13844887Schin om = (e = ++op) + 1;
13854887Schin while (e > v)
13864887Schin {
13874887Schin *e = *(e - 1);
13884887Schin e--;
13894887Schin }
13904887Schin }
13914887Schin }
13924887Schin om = (v = (op += 7)) + 1;
13934887Schin while (v >= ko + 7)
13944887Schin {
13954887Schin *v = *(v - 7);
13964887Schin v--;
13974887Schin }
13984887Schin memcopy(ko, "extern ", 7);
13994887Schin }
14004887Schin PUTCHR('(');
14014887Schin t = op;
14024887Schin e = 0;
14034887Schin /*UNDENT...*/
14044887Schin while (ie < ip)
14054887Schin {
14064887Schin if ((c = *ie) == ' ' || c == '\t' || c == '\n')
14074887Schin {
14084887Schin while ((c = *++ie) == ' ' || c == '\t' || c == '\n');
14094887Schin if (ie >= ip) break;
14104887Schin if (c != '*' && op > om) PUTCHR(' ');
14114887Schin }
14124887Schin if ((n = ((c = *ie) == ',')) || c == ';')
14134887Schin {
14144887Schin if (flags & EXTERN)
14154887Schin {
14164887Schin m = op;
14174887Schin while (op > om && ((c = *(op - 1)) == '(' || c == ')' || c == '[' || c == ']'))
14184887Schin op--;
14194887Schin v = op;
14204887Schin while (op > om && (c = *(op - 1)) != ' ' && c != '*')
14214887Schin op--;
14224887Schin while (*(op - 1) == ' ')
14234887Schin op--;
14244887Schin if (!e)
14254887Schin {
14264887Schin e = op;
14274887Schin while (e > om && *(e - 1) == '*')
14284887Schin e--;
14294887Schin }
14304887Schin #if _s5r4_386_compiler_bug_fixed_
14314887Schin if (op <= om || *(op - 1) == ',' && (*op++ = ' '))
14324887Schin op = strcopy(op, "int");
14334887Schin #else
14344887Schin if (op <= om)
14354887Schin op = strcopy(op, "int");
14364887Schin else if (*(op - 1) == ',')
14374887Schin op = strcopy(op, " int");
14384887Schin #endif
14394887Schin while (v < m)
14404887Schin PUTCHR(*v++);
14414887Schin }
14424887Schin PUTCHR(',');
14434887Schin if (n)
14444887Schin {
14454887Schin if (x = !e) e = op - 1;
14464887Schin PUTCHR(' ');
14474887Schin m = t;
14484887Schin while (m < e)
14494887Schin PUTCHR(*m++);
14504887Schin if (x)
14514887Schin {
14524887Schin m = e;
14534887Schin while (*--e != ' ');
14544887Schin while (*(e - 1) == '*') e--;
14554887Schin op -= m - e;
14564887Schin }
14574887Schin }
14584887Schin while ((c = *++ie) == ' ' || c == '\t' || c == '\n');
14594887Schin if (ie >= ip) UNPUTCHR();
14604887Schin else PUTCHR(' ');
14614887Schin if (!n)
14624887Schin {
14634887Schin t = op;
14644887Schin e = 0;
14654887Schin }
14664887Schin }
14674887Schin else if (*ie == '*')
14684887Schin {
14694887Schin if (op > om && (c = *(op - 1)) == ' ') op--;
14704887Schin while (*ie == '*') PUTCHR(*ie++);
14714887Schin while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++;
14724887Schin if (c != '(') PUTCHR(' ');
14734887Schin }
14744887Schin else if (*ie == '(')
14754887Schin {
14764887Schin if (op > om && *(op - 1) == ' ') op--;
14774887Schin PUTCHR(*ie++);
14784887Schin while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++;
14794887Schin }
14804887Schin else if (*ie == ')')
14814887Schin {
14824887Schin if (op > om && *(op - 1) == '(')
14834887Schin proto_error((char*)proto + sizeof(struct proto), 1, "function pointer argument prototype omitted", NiL);
14844887Schin PUTCHR(*ie++);
14854887Schin while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++;
14864887Schin }
14874887Schin else if ((flags & EXTERN) && (op == om || *(op - 1) == ' ') && *ie == 'r' && !strncmp(ie, "register", 8) && (*(ie + 8) == ' ' || *(ie + 8) == '\t' || *(ie + 8) == '\n'))
14884887Schin {
14894887Schin ie += 8;
14904887Schin if (op > om) UNPUTCHR();
14914887Schin }
14924887Schin else PUTCHR(*ie++);
14934887Schin }
14944887Schin /*...INDENT*/
14954887Schin if (op <= om) op = strcopy(op, "void");
14964887Schin PUTCHR(')');
14974887Schin if (flags & EXTERN)
14984887Schin {
14994887Schin PUTCHR(';');
15004887Schin PUTCHR('\n');
15014887Schin SYNCOUT();
15024887Schin KEEPOUT();
15034887Schin }
15044887Schin else
15054887Schin {
15064887Schin PUTCHR('\n');
15074887Schin PUTCHR(*ip);
15084887Schin }
15094887Schin ip++;
15104887Schin flags &= ~(MATCH|SKIP);
15114887Schin }
15124887Schin }
15134887Schin #endif
15144887Schin else if ((flags & (MATCH|PLUSONLY|SKIP|TOKENS)) == (MATCH|TOKENS))
15154887Schin {
15164887Schin line = proto->line;
15174887Schin op = strcopy(om, " __PARAM__(");
15184887Schin op = memcopy(op, im, ie - im);
15194887Schin PUTCHR(',');
15204887Schin PUTCHR(' ');
15214887Schin PUTCHR('(');
15224887Schin flags &= ~(MATCH|SKIP);
15234887Schin if (flags & VARIADIC)
15244887Schin {
15254887Schin if ((vc = ie - im + 1) > sizeof(proto->variadic)) vc = sizeof(proto->variadic);
15264887Schin memcopy(proto->variadic, im, vc);
15274887Schin op = strcopy(op, "va_alist)) __OTORP__(va_dcl)\n{");
15284887Schin }
15294887Schin else
15304887Schin {
15314887Schin flags |= SKIP;
15324887Schin proto->ip = im;
15334887Schin proto->op = op;
15344887Schin group = 0;
15354887Schin brack = 0;
15364887Schin for (;;)
15374887Schin {
15384887Schin switch (lex(proto, (flags & GLOBAL) | RECURSIVE))
15394887Schin {
15404887Schin case '[':
15414887Schin brack++;
15424887Schin continue;
15434887Schin case ']':
15444887Schin brack--;
15454887Schin continue;
15464887Schin case '(':
15474887Schin if (paren++) group++;
15484887Schin continue;
15494887Schin case ')':
15504887Schin if (--paren == 0)
15514887Schin {
15524887Schin group = 0;
15534887Schin if (flags & MATCH)
15544887Schin {
15554887Schin flags &= ~(MATCH|SKIP);
15564887Schin op = memcopy(op, m, e - m);
15574887Schin }
15584887Schin break;
15594887Schin }
15604887Schin continue;
15614887Schin case ',':
15624887Schin if (paren == 1)
15634887Schin {
15644887Schin group = 0;
15654887Schin if (flags & MATCH)
15664887Schin {
15674887Schin flags &= ~(MATCH|SKIP);
15684887Schin op = memcopy(op, m, e - m);
15694887Schin }
15704887Schin PUTCHR(',');
15714887Schin PUTCHR(' ');
15724887Schin proto->op = op;
15734887Schin }
15744887Schin continue;
15754887Schin case T_ID:
15764887Schin if (group <= 1 && !brack)
15774887Schin {
15784887Schin flags |= MATCH;
15794887Schin m = proto->tp;
15804887Schin e = proto->ip;
15814887Schin }
15824887Schin continue;
15834887Schin default:
15844887Schin continue;
15854887Schin }
15864887Schin break;
15874887Schin }
15884887Schin PUTCHR(')');
15894887Schin PUTCHR(')');
15904887Schin }
15914887Schin if (!(flags & SKIP))
15924887Schin {
15934887Schin flags |= SKIP;
15944887Schin proto->op = strcopy(op, " __OTORP__(");
15954887Schin proto->ip = im + 1;
15964887Schin n = *(ie - 1);
15974887Schin *(ie - 1) = ';';
15984887Schin c = *ie;
15994887Schin *ie = 0;
16004887Schin lex(proto, (flags & GLOBAL) | DECLARE);
16014887Schin *(ie - 1) = n;
16024887Schin *ie = c;
16034887Schin proto->ip = ie;
16044887Schin op = proto->op;
16054887Schin PUTCHR(')');
16064887Schin }
16074887Schin if (flags & EXTERNALIZE) memcpy(proto->ox, "extern", 6);
16084887Schin op = linesync(proto, op, proto->line = line);
16094887Schin if (flags & DIRECTIVE)
16104887Schin {
16114887Schin proto->brace = 0;
16124887Schin PUTCHR('\n');
16134887Schin PUTCHR('#');
16144887Schin }
16154887Schin else if (!(flags & VARIADIC)) PUTCHR('{');
16164887Schin }
16174887Schin }
16184887Schin flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP);
16194887Schin call = 0;
16204887Schin group = 0;
16214887Schin break;
16224887Schin case '}':
16234887Schin flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP|TOKENS);
16244887Schin if (--proto->brace == 0)
16254887Schin {
16264887Schin flags &= ~(INIT|VARIADIC|VARIADIC2);
16274887Schin #if PROTOMAIN
16284887Schin if (flags & EXTERN) BACKOUT();
16294887Schin #endif
16304887Schin }
16314887Schin call = 0;
16324887Schin group = 0;
16334887Schin paren = 0;
16344887Schin break;
16354887Schin case '=':
16364887Schin if (last == '?') flags |= DIRECTIVE;
16378462SApril.Chin@Sun.COM else if (paren == 0 && (flags & (INIT|MATCH|SKIP)) == MATCH)
16388462SApril.Chin@Sun.COM {
16398462SApril.Chin@Sun.COM if (last == ')' && proto->brace && (group != 2 || call != 2)) flags |= SKIP;
16408462SApril.Chin@Sun.COM else goto fsm_statement;
16418462SApril.Chin@Sun.COM }
16424887Schin goto fsm_other;
16434887Schin case ',':
16444887Schin #if PROTOMAIN
16454887Schin if (flags & CLASSIC)
16464887Schin {
16474887Schin if (paren == 1) args++;
16484887Schin else
16494887Schin {
16504887Schin args--;
16514887Schin flags &= ~MATCH;
16524887Schin }
16534887Schin break;
16544887Schin }
16554887Schin #endif
16564887Schin if (paren == 0 && (flags & DECLARE)) *(op - 1) = c = ';';
16574887Schin /*FALLTHROUGH*/
16584887Schin case ';':
16594887Schin fsm_statement:
16604887Schin if (flags & INIT) /* ignore */;
16614887Schin #if PROTOMAIN
16624887Schin else if (flags & CLASSIC)
16634887Schin {
16644887Schin if (paren == 0)
16654887Schin {
16664887Schin if ((flags & MATCH) && last == ')')
16674887Schin flags &= ~MATCH;
16684887Schin if (!(flags & MATCH))
16694887Schin {
16704887Schin call = 0;
16714887Schin group = 0;
16724887Schin flags &= ~SKIP;
16734887Schin if (flags & EXTERN) BACKOUT();
16744887Schin if (flags & SLIDE)
16754887Schin {
16764887Schin SYNC();
16774887Schin return 0;
16784887Schin }
16794887Schin }
16804887Schin else
16814887Schin {
16824887Schin args--;
16834887Schin if ((flags & (EXTERN|SKIP)) == (EXTERN|SKIP))
16844887Schin BACKOUT();
16854887Schin }
16864887Schin }
16874887Schin }
16884887Schin #endif
16894887Schin else if (paren == 0)
16904887Schin {
16914887Schin if ((flags & (MATCH|OTHER|SKIP)) == MATCH && call > 1)
16924887Schin {
16934887Schin if ((flags & MANGLE) && func)
16944887Schin {
16954887Schin func[0] = 'F';
16964887Schin func[1] = 'U';
16974887Schin func[2] = 'N';
16984887Schin func[3] = 'C';
16994887Schin func = 0;
17004887Schin }
17014887Schin if ((flags & (DECLARE|INDIRECT)) == INDIRECT && aim && aie < im)
17024887Schin {
17034887Schin while (aie < ip && (*aie == ' ' || *aie == '\t' || *aie == '\n')) aie++;
17044887Schin v = aim;
17054887Schin while (v < aie)
17064887Schin if (*v++ == ')') break;
17074887Schin while (v < aie && (*v == ' ' || *v == '\t' || *v == '\n')) v++;
17084887Schin if (v == aie || !(flags & PLUSPLUS))
17094887Schin {
17104887Schin if (flags & PLUSPLUS) n = 3;
17114887Schin else if (v == aie && *v == '(') n = 10;
17124887Schin else n = 11;
17134887Schin ko = op;
17144887Schin om += n;
17154887Schin v = op += n;
17164887Schin while (v >= ko + n)
17174887Schin {
17184887Schin *v = *(v - n);
17194887Schin v--;
17204887Schin }
17214887Schin if (flags & PLUSPLUS) memcopy(aom, "(...))", 6);
17224887Schin else if (n == 10) memcopy(aom, "(__VARARG__))", 13);
17234887Schin else
17244887Schin {
17254887Schin ko = strcopy(aom, " __PROTO__(");
17264887Schin ko = memcopy(ko, aim, aie - aim);
17274887Schin *ko = ')';
17284887Schin if (++ko >= om)
17294887Schin {
17304887Schin *ko++ = ')';
17314887Schin om = ko;
17324887Schin }
17334887Schin }
17344887Schin }
17354887Schin }
17364887Schin else if (flags & TYPEDEF)
17374887Schin {
17384887Schin op = om;
17394887Schin while (*--op == ' ' || *op == '\t' || *op == '\n');
17404887Schin if (*op != ')')
17414887Schin {
17424887Schin op = om += 14;
17434887Schin *--op = ')';
17444887Schin while ((x = *(op - 14)) >= 'A' && x <= 'Z' || x >= 'a' && x <= 'z' || x >= '0' && x <= '9' || x == '_')
17454887Schin *--op = x;
17464887Schin memcopy(op - 13, "(__OTORP__(*)", 13);
17474887Schin }
17484887Schin }
17494887Schin if (flags & OTHER)
17504887Schin ;
17514887Schin else if (flags & PLUSPLUS)
17524887Schin {
17534887Schin op = om;
17544887Schin if (!(flags & TOKENS)) op = strcopy(op, "(...)");
17554887Schin else op = memcopy(op, im, ie - im);
17564887Schin PUTCHR(c);
17574887Schin }
17584887Schin else
17594887Schin {
17604887Schin if (flags & DECLARE) op = strcopy(om, "()");
17614887Schin else if (!(flags & TOKENS)) op = strcopy(om, "(__VARARG__)");
17624887Schin else
17634887Schin {
17644887Schin op = strcopy(om, " __PROTO__(");
17654887Schin op = memcopy(op, im, ie - im);
17664887Schin PUTCHR(')');
17674887Schin }
17684887Schin if (flags & EXTERNALIZE) memcpy(proto->ox, "extern", 6);
17694887Schin PUTCHR(c);
17704887Schin }
17714887Schin flags &= ~(MATCH|VARIADIC|VARIADIC2);
17724887Schin if (c == ',' && !(flags & INDIRECT))
17734887Schin {
17744887Schin call = 1;
17754887Schin group = 0;
17764887Schin break;
17774887Schin }
17784887Schin }
17794887Schin else if (flags & (OTHER|SKIP)) call = 0;
17804887Schin if (c == ';')
17814887Schin {
17824887Schin flags &= ~(EXTERNALIZE|MANGLE|TOKENS|TYPEDEF);
17834887Schin call = 0;
17844887Schin if (flags & SLIDE)
17854887Schin {
17864887Schin SYNC();
17874887Schin return 0;
17884887Schin }
17894887Schin }
17904887Schin else call = call > 1 && c == ',';
17914887Schin group = 0;
17924887Schin flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP);
17934887Schin }
17944887Schin else if (paren == 1 && group == 1 && !(flags & (IDID|MANGLE))) flags |= TOKENS|OTHER;
17954887Schin break;
17964887Schin case T_DO:
17974887Schin case T_IF:
17984887Schin flags |= TOKENS|SKIP;
17994887Schin break;
18004887Schin case T_EXTERN:
18014887Schin #if PROTOMAIN
18024887Schin if (flags & CLASSIC)
18034887Schin {
18044887Schin if (proto->brace == 0)
18054887Schin flags |= SKIP;
18064887Schin }
18074887Schin else
18084887Schin #endif
18094887Schin if (paren == 0 && !(flags & TYPEDEF))
18104887Schin {
18114887Schin flags |= MANGLE;
18124887Schin if (!(flags & PLUSONLY) || proto->package)
18134887Schin {
18144887Schin op = strcopy(op, " __MANGLE__");
18154887Schin if (proto->package)
18164887Schin {
18174887Schin op = strcopy(op - 1, proto->package);
18184887Schin func = op + 1;
18194887Schin op = strcopy(op, "_DATA__");
18204887Schin }
18214887Schin }
18224887Schin else
18234887Schin func = 0;
18244887Schin }
18254887Schin break;
18264887Schin case T_VARIADIC:
18274887Schin if (paren == 0 && (flags & (DECLARE|VARIADIC)) == DECLARE)
18284887Schin {
18294887Schin op -= 3;
18304887Schin SYNC();
18314887Schin return c;
18324887Schin }
18334887Schin if (paren == 1 && !(flags & SKIP))
18344887Schin flags |= VARIADIC;
18354887Schin flags |= TOKENS;
18364887Schin break;
18374887Schin case T_VOID:
18384887Schin goto fsm_id;
18394887Schin case T_VA_START:
18404887Schin if ((flags & (PLUSONLY|VARIADIC)) == VARIADIC)
18414887Schin {
18424887Schin flags &= ~MATCH;
18434887Schin line = proto->line;
18444887Schin op = strcopy(op - 8, "__VA_START__");
18454887Schin SYNC();
18464887Schin for (;;)
18474887Schin {
18484887Schin switch (lex(proto, (flags & GLOBAL) | RECURSIVE))
18494887Schin {
18504887Schin case 0:
18514887Schin case ';':
18524887Schin break;
18534887Schin case T_ID:
18544887Schin if (!(flags & MATCH))
18554887Schin {
18564887Schin flags |= MATCH;
18574887Schin m = proto->tp;
18584887Schin e = proto->ip;
18594887Schin }
18604887Schin continue;
18614887Schin default:
18624887Schin continue;
18634887Schin }
18644887Schin break;
18654887Schin }
18664887Schin CACHE();
18674887Schin if (flags & MATCH)
18684887Schin {
18694887Schin v = m;
18704887Schin n = e - m;
18714887Schin }
18724887Schin else
18734887Schin {
18744887Schin v = "ap";
18754887Schin n = 2;
18764887Schin }
18774887Schin op = strcopy(op, " __OTORP__(");
18784887Schin proto->ip = proto->variadic;
18794887Schin proto->op = op;
18804887Schin flags &= ~MATCH;
18814887Schin group = 0;
18824887Schin bp = proto->ip + 1;
18834887Schin if (*bp == 'r' && !strncmp(bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9;
18844887Schin for (;;)
18854887Schin {
18864887Schin switch (lex(proto, (flags & GLOBAL) | RECURSIVE))
18874887Schin {
18884887Schin case '(':
18894887Schin if (paren++) group++;
18904887Schin continue;
18914887Schin case ')':
18924887Schin if (--paren == 0)
18934887Schin {
18944887Schin if (flags & MATCH)
18954887Schin {
18964887Schin flags &= ~MATCH;
18974887Schin if (!(flags & VARIADIC2))
18984887Schin {
18994887Schin op = memcopy(op, m, e - m);
19004887Schin op = strcopy(op, " = ");
19014887Schin }
19024887Schin op = strcopy(op, "va_arg(");
19034887Schin op = memcopy(op, v, n);
19044887Schin PUTCHR(',');
19054887Schin PUTCHR(' ');
19064887Schin if (m > bp) op = memcopy(op, bp, m - bp);
19074887Schin else op = strcopy(op, "int ");
19084887Schin if (group > 1) op = strcopy(op, ")()");
19094887Schin else op = memcopy(op, e, proto->ip - e - 1);
19104887Schin PUTCHR(')');
19114887Schin PUTCHR(';');
19124887Schin }
19134887Schin group = 0;
19144887Schin break;
19154887Schin }
19164887Schin continue;
19174887Schin case ',':
19184887Schin if (paren == 1)
19194887Schin {
19204887Schin if (flags & MATCH)
19214887Schin {
19224887Schin flags &= ~MATCH;
19234887Schin if (!(flags & VARIADIC2))
19244887Schin {
19254887Schin op = memcopy(op, m, e - m);
19264887Schin op = strcopy(op, " = ");
19274887Schin }
19284887Schin op = strcopy(op, "va_arg(");
19294887Schin op = memcopy(op, v, n);
19304887Schin PUTCHR(',');
19314887Schin PUTCHR(' ');
19324887Schin if (m > bp) op = memcopy(op, bp, m - bp);
19334887Schin else op = strcopy(op, "int ");
19344887Schin if (group > 1) op = strcopy(op, ")()");
19354887Schin else op = memcopy(op, e, proto->ip - e - 1);
19364887Schin PUTCHR(')');
19374887Schin PUTCHR(';');
19384887Schin bp = proto->ip + 1;
19394887Schin if (*bp == 'r' && !strncmp(bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9;
19404887Schin }
19414887Schin group = 0;
19424887Schin proto->op = op;
19434887Schin }
19444887Schin continue;
19454887Schin case T_ID:
19464887Schin if (group <= 1)
19474887Schin {
19484887Schin flags |= MATCH;
19494887Schin m = proto->tp;
19504887Schin e = proto->ip;
19514887Schin }
19524887Schin continue;
19534887Schin default:
19544887Schin continue;
19554887Schin }
19564887Schin break;
19574887Schin }
19584887Schin op = strcopy(op, ")");
19594887Schin flags |= VARIADIC2;
19604887Schin proto->line = line;
19614887Schin call = 0;
19624887Schin break;
19634887Schin }
19644887Schin /*FALLTHROUGH*/
19654887Schin case T_ID:
19664887Schin fsm_id:
19674887Schin #if PROTOMAIN
19684887Schin if (flags & CLASSIC)
19694887Schin {
19704887Schin if (!args && paren == 1) args++;
19714887Schin break;
19724887Schin }
19734887Schin #endif
19744887Schin if (paren == 0)
19754887Schin {
19764887Schin if (last == ')')
19774887Schin {
19784887Schin if (proto->brace == 0 && !(flags & DECLARE)) flags |= SKIP;
19794887Schin call = !call;
19804887Schin }
19814887Schin else if ((flags & SKIP) || c == T_ID || c == T_VOID) call++;
19824887Schin else flags |= SKIP;
19834887Schin if (last == T_ID) flags |= IDID;
19844887Schin }
19854887Schin c = T_ID;
19864887Schin flags |= TOKENS;
19874887Schin break;
19884887Schin case T_INVALID:
19894887Schin if (*proto->tp >= '0' && *proto->tp <= '9')
19904887Schin {
19914887Schin n = 0;
19924887Schin for (;; op--)
19934887Schin {
19944887Schin switch (*(op - 1))
19954887Schin {
19964887Schin case 'f':
19974887Schin case 'F':
19984887Schin t = op;
19994887Schin while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
20004887Schin if (*t == '.')
20014887Schin op--;
20024887Schin n = 0;
20034887Schin break;
20044887Schin case 'l':
20054887Schin case 'L':
20064887Schin if (!(n & 01))
20074887Schin {
20084887Schin n |= 01;
20094887Schin t = op;
20104887Schin while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
20114887Schin if (*t == '.')
20124887Schin {
20134887Schin n = 0;
20144887Schin op--;
20154887Schin break;
20164887Schin }
20174887Schin }
20184887Schin continue;
20194887Schin case 'u':
20204887Schin case 'U':
20214887Schin n |= 02;
20224887Schin continue;
20234887Schin }
20244887Schin break;
20254887Schin }
20264887Schin if (n & 01)
20274887Schin *op++ = 'L';
20284887Schin if (n & 02)
20294887Schin {
20304887Schin m = op;
20314887Schin t = op = m + 10;
20324887Schin while ((c = *--m) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
20334887Schin *--t = c;
20344887Schin c = *t;
20354887Schin strcopy(m + 1, "(unsigned)");
20364887Schin *t = c;
20374887Schin break;
20384887Schin }
20394887Schin }
20404887Schin goto fsm_other;
20414887Schin #if PROTOMAIN
20424887Schin case '[':
20434887Schin if ((flags & CLASSIC) && paren == 0 && group <= 2) flags |= SKIP;
20444887Schin /*FALLTHROUGH*/
20454887Schin #endif
20464887Schin default:
20474887Schin fsm_other:
20484887Schin #if PROTOMAIN
20494887Schin if (flags & CLASSIC) break;
20504887Schin #endif
20514887Schin flags |= TOKENS;
20524887Schin if (paren == 0) flags |= OTHER;
20534887Schin break;
20544887Schin }
20554887Schin else if (c == '#' && *ip != '(') flags |= SHARP;
20564887Schin last = c;
20574887Schin #if PROTOMAIN
20584887Schin if ((flags & (EXTERN|MATCH)) == (EXTERN|MATCH) && ((flags & (DIRECTIVE|SKIP)) || proto->brace || c != '(' && c != ')' && c != '*' && c != T_ID))
20594887Schin CACHEOUT();
20604887Schin else
20614887Schin #endif
20624887Schin SYNCOUT();
20634887Schin goto fsm_start;
20644887Schin }
20654887Schin else if (flags & (INIT_DEFINE|INIT_INCLUDE))
20664887Schin {
20674887Schin #if PROTOMAIN
20684887Schin if ((flags & YACC) && c == '%' && *ip == '{') t = 0;
20694887Schin else
20704887Schin #endif
20714887Schin {
20724887Schin if (c == '#') for (t = ip; *t == ' ' || *t == '\t'; t++);
20734887Schin else t = "";
20744887Schin if (*t++ == 'i' && *t++ == 'f' && *t++ == 'n' && *t++ == 'd' && *t++ == 'e' && *t++ == 'f')
20754887Schin {
20764887Schin #if !PROTOMAIN
20774887Schin while (*t == ' ' || *t == '\t') t++;
20784887Schin if (*t != '_')
20794887Schin #endif
20804887Schin t = 0;
20814887Schin }
20824887Schin }
20834887Schin if (t)
20844887Schin {
20854887Schin ip = bp;
20864887Schin op = proto->op;
20874887Schin }
20884887Schin else while (*ip != '\n') *op++ = *ip++;
20894887Schin op = init(proto, op, flags);
20904887Schin op = linesync(proto, op, proto->line);
20914887Schin flags &= ~(INIT_DEFINE|INIT_INCLUDE);
20924887Schin proto->flags &= ~(INIT_DEFINE|INIT_INCLUDE);
20934887Schin goto fsm_start;
20944887Schin }
20954887Schin SYNC();
20964887Schin return c;
20974887Schin }
20984887Schin
20994887Schin /*
21004887Schin * close a proto buffer stream
21014887Schin */
21024887Schin
21034887Schin void
pppclose(char * iob)21044887Schin pppclose(char* iob)
21054887Schin {
21064887Schin register struct proto* proto = (struct proto*)(iob - sizeof(struct proto));
21074887Schin
21084887Schin if (proto->flags & MORE) close(proto->fd);
21094887Schin free((char*)proto); /* some ANSI cc's botch the free() prototype */
21104887Schin }
21114887Schin
21124887Schin /*
21134887Schin * open a new proto buffer stream
21144887Schin * read buffer pointer returned
21154887Schin * 0 returned on error or if no magic
21164887Schin *
21174887Schin * file !=0 file path to open, otherwise use fd
21184887Schin * fd open file fd if file==0
21194887Schin * notice !=0 copyright notice info commented at the top
21204887Schin * options !=0 additional notice name=value pairs, space or ; separated
21214887Schin * package !=0 generate header for this package
21224887Schin */
21234887Schin
21244887Schin char*
pppopen(char * file,int fd,char * notice,char * options,char * package,char * comment,int flags)21254887Schin pppopen(char* file, int fd, char* notice, char* options, char* package, char* comment, int flags)
21264887Schin {
21274887Schin register struct proto* proto;
21284887Schin register char* iob;
21294887Schin register long n;
21304887Schin register char* s;
21314887Schin int pragma;
21324887Schin char* b;
21334887Schin #if PROTOMAIN
21344887Schin int comlen;
21354887Schin char com[80];
21364887Schin #endif
21374887Schin int m = 0;
21384887Schin
21394887Schin static int retain;
21404887Schin
21414887Schin /*
21424887Schin * initialize proto
21434887Schin */
21444887Schin
21454887Schin #if PROTOMAIN
21464887Schin if (flags & PROTO_CLASSIC) flags &= ~PROTO_INCLUDE;
21474887Schin #endif
21484887Schin if (flags & PROTO_RETAIN) flags &= ~retain;
21494887Schin else retain &= PROTO_INITIALIZED;
21504887Schin if (file && (fd = open(file, O_RDONLY)) < 0) return 0;
21514887Schin #if !PROTOMAIN
21524887Schin if ((n = lseek(fd, 0L, 2)) > 0)
21534887Schin {
21544887Schin if (lseek(fd, 0L, 0)) return 0;
21554887Schin if (n < CHUNK) n = CHUNK;
21564887Schin else if (n > 2 * BLOCK) n = 0;
21574887Schin m = 1;
21584887Schin }
21594887Schin if (n > 0)
21604887Schin {
21614887Schin /*
21624887Schin * file read in one chunk
21634887Schin */
21644887Schin
21654887Schin if (!(proto = newof(0, struct proto, 1, 4 * n + 2)))
21664887Schin return 0;
21674887Schin proto->iz = n;
21684887Schin proto->oz = 3 * n;
21694887Schin n = 0;
21704887Schin }
21714887Schin else
21724887Schin #endif
21734887Schin {
21744887Schin /*
21754887Schin * file read in BLOCK chunks
21764887Schin */
21774887Schin
21784887Schin n = BLOCK;
21794887Schin if (!(proto = newof(0, struct proto, 1, 5 * n + 2)))
21804887Schin return 0;
21814887Schin proto->iz = n;
21824887Schin proto->oz = 3 * n;
21834887Schin proto->flags |= MORE;
21844887Schin }
21854887Schin proto->fd = fd;
21864887Schin proto->package = package;
21874887Schin iob = (char*)proto + sizeof(struct proto);
21884887Schin proto->op = proto->ob = iob;
21894887Schin proto->ip = proto->ib = iob + proto->oz + n;
21904887Schin if (m) proto->options |= REGULAR;
21914887Schin if (!comment)
21924887Schin comment = "/*";
21934887Schin if (!(proto->cc[0] = comment[0]))
21944887Schin notice = options = 0;
21954887Schin else if (comment[1])
21964887Schin {
21974887Schin proto->cc[1] = comment[1];
21984887Schin proto->cc[2] = comment[2] ? comment[2] : comment[0];
21994887Schin }
22004887Schin else
22014887Schin proto->cc[1] = proto->cc[2] = comment[0];
22024887Schin
22034887Schin /*
22044887Schin * read the first chunk
22054887Schin */
22064887Schin
22074887Schin n = read(fd, proto->ip, proto->iz);
22084887Schin if (!(proto->flags & MORE))
22094887Schin close(fd);
22104887Schin if (n < 0)
22114887Schin {
22124887Schin pppclose(iob);
22134887Schin return 0;
22144887Schin }
22154887Schin *(proto->ip + n) = 0;
22164887Schin
22174887Schin /*
22184887Schin * check for proto pragma in first block of lines
22194887Schin * pragma blanked out if found
22204887Schin *
22214887Schin * -1 no pragma
22224887Schin * 0 #pragma noprototyped
22234887Schin * 1 #pragma prototyped
22244887Schin *
22254887Schin * NOTE: matches may occur inside comments and quotes
22264887Schin */
22274887Schin
22284887Schin #if PROTOMAIN
22294887Schin if (!notice && !options || (comlen = astlicense(com, sizeof(com), NiL, "type=check", proto->cc[0], proto->cc[1], proto->cc[2])) <= 0)
22304887Schin *com = 0;
22314887Schin #endif
22324887Schin pragma = -1;
22334887Schin s = proto->ip;
22344887Schin m = MAGICTOP;
22354887Schin while (m-- > 0 && *s)
22364887Schin {
22374887Schin while (*s == ' ' || *s == '\t') s++;
22384887Schin if (*s == '#')
22394887Schin {
22404887Schin b = s++;
22414887Schin while (*s == ' ' || *s == '\t') s++;
22424887Schin if (!strncmp(s, MAGICDIR, sizeof(MAGICDIR) - 1) && (*(s += sizeof(MAGICDIR) - 1) == ' ' || *s == '\t'))
22434887Schin {
22444887Schin while (*s == ' ' || *s == '\t') s++;
22454887Schin if (*s == 'n' && *(s + 1) == 'o')
22464887Schin {
22474887Schin s += 2;
22484887Schin pragma = -2;
22494887Schin }
22504887Schin if (!strncmp(s, MAGICARG, sizeof(MAGICARG) - 1) && (*(s += sizeof(MAGICARG) - 1) == ' ' || *s == '\t' || *s == '\n' || *s == '\r'))
22514887Schin while (*s)
22524887Schin {
22534887Schin if ((*(s - 1) == ' ' || *(s - 1) == '\t') && *s == *MAGICOFF && !strncmp(s, MAGICOFF, sizeof(MAGICOFF) - 1))
22544887Schin notice = options = 0;
22554887Schin if (*s++ == '\n')
22564887Schin {
22574887Schin pragma += 2;
22584887Schin #if PROTOMAIN
22594887Schin if (!(flags & PROTO_DISABLE) || (flags & PROTO_NOPRAGMA))
22604887Schin #endif
22614887Schin for (s--; b < s; *b++ = ' ');
22624887Schin goto magic;
22634887Schin }
22644887Schin }
22654887Schin pragma = -1;
22664887Schin }
22674887Schin }
22684887Schin else if (*s == '/' && !strncmp(s, MAGICGEN, sizeof(MAGICGEN) - 1))
22694887Schin {
22704887Schin pragma = 0;
22714887Schin break;
22724887Schin }
22734887Schin #if PROTOMAIN
22744887Schin else if (*s == '%' && *(s + 1) == '{')
22754887Schin proto->flags |= YACC;
22764887Schin if (notice || options)
22774887Schin {
22784887Schin if (*s == *com && !strncmp(s, com, comlen))
22794887Schin notice = options = 0;
22804887Schin else
22814887Schin while (*s)
22824887Schin {
22834887Schin if (*s == *NOTICED && !strncmp(s, NOTICED, sizeof(NOTICED) - 1))
22844887Schin {
22854887Schin s += sizeof(NOTICED) - 1;
22864887Schin while (*s == ' ' || *s == '\t')
22874887Schin s++;
22884887Schin if (*s == '(' && (*(s + 1) == 'c' || *(s + 1) == 'C') && *(s + 2) == ')' || *s >= '0' && *s <= '9' && *(s + 1) >= '0' && *(s + 1) <= '9')
22894887Schin {
22904887Schin notice = options = 0;
22914887Schin break;
22924887Schin }
22934887Schin }
22948462SApril.Chin@Sun.COM if (*s == *PUBLICDOMAIN && !strncmp(s, PUBLICDOMAIN, sizeof(PUBLICDOMAIN) - 1))
22958462SApril.Chin@Sun.COM {
22968462SApril.Chin@Sun.COM notice = options = 0;
22978462SApril.Chin@Sun.COM break;
22988462SApril.Chin@Sun.COM }
22994887Schin else if (*s++ == '\n')
23004887Schin {
23014887Schin s--;
23024887Schin break;
23034887Schin }
23044887Schin }
23054887Schin }
23064887Schin #endif
23074887Schin while (*s && *s++ != '\n');
23084887Schin }
23094887Schin magic:
23104887Schin if (flags & PROTO_PLUSPLUS) proto->flags |= PLUSPLUS;
23114887Schin if (flags & PROTO_TEST) proto->test = 1;
23124887Schin if (flags & PROTO_EXTERNALIZE) proto->options |= EXTERNALIZE;
23134887Schin #if PROTOMAIN
23144887Schin if (flags & PROTO_CLASSIC) pragma = -pragma;
23154887Schin if (flags & PROTO_DISABLE) pragma = 0;
23164887Schin if (flags & PROTO_LINESYNC) proto->flags |= LINESYNC;
23174887Schin if (!(proto->flags & YACC) && file && (m = strlen(file)) > 2 && file[--m] == 'y' && file[--m] == '.')
23184887Schin proto->flags |= YACC;
23194887Schin #endif
23204887Schin if (pragma <= 0)
23214887Schin {
23224887Schin if (flags & PROTO_PLUSPLUS)
23234887Schin {
23244887Schin flags &= ~(PROTO_HEADER|PROTO_INCLUDE);
23254887Schin proto->flags |= PLUSONLY;
23264887Schin }
23274887Schin else if (!(flags & (PROTO_FORCE|PROTO_PASS)))
23284887Schin {
23294887Schin pppclose(iob);
23304887Schin return 0;
23314887Schin }
23324887Schin else if ((flags & (PROTO_FORCE|PROTO_PASS)) == PROTO_PASS || !pragma)
23334887Schin {
23344887Schin proto->flags |= PASS;
23354887Schin if (proto->flags & MORE)
23364887Schin proto->oz += proto->iz;
23374887Schin proto->iz = n;
23384887Schin if (notice || options)
23394887Schin {
23404887Schin if (proto->cc[0] == '#' && proto->ip[0] == '#' && proto->ip[1] == '!')
23414887Schin {
23424887Schin s = proto->ip;
23434887Schin while (*s && *s++ != '\n');
23444887Schin m = s - proto->ip;
23454887Schin proto->op = memcopy(proto->op, proto->ip, m);
23464887Schin proto->ip = s;
23474887Schin proto->iz = n -= m;
23484887Schin }
23494887Schin #if PROTOMAIN
23504887Schin if (proto->cc[0])
23514887Schin {
23524887Schin if ((comlen = astlicense(proto->op, proto->oz, notice, options, proto->cc[0], proto->cc[1], proto->cc[2])) < 0)
23534887Schin proto_error((char*)proto + sizeof(struct proto), 1, proto->op, NiL);
23544887Schin else
23554887Schin proto->op += comlen;
23564887Schin }
23574887Schin if (!(flags & PROTO_CLASSIC) && !(proto->flags & YACC))
23584887Schin #endif
23594887Schin proto->op = linesync(proto, proto->op, 1);
23604887Schin proto->iz += proto->op - proto->ob;
23614887Schin }
23624887Schin memcopy(proto->op, proto->ip, n);
23634887Schin return iob;
23644887Schin }
23654887Schin }
23664887Schin #if PROTOMAIN
23674887Schin if (!(retain & PROTO_INITIALIZED))
23684887Schin {
23694887Schin retain |= PROTO_INITIALIZED;
23704887Schin ppfsm(FSM_INIT, NiL);
23714887Schin }
23724887Schin #endif
23734887Schin proto->line = 1;
23744887Schin #if CHUNK >= 512
23754887Schin if (notice || options || (flags & (PROTO_HEADER|PROTO_INCLUDE)))
23764887Schin {
23774887Schin #if PROTOMAIN
23784887Schin if (notice || options)
23794887Schin {
23804887Schin if ((comlen = astlicense(proto->op, proto->oz, notice, options, proto->cc[0], proto->cc[1], proto->cc[2])) < 0)
23814887Schin proto_error((char*)proto + sizeof(struct proto), 1, proto->op, NiL);
23824887Schin else
23834887Schin proto->op += comlen;
23844887Schin }
23854887Schin #endif
23864887Schin if (flags & PROTO_INCLUDE)
23874887Schin {
23884887Schin proto->flags |= INIT_INCLUDE;
23894887Schin if (flags & PROTO_RETAIN)
23904887Schin retain |= PROTO_INCLUDE;
23914887Schin }
23924887Schin else if (flags & PROTO_HEADER)
23934887Schin {
23944887Schin if (flags & PROTO_RETAIN) retain |= PROTO_HEADER;
23954887Schin #if PROTOMAIN
23964887Schin if (flags & PROTO_CLASSIC)
23974887Schin {
23984887Schin *proto->op++ = '#';
23994887Schin proto->op = strcopy(proto->op, MAGICDIR);
24004887Schin *proto->op++ = ' ';
24014887Schin proto->op = strcopy(proto->op, MAGICARG);
24024887Schin *proto->op++ = '\n';
24034887Schin }
24044887Schin else
24054887Schin #endif
24064887Schin proto->flags |= INIT_DEFINE;
24074887Schin }
24084887Schin #if PROTOMAIN
24094887Schin if (!(flags & PROTO_CLASSIC))
24104887Schin {
24114887Schin if (proto->flags & YACC)
24124887Schin {
24134887Schin proto->op = strcopy(proto->op, "\n%{\n" + !notice);
24144887Schin proto->op = strcopy(proto->op, MAGICGEN);
24154887Schin proto->op = strcopy(proto->op, "%}\n");
24164887Schin }
24174887Schin else
24184887Schin {
24194887Schin if (n || notice || options)
24204887Schin *proto->op++ = '\n';
24214887Schin proto->op = strcopy(proto->op, MAGICGEN);
24224887Schin if (n)
24234887Schin proto->op = linesync(proto, proto->op, proto->line);
24244887Schin else if (proto->flags & (INIT_DEFINE|INIT_INCLUDE))
24254887Schin proto->op = init(proto, proto->op, proto->flags);
24264887Schin }
24274887Schin }
24284887Schin #endif
24294887Schin }
24304887Schin #endif
24314887Schin #if PROTOMAIN
24324887Schin proto->file = file;
24334887Schin if (flags & PROTO_CLASSIC)
24344887Schin {
24354887Schin proto->flags |= CLASSIC;
24364887Schin if (!(flags & PROTO_HEADER)) proto->flags |= EXTERN;
24374887Schin }
24384887Schin #endif
24394887Schin return iob;
24404887Schin }
24414887Schin
24424887Schin /*
24434887Schin * read next proto'd chunk into iob
24444887Schin * the chunk is 0 terminated and its size is returned
24454887Schin */
24464887Schin
24474887Schin int
pppread(char * iob)24484887Schin pppread(char* iob)
24494887Schin {
24504887Schin register struct proto* proto = (struct proto*)(iob - sizeof(struct proto));
24514887Schin register int n;
24524887Schin
24534887Schin if (proto->flags & PASS)
24544887Schin {
24554887Schin if (proto->iz)
24564887Schin {
24574887Schin n = proto->iz;
24584887Schin proto->iz = 0;
24594887Schin }
24604887Schin else if (!(proto->flags & MORE)) n = 0;
24614887Schin else if ((n = read(proto->fd, proto->ob, proto->oz)) <= 0 || (proto->options & REGULAR) && n < proto->oz)
24624887Schin {
24634887Schin proto->flags &= ~MORE;
24644887Schin close(proto->fd);
24654887Schin }
24664887Schin }
24674887Schin else
24684887Schin {
24694887Schin if (proto->op == proto->ob)
24704887Schin {
24714887Schin if (proto->flags & ERROR) return -1;
24724887Schin #if PROTOMAIN
24734887Schin if (proto->flags & YACC)
24744887Schin {
24754887Schin register char* ip = proto->ip;
24764887Schin register char* op = proto->ob;
24774887Schin register char* ep = proto->ob + proto->oz - 2;
24784887Schin
24794887Schin if (!*ip)
24804887Schin {
24814887Schin ip = proto->ip = proto->ib;
24824887Schin if (!(proto->flags & MORE)) n = 0;
24834887Schin else if ((n = read(proto->fd, ip, proto->iz)) <= 0 || (proto->options & REGULAR) && n < proto->iz)
24844887Schin {
24854887Schin if (n < 0) n = 0;
24864887Schin proto->flags &= ~MORE;
24874887Schin close(proto->fd);
24884887Schin }
24894887Schin ip[n] = 0;
24904887Schin }
24914887Schin if (proto->flags & YACCSPLIT)
24924887Schin {
24934887Schin proto->flags &= ~YACCSPLIT;
24944887Schin if (*ip == '%')
24954887Schin {
24964887Schin *op++ = *ip++;
24974887Schin if (proto->flags & YACC2) proto->flags &= ~YACC;
24984887Schin else proto->flags |= YACC2;
24994887Schin }
25004887Schin }
25014887Schin if (proto->flags & YACC)
25024887Schin while (op < ep && (n = *op++ = *ip))
25034887Schin {
25044887Schin ip++;
25054887Schin if (n == '%')
25064887Schin {
25074887Schin if (*ip == '%' && (ip == proto->ip + 1 || *(ip - 2) == '\n'))
25084887Schin {
25094887Schin *op++ = *ip++;
25104887Schin if (proto->flags & YACC2) proto->flags &= ~YACC;
25114887Schin else proto->flags |= YACC2;
25124887Schin break;
25134887Schin }
25144887Schin if (!*ip)
25154887Schin {
25164887Schin *op++ = '%';
25174887Schin proto->flags |= YACCSPLIT;
25184887Schin break;
25194887Schin }
25204887Schin }
25214887Schin else if (n == '\n') proto->line++;
25224887Schin }
25234887Schin proto->op = memcopy(proto->ob, proto->ip, ip - proto->ip);
25244887Schin proto->ip = ip;
25254887Schin }
25264887Schin else
25274887Schin #endif
25284887Schin lex(proto, proto->flags);
25294887Schin if ((proto->flags & (ERROR|MORE)) == ERROR)
25304887Schin proto->op = strcopy(proto->op, "/* NOTE: some constructs may not have been converted */\n");
25314887Schin }
25324887Schin n = proto->op - proto->ob;
25334887Schin proto->op = proto->ob;
25344887Schin }
25354887Schin return n;
25364887Schin }
25374887Schin
25384887Schin #if !PROTOMAIN
25394887Schin
25404887Schin /*
25414887Schin * drop control of iob after first pppread()
25424887Schin * return value is input fd
25434887Schin * if fd<0 then all data in iob
25444887Schin */
25454887Schin
25464887Schin int
pppdrop(char * iob)25474887Schin pppdrop(char* iob)
25484887Schin {
25494887Schin register struct proto* proto = (struct proto*)(iob - sizeof(struct proto));
25504887Schin
25514887Schin if (proto->flags & MORE)
25524887Schin {
25534887Schin proto->flags &= ~MORE;
25544887Schin return proto->fd;
25554887Schin }
25564887Schin return -1;
25574887Schin }
25584887Schin
25594887Schin #endif
2560