14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1986-2008 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 7*8462SApril.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 32*8462SApril.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 */ 58*8462SApril.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* 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 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 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* 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 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* 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* 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* 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* 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 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 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; 1637*8462SApril.Chin@Sun.COM else if (paren == 0 && (flags & (INIT|MATCH|SKIP)) == MATCH) 1638*8462SApril.Chin@Sun.COM { 1639*8462SApril.Chin@Sun.COM if (last == ')' && proto->brace && (group != 2 || call != 2)) flags |= SKIP; 1640*8462SApril.Chin@Sun.COM else goto fsm_statement; 1641*8462SApril.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 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* 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 } 2294*8462SApril.Chin@Sun.COM if (*s == *PUBLICDOMAIN && !strncmp(s, PUBLICDOMAIN, sizeof(PUBLICDOMAIN) - 1)) 2295*8462SApril.Chin@Sun.COM { 2296*8462SApril.Chin@Sun.COM notice = options = 0; 2297*8462SApril.Chin@Sun.COM break; 2298*8462SApril.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 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 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