1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1986-2011 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Eclipse Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.eclipse.org/org/documents/epl-v10.html * 11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 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 long ro_op[2]; /* readonly op */ \ 265 struct pathid cdir; /* arg C dir */ \ 266 struct pathid hostdir; /* arg host dir */ \ 267 char* ppdefault; /* arg default info file */ \ 268 struct ppindex* firstindex; /* first include index entry */ \ 269 struct ppindex* lastindex; /* last include index entry */ \ 270 struct oplist* firstop; /* first arg op */ \ 271 struct oplist* lastop; /* last arg op */ \ 272 struct oplist* firsttx; /* first text file */ \ 273 struct oplist* lasttx; /* last text file */ \ 274 unsigned char arg_file; /* arg file index */ \ 275 unsigned char arg_mode; /* arg mode */ \ 276 unsigned char arg_style; /* arg style */ \ 277 unsigned char c; /* arg C state */ \ 278 unsigned char hosted; /* arg hosted state */ \ 279 unsigned char ignoresrc; /* arg ignore source state */ \ 280 unsigned char initialized; /* arg initialized state */ \ 281 unsigned char standalone; /* arg standalone state */ \ 282 unsigned char spare_1; /* padding spare */ 283 284 #define _PP_GLOBALS_PRIVATE_ /* ppglobals private additions */ \ 285 char* checkpoint; /* checkpoint version */ \ 286 int constack; /* pp.control size */ \ 287 struct ppinstk* in; /* input stream stack pointer */ \ 288 char* addp; /* addbuf pointer */ \ 289 char* args; /* predicate args */ \ 290 char* addbuf; /* ADD buffer */ \ 291 char* catbuf; /* catenation buffer */ \ 292 char* hdrbuf; /* HEADEREXPAND buffer */ \ 293 char* hidebuf; /* pp:hide buffer */ \ 294 char* path; /* full path of last #include */ \ 295 char* tmpbuf; /* very temporary buffer */ \ 296 char* valbuf; /* builtin macro value buffer */ \ 297 char* optflags; /* OPT_* flags indexed by X_* */ \ 298 int lastout; /* last output char */ \ 299 /* the rest are implicitly initialized */ \ 300 char* include; /* saved path of last #include */ \ 301 char* prefix; /* current directory prefix */ \ 302 struct ppmember* member; /* include archive member data */ \ 303 int hidden; /* hidden newline count */ \ 304 int hiding; /* number of symbols in hiding */ \ 305 int level; /* pplex() recursion level */ \ 306 struct \ 307 { \ 308 int input; /* pool input */ \ 309 int output; /* pool output */ \ 310 } pool; /* loop on input,output,error */ \ 311 struct \ 312 { \ 313 long ro_state; /* original pp.ro_state */ \ 314 long ro_mode; /* original pp.ro_mode */ \ 315 long ro_option; /* original pp.ro_option */ \ 316 long ro_op[2]; /* original pp.ro_op[] */ \ 317 int on; /* PP_RESET enabled */ \ 318 Hash_table_t* symtab; /* original pp.symtab scope */ \ 319 } reset; /* PP_RESET state */ \ 320 int truncate; /* identifier truncation length */ \ 321 struct ppmacstk* macp; /* top of macro actual stack */ \ 322 char* maxmac; /* maximum size of macro stack */ \ 323 char* mactop; /* top of current macro frame */ \ 324 char* toknxt; /* '\0' of pp.token */ \ 325 long* control; /* control block flags pointer */ \ 326 long* maxcon; /* max control block frame */ \ 327 struct oplist* chop; /* include prefix chop list */ \ 328 struct ppfile* insert; /* inserted line sync file */ \ 329 struct ppfile* original; /* original include name */ \ 330 struct ppdirs* found; /* last successful ppsearch dir */ \ 331 int vendor; /* vendor includes only */ \ 332 Hash_table_t* dirtab; /* directive hash table */ \ 333 Hash_table_t* strtab; /* string hash table */ \ 334 PPBUILTIN builtin; /* builtin macro handler */ \ 335 PPCOMMENT comment; /* pass along comments */ \ 336 PPINCREF incref; /* include file push/return */ \ 337 PPLINESYNC linesync; /* pass along line sync info */ \ 338 PPLINESYNC olinesync; /* original linesync value */ \ 339 PPMACREF macref; /* called on macro def/ref */ \ 340 PPOPTARG optarg; /* unknown option arg handler */ \ 341 PPPRAGMA pragma; /* pass along unknown pragmas */ \ 342 struct counter counter; /* monitoring counters */ \ 343 char funbuf[256]; /* last __FUNCTION__ */ 344 345 #define _PP_SYMBOL_PRIVATE_ /* ppsymbol private additions */ \ 346 struct pphide* hidden; /* hidden symbol info */ 347 348 #if MACKEYARGS 349 #define _PP_MACRO_PRIVATE_ /* ppmacro private additions */ \ 350 struct pptuple* tuple; /* tuple macro */ \ 351 union \ 352 { \ 353 char* formal; /* normal formals list */ \ 354 struct ppkeyarg* key; /* keyword formals table */ \ 355 } args; /* macro args info */ \ 356 int size; /* body size */ 357 #define formals args.formal /* formal argument list */ 358 #define formkeys args.key /* formal keyword argument list */ 359 #else 360 #define _PP_MACRO_PRIVATE_ /* ppmacro private additions */ \ 361 struct pptuple* tuple; /* tuple macro */ \ 362 char* formals; /* formal argument list */ \ 363 int size; /* body size */ 364 #endif 365 366 #define _PP_DIRS_PRIVATE_ /* ppdirs private additions */ \ 367 unsigned char c; /* files here are C language */ \ 368 unsigned char index; /* prefix,local,standard index */ \ 369 unsigned char type; /* dir type */ \ 370 union \ 371 { \ 372 char* buffer; /* TYPE_BUFFER buffer */ \ 373 Sfio_t* sp; /* archive stream */ \ 374 struct ppdirs* subdir; /* subdir list */ \ 375 } info; /* type info */ \ 376 struct ppfileid id; /* directory id */ \ 377 378 #if !PROTOMAIN 379 #include <ast.h> 380 #include <error.h> 381 #endif 382 383 #undef newof 384 #define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x))) 385 386 #include "pp.h" 387 #include "ppdef.h" 388 #include "ppkey.h" 389 390 #undef setstate /* random clash! */ 391 392 /* 393 * DEBUG is encoded with the following bits 394 */ 395 396 #define TRACE_message 01 397 #define TRACE_count 02 398 #define TRACE_debug 04 399 400 #if DEBUG && !lint 401 #define PANIC (ERROR_PANIC|ERROR_SOURCE|ERROR_SYSTEM),__FILE__,__LINE__ 402 #else 403 #define PANIC ERROR_PANIC 404 #endif 405 406 #if DEBUG & TRACE_count 407 #define count(x) pp.counter.x++ 408 #else 409 #define count(x) 410 #endif 411 412 #if DEBUG & TRACE_message 413 #define message(x) do { if (tracing) error x; } while (0) 414 #else 415 #define message(x) 416 #endif 417 418 #if DEBUG & TRACE_debug 419 #define debug(x) do { if (tracing) error x; } while (0) 420 #else 421 #define debug(x) 422 #endif 423 424 /* 425 * note that MEMCPY advances the associated pointers 426 */ 427 428 #define MEMCPY(to,fr,n) \ 429 { memcpy((Void_t*)to,(Void_t*)fr,n); to += n; fr += n; } 430 431 #define NEWDIRECTIVE (-1) 432 433 #undef dirname 434 #undef error 435 436 #define dirname(x) ppkeyname(x,1) 437 #define error pperror 438 #define keyname(x) ppkeyname(x,0) 439 #define nextframe(m,p) (m->next=m+(p-(char*)m+sizeof(struct ppmacstk)-1)/sizeof(struct ppmacstk)+1) 440 #define popframe(m) (m=m->prev) 441 #define pptokchr(c) pptokstr(NiL,(c)) 442 #define pushcontrol() do { if (pp.control++ >= pp.maxcon) ppnest(); } while (0) 443 #define pushframe(m) (m->next->prev=m,m=m->next) 444 #define setmode(m,v) ppset(&pp.mode,m,v) 445 #define setoption(m,v) ppset(&pp.option,m,v) 446 #define setstate(m,v) ppset(&pp.state,m,v) 447 #define tracing (error_info.trace<0) 448 449 #define ppgetfile(x) ((struct ppfile*)hashlook(pp.filtab,x,HASH_LOOKUP,NiL)) 450 #define ppsetfile(x) ((struct ppfile*)hashlook(pp.filtab,x,HASH_CREATE|HASH_SIZE(sizeof(struct ppfile)),NiL)) 451 452 #define ppkeyget(t,n) (struct ppsymkey*)hashlook(t,n,HASH_LOOKUP,NiL) 453 #define ppkeyref(t,n) (struct ppsymkey*)hashlook(t,n,HASH_LOOKUP|HASH_INTERNAL,NiL) 454 #define ppkeyset(t,n) (struct ppsymkey*)hashlook(t,n,HASH_CREATE|HASH_SIZE(sizeof(struct ppsymkey)),NiL) 455 456 #define MARK '@' /* internal mark */ 457 #define ARGOFFSET '1' /* macro arg mark offset */ 458 459 #define STRAPP(p,v,r) do{r=(v);while((*p++)=(*r++));}while(0) 460 #define STRCOPY(p,v,r) do{r=(v);while((*p++)=(*r++));p--;}while(0) 461 #define STRCOPY2(p,r) do{while((*p++)=(*r++));p--;}while(0) 462 463 #define SETFILE(p,v) (p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'F',(long)v,MARK)) 464 #define SETLINE(p,v) (p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'L',(long)v,MARK)) 465 466 #define peekchr() (*pp.in->nextchr) 467 #define ungetchr(c) (*--pp.in->nextchr=(c)) 468 469 #define MAXID 255 /* maximum identifier size */ 470 #define MAXTOKEN PPTOKSIZ /* maximum token size */ 471 #define MAXFORMALS 64 /* maximum number macro formals */ 472 #define MAXHIDDEN 8 /* ppline if hidden>=MAXHIDDEN */ 473 #define DEFMACSTACK (MAXFORMALS*32*32)/* default macstack size */ 474 475 #define FSM_COMPATIBILITY 1 /* compatibility mode */ 476 #define FSM_IDADD 2 /* add to identifer set */ 477 #define FSM_IDDEL 3 /* delete from identifer set */ 478 #define FSM_INIT 4 /* initilize */ 479 #define FSM_MACRO 5 /* add new macro */ 480 #define FSM_OPSPACE 6 /* handle <binop><space>= */ 481 #define FSM_PLUSPLUS 7 /* C++ lexical analysis */ 482 #define FSM_QUOTADD 8 /* add to quote set */ 483 #define FSM_QUOTDEL 9 /* delete from quote set */ 484 485 #define IN_TOP 01 /* top level -- directives ok */ 486 487 #define IN_BUFFER (2|IN_TOP) /* buffer of lines */ 488 #define IN_COPY 2 /* macro arg (copied) */ 489 #define IN_EXPAND 4 /* macro arg (expanded) */ 490 #define IN_FILE (4|IN_TOP) /* file */ 491 #define IN_INIT (6|IN_TOP) /* initialization IN_BUFFER */ 492 #define IN_MACRO 8 /* macro text */ 493 #define IN_MULTILINE (8|IN_TOP) /* multi-line macro text */ 494 #define IN_QUOTE 10 /* "..." macro arg (copied) */ 495 #define IN_RESCAN (10|IN_TOP) /* directive rescan buffer */ 496 #define IN_SQUOTE 12 /* '...' macro arg (copied) */ 497 #define IN_STRING 14 /* string */ 498 499 #define INC_CLEAR ((struct ppsymbol*)0) 500 #define INC_IGNORE ((struct ppsymbol*)pp.addbuf) 501 #define INC_TEST ((struct ppsymbol*)pp.catbuf) 502 503 #define INC_BOUND(n) (1<<(n)) 504 #define INC_MEMBER(n) (1<<((n)+INC_MAX)) 505 #define INC_PREFIX 0 506 #define INC_LOCAL 1 507 #define INC_STANDARD 2 508 #define INC_VENDOR 3 509 #define INC_MAX 4 510 #define INC_SELF (1<<(2*INC_MAX+0)) 511 #define INC_EXISTS (1<<(2*INC_MAX+1)) 512 #define INC_LISTED (1<<(2*INC_MAX+2)) 513 #define INC_MAPALL (1<<(2*INC_MAX+3)) 514 #define INC_MAPHOSTED (1<<(2*INC_MAX+4)) 515 #define INC_MAPNOHOSTED (1<<(2*INC_MAX+5)) 516 #define INC_MAPNOLOCAL (1<<(2*INC_MAX+6)) 517 #define INC_HOSTED (1<<(2*INC_MAX+7)) 518 519 #define TYPE_ARCHIVE (1<<0) 520 #define TYPE_BUFFER (1<<1) 521 #define TYPE_CHECKPOINT (1<<2) 522 #define TYPE_DIRECTORY (1<<3) 523 #define TYPE_HOSTED (1<<4) 524 #define TYPE_INCLUDE (1<<5) 525 #define TYPE_VENDOR (1<<6) 526 527 #define TOK_BUILTIN (1<<0) /* last token was #( */ 528 #define TOK_FORMAL (1<<1) /* last token was arg formal id */ 529 #define TOK_ID (1<<2) /* last token was identifier */ 530 #define TOK_TOKCAT (1<<3) /* last token was ## */ 531 532 #define HADELSE (1<<0) /* already had else part */ 533 #define KEPT (1<<1) /* already kept part of block */ 534 #define SKIP (1<<2) /* skip this block */ 535 #define BLOCKBITS 3 /* block flag bits */ 536 537 #define SETIFBLOCK(p) (*(p)=(*((p)-1)&SKIP)|((long)error_info.line<<BLOCKBITS)) 538 #define GETIFLINE(p) ((*(p)>>BLOCKBITS)&((1L<<(sizeof(long)*CHAR_BIT-BLOCKBITS))-1)) 539 540 #define PUSH(t,p) \ 541 do \ 542 { \ 543 count(push); \ 544 if (!pp.in->next) \ 545 { \ 546 pp.in->next = newof(0, struct ppinstk, 1, 0); \ 547 pp.in->next->prev = pp.in; \ 548 } \ 549 p = pp.in = pp.in->next; \ 550 p->type = t; \ 551 p->flags = 0; \ 552 } while (0) 553 554 #define PUSH_BUFFER(f,p,n) \ 555 pppush(IN_BUFFER,f,p,n) 556 557 #define PUSH_COPY(p,n) \ 558 do \ 559 { \ 560 register struct ppinstk* cur; \ 561 PUSH(IN_COPY, cur); \ 562 cur->line = error_info.line; \ 563 error_info.line = n; \ 564 cur->nextchr = p; \ 565 cur->prev->symbol->flags &= ~SYM_DISABLED; \ 566 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 567 } while (0) 568 569 #define PUSH_EXPAND(p,n) \ 570 do \ 571 { \ 572 register struct ppinstk* cur; \ 573 PUSH(IN_EXPAND, cur); \ 574 cur->line = error_info.line; \ 575 error_info.line = n; \ 576 cur->prev->symbol->flags &= ~SYM_DISABLED; \ 577 cur->buffer = cur->nextchr = ppexpand(p); \ 578 if (!(cur->prev->symbol->flags & SYM_MULTILINE)) \ 579 cur->prev->symbol->flags |= SYM_DISABLED; \ 580 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 581 } while (0) 582 583 #define PUSH_FILE(f,d) \ 584 pppush(IN_FILE,f,NiL,d) 585 586 #define PUSH_INIT(f,p) \ 587 pppush(IN_INIT,f,p,1) 588 589 #define PUSH_MACRO(p) \ 590 do \ 591 { \ 592 register struct ppinstk* cur; \ 593 PUSH(IN_MACRO, cur); \ 594 cur->symbol = p; \ 595 cur->nextchr = p->macro->value; \ 596 p->flags |= SYM_DISABLED; \ 597 if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \ 598 pp.state &= ~NEWLINE; \ 599 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 600 } while (0) 601 602 #define PUSH_TUPLE(p,v) \ 603 do \ 604 { \ 605 register struct ppinstk* cur; \ 606 PUSH(IN_MACRO, cur); \ 607 cur->symbol = p; \ 608 cur->nextchr = v; \ 609 p->flags |= SYM_DISABLED; \ 610 pp.state &= ~NEWLINE; \ 611 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 612 } while (0) 613 614 #define PUSH_MULTILINE(p) \ 615 do \ 616 { \ 617 register struct ppinstk* cur; \ 618 register int n; \ 619 PUSH(IN_MULTILINE, cur); \ 620 cur->symbol = p; \ 621 cur->flags |= IN_defguard|IN_endguard|IN_noguard; \ 622 pushcontrol(); \ 623 cur->control = pp.control; \ 624 *pp.control = 0; \ 625 cur->file = error_info.file; \ 626 n = strlen(error_info.file) + strlen(((struct ppsymbol*)p)->name) + 24; \ 627 error_info.file = cur->buffer = newof(0, char, n, 0); \ 628 sfsprintf(error_info.file, n, "%s:%s,%d", cur->file, p->name, error_info.line); \ 629 cur->line = error_info.line; \ 630 error_info.line = 1; \ 631 cur->nextchr = p->macro->value; \ 632 if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \ 633 pp.state &= ~NEWLINE; \ 634 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 635 } while (0) 636 637 #define PUSH_QUOTE(p,n) \ 638 do \ 639 { \ 640 register struct ppinstk* cur; \ 641 PUSH(IN_QUOTE, cur); \ 642 cur->nextchr = p; \ 643 pp.state |= QUOTE; \ 644 cur->line = error_info.line; \ 645 error_info.line = n; \ 646 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 647 } while (0) 648 649 #define PUSH_RESCAN(p) \ 650 pppush(IN_RESCAN,NiL,p,0) 651 652 #define PUSH_SQUOTE(p,n) \ 653 do \ 654 { \ 655 register struct ppinstk* cur; \ 656 PUSH(IN_SQUOTE, cur); \ 657 cur->nextchr = p; \ 658 pp.state |= SQUOTE; \ 659 cur->line = error_info.line; \ 660 error_info.line = n; \ 661 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 662 } while (0) 663 664 #define PUSH_STRING(p) \ 665 do \ 666 { \ 667 register struct ppinstk* cur; \ 668 PUSH(IN_STRING, cur); \ 669 cur->nextchr = p; \ 670 if (pp.state & DISABLE) cur->flags |= IN_disable; \ 671 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 672 } while (0) 673 674 #define PUSH_LINE(p) \ 675 do \ 676 { \ 677 register struct ppinstk* cur; \ 678 PUSH(IN_STRING, cur); \ 679 cur->nextchr = p; \ 680 pp.state |= DISABLE|NOSPACE|PASSEOF|STRIP; \ 681 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \ 682 } while (0) 683 684 #define POP_LINE() \ 685 do \ 686 { \ 687 debug((-7, "POP in=%s", ppinstr(pp.in))); \ 688 pp.in = pp.in->prev; \ 689 pp.state &= ~(DISABLE|NOSPACE|PASSEOF|STRIP); \ 690 } while (0) 691 692 struct ppcontext /* pp context */ 693 { 694 _PP_CONTEXT_PUBLIC_ 695 _PP_CONTEXT_PRIVATE_ 696 }; 697 698 struct ppfile /* include file info */ 699 { 700 HASH_HEADER; /* this is a hash bucket too */ 701 struct ppsymbol* guard; /* guard symbol */ 702 struct ppfile* bound[INC_MAX]; /* include bindings */ 703 int flags; /* INC_* flags */ 704 }; 705 706 #if CHECKPOINT 707 708 struct ppindex /* checkpoint include index */ 709 { 710 struct ppindex* next; /* next in list */ 711 struct ppfile* file; /* include file */ 712 unsigned long begin; /* beginning output offset */ 713 unsigned long end; /* ending output offset */ 714 }; 715 716 #endif 717 718 struct ppsymkey /* pun for SYM_KEYWORD lex val */ 719 { 720 struct ppsymbol sym; /* symbol as usual */ 721 int lex; /* lex value for SYM_KEYWORD */ 722 }; 723 724 #if PROTOMAIN && PROTO_STANDALONE 725 726 #if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) 727 #define NiL 0 728 #define NoP(x) (&x,1) 729 #else 730 #define NiL ((char*)0) 731 #define NoP(x) 732 #endif 733 734 #define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x))) 735 736 #define _PP_DELAY_ # 737 738 _PP_DELAY_ ifdef __STDC__ 739 740 _PP_DELAY_ include <stdlib.h> 741 _PP_DELAY_ include <unistd.h> 742 _PP_DELAY_ include <time.h> 743 _PP_DELAY_ include <string.h> 744 745 _PP_DELAY_ else 746 747 _PP_DELAY_ define size_t int 748 749 extern void* realloc(void*, size_t); 750 extern void* calloc(size_t, size_t); 751 extern char* ctime(time_t*); 752 extern void free(void*); 753 754 _PP_DELAY_ ifndef O_RDONLY 755 756 extern int access(const char*, int); 757 extern int close(int); 758 extern int creat(const char*, int); 759 extern void exit(int); 760 extern int link(const char*, const char*); 761 extern int open(const char*, int, ...); 762 extern int read(int, void*, int); 763 extern time_t time(time_t*); 764 extern int unlink(const char*); 765 extern int write(int, const void*, int); 766 767 _PP_DELAY_ endif 768 769 _PP_DELAY_ endif 770 771 #else 772 773 /* 774 * library implementation globals 775 */ 776 777 #define ppassert _pp_assert 778 #define ppbuiltin _pp_builtin 779 #define ppcall _pp_call 780 #define ppcontrol _pp_control 781 #define ppdump _pp_dump 782 #define ppexpand _pp_expand 783 #define ppexpr _pp_expr 784 #define ppfsm _pp_fsm 785 #define ppinmap _pp_inmap 786 #define ppinstr _pp_instr 787 #define ppkeyname _pp_keyname 788 #define pplexmap _pp_lexmap 789 #define pplexstr _pp_lexstr 790 #define ppload _pp_load 791 #define ppmodestr _pp_modestr 792 #define ppmultiple _pp_multiple 793 #define ppnest _pp_nest 794 #define ppoption _pp_option 795 #define ppoptionstr _pp_optionstr 796 #define pppclose _pp_pclose 797 #define pppdrop _pp_pdrop 798 #define pppopen _pp_popen 799 #define pppread _pp_pread 800 #define pppredargs _pp_predargs 801 #define pppush _pp_push 802 #define pprefmac _pp_refmac 803 #define ppsearch _pp_search 804 #define ppset _pp_set 805 #define ppstatestr _pp_statestr 806 #define pptokstr _pp_tokstr 807 #define pptrace _pp_trace 808 809 #endif 810 811 extern void ppassert(int, char*, char*); 812 extern void ppbuiltin(void); 813 extern int ppcall(struct ppsymbol*, int); 814 extern int ppcontrol(void); 815 extern void ppdump(void); 816 extern char* ppexpand(char*); 817 extern long ppexpr(int*); 818 extern void ppfsm(int, char*); 819 extern char* ppinstr(struct ppinstk*); 820 extern char* ppkeyname(int, int); 821 extern char* pplexstr(int); 822 extern void ppload(char*); 823 extern void ppmapinclude(char*, char*); 824 extern char* ppmodestr(long); 825 extern int ppmultiple(struct ppfile*, struct ppsymbol*); 826 extern void ppnest(void); 827 extern int ppoption(char*); 828 extern char* ppoptionstr(long); 829 extern void pppclose(char*); 830 extern int pppdrop(char*); 831 extern char* pppopen(char*, int, char*, char*, char*, char*, int); 832 extern int pppread(char*); 833 extern int pppredargs(void); 834 extern void pppush(int, char*, char*, int); 835 extern struct ppsymbol* pprefmac(char*, int); 836 extern int ppsearch(char*, int, int); 837 extern int ppset(long*, long, int); 838 extern char* ppstatestr(long); 839 extern char* pptokstr(char*, int); 840 extern void pptrace(int); 841 842 #if _std_malloc 843 844 #include <vmalloc.h> 845 846 #undef free 847 #define free(p) vmfree(Vmregion,(void*)p) 848 #undef newof 849 #define newof(p,t,n,x) vmnewof(Vmregion,p,t,n,x) 850 #undef oldof 851 #define oldof(p,t,n,x) vmoldof(Vmregion,p,t,n,x) 852 #undef strdup 853 #define strdup(s) vmstrdup(Vmregion,s) 854 855 #endif 856 857 #endif 858