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 * preprocessor library private definitions 264887Schin */ 274887Schin 284887Schin #ifndef _PPLIB_H 294887Schin #define _PPLIB_H 304887Schin 314887Schin /* 324887Schin * the first definitions control optional code -- 0 disables 334887Schin */ 344887Schin 354887Schin #ifndef ARCHIVE 364887Schin #define ARCHIVE 1 /* -I can specify header archives */ 374887Schin #endif 384887Schin #ifndef CATSTRINGS 394887Schin #define CATSTRINGS 1 /* concatenate adjacent strings */ 404887Schin #endif 414887Schin #ifndef CHECKPOINT 424887Schin #define CHECKPOINT 1 /* checkpoint preprocessed files */ 434887Schin #endif 444887Schin #ifndef COMPATIBLE 454887Schin #define COMPATIBLE 1 /* enable COMPATIBILITY related code */ 464887Schin #endif 474887Schin #ifndef MACKEYARGS 484887Schin #define MACKEYARGS _BLD_DEBUG /* name=value macro formals and actuals */ 494887Schin #endif 504887Schin #ifndef POOL 514887Schin #define POOL 1 /* enable loop on input,output,error */ 524887Schin #endif 534887Schin #ifndef PROTOTYPE 544887Schin #define PROTOTYPE 1 /* enable ppproto code */ 554887Schin #endif 564887Schin 574887Schin #define TRUNCLENGTH 8 /* default TRUNCATE length */ 584887Schin 594887Schin #if _BLD_DEBUG 604887Schin #undef DEBUG 614887Schin #define DEBUG (TRACE_message|TRACE_count|TRACE_debug) 624887Schin #else 634887Schin #ifndef DEBUG 644887Schin #define DEBUG (TRACE_message) 654887Schin #endif 664887Schin #endif 674887Schin 684887Schin /* 694887Schin * the lower tests are transient 704887Schin */ 714887Schin 724887Schin #define TEST_count (1L<<24) 734887Schin #define TEST_hashcount (1L<<25) 744887Schin #define TEST_hashdump (1L<<26) 754887Schin #define TEST_hit (1L<<27) 764887Schin #define TEST_noinit (1L<<28) 774887Schin #define TEST_nonoise (1L<<29) 784887Schin #define TEST_noproto (1L<<30) 794887Schin 804887Schin #define TEST_INVERT (1L<<31) 814887Schin 824887Schin #define PROTO_CLASSIC (1<<0) /* classic to prototyped */ 834887Schin #define PROTO_DISABLE (1<<1) /* disable conversion */ 844887Schin #define PROTO_EXTERNALIZE (1<<2) /* static fun() => extern fun() */ 854887Schin #define PROTO_FORCE (1<<3) /* force even if no magic */ 864887Schin #define PROTO_HEADER (1<<4) /* header defines too */ 874887Schin #define PROTO_INCLUDE (1<<5) /* <prototyped.h> instead */ 884887Schin #define PROTO_INITIALIZED (1<<6) /* internal initialization */ 894887Schin #define PROTO_LINESYNC (1<<7) /* force standalone line syncs */ 904887Schin #define PROTO_NOPRAGMA (1<<8) /* delete pragma prototyped */ 914887Schin #define PROTO_PASS (1<<9) /* pass blocks if no magic */ 924887Schin #define PROTO_PLUSPLUS (1<<10) /* extern () -> extern (...) */ 934887Schin #define PROTO_RETAIN (1<<11) /* defines retained after close */ 944887Schin #define PROTO_TEST (1<<12) /* enable test code */ 954887Schin 964887Schin #define PROTO_USER (1<<13) /* first user flag */ 974887Schin 984887Schin #define SEARCH_EXISTS 0 /* ppsearch for existence */ 994887Schin #define SEARCH_HOSTED (1<<0) /* search hosted dirs only */ 1004887Schin #define SEARCH_IGNORE (1<<1) /* ignore if not found */ 1014887Schin #define SEARCH_INCLUDE (1<<2) /* ppsearch for include */ 1024887Schin #define SEARCH_VENDOR (1<<3) /* search vendor dirs only */ 1034887Schin #define SEARCH_USER (1<<4) /* first user flag */ 1044887Schin 1054887Schin #define STYLE_gnu (1<<0) /* gnu style args */ 1064887Schin 1074887Schin #define IN_c (1<<0) /* C language file */ 1084887Schin #define IN_defguard (1<<1) /* did multiple include check */ 1094887Schin #define IN_disable (1<<2) /* saved state&DISABLE */ 1104887Schin #define IN_endguard (1<<3) /* did multiple include check */ 1114887Schin #define IN_eof (1<<4) /* reached EOF */ 1124887Schin #define IN_expand (1<<5) /* ppexpand buffer */ 1134887Schin #define IN_flush (1<<6) /* flush stdout on file_refill()*/ 1144887Schin #define IN_hosted (1<<7) /* saved mode&HOSTED */ 1154887Schin #define IN_ignoreline (1<<8) /* ignore #line until file */ 1164887Schin #define IN_newline (1<<9) /* newline at end of last fill */ 1174887Schin #define IN_noguard (1<<10) /* no multiple include guard */ 1184887Schin #define IN_prototype (1<<11) /* ppproto() input */ 1194887Schin #define IN_regular (1<<12) /* regular input file */ 1204887Schin #define IN_static (1<<13) /* static buffer - don't free */ 1214887Schin #define IN_sync (1<<14) /* line sync required on pop */ 1224887Schin #define IN_tokens (1L<<15)/* non-space tokens encountered */ 1234887Schin 1244887Schin #define OPT_GLOBAL (1<<0) /* pp: pass optional */ 1254887Schin #define OPT_PASS (1<<1) /* pass on */ 1264887Schin 1274887Schin struct ppsymbol; 1284887Schin struct ppindex; 1294887Schin 1304887Schin typedef char* (*PPBUILTIN)(char*, const char*, const char*); 1314887Schin typedef void (*PPCOMMENT)(const char*, const char*, const char*, int); 1324887Schin typedef void (*PPINCREF)(const char*, const char*, int, int); 1334887Schin typedef void (*PPLINESYNC)(int, const char*); 1344887Schin typedef void (*PPMACREF)(struct ppsymbol*, const char*, int, int, unsigned long); 1354887Schin typedef int (*PPOPTARG)(int, int, const char*); 1364887Schin typedef void (*PPPRAGMA)(const char*, const char*, const char*, const char*, int); 1374887Schin 1384887Schin struct ppinstk /* input stream stack frame */ 1394887Schin { 1404887Schin char* nextchr; /* next input char (first elt) */ 1414887Schin struct ppinstk* next; /* next frame (for allocation) */ 1424887Schin struct ppinstk* prev; /* previous frame */ 1434887Schin long* control; /* control block level */ 1444887Schin char* buffer; /* buffer base pointer */ 1454887Schin char* file; /* saved file name */ 1464887Schin char* prefix; /* directory prefix */ 1474887Schin struct ppsymbol* symbol; /* macro info */ 1484887Schin #if CHECKPOINT 1494887Schin struct ppindex* index; /* checkpoint include index */ 1504887Schin int buflen; /* buffer count */ 1514887Schin #endif 1524887Schin int line; /* saved line number */ 1534887Schin int vendor; /* saved pp.vendor */ 1544887Schin short fd; /* file descriptor */ 1554887Schin short hide; /* hide index (from pp.hide) */ 1564887Schin short flags; /* IN_[a-z]* flags */ 1574887Schin char type; /* input type */ 1584887Schin }; 1594887Schin 1604887Schin #if MACKEYARGS 1614887Schin struct ppkeyarg /* pp macro keyword arg info */ 1624887Schin { 1634887Schin char* name; /* keyword arg name */ 1644887Schin char* value; /* keyword arg value */ 1654887Schin }; 1664887Schin #endif 1674887Schin 1684887Schin struct pplist /* string list */ 1694887Schin { 1704887Schin char* value; /* string value */ 1714887Schin struct pplist* next; /* next in list */ 1724887Schin }; 1734887Schin 1744887Schin struct oplist /* queue op until PP_INIT */ 1754887Schin { 1764887Schin int op; /* PP_* op */ 1774887Schin char* value; /* op value */ 1784887Schin struct oplist* next; /* next op */ 1794887Schin }; 1804887Schin 1814887Schin struct pphide /* hidden symbol info */ 1824887Schin { 1834887Schin struct ppmacro* macro; /* saved macro info */ 1844887Schin unsigned long flags; /* saved symbol flags if macro */ 1854887Schin int level; /* nesting level */ 1864887Schin }; 1874887Schin 1884887Schin struct ppmacstk /* macro invocation stack frame */ 1894887Schin { 1904887Schin struct ppmacstk* next; /* next frame (for allocation) */ 1914887Schin struct ppmacstk* prev; /* previous frame */ 1924887Schin int line; /* line number of first arg */ 1934887Schin char* arg[1]; /* arg text pointers */ 1944887Schin }; 1954887Schin 1964887Schin struct ppmember /* archive member pun on ppfile */ 1974887Schin { 1984887Schin struct ppdirs* archive; /* archive holding file */ 1994887Schin unsigned long offset; /* data offset */ 2004887Schin unsigned long size; /* data size */ 2014887Schin }; 2024887Schin 2034887Schin struct counter /* monitoring counters */ 2044887Schin { 2054887Schin int candidate; /* macro candidates */ 2064887Schin int function; /* function macros */ 2074887Schin int macro; /* macro hits */ 2084887Schin int pplex; /* pplex() calls */ 2094887Schin int push; /* input stream pushes */ 2104887Schin int terminal; /* terminal states */ 2114887Schin int token; /* emitted tokens */ 2124887Schin }; 2134887Schin 2144887Schin struct pptuple /* tuple macro */ 2154887Schin { 2164887Schin struct pptuple* nomatch; /* nomatch tuple */ 2174887Schin struct pptuple* match; /* match tuple */ 2184887Schin char token[1]; /* matching token */ 2194887Schin }; 2204887Schin 2214887Schin struct ppfileid /* physical file id */ 2224887Schin { 2234887Schin unsigned long st_dev; /* dev */ 2244887Schin unsigned long st_ino; /* ino */ 2254887Schin }; 2264887Schin 2274887Schin struct pathid /* physical file name and id */ 2284887Schin { 2294887Schin char* path; /* file path */ 2304887Schin struct ppfileid id; /* file id */ 2314887Schin }; 2324887Schin 2334887Schin #define SAMEID(a,b) ((a)->st_ino==(unsigned long)(b)->st_ino&&(a)->st_dev==(unsigned long)(b)->st_dev) 2344887Schin #define SAVEID(a,b) ((a)->st_ino=(unsigned long)(b)->st_ino,(a)->st_dev=(unsigned long)(b)->st_dev) 2354887Schin 2364887Schin #define _PP_CONTEXT_PRIVATE_ /* ppglobals private context */ \ 2374887Schin struct ppcontext* context; /* current context */ \ 2384887Schin long state; /* pp state flags */ \ 2394887Schin long mode; /* uncoupled pp state flags */ \ 2404887Schin long option; /* option flags */ \ 2414887Schin long test; /* implementation tests */ \ 2424887Schin struct \ 2434887Schin { \ 2444887Schin Sfio_t* sp; /* FILEDEPS output stream */ \ 2454887Schin long flags; /* PP_FILEDEPS flags */ \ 2464887Schin } filedeps; /* FILEDEPS info */ \ 2474887Schin struct ppdirs* firstdir; /* first include dir */ \ 2484887Schin struct ppdirs* lastdir; /* last include dir */ \ 2494887Schin int hide; /* current include hide index */ \ 2504887Schin int column; /* FILEDEPS column */ \ 2514887Schin int pending; /* ppline() pending output */ \ 2524887Schin char* firstfile; /* ppline() first file */ \ 2534887Schin char* lastfile; /* ppline() most recent file */ \ 2544887Schin char* ignore; /* include ignore list file */ \ 2554887Schin char* probe; /* ppdefault probe key */ \ 2564887Schin Hash_table_t* filtab; /* file name hash table */ \ 2574887Schin Hash_table_t* prdtab; /* predicate hash table */ \ 2584887Schin char* date; /* start date string */ \ 2594887Schin char* time; /* start time string */ \ 2604887Schin char* maps; /* directive maps */ \ 2614887Schin long ro_state; /* readonly state */ \ 2624887Schin long ro_mode; /* readonly mode */ \ 2634887Schin long ro_option; /* readonly option */ \ 2644887Schin struct pathid cdir; /* arg C dir */ \ 2654887Schin struct pathid hostdir; /* arg host dir */ \ 2664887Schin char* ppdefault; /* arg default info file */ \ 2674887Schin struct ppindex* firstindex; /* first include index entry */ \ 2684887Schin struct ppindex* lastindex; /* last include index entry */ \ 2694887Schin struct oplist* firstop; /* first arg op */ \ 2704887Schin struct oplist* lastop; /* last arg op */ \ 2714887Schin struct oplist* firsttx; /* first text file */ \ 2724887Schin struct oplist* lasttx; /* last text file */ \ 2734887Schin unsigned char arg_file; /* arg file index */ \ 2744887Schin unsigned char arg_mode; /* arg mode */ \ 2754887Schin unsigned char arg_style; /* arg style */ \ 2764887Schin unsigned char c; /* arg C state */ \ 2774887Schin unsigned char hosted; /* arg hosted state */ \ 2784887Schin unsigned char ignoresrc; /* arg ignore source state */ \ 2794887Schin unsigned char initialized; /* arg initialized state */ \ 2804887Schin unsigned char standalone; /* arg standalone state */ \ 2814887Schin unsigned char spare_1; /* padding spare */ 2824887Schin 2834887Schin #define _PP_GLOBALS_PRIVATE_ /* ppglobals private additions */ \ 2844887Schin char* checkpoint; /* checkpoint version */ \ 2854887Schin int constack; /* pp.control size */ \ 2864887Schin struct ppinstk* in; /* input stream stack pointer */ \ 2874887Schin char* addp; /* addbuf pointer */ \ 2884887Schin char* args; /* predicate args */ \ 2894887Schin char* addbuf; /* ADD buffer */ \ 2904887Schin char* catbuf; /* catenation buffer */ \ 2914887Schin char* hdrbuf; /* HEADEREXPAND buffer */ \ 2924887Schin char* hidebuf; /* pp:hide buffer */ \ 2934887Schin char* path; /* full path of last #include */ \ 2944887Schin char* tmpbuf; /* very temporary buffer */ \ 2954887Schin char* valbuf; /* builtin macro value buffer */ \ 2964887Schin char* optflags; /* OPT_* flags indexed by X_* */ \ 2974887Schin int lastout; /* last output char */ \ 2984887Schin /* the rest are implicitly initialized */ \ 2994887Schin char* include; /* saved path of last #include */ \ 3004887Schin char* prefix; /* current directory prefix */ \ 3014887Schin struct ppmember* member; /* include archive member data */ \ 3024887Schin int hidden; /* hidden newline count */ \ 3034887Schin int hiding; /* number of symbols in hiding */ \ 3044887Schin int level; /* pplex() recursion level */ \ 3054887Schin struct \ 3064887Schin { \ 3074887Schin int input; /* pool input */ \ 3084887Schin int output; /* pool output */ \ 3094887Schin } pool; /* loop on input,output,error */ \ 3104887Schin struct \ 3114887Schin { \ 3124887Schin long ro_state; /* original pp.ro_state */ \ 3134887Schin long ro_mode; /* original pp.ro_mode */ \ 3144887Schin long ro_option; /* original pp.ro_option */ \ 3154887Schin int on; /* PP_RESET enabled */ \ 3164887Schin Hash_table_t* symtab; /* original pp.symtab scope */ \ 3174887Schin } reset; /* PP_RESET state */ \ 3184887Schin int truncate; /* identifier truncation length */ \ 3194887Schin struct ppmacstk* macp; /* top of macro actual stack */ \ 3204887Schin char* maxmac; /* maximum size of macro stack */ \ 3214887Schin char* mactop; /* top of current macro frame */ \ 3224887Schin char* toknxt; /* '\0' of pp.token */ \ 3234887Schin long* control; /* control block flags pointer */ \ 3244887Schin long* maxcon; /* max control block frame */ \ 3254887Schin struct oplist* chop; /* include prefix chop list */ \ 3264887Schin struct ppfile* insert; /* inserted line sync file */ \ 3274887Schin struct ppfile* original; /* original include name */ \ 3284887Schin struct ppdirs* found; /* last successful ppsearch dir */ \ 3294887Schin int vendor; /* vendor includes only */ \ 3304887Schin Hash_table_t* dirtab; /* directive hash table */ \ 3314887Schin Hash_table_t* strtab; /* string hash table */ \ 3324887Schin PPBUILTIN builtin; /* builtin macro handler */ \ 3334887Schin PPCOMMENT comment; /* pass along comments */ \ 3344887Schin PPINCREF incref; /* include file push/return */ \ 3354887Schin PPLINESYNC linesync; /* pass along line sync info */ \ 3364887Schin PPLINESYNC olinesync; /* original linesync value */ \ 3374887Schin PPMACREF macref; /* called on macro def/ref */ \ 3384887Schin PPOPTARG optarg; /* unknown option arg handler */ \ 3394887Schin PPPRAGMA pragma; /* pass along unknown pragmas */ \ 3404887Schin struct counter counter; /* monitoring counters */ \ 3414887Schin char funbuf[256]; /* last __FUNCTION__ */ 3424887Schin 3434887Schin #define _PP_SYMBOL_PRIVATE_ /* ppsymbol private additions */ \ 3444887Schin struct pphide* hidden; /* hidden symbol info */ 3454887Schin 3464887Schin #if MACKEYARGS 3474887Schin #define _PP_MACRO_PRIVATE_ /* ppmacro private additions */ \ 3484887Schin struct pptuple* tuple; /* tuple macro */ \ 3494887Schin union \ 3504887Schin { \ 3514887Schin char* formal; /* normal formals list */ \ 3524887Schin struct ppkeyarg* key; /* keyword formals table */ \ 3534887Schin } args; /* macro args info */ \ 3544887Schin int size; /* body size */ 3554887Schin #define formals args.formal /* formal argument list */ 3564887Schin #define formkeys args.key /* formal keyword argument list */ 3574887Schin #else 3584887Schin #define _PP_MACRO_PRIVATE_ /* ppmacro private additions */ \ 3594887Schin struct pptuple* tuple; /* tuple macro */ \ 3604887Schin char* formals; /* formal argument list */ \ 3614887Schin int size; /* body size */ 3624887Schin #endif 3634887Schin 3644887Schin #define _PP_DIRS_PRIVATE_ /* ppdirs private additions */ \ 3654887Schin unsigned char c; /* files here are C language */ \ 3664887Schin unsigned char index; /* prefix,local,standard index */ \ 3674887Schin unsigned char type; /* dir type */ \ 3684887Schin union \ 3694887Schin { \ 3704887Schin char* buffer; /* TYPE_BUFFER buffer */ \ 3714887Schin Sfio_t* sp; /* archive stream */ \ 3724887Schin struct ppdirs* subdir; /* subdir list */ \ 3734887Schin } info; /* type info */ \ 3744887Schin struct ppfileid id; /* directory id */ \ 3754887Schin 3764887Schin #if !PROTOMAIN 3774887Schin #include <ast.h> 3784887Schin #include <error.h> 3794887Schin #endif 3804887Schin 3814887Schin #undef newof 3824887Schin #define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x))) 3834887Schin 3844887Schin #include "pp.h" 3854887Schin #include "ppdef.h" 3864887Schin #include "ppkey.h" 3874887Schin 3884887Schin #undef setstate /* random clash! */ 3894887Schin 3904887Schin /* 3914887Schin * DEBUG is encoded with the following bits 3924887Schin */ 3934887Schin 3944887Schin #define TRACE_message 01 3954887Schin #define TRACE_count 02 3964887Schin #define TRACE_debug 04 3974887Schin 3984887Schin #if DEBUG && !lint 3994887Schin #define PANIC (ERROR_PANIC|ERROR_SOURCE|ERROR_SYSTEM),__FILE__,__LINE__ 4004887Schin #else 4014887Schin #define PANIC ERROR_PANIC 4024887Schin #endif 4034887Schin 4044887Schin #if DEBUG & TRACE_count 4054887Schin #define count(x) pp.counter.x++ 4064887Schin #else 4074887Schin #define count(x) 4084887Schin #endif 4094887Schin 4104887Schin #if DEBUG & TRACE_message 4114887Schin #define message(x) do { if (tracing) error x; } while (0) 4124887Schin #else 4134887Schin #define message(x) 4144887Schin #endif 4154887Schin 4164887Schin #if DEBUG & TRACE_debug 4174887Schin #define debug(x) do { if (tracing) error x; } while (0) 4184887Schin #else 4194887Schin #define debug(x) 4204887Schin #endif 4214887Schin 4224887Schin /* 4234887Schin * note that MEMCPY advances the associated pointers 4244887Schin */ 4254887Schin 4264887Schin #define MEMCPY(to,fr,n) \ 4274887Schin do switch(n) \ 4284887Schin { default : memcpy(to,fr,n); to += n; fr += n; break; \ 4294887Schin case 7 : *to++ = *fr++; \ 4304887Schin case 6 : *to++ = *fr++; \ 4314887Schin case 5 : *to++ = *fr++; \ 4324887Schin case 4 : *to++ = *fr++; \ 4334887Schin case 3 : *to++ = *fr++; \ 4344887Schin case 2 : *to++ = *fr++; \ 4354887Schin case 1 : *to++ = *fr++; \ 4364887Schin case 0 : break; \ 4374887Schin } while (0) 4384887Schin 4394887Schin #define NEWDIRECTIVE (-1) 4404887Schin 4414887Schin #undef dirname 4424887Schin #undef error 4434887Schin 4444887Schin #define dirname(x) ppkeyname(x,1) 4454887Schin #define error pperror 4464887Schin #define keyname(x) ppkeyname(x,0) 4474887Schin #define nextframe(m,p) (m->next=m+(p-(char*)m+sizeof(struct ppmacstk)-1)/sizeof(struct ppmacstk)+1) 4484887Schin #define popframe(m) (m=m->prev) 4494887Schin #define pptokchr(c) pptokstr(NiL,(c)) 4504887Schin #define pushcontrol() do { if (pp.control++ >= pp.maxcon) ppnest(); } while (0) 4514887Schin #define pushframe(m) (m->next->prev=m,m=m->next) 4524887Schin #define setmode(m,v) ((v)?(pp.mode|=(m)):(pp.mode&=~(m))) 4534887Schin #define setoption(m,v) ((v)?(pp.option|=(m)):(pp.option&=~(m))) 4544887Schin #define setstate(s,v) ((v)?(pp.state|=(s)):(pp.state&=~(s))) 4554887Schin #define tracing (error_info.trace<0) 4564887Schin 4574887Schin #define ppgetfile(x) ((struct ppfile*)hashlook(pp.filtab,x,HASH_LOOKUP,NiL)) 4584887Schin #define ppsetfile(x) ((struct ppfile*)hashlook(pp.filtab,x,HASH_CREATE|HASH_SIZE(sizeof(struct ppfile)),NiL)) 4594887Schin 4604887Schin #define ppkeyget(t,n) (struct ppsymkey*)hashlook(t,n,HASH_LOOKUP,NiL) 4614887Schin #define ppkeyref(t,n) (struct ppsymkey*)hashlook(t,n,HASH_LOOKUP|HASH_INTERNAL,NiL) 4624887Schin #define ppkeyset(t,n) (struct ppsymkey*)hashlook(t,n,HASH_CREATE|HASH_SIZE(sizeof(struct ppsymkey)),NiL) 4634887Schin 4644887Schin #define MARK '@' /* internal mark */ 4654887Schin #define ARGOFFSET '1' /* macro arg mark offset */ 4664887Schin 4674887Schin #define STRAPP(p,v,r) do{r=(v);while((*p++)=(*r++));}while(0) 4684887Schin #define STRCOPY(p,v,r) do{r=(v);while((*p++)=(*r++));p--;}while(0) 4694887Schin #define STRCOPY2(p,r) do{while((*p++)=(*r++));p--;}while(0) 4704887Schin 4714887Schin #define SETFILE(p,v) (p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'F',(long)v,MARK)) 4724887Schin #define SETLINE(p,v) (p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'L',(long)v,MARK)) 4734887Schin 4744887Schin #define peekchr() (*pp.in->nextchr) 4754887Schin #define ungetchr(c) (*--pp.in->nextchr=(c)) 4764887Schin 4774887Schin #define MAXID 255 /* maximum identifier size */ 4784887Schin #define MAXTOKEN PPTOKSIZ /* maximum token size */ 4794887Schin #define MAXFORMALS 64 /* maximum number macro formals */ 4804887Schin #define MAXHIDDEN 8 /* ppline if hidden>=MAXHIDDEN */ 4814887Schin #define DEFMACSTACK (MAXFORMALS*32*32)/* default macstack size */ 4824887Schin 4834887Schin #define FSM_COMPATIBILITY 1 /* compatibility mode */ 4844887Schin #define FSM_IDADD 2 /* add to identifer set */ 4854887Schin #define FSM_IDDEL 3 /* delete from identifer set */ 4864887Schin #define FSM_INIT 4 /* initilize */ 4874887Schin #define FSM_MACRO 5 /* add new macro */ 4884887Schin #define FSM_OPSPACE 6 /* handle <binop><space>= */ 4894887Schin #define FSM_PLUSPLUS 7 /* C++ lexical analysis */ 4904887Schin #define FSM_QUOTADD 8 /* add to quote set */ 4914887Schin #define FSM_QUOTDEL 9 /* delete from quote set */ 4924887Schin 4934887Schin #define IN_TOP 01 /* top level -- directives ok */ 4944887Schin 4954887Schin #define IN_BUFFER (2|IN_TOP) /* buffer of lines */ 4964887Schin #define IN_COPY 2 /* macro arg (copied) */ 4974887Schin #define IN_EXPAND 4 /* macro arg (expanded) */ 4984887Schin #define IN_FILE (4|IN_TOP) /* file */ 4994887Schin #define IN_INIT (6|IN_TOP) /* initialization IN_BUFFER */ 5004887Schin #define IN_MACRO 8 /* macro text */ 5014887Schin #define IN_MULTILINE (8|IN_TOP) /* multi-line macro text */ 5024887Schin #define IN_QUOTE 10 /* "..." macro arg (copied) */ 5034887Schin #define IN_RESCAN (10|IN_TOP) /* directive rescan buffer */ 5044887Schin #define IN_SQUOTE 12 /* '...' macro arg (copied) */ 5054887Schin #define IN_STRING 14 /* string */ 5064887Schin 5074887Schin #define INC_CLEAR ((struct ppsymbol*)0) 5084887Schin #define INC_IGNORE ((struct ppsymbol*)pp.addbuf) 5094887Schin #define INC_TEST ((struct ppsymbol*)pp.catbuf) 5104887Schin 5114887Schin #define INC_BOUND(n) (1<<(n)) 5124887Schin #define INC_MEMBER(n) (1<<((n)+INC_MAX)) 5134887Schin #define INC_PREFIX 0 5144887Schin #define INC_LOCAL 1 5154887Schin #define INC_STANDARD 2 5164887Schin #define INC_VENDOR 3 5174887Schin #define INC_MAX 4 5184887Schin #define INC_SELF (1<<(2*INC_MAX+0)) 5194887Schin #define INC_EXISTS (1<<(2*INC_MAX+1)) 5204887Schin #define INC_LISTED (1<<(2*INC_MAX+2)) 5214887Schin #define INC_MAPALL (1<<(2*INC_MAX+3)) 5224887Schin #define INC_MAPHOSTED (1<<(2*INC_MAX+4)) 5234887Schin #define INC_MAPNOHOSTED (1<<(2*INC_MAX+5)) 5244887Schin #define INC_MAPNOLOCAL (1<<(2*INC_MAX+6)) 5254887Schin #define INC_HOSTED (1<<(2*INC_MAX+7)) 5264887Schin 5274887Schin #define TYPE_ARCHIVE (1<<0) 5284887Schin #define TYPE_BUFFER (1<<1) 5294887Schin #define TYPE_CHECKPOINT (1<<2) 5304887Schin #define TYPE_DIRECTORY (1<<3) 5314887Schin #define TYPE_HOSTED (1<<4) 5324887Schin #define TYPE_INCLUDE (1<<5) 5334887Schin #define TYPE_VENDOR (1<<6) 5344887Schin 5354887Schin #define TOK_BUILTIN (1<<0) /* last token was #( */ 5364887Schin #define TOK_FORMAL (1<<1) /* last token was arg formal id */ 5374887Schin #define TOK_ID (1<<2) /* last token was identifier */ 5384887Schin #define TOK_TOKCAT (1<<3) /* last token was ## */ 5394887Schin 5404887Schin #define HADELSE (1<<0) /* already had else part */ 5414887Schin #define KEPT (1<<1) /* already kept part of block */ 5424887Schin #define SKIP (1<<2) /* skip this block */ 5434887Schin #define BLOCKBITS 3 /* block flag bits */ 5444887Schin 5454887Schin #define SETIFBLOCK(p) (*(p)=(*((p)-1)&SKIP)|((long)error_info.line<<BLOCKBITS)) 5464887Schin #define GETIFLINE(p) ((*(p)>>BLOCKBITS)&((1L<<(sizeof(long)*CHAR_BIT-BLOCKBITS))-1)) 5474887Schin 5484887Schin #define PUSH(t,p) \ 5494887Schin do \ 5504887Schin { \ 5514887Schin count(push); \ 5524887Schin if (!pp.in->next) \ 5534887Schin { \ 5544887Schin pp.in->next = newof(0, struct ppinstk, 1, 0); \ 5554887Schin pp.in->next->prev = pp.in; \ 5564887Schin } \ 5574887Schin p = pp.in = pp.in->next; \ 5584887Schin p->type = t; \ 5594887Schin p->flags = 0; \ 5604887Schin } while (0) 5614887Schin 5624887Schin #define PUSH_BUFFER(f,p,n) \ 5634887Schin pppush(IN_BUFFER,f,p,n) 5644887Schin 5654887Schin #define PUSH_COPY(p,n) \ 5664887Schin do \ 5674887Schin { \ 5684887Schin register struct ppinstk* cur; \ 5694887Schin PUSH(IN_COPY, cur); \ 5704887Schin cur->line = error_info.line; \ 5714887Schin error_info.line = n; \ 5724887Schin cur->nextchr = p; \ 5734887Schin cur->prev->symbol->flags &= ~SYM_DISABLED; \ 5744887Schin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 5754887Schin } while (0) 5764887Schin 5774887Schin #define PUSH_EXPAND(p,n) \ 5784887Schin do \ 5794887Schin { \ 5804887Schin register struct ppinstk* cur; \ 5814887Schin PUSH(IN_EXPAND, cur); \ 5824887Schin cur->line = error_info.line; \ 5834887Schin error_info.line = n; \ 5844887Schin cur->prev->symbol->flags &= ~SYM_DISABLED; \ 5854887Schin cur->buffer = cur->nextchr = ppexpand(p); \ 5864887Schin if (!(cur->prev->symbol->flags & SYM_MULTILINE)) \ 5874887Schin cur->prev->symbol->flags |= SYM_DISABLED; \ 5884887Schin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 5894887Schin } while (0) 5904887Schin 5914887Schin #define PUSH_FILE(f,d) \ 5924887Schin pppush(IN_FILE,f,NiL,d) 5934887Schin 5944887Schin #define PUSH_INIT(f,p) \ 5954887Schin pppush(IN_INIT,f,p,1) 5964887Schin 5974887Schin #define PUSH_MACRO(p) \ 5984887Schin do \ 5994887Schin { \ 6004887Schin register struct ppinstk* cur; \ 6014887Schin PUSH(IN_MACRO, cur); \ 6024887Schin cur->symbol = p; \ 6034887Schin cur->nextchr = p->macro->value; \ 6044887Schin p->flags |= SYM_DISABLED; \ 6054887Schin if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \ 6064887Schin pp.state &= ~NEWLINE; \ 6074887Schin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 6084887Schin } while (0) 6094887Schin 6104887Schin #define PUSH_TUPLE(p,v) \ 6114887Schin do \ 6124887Schin { \ 6134887Schin register struct ppinstk* cur; \ 6144887Schin PUSH(IN_MACRO, cur); \ 6154887Schin cur->symbol = p; \ 6164887Schin cur->nextchr = v; \ 6174887Schin p->flags |= SYM_DISABLED; \ 6184887Schin pp.state &= ~NEWLINE; \ 6194887Schin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 6204887Schin } while (0) 6214887Schin 6224887Schin #define PUSH_MULTILINE(p) \ 6234887Schin do \ 6244887Schin { \ 6254887Schin register struct ppinstk* cur; \ 6264887Schin register int n; \ 6274887Schin PUSH(IN_MULTILINE, cur); \ 6284887Schin cur->symbol = p; \ 6294887Schin cur->flags |= IN_defguard|IN_endguard|IN_noguard; \ 6304887Schin pushcontrol(); \ 6314887Schin cur->control = pp.control; \ 6324887Schin *pp.control = 0; \ 6334887Schin cur->file = error_info.file; \ 6344887Schin n = strlen(error_info.file) + strlen(((struct ppsymbol*)p)->name) + 24; \ 6354887Schin error_info.file = cur->buffer = newof(0, char, n, 0); \ 6364887Schin sfsprintf(error_info.file, n, "%s:%s,%d", cur->file, p->name, error_info.line); \ 6374887Schin cur->line = error_info.line; \ 6384887Schin error_info.line = 1; \ 6394887Schin cur->nextchr = p->macro->value; \ 6404887Schin if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \ 6414887Schin pp.state &= ~NEWLINE; \ 6424887Schin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 6434887Schin } while (0) 6444887Schin 6454887Schin #define PUSH_QUOTE(p,n) \ 6464887Schin do \ 6474887Schin { \ 6484887Schin register struct ppinstk* cur; \ 6494887Schin PUSH(IN_QUOTE, cur); \ 6504887Schin cur->nextchr = p; \ 6514887Schin pp.state |= QUOTE; \ 6524887Schin cur->line = error_info.line; \ 6534887Schin error_info.line = n; \ 6544887Schin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 6554887Schin } while (0) 6564887Schin 6574887Schin #define PUSH_RESCAN(p) \ 6584887Schin pppush(IN_RESCAN,NiL,p,0) 6594887Schin 6604887Schin #define PUSH_SQUOTE(p,n) \ 6614887Schin do \ 6624887Schin { \ 6634887Schin register struct ppinstk* cur; \ 6644887Schin PUSH(IN_SQUOTE, cur); \ 6654887Schin cur->nextchr = p; \ 6664887Schin pp.state |= SQUOTE; \ 6674887Schin cur->line = error_info.line; \ 6684887Schin error_info.line = n; \ 6694887Schin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 6704887Schin } while (0) 6714887Schin 6724887Schin #define PUSH_STRING(p) \ 6734887Schin do \ 6744887Schin { \ 6754887Schin register struct ppinstk* cur; \ 6764887Schin PUSH(IN_STRING, cur); \ 6774887Schin cur->nextchr = p; \ 6784887Schin if (pp.state & DISABLE) cur->flags |= IN_disable; \ 6794887Schin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 6804887Schin } while (0) 6814887Schin 6824887Schin #define PUSH_LINE(p) \ 6834887Schin do \ 6844887Schin { \ 6854887Schin register struct ppinstk* cur; \ 6864887Schin PUSH(IN_STRING, cur); \ 6874887Schin cur->nextchr = p; \ 6884887Schin pp.state |= DISABLE|NOSPACE|PASSEOF|STRIP; \ 6894887Schin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 6904887Schin } while (0) 6914887Schin 6924887Schin #define POP_LINE() \ 6934887Schin do \ 6944887Schin { \ 6954887Schin debug((-7, "POP in=%s", ppinstr(pp.in))); \ 6964887Schin pp.in = pp.in->prev; \ 6974887Schin pp.state &= ~(DISABLE|NOSPACE|PASSEOF|STRIP); \ 6984887Schin } while (0) 6994887Schin 7004887Schin struct ppcontext /* pp context */ 7014887Schin { 7024887Schin _PP_CONTEXT_PUBLIC_ 7034887Schin _PP_CONTEXT_PRIVATE_ 7044887Schin }; 7054887Schin 7064887Schin struct ppfile /* include file info */ 7074887Schin { 7084887Schin HASH_HEADER; /* this is a hash bucket too */ 7094887Schin struct ppsymbol* guard; /* guard symbol */ 7104887Schin struct ppfile* bound[INC_MAX]; /* include bindings */ 7114887Schin int flags; /* INC_* flags */ 7124887Schin }; 7134887Schin 7144887Schin #if CHECKPOINT 7154887Schin 7164887Schin struct ppindex /* checkpoint include index */ 7174887Schin { 7184887Schin struct ppindex* next; /* next in list */ 7194887Schin struct ppfile* file; /* include file */ 7204887Schin unsigned long begin; /* beginning output offset */ 7214887Schin unsigned long end; /* ending output offset */ 7224887Schin }; 7234887Schin 7244887Schin #endif 7254887Schin 7264887Schin struct ppsymkey /* pun for SYM_KEYWORD lex val */ 7274887Schin { 7284887Schin struct ppsymbol sym; /* symbol as usual */ 7294887Schin int lex; /* lex value for SYM_KEYWORD */ 7304887Schin }; 7314887Schin 7324887Schin #if PROTOMAIN && PROTO_STANDALONE 7334887Schin 7344887Schin #if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) 7354887Schin #define NiL 0 7364887Schin #define NoP(x) (&x,1) 7374887Schin #else 7384887Schin #define NiL ((char*)0) 7394887Schin #define NoP(x) 7404887Schin #endif 7414887Schin 7424887Schin #define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x))) 7434887Schin 7444887Schin #define _PP_DELAY_ # 7454887Schin 7464887Schin _PP_DELAY_ ifdef __STDC__ 7474887Schin 7484887Schin _PP_DELAY_ include <stdlib.h> 7494887Schin _PP_DELAY_ include <unistd.h> 7504887Schin _PP_DELAY_ include <time.h> 7514887Schin _PP_DELAY_ include <string.h> 7524887Schin 7534887Schin _PP_DELAY_ else 7544887Schin 7554887Schin _PP_DELAY_ define size_t int 7564887Schin 7574887Schin extern void* realloc(void*, size_t); 7584887Schin extern void* calloc(size_t, size_t); 7594887Schin extern char* ctime(time_t*); 7604887Schin extern void free(void*); 7614887Schin 7624887Schin _PP_DELAY_ ifndef O_RDONLY 7634887Schin 7644887Schin extern int access(const char*, int); 7654887Schin extern int close(int); 7664887Schin extern int creat(const char*, int); 7674887Schin extern void exit(int); 7684887Schin extern int link(const char*, const char*); 7694887Schin extern int open(const char*, int, ...); 7704887Schin extern int read(int, void*, int); 7714887Schin extern time_t time(time_t*); 7724887Schin extern int unlink(const char*); 7734887Schin extern int write(int, const void*, int); 7744887Schin 7754887Schin _PP_DELAY_ endif 7764887Schin 7774887Schin _PP_DELAY_ endif 7784887Schin 7794887Schin #else 7804887Schin 7814887Schin /* 7824887Schin * library implementation globals 7834887Schin */ 7844887Schin 7854887Schin #define ppassert _pp_assert 7864887Schin #define ppbuiltin _pp_builtin 7874887Schin #define ppcall _pp_call 7884887Schin #define ppcontrol _pp_control 7894887Schin #define ppdump _pp_dump 7904887Schin #define ppexpand _pp_expand 7914887Schin #define ppexpr _pp_expr 7924887Schin #define ppfsm _pp_fsm 7934887Schin #define ppinmap _pp_inmap 7944887Schin #define ppinstr _pp_instr 7954887Schin #define ppkeyname _pp_keyname 7964887Schin #define pplexmap _pp_lexmap 7974887Schin #define pplexstr _pp_lexstr 7984887Schin #define ppload _pp_load 7994887Schin #define ppmodestr _pp_modestr 8004887Schin #define ppmultiple _pp_multiple 8014887Schin #define ppnest _pp_nest 8024887Schin #define ppoption _pp_option 8034887Schin #define ppoptionstr _pp_optionstr 8044887Schin #define pppclose _pp_pclose 8054887Schin #define pppdrop _pp_pdrop 8064887Schin #define pppopen _pp_popen 8074887Schin #define pppread _pp_pread 8084887Schin #define pppredargs _pp_predargs 8094887Schin #define pppush _pp_push 8104887Schin #define pprefmac _pp_refmac 8114887Schin #define ppsearch _pp_search 8124887Schin #define ppstatestr _pp_statestr 8134887Schin #define pptokstr _pp_tokstr 8144887Schin #define pptrace _pp_trace 8154887Schin 8164887Schin #endif 8174887Schin 8184887Schin extern void ppassert(int, char*, char*); 8194887Schin extern void ppbuiltin(void); 8204887Schin extern int ppcall(struct ppsymbol*, int); 8214887Schin extern int ppcontrol(void); 8224887Schin extern void ppdump(void); 8234887Schin extern char* ppexpand(char*); 8244887Schin extern long ppexpr(int*); 8254887Schin extern void ppfsm(int, char*); 8264887Schin extern char* ppinstr(struct ppinstk*); 8274887Schin extern char* ppkeyname(int, int); 8284887Schin extern char* pplexstr(int); 8294887Schin extern void ppload(char*); 8304887Schin extern void ppmapinclude(char*, char*); 8314887Schin extern char* ppmodestr(long); 8324887Schin extern int ppmultiple(struct ppfile*, struct ppsymbol*); 8334887Schin extern void ppnest(void); 8344887Schin extern int ppoption(char*); 8354887Schin extern char* ppoptionstr(long); 8364887Schin extern void pppclose(char*); 8374887Schin extern int pppdrop(char*); 8384887Schin extern char* pppopen(char*, int, char*, char*, char*, char*, int); 8394887Schin extern int pppread(char*); 8404887Schin extern int pppredargs(void); 8414887Schin extern void pppush(int, char*, char*, int); 8424887Schin extern struct ppsymbol* pprefmac(char*, int); 8434887Schin extern int ppsearch(char*, int, int); 8444887Schin extern char* ppstatestr(long); 8454887Schin extern char* pptokstr(char*, int); 8464887Schin extern void pptrace(int); 8474887Schin 8484887Schin #if _std_malloc 8494887Schin 8504887Schin #include <vmalloc.h> 8514887Schin 8524887Schin #undef free 8534887Schin #define free(p) vmfree(Vmregion,(void*)p) 8544887Schin #undef newof 8554887Schin #define newof(p,t,n,x) vmnewof(Vmregion,p,t,n,x) 8564887Schin #undef oldof 8574887Schin #define oldof(p,t,n,x) vmoldof(Vmregion,p,t,n,x) 8584887Schin #undef strdup 8594887Schin #define strdup(s) vmstrdup(Vmregion,s) 8604887Schin 8614887Schin #endif 8624887Schin 8634887Schin #endif 864