1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1986-2009 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * * 19 ***********************************************************************/ 20 #pragma prototyped 21 /* 22 * Glenn Fowler 23 * AT&T Research 24 * 25 * preprocessor library private definitions 26 */ 27 28 #ifndef _PPLIB_H 29 #define _PPLIB_H 30 31 /* 32 * the first definitions control optional code -- 0 disables 33 */ 34 35 #ifndef ARCHIVE 36 #define ARCHIVE 1 /* -I can specify header archives */ 37 #endif 38 #ifndef CATSTRINGS 39 #define CATSTRINGS 1 /* concatenate adjacent strings */ 40 #endif 41 #ifndef CHECKPOINT 42 #define CHECKPOINT 1 /* checkpoint preprocessed files */ 43 #endif 44 #ifndef COMPATIBLE 45 #define COMPATIBLE 1 /* enable COMPATIBILITY related code */ 46 #endif 47 #ifndef MACKEYARGS 48 #define MACKEYARGS _BLD_DEBUG /* name=value macro formals and actuals */ 49 #endif 50 #ifndef POOL 51 #define POOL 1 /* enable loop on input,output,error */ 52 #endif 53 #ifndef PROTOTYPE 54 #define PROTOTYPE 1 /* enable ppproto code */ 55 #endif 56 57 #define TRUNCLENGTH 8 /* default TRUNCATE length */ 58 59 #if _BLD_DEBUG 60 #undef DEBUG 61 #define DEBUG (TRACE_message|TRACE_count|TRACE_debug) 62 #else 63 #ifndef DEBUG 64 #define DEBUG (TRACE_message) 65 #endif 66 #endif 67 68 /* 69 * the lower tests are transient 70 */ 71 72 #define TEST_count (1L<<24) 73 #define TEST_hashcount (1L<<25) 74 #define TEST_hashdump (1L<<26) 75 #define TEST_hit (1L<<27) 76 #define TEST_noinit (1L<<28) 77 #define TEST_nonoise (1L<<29) 78 #define TEST_noproto (1L<<30) 79 80 #define TEST_INVERT (1L<<31) 81 82 #define PROTO_CLASSIC (1<<0) /* classic to prototyped */ 83 #define PROTO_DISABLE (1<<1) /* disable conversion */ 84 #define PROTO_EXTERNALIZE (1<<2) /* static fun() => extern fun() */ 85 #define PROTO_FORCE (1<<3) /* force even if no magic */ 86 #define PROTO_HEADER (1<<4) /* header defines too */ 87 #define PROTO_INCLUDE (1<<5) /* <prototyped.h> instead */ 88 #define PROTO_INITIALIZED (1<<6) /* internal initialization */ 89 #define PROTO_LINESYNC (1<<7) /* force standalone line syncs */ 90 #define PROTO_NOPRAGMA (1<<8) /* delete pragma prototyped */ 91 #define PROTO_PASS (1<<9) /* pass blocks if no magic */ 92 #define PROTO_PLUSPLUS (1<<10) /* extern () -> extern (...) */ 93 #define PROTO_RETAIN (1<<11) /* defines retained after close */ 94 #define PROTO_TEST (1<<12) /* enable test code */ 95 96 #define PROTO_USER (1<<13) /* first user flag */ 97 98 #define SEARCH_EXISTS 0 /* ppsearch for existence */ 99 #define SEARCH_HOSTED (1<<0) /* search hosted dirs only */ 100 #define SEARCH_IGNORE (1<<1) /* ignore if not found */ 101 #define SEARCH_INCLUDE (1<<2) /* ppsearch for include */ 102 #define SEARCH_VENDOR (1<<3) /* search vendor dirs only */ 103 #define SEARCH_USER (1<<4) /* first user flag */ 104 105 #define STYLE_gnu (1<<0) /* gnu style args */ 106 107 #define IN_c (1<<0) /* C language file */ 108 #define IN_defguard (1<<1) /* did multiple include check */ 109 #define IN_disable (1<<2) /* saved state&DISABLE */ 110 #define IN_endguard (1<<3) /* did multiple include check */ 111 #define IN_eof (1<<4) /* reached EOF */ 112 #define IN_expand (1<<5) /* ppexpand buffer */ 113 #define IN_flush (1<<6) /* flush stdout on file_refill()*/ 114 #define IN_hosted (1<<7) /* saved mode&HOSTED */ 115 #define IN_ignoreline (1<<8) /* ignore #line until file */ 116 #define IN_newline (1<<9) /* newline at end of last fill */ 117 #define IN_noguard (1<<10) /* no multiple include guard */ 118 #define IN_prototype (1<<11) /* ppproto() input */ 119 #define IN_regular (1<<12) /* regular input file */ 120 #define IN_static (1<<13) /* static buffer - don't free */ 121 #define IN_sync (1<<14) /* line sync required on pop */ 122 #define IN_tokens (1L<<15)/* non-space tokens encountered */ 123 124 #define OPT_GLOBAL (1<<0) /* pp: pass optional */ 125 #define OPT_PASS (1<<1) /* pass on */ 126 127 struct ppsymbol; 128 struct ppindex; 129 130 typedef char* (*PPBUILTIN)(char*, const char*, const char*); 131 typedef void (*PPCOMMENT)(const char*, const char*, const char*, int); 132 typedef void (*PPINCREF)(const char*, const char*, int, int); 133 typedef void (*PPLINESYNC)(int, const char*); 134 typedef void (*PPMACREF)(struct ppsymbol*, const char*, int, int, unsigned long); 135 typedef int (*PPOPTARG)(int, int, const char*); 136 typedef void (*PPPRAGMA)(const char*, const char*, const char*, const char*, int); 137 138 struct ppinstk /* input stream stack frame */ 139 { 140 char* nextchr; /* next input char (first elt) */ 141 struct ppinstk* next; /* next frame (for allocation) */ 142 struct ppinstk* prev; /* previous frame */ 143 long* control; /* control block level */ 144 char* buffer; /* buffer base pointer */ 145 char* file; /* saved file name */ 146 char* prefix; /* directory prefix */ 147 struct ppsymbol* symbol; /* macro info */ 148 #if CHECKPOINT 149 struct ppindex* index; /* checkpoint include index */ 150 int buflen; /* buffer count */ 151 #endif 152 int line; /* saved line number */ 153 int vendor; /* saved pp.vendor */ 154 short fd; /* file descriptor */ 155 short hide; /* hide index (from pp.hide) */ 156 short flags; /* IN_[a-z]* flags */ 157 char type; /* input type */ 158 }; 159 160 #if MACKEYARGS 161 struct ppkeyarg /* pp macro keyword arg info */ 162 { 163 char* name; /* keyword arg name */ 164 char* value; /* keyword arg value */ 165 }; 166 #endif 167 168 struct pplist /* string list */ 169 { 170 char* value; /* string value */ 171 struct pplist* next; /* next in list */ 172 }; 173 174 struct oplist /* queue op until PP_INIT */ 175 { 176 int op; /* PP_* op */ 177 char* value; /* op value */ 178 struct oplist* next; /* next op */ 179 }; 180 181 struct pphide /* hidden symbol info */ 182 { 183 struct ppmacro* macro; /* saved macro info */ 184 unsigned long flags; /* saved symbol flags if macro */ 185 int level; /* nesting level */ 186 }; 187 188 struct ppmacstk /* macro invocation stack frame */ 189 { 190 struct ppmacstk* next; /* next frame (for allocation) */ 191 struct ppmacstk* prev; /* previous frame */ 192 int line; /* line number of first arg */ 193 char* arg[1]; /* arg text pointers */ 194 }; 195 196 struct ppmember /* archive member pun on ppfile */ 197 { 198 struct ppdirs* archive; /* archive holding file */ 199 unsigned long offset; /* data offset */ 200 unsigned long size; /* data size */ 201 }; 202 203 struct counter /* monitoring counters */ 204 { 205 int candidate; /* macro candidates */ 206 int function; /* function macros */ 207 int macro; /* macro hits */ 208 int pplex; /* pplex() calls */ 209 int push; /* input stream pushes */ 210 int terminal; /* terminal states */ 211 int token; /* emitted tokens */ 212 }; 213 214 struct pptuple /* tuple macro */ 215 { 216 struct pptuple* nomatch; /* nomatch tuple */ 217 struct pptuple* match; /* match tuple */ 218 char token[1]; /* matching token */ 219 }; 220 221 struct ppfileid /* physical file id */ 222 { 223 unsigned long st_dev; /* dev */ 224 unsigned long st_ino; /* ino */ 225 }; 226 227 struct pathid /* physical file name and id */ 228 { 229 char* path; /* file path */ 230 struct ppfileid id; /* file id */ 231 }; 232 233 #define SAMEID(a,b) ((a)->st_ino==(unsigned long)(b)->st_ino&&(a)->st_dev==(unsigned long)(b)->st_dev) 234 #define SAVEID(a,b) ((a)->st_ino=(unsigned long)(b)->st_ino,(a)->st_dev=(unsigned long)(b)->st_dev) 235 236 #define _PP_CONTEXT_PRIVATE_ /* ppglobals private context */ \ 237 struct ppcontext* context; /* current context */ \ 238 long state; /* pp state flags */ \ 239 long mode; /* uncoupled pp state flags */ \ 240 long option; /* option flags */ \ 241 long test; /* implementation tests */ \ 242 struct \ 243 { \ 244 Sfio_t* sp; /* FILEDEPS output stream */ \ 245 long flags; /* PP_FILEDEPS flags */ \ 246 } filedeps; /* FILEDEPS info */ \ 247 struct ppdirs* firstdir; /* first include dir */ \ 248 struct ppdirs* lastdir; /* last include dir */ \ 249 int hide; /* current include hide index */ \ 250 int column; /* FILEDEPS column */ \ 251 int pending; /* ppline() pending output */ \ 252 char* firstfile; /* ppline() first file */ \ 253 char* lastfile; /* ppline() most recent file */ \ 254 char* ignore; /* include ignore list file */ \ 255 char* probe; /* ppdefault probe key */ \ 256 Hash_table_t* filtab; /* file name hash table */ \ 257 Hash_table_t* prdtab; /* predicate hash table */ \ 258 char* date; /* start date string */ \ 259 char* time; /* start time string */ \ 260 char* maps; /* directive maps */ \ 261 long ro_state; /* readonly state */ \ 262 long ro_mode; /* readonly mode */ \ 263 long ro_option; /* readonly option */ \ 264 struct pathid cdir; /* arg C dir */ \ 265 struct pathid hostdir; /* arg host dir */ \ 266 char* ppdefault; /* arg default info file */ \ 267 struct ppindex* firstindex; /* first include index entry */ \ 268 struct ppindex* lastindex; /* last include index entry */ \ 269 struct oplist* firstop; /* first arg op */ \ 270 struct oplist* lastop; /* last arg op */ \ 271 struct oplist* firsttx; /* first text file */ \ 272 struct oplist* lasttx; /* last text file */ \ 273 unsigned char arg_file; /* arg file index */ \ 274 unsigned char arg_mode; /* arg mode */ \ 275 unsigned char arg_style; /* arg style */ \ 276 unsigned char c; /* arg C state */ \ 277 unsigned char hosted; /* arg hosted state */ \ 278 unsigned char ignoresrc; /* arg ignore source state */ \ 279 unsigned char initialized; /* arg initialized state */ \ 280 unsigned char standalone; /* arg standalone state */ \ 281 unsigned char spare_1; /* padding spare */ 282 283 #define _PP_GLOBALS_PRIVATE_ /* ppglobals private additions */ \ 284 char* checkpoint; /* checkpoint version */ \ 285 int constack; /* pp.control size */ \ 286 struct ppinstk* in; /* input stream stack pointer */ \ 287 char* addp; /* addbuf pointer */ \ 288 char* args; /* predicate args */ \ 289 char* addbuf; /* ADD buffer */ \ 290 char* catbuf; /* catenation buffer */ \ 291 char* hdrbuf; /* HEADEREXPAND buffer */ \ 292 char* hidebuf; /* pp:hide buffer */ \ 293 char* path; /* full path of last #include */ \ 294 char* tmpbuf; /* very temporary buffer */ \ 295 char* valbuf; /* builtin macro value buffer */ \ 296 char* optflags; /* OPT_* flags indexed by X_* */ \ 297 int lastout; /* last output char */ \ 298 /* the rest are implicitly initialized */ \ 299 char* include; /* saved path of last #include */ \ 300 char* prefix; /* current directory prefix */ \ 301 struct ppmember* member; /* include archive member data */ \ 302 int hidden; /* hidden newline count */ \ 303 int hiding; /* number of symbols in hiding */ \ 304 int level; /* pplex() recursion level */ \ 305 struct \ 306 { \ 307 int input; /* pool input */ \ 308 int output; /* pool output */ \ 309 } pool; /* loop on input,output,error */ \ 310 struct \ 311 { \ 312 long ro_state; /* original pp.ro_state */ \ 313 long ro_mode; /* original pp.ro_mode */ \ 314 long ro_option; /* original pp.ro_option */ \ 315 int on; /* PP_RESET enabled */ \ 316 Hash_table_t* symtab; /* original pp.symtab scope */ \ 317 } reset; /* PP_RESET state */ \ 318 int truncate; /* identifier truncation length */ \ 319 struct ppmacstk* macp; /* top of macro actual stack */ \ 320 char* maxmac; /* maximum size of macro stack */ \ 321 char* mactop; /* top of current macro frame */ \ 322 char* toknxt; /* '\0' of pp.token */ \ 323 long* control; /* control block flags pointer */ \ 324 long* maxcon; /* max control block frame */ \ 325 struct oplist* chop; /* include prefix chop list */ \ 326 struct ppfile* insert; /* inserted line sync file */ \ 327 struct ppfile* original; /* original include name */ \ 328 struct ppdirs* found; /* last successful ppsearch dir */ \ 329 int vendor; /* vendor includes only */ \ 330 Hash_table_t* dirtab; /* directive hash table */ \ 331 Hash_table_t* strtab; /* string hash table */ \ 332 PPBUILTIN builtin; /* builtin macro handler */ \ 333 PPCOMMENT comment; /* pass along comments */ \ 334 PPINCREF incref; /* include file push/return */ \ 335 PPLINESYNC linesync; /* pass along line sync info */ \ 336 PPLINESYNC olinesync; /* original linesync value */ \ 337 PPMACREF macref; /* called on macro def/ref */ \ 338 PPOPTARG optarg; /* unknown option arg handler */ \ 339 PPPRAGMA pragma; /* pass along unknown pragmas */ \ 340 struct counter counter; /* monitoring counters */ \ 341 char funbuf[256]; /* last __FUNCTION__ */ 342 343 #define _PP_SYMBOL_PRIVATE_ /* ppsymbol private additions */ \ 344 struct pphide* hidden; /* hidden symbol info */ 345 346 #if MACKEYARGS 347 #define _PP_MACRO_PRIVATE_ /* ppmacro private additions */ \ 348 struct pptuple* tuple; /* tuple macro */ \ 349 union \ 350 { \ 351 char* formal; /* normal formals list */ \ 352 struct ppkeyarg* key; /* keyword formals table */ \ 353 } args; /* macro args info */ \ 354 int size; /* body size */ 355 #define formals args.formal /* formal argument list */ 356 #define formkeys args.key /* formal keyword argument list */ 357 #else 358 #define _PP_MACRO_PRIVATE_ /* ppmacro private additions */ \ 359 struct pptuple* tuple; /* tuple macro */ \ 360 char* formals; /* formal argument list */ \ 361 int size; /* body size */ 362 #endif 363 364 #define _PP_DIRS_PRIVATE_ /* ppdirs private additions */ \ 365 unsigned char c; /* files here are C language */ \ 366 unsigned char index; /* prefix,local,standard index */ \ 367 unsigned char type; /* dir type */ \ 368 union \ 369 { \ 370 char* buffer; /* TYPE_BUFFER buffer */ \ 371 Sfio_t* sp; /* archive stream */ \ 372 struct ppdirs* subdir; /* subdir list */ \ 373 } info; /* type info */ \ 374 struct ppfileid id; /* directory id */ \ 375 376 #if !PROTOMAIN 377 #include <ast.h> 378 #include <error.h> 379 #endif 380 381 #undef newof 382 #define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x))) 383 384 #include "pp.h" 385 #include "ppdef.h" 386 #include "ppkey.h" 387 388 #undef setstate /* random clash! */ 389 390 /* 391 * DEBUG is encoded with the following bits 392 */ 393 394 #define TRACE_message 01 395 #define TRACE_count 02 396 #define TRACE_debug 04 397 398 #if DEBUG && !lint 399 #define PANIC (ERROR_PANIC|ERROR_SOURCE|ERROR_SYSTEM),__FILE__,__LINE__ 400 #else 401 #define PANIC ERROR_PANIC 402 #endif 403 404 #if DEBUG & TRACE_count 405 #define count(x) pp.counter.x++ 406 #else 407 #define count(x) 408 #endif 409 410 #if DEBUG & TRACE_message 411 #define message(x) do { if (tracing) error x; } while (0) 412 #else 413 #define message(x) 414 #endif 415 416 #if DEBUG & TRACE_debug 417 #define debug(x) do { if (tracing) error x; } while (0) 418 #else 419 #define debug(x) 420 #endif 421 422 /* 423 * note that MEMCPY advances the associated pointers 424 */ 425 426 #define MEMCPY(to,fr,n) \ 427 do switch(n) \ 428 { default : memcpy(to,fr,n); to += n; fr += n; break; \ 429 case 7 : *to++ = *fr++; \ 430 case 6 : *to++ = *fr++; \ 431 case 5 : *to++ = *fr++; \ 432 case 4 : *to++ = *fr++; \ 433 case 3 : *to++ = *fr++; \ 434 case 2 : *to++ = *fr++; \ 435 case 1 : *to++ = *fr++; \ 436 case 0 : break; \ 437 } while (0) 438 439 #define NEWDIRECTIVE (-1) 440 441 #undef dirname 442 #undef error 443 444 #define dirname(x) ppkeyname(x,1) 445 #define error pperror 446 #define keyname(x) ppkeyname(x,0) 447 #define nextframe(m,p) (m->next=m+(p-(char*)m+sizeof(struct ppmacstk)-1)/sizeof(struct ppmacstk)+1) 448 #define popframe(m) (m=m->prev) 449 #define pptokchr(c) pptokstr(NiL,(c)) 450 #define pushcontrol() do { if (pp.control++ >= pp.maxcon) ppnest(); } while (0) 451 #define pushframe(m) (m->next->prev=m,m=m->next) 452 #define setmode(m,v) ((v)?(pp.mode|=(m)):(pp.mode&=~(m))) 453 #define setoption(m,v) ((v)?(pp.option|=(m)):(pp.option&=~(m))) 454 #define setstate(s,v) ((v)?(pp.state|=(s)):(pp.state&=~(s))) 455 #define tracing (error_info.trace<0) 456 457 #define ppgetfile(x) ((struct ppfile*)hashlook(pp.filtab,x,HASH_LOOKUP,NiL)) 458 #define ppsetfile(x) ((struct ppfile*)hashlook(pp.filtab,x,HASH_CREATE|HASH_SIZE(sizeof(struct ppfile)),NiL)) 459 460 #define ppkeyget(t,n) (struct ppsymkey*)hashlook(t,n,HASH_LOOKUP,NiL) 461 #define ppkeyref(t,n) (struct ppsymkey*)hashlook(t,n,HASH_LOOKUP|HASH_INTERNAL,NiL) 462 #define ppkeyset(t,n) (struct ppsymkey*)hashlook(t,n,HASH_CREATE|HASH_SIZE(sizeof(struct ppsymkey)),NiL) 463 464 #define MARK '@' /* internal mark */ 465 #define ARGOFFSET '1' /* macro arg mark offset */ 466 467 #define STRAPP(p,v,r) do{r=(v);while((*p++)=(*r++));}while(0) 468 #define STRCOPY(p,v,r) do{r=(v);while((*p++)=(*r++));p--;}while(0) 469 #define STRCOPY2(p,r) do{while((*p++)=(*r++));p--;}while(0) 470 471 #define SETFILE(p,v) (p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'F',(long)v,MARK)) 472 #define SETLINE(p,v) (p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'L',(long)v,MARK)) 473 474 #define peekchr() (*pp.in->nextchr) 475 #define ungetchr(c) (*--pp.in->nextchr=(c)) 476 477 #define MAXID 255 /* maximum identifier size */ 478 #define MAXTOKEN PPTOKSIZ /* maximum token size */ 479 #define MAXFORMALS 64 /* maximum number macro formals */ 480 #define MAXHIDDEN 8 /* ppline if hidden>=MAXHIDDEN */ 481 #define DEFMACSTACK (MAXFORMALS*32*32)/* default macstack size */ 482 483 #define FSM_COMPATIBILITY 1 /* compatibility mode */ 484 #define FSM_IDADD 2 /* add to identifer set */ 485 #define FSM_IDDEL 3 /* delete from identifer set */ 486 #define FSM_INIT 4 /* initilize */ 487 #define FSM_MACRO 5 /* add new macro */ 488 #define FSM_OPSPACE 6 /* handle <binop><space>= */ 489 #define FSM_PLUSPLUS 7 /* C++ lexical analysis */ 490 #define FSM_QUOTADD 8 /* add to quote set */ 491 #define FSM_QUOTDEL 9 /* delete from quote set */ 492 493 #define IN_TOP 01 /* top level -- directives ok */ 494 495 #define IN_BUFFER (2|IN_TOP) /* buffer of lines */ 496 #define IN_COPY 2 /* macro arg (copied) */ 497 #define IN_EXPAND 4 /* macro arg (expanded) */ 498 #define IN_FILE (4|IN_TOP) /* file */ 499 #define IN_INIT (6|IN_TOP) /* initialization IN_BUFFER */ 500 #define IN_MACRO 8 /* macro text */ 501 #define IN_MULTILINE (8|IN_TOP) /* multi-line macro text */ 502 #define IN_QUOTE 10 /* "..." macro arg (copied) */ 503 #define IN_RESCAN (10|IN_TOP) /* directive rescan buffer */ 504 #define IN_SQUOTE 12 /* '...' macro arg (copied) */ 505 #define IN_STRING 14 /* string */ 506 507 #define INC_CLEAR ((struct ppsymbol*)0) 508 #define INC_IGNORE ((struct ppsymbol*)pp.addbuf) 509 #define INC_TEST ((struct ppsymbol*)pp.catbuf) 510 511 #define INC_BOUND(n) (1<<(n)) 512 #define INC_MEMBER(n) (1<<((n)+INC_MAX)) 513 #define INC_PREFIX 0 514 #define INC_LOCAL 1 515 #define INC_STANDARD 2 516 #define INC_VENDOR 3 517 #define INC_MAX 4 518 #define INC_SELF (1<<(2*INC_MAX+0)) 519 #define INC_EXISTS (1<<(2*INC_MAX+1)) 520 #define INC_LISTED (1<<(2*INC_MAX+2)) 521 #define INC_MAPALL (1<<(2*INC_MAX+3)) 522 #define INC_MAPHOSTED (1<<(2*INC_MAX+4)) 523 #define INC_MAPNOHOSTED (1<<(2*INC_MAX+5)) 524 #define INC_MAPNOLOCAL (1<<(2*INC_MAX+6)) 525 #define INC_HOSTED (1<<(2*INC_MAX+7)) 526 527 #define TYPE_ARCHIVE (1<<0) 528 #define TYPE_BUFFER (1<<1) 529 #define TYPE_CHECKPOINT (1<<2) 530 #define TYPE_DIRECTORY (1<<3) 531 #define TYPE_HOSTED (1<<4) 532 #define TYPE_INCLUDE (1<<5) 533 #define TYPE_VENDOR (1<<6) 534 535 #define TOK_BUILTIN (1<<0) /* last token was #( */ 536 #define TOK_FORMAL (1<<1) /* last token was arg formal id */ 537 #define TOK_ID (1<<2) /* last token was identifier */ 538 #define TOK_TOKCAT (1<<3) /* last token was ## */ 539 540 #define HADELSE (1<<0) /* already had else part */ 541 #define KEPT (1<<1) /* already kept part of block */ 542 #define SKIP (1<<2) /* skip this block */ 543 #define BLOCKBITS 3 /* block flag bits */ 544 545 #define SETIFBLOCK(p) (*(p)=(*((p)-1)&SKIP)|((long)error_info.line<<BLOCKBITS)) 546 #define GETIFLINE(p) ((*(p)>>BLOCKBITS)&((1L<<(sizeof(long)*CHAR_BIT-BLOCKBITS))-1)) 547 548 #define PUSH(t,p) \ 549 do \ 550 { \ 551 count(push); \ 552 if (!pp.in->next) \ 553 { \ 554 pp.in->next = newof(0, struct ppinstk, 1, 0); \ 555 pp.in->next->prev = pp.in; \ 556 } \ 557 p = pp.in = pp.in->next; \ 558 p->type = t; \ 559 p->flags = 0; \ 560 } while (0) 561 562 #define PUSH_BUFFER(f,p,n) \ 563 pppush(IN_BUFFER,f,p,n) 564 565 #define PUSH_COPY(p,n) \ 566 do \ 567 { \ 568 register struct ppinstk* cur; \ 569 PUSH(IN_COPY, cur); \ 570 cur->line = error_info.line; \ 571 error_info.line = n; \ 572 cur->nextchr = p; \ 573 cur->prev->symbol->flags &= ~SYM_DISABLED; \ 574 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 575 } while (0) 576 577 #define PUSH_EXPAND(p,n) \ 578 do \ 579 { \ 580 register struct ppinstk* cur; \ 581 PUSH(IN_EXPAND, cur); \ 582 cur->line = error_info.line; \ 583 error_info.line = n; \ 584 cur->prev->symbol->flags &= ~SYM_DISABLED; \ 585 cur->buffer = cur->nextchr = ppexpand(p); \ 586 if (!(cur->prev->symbol->flags & SYM_MULTILINE)) \ 587 cur->prev->symbol->flags |= SYM_DISABLED; \ 588 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 589 } while (0) 590 591 #define PUSH_FILE(f,d) \ 592 pppush(IN_FILE,f,NiL,d) 593 594 #define PUSH_INIT(f,p) \ 595 pppush(IN_INIT,f,p,1) 596 597 #define PUSH_MACRO(p) \ 598 do \ 599 { \ 600 register struct ppinstk* cur; \ 601 PUSH(IN_MACRO, cur); \ 602 cur->symbol = p; \ 603 cur->nextchr = p->macro->value; \ 604 p->flags |= SYM_DISABLED; \ 605 if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \ 606 pp.state &= ~NEWLINE; \ 607 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 608 } while (0) 609 610 #define PUSH_TUPLE(p,v) \ 611 do \ 612 { \ 613 register struct ppinstk* cur; \ 614 PUSH(IN_MACRO, cur); \ 615 cur->symbol = p; \ 616 cur->nextchr = v; \ 617 p->flags |= SYM_DISABLED; \ 618 pp.state &= ~NEWLINE; \ 619 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 620 } while (0) 621 622 #define PUSH_MULTILINE(p) \ 623 do \ 624 { \ 625 register struct ppinstk* cur; \ 626 register int n; \ 627 PUSH(IN_MULTILINE, cur); \ 628 cur->symbol = p; \ 629 cur->flags |= IN_defguard|IN_endguard|IN_noguard; \ 630 pushcontrol(); \ 631 cur->control = pp.control; \ 632 *pp.control = 0; \ 633 cur->file = error_info.file; \ 634 n = strlen(error_info.file) + strlen(((struct ppsymbol*)p)->name) + 24; \ 635 error_info.file = cur->buffer = newof(0, char, n, 0); \ 636 sfsprintf(error_info.file, n, "%s:%s,%d", cur->file, p->name, error_info.line); \ 637 cur->line = error_info.line; \ 638 error_info.line = 1; \ 639 cur->nextchr = p->macro->value; \ 640 if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \ 641 pp.state &= ~NEWLINE; \ 642 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 643 } while (0) 644 645 #define PUSH_QUOTE(p,n) \ 646 do \ 647 { \ 648 register struct ppinstk* cur; \ 649 PUSH(IN_QUOTE, cur); \ 650 cur->nextchr = p; \ 651 pp.state |= QUOTE; \ 652 cur->line = error_info.line; \ 653 error_info.line = n; \ 654 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 655 } while (0) 656 657 #define PUSH_RESCAN(p) \ 658 pppush(IN_RESCAN,NiL,p,0) 659 660 #define PUSH_SQUOTE(p,n) \ 661 do \ 662 { \ 663 register struct ppinstk* cur; \ 664 PUSH(IN_SQUOTE, cur); \ 665 cur->nextchr = p; \ 666 pp.state |= SQUOTE; \ 667 cur->line = error_info.line; \ 668 error_info.line = n; \ 669 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 670 } while (0) 671 672 #define PUSH_STRING(p) \ 673 do \ 674 { \ 675 register struct ppinstk* cur; \ 676 PUSH(IN_STRING, cur); \ 677 cur->nextchr = p; \ 678 if (pp.state & DISABLE) cur->flags |= IN_disable; \ 679 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 680 } while (0) 681 682 #define PUSH_LINE(p) \ 683 do \ 684 { \ 685 register struct ppinstk* cur; \ 686 PUSH(IN_STRING, cur); \ 687 cur->nextchr = p; \ 688 pp.state |= DISABLE|NOSPACE|PASSEOF|STRIP; \ 689 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 690 } while (0) 691 692 #define POP_LINE() \ 693 do \ 694 { \ 695 debug((-7, "POP in=%s", ppinstr(pp.in))); \ 696 pp.in = pp.in->prev; \ 697 pp.state &= ~(DISABLE|NOSPACE|PASSEOF|STRIP); \ 698 } while (0) 699 700 struct ppcontext /* pp context */ 701 { 702 _PP_CONTEXT_PUBLIC_ 703 _PP_CONTEXT_PRIVATE_ 704 }; 705 706 struct ppfile /* include file info */ 707 { 708 HASH_HEADER; /* this is a hash bucket too */ 709 struct ppsymbol* guard; /* guard symbol */ 710 struct ppfile* bound[INC_MAX]; /* include bindings */ 711 int flags; /* INC_* flags */ 712 }; 713 714 #if CHECKPOINT 715 716 struct ppindex /* checkpoint include index */ 717 { 718 struct ppindex* next; /* next in list */ 719 struct ppfile* file; /* include file */ 720 unsigned long begin; /* beginning output offset */ 721 unsigned long end; /* ending output offset */ 722 }; 723 724 #endif 725 726 struct ppsymkey /* pun for SYM_KEYWORD lex val */ 727 { 728 struct ppsymbol sym; /* symbol as usual */ 729 int lex; /* lex value for SYM_KEYWORD */ 730 }; 731 732 #if PROTOMAIN && PROTO_STANDALONE 733 734 #if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) 735 #define NiL 0 736 #define NoP(x) (&x,1) 737 #else 738 #define NiL ((char*)0) 739 #define NoP(x) 740 #endif 741 742 #define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x))) 743 744 #define _PP_DELAY_ # 745 746 _PP_DELAY_ ifdef __STDC__ 747 748 _PP_DELAY_ include <stdlib.h> 749 _PP_DELAY_ include <unistd.h> 750 _PP_DELAY_ include <time.h> 751 _PP_DELAY_ include <string.h> 752 753 _PP_DELAY_ else 754 755 _PP_DELAY_ define size_t int 756 757 extern void* realloc(void*, size_t); 758 extern void* calloc(size_t, size_t); 759 extern char* ctime(time_t*); 760 extern void free(void*); 761 762 _PP_DELAY_ ifndef O_RDONLY 763 764 extern int access(const char*, int); 765 extern int close(int); 766 extern int creat(const char*, int); 767 extern void exit(int); 768 extern int link(const char*, const char*); 769 extern int open(const char*, int, ...); 770 extern int read(int, void*, int); 771 extern time_t time(time_t*); 772 extern int unlink(const char*); 773 extern int write(int, const void*, int); 774 775 _PP_DELAY_ endif 776 777 _PP_DELAY_ endif 778 779 #else 780 781 /* 782 * library implementation globals 783 */ 784 785 #define ppassert _pp_assert 786 #define ppbuiltin _pp_builtin 787 #define ppcall _pp_call 788 #define ppcontrol _pp_control 789 #define ppdump _pp_dump 790 #define ppexpand _pp_expand 791 #define ppexpr _pp_expr 792 #define ppfsm _pp_fsm 793 #define ppinmap _pp_inmap 794 #define ppinstr _pp_instr 795 #define ppkeyname _pp_keyname 796 #define pplexmap _pp_lexmap 797 #define pplexstr _pp_lexstr 798 #define ppload _pp_load 799 #define ppmodestr _pp_modestr 800 #define ppmultiple _pp_multiple 801 #define ppnest _pp_nest 802 #define ppoption _pp_option 803 #define ppoptionstr _pp_optionstr 804 #define pppclose _pp_pclose 805 #define pppdrop _pp_pdrop 806 #define pppopen _pp_popen 807 #define pppread _pp_pread 808 #define pppredargs _pp_predargs 809 #define pppush _pp_push 810 #define pprefmac _pp_refmac 811 #define ppsearch _pp_search 812 #define ppstatestr _pp_statestr 813 #define pptokstr _pp_tokstr 814 #define pptrace _pp_trace 815 816 #endif 817 818 extern void ppassert(int, char*, char*); 819 extern void ppbuiltin(void); 820 extern int ppcall(struct ppsymbol*, int); 821 extern int ppcontrol(void); 822 extern void ppdump(void); 823 extern char* ppexpand(char*); 824 extern long ppexpr(int*); 825 extern void ppfsm(int, char*); 826 extern char* ppinstr(struct ppinstk*); 827 extern char* ppkeyname(int, int); 828 extern char* pplexstr(int); 829 extern void ppload(char*); 830 extern void ppmapinclude(char*, char*); 831 extern char* ppmodestr(long); 832 extern int ppmultiple(struct ppfile*, struct ppsymbol*); 833 extern void ppnest(void); 834 extern int ppoption(char*); 835 extern char* ppoptionstr(long); 836 extern void pppclose(char*); 837 extern int pppdrop(char*); 838 extern char* pppopen(char*, int, char*, char*, char*, char*, int); 839 extern int pppread(char*); 840 extern int pppredargs(void); 841 extern void pppush(int, char*, char*, int); 842 extern struct ppsymbol* pprefmac(char*, int); 843 extern int ppsearch(char*, int, int); 844 extern char* ppstatestr(long); 845 extern char* pptokstr(char*, int); 846 extern void pptrace(int); 847 848 #if _std_malloc 849 850 #include <vmalloc.h> 851 852 #undef free 853 #define free(p) vmfree(Vmregion,(void*)p) 854 #undef newof 855 #define newof(p,t,n,x) vmnewof(Vmregion,p,t,n,x) 856 #undef oldof 857 #define oldof(p,t,n,x) vmoldof(Vmregion,p,t,n,x) 858 #undef strdup 859 #define strdup(s) vmstrdup(Vmregion,s) 860 861 #endif 862 863 #endif 864