1 /***********************************************************************
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 *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
19 ***********************************************************************/
25 * preprocessor library private definitions
32 * the first definitions control optional code -- 0 disables
36 #define ARCHIVE 1 /* -I can specify header archives */
39 #define CATSTRINGS 1 /* concatenate adjacent strings */
42 #define CHECKPOINT 1 /* checkpoint preprocessed files */
45 #define COMPATIBLE 1 /* enable COMPATIBILITY related code */
48 #define MACKEYARGS _BLD_DEBUG /* name=value macro formals and actuals */
51 #define POOL 1 /* enable loop on input,output,error */
54 #define PROTOTYPE 1 /* enable ppproto code */
57 #define TRUNCLENGTH 8 /* default TRUNCATE length */
61 #define DEBUG (TRACE_message|TRACE_count|TRACE_debug)
64 #define DEBUG (TRACE_message)
69 * the lower tests are transient
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)
80 #define TEST_INVERT (1L<<31)
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 */
96 #define PROTO_USER (1<<13) /* first user flag */
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 */
105 #define STYLE_gnu (1<<0) /* gnu style args */
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 */
124 #define OPT_GLOBAL (1<<0) /* pp: pass optional */
125 #define OPT_PASS (1<<1) /* pass on */
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);
138 struct ppinstk
/* input stream stack frame */
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 */
149 struct ppindex
* index
; /* checkpoint include index */
150 int buflen
; /* buffer count */
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 */
161 struct ppkeyarg
/* pp macro keyword arg info */
163 char* name
; /* keyword arg name */
164 char* value
; /* keyword arg value */
168 struct pplist
/* string list */
170 char* value
; /* string value */
171 struct pplist
* next
; /* next in list */
174 struct oplist
/* queue op until PP_INIT */
176 int op
; /* PP_* op */
177 char* value
; /* op value */
178 struct oplist
* next
; /* next op */
181 struct pphide
/* hidden symbol info */
183 struct ppmacro
* macro
; /* saved macro info */
184 unsigned long flags
; /* saved symbol flags if macro */
185 int level
; /* nesting level */
188 struct ppmacstk
/* macro invocation stack frame */
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 */
196 struct ppmember
/* archive member pun on ppfile */
198 struct ppdirs
* archive
; /* archive holding file */
199 unsigned long offset
; /* data offset */
200 unsigned long size
; /* data size */
203 struct counter
/* monitoring counters */
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 */
214 struct pptuple
/* tuple macro */
216 struct pptuple
* nomatch
; /* nomatch tuple */
217 struct pptuple
* match
; /* match tuple */
218 char token
[1]; /* matching token */
221 struct ppfileid
/* physical file id */
223 unsigned long st_dev
; /* dev */
224 unsigned long st_ino
; /* ino */
227 struct pathid
/* physical file name and id */
229 char* path
; /* file path */
230 struct ppfileid id
; /* file id */
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)
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 */ \
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 */
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 */ \
307 int input; /* pool input */ \
308 int output; /* pool output */ \
309 } pool; /* loop on input,output,error */ \
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__ */
343 #define _PP_SYMBOL_PRIVATE_ /* ppsymbol private additions */ \
344 struct pphide* hidden; /* hidden symbol info */
347 #define _PP_MACRO_PRIVATE_ /* ppmacro private additions */ \
348 struct pptuple* tuple; /* tuple macro */ \
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 */
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 */
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 */ \
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 */ \
382 #define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
388 #undef setstate /* random clash! */
391 * DEBUG is encoded with the following bits
394 #define TRACE_message 01
395 #define TRACE_count 02
396 #define TRACE_debug 04
399 #define PANIC (ERROR_PANIC|ERROR_SOURCE|ERROR_SYSTEM),__FILE__,__LINE__
401 #define PANIC ERROR_PANIC
404 #if DEBUG & TRACE_count
405 #define count(x) pp.counter.x++
410 #if DEBUG & TRACE_message
411 #define message(x) do { if (tracing) error x; } while (0)
416 #if DEBUG & TRACE_debug
417 #define debug(x) do { if (tracing) error x; } while (0)
423 * note that MEMCPY advances the associated pointers
426 #define MEMCPY(to,fr,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++; \
439 #define NEWDIRECTIVE (-1)
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)
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))
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)
464 #define MARK '@' /* internal mark */
465 #define ARGOFFSET '1' /* macro arg mark offset */
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)
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))
474 #define peekchr() (*pp.in->nextchr)
475 #define ungetchr(c) (*--pp.in->nextchr=(c))
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 */
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 */
493 #define IN_TOP 01 /* top level -- directives ok */
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 */
507 #define INC_CLEAR ((struct ppsymbol *)NULL)
508 #define INC_IGNORE ((struct ppsymbol*)pp.addbuf)
509 #define INC_TEST ((struct ppsymbol*)pp.catbuf)
511 #define INC_BOUND(n) (1<<(n))
512 #define INC_MEMBER(n) (1<<((n)+INC_MAX))
515 #define INC_STANDARD 2
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))
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)
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 ## */
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 */
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))
554 pp.in->next = newof(0, struct ppinstk, 1, 0); \
555 pp.in->next->prev = pp.in; \
557 p = pp.in = pp.in->next; \
562 #define PUSH_BUFFER(f,p,n) \
563 pppush(IN_BUFFER,f,p,n)
565 #define PUSH_COPY(p,n) \
568 register struct ppinstk* cur; \
569 PUSH(IN_COPY, cur); \
570 cur->line = error_info.line; \
571 error_info.line = n; \
573 cur->prev->symbol->flags &= ~SYM_DISABLED; \
574 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
577 #define PUSH_EXPAND(p,n) \
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))); \
591 #define PUSH_FILE(f,d) \
592 pppush(IN_FILE,f,NiL,d)
594 #define PUSH_INIT(f,p) \
595 pppush(IN_INIT,f,p,1)
597 #define PUSH_MACRO(p) \
600 register struct ppinstk* cur; \
601 PUSH(IN_MACRO, cur); \
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))); \
610 #define PUSH_TUPLE(p,v) \
613 register struct ppinstk* cur; \
614 PUSH(IN_MACRO, cur); \
617 p->flags |= SYM_DISABLED; \
618 pp.state &= ~NEWLINE; \
619 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
622 #define PUSH_MULTILINE(p) \
625 register struct ppinstk* cur; \
627 PUSH(IN_MULTILINE, cur); \
629 cur->flags |= IN_defguard|IN_endguard|IN_noguard; \
631 cur->control = pp.control; \
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))); \
645 #define PUSH_QUOTE(p,n) \
648 register struct ppinstk* cur; \
649 PUSH(IN_QUOTE, cur); \
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))); \
657 #define PUSH_RESCAN(p) \
658 pppush(IN_RESCAN,NiL,p,0)
660 #define PUSH_SQUOTE(p,n) \
663 register struct ppinstk* cur; \
664 PUSH(IN_SQUOTE, cur); \
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))); \
672 #define PUSH_STRING(p) \
675 register struct ppinstk* cur; \
676 PUSH(IN_STRING, cur); \
678 if (pp.state & DISABLE) cur->flags |= IN_disable; \
679 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
682 #define PUSH_LINE(p) \
685 register struct ppinstk* cur; \
686 PUSH(IN_STRING, cur); \
688 pp.state |= DISABLE|NOSPACE|PASSEOF|STRIP; \
689 debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
695 debug((-7, "POP in=%s", ppinstr(pp.in))); \
696 pp.in = pp.in->prev; \
697 pp.state &= ~(DISABLE|NOSPACE|PASSEOF|STRIP); \
700 struct ppcontext
/* pp context */
706 struct ppfile
/* include file info */
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 */
716 struct ppindex
/* checkpoint include index */
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 */
726 struct ppsymkey
/* pun for SYM_KEYWORD lex val */
728 struct ppsymbol sym
; /* symbol as usual */
729 int lex
; /* lex value for SYM_KEYWORD */
732 #if PROTOMAIN && PROTO_STANDALONE
734 #if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
736 #define NoP(x) (&x,1)
738 #define NiL ((char*)0)
742 #define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
746 _PP_DELAY_ ifdef __STDC__
748 _PP_DELAY_ include
<stdlib
.h
>
749 _PP_DELAY_ include
<unistd
.h
>
750 _PP_DELAY_ include
<time
.h
>
751 _PP_DELAY_ include
<string
.h
>
755 _PP_DELAY_ define
size_t int
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*);
762 _PP_DELAY_ ifndef O_RDONLY
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);
782 * library implementation globals
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
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);
853 #define free(p) vmfree(Vmregion,(void*)p)
855 #define newof(p,t,n,x) vmnewof(Vmregion,p,t,n,x)
857 #define oldof(p,t,n,x) vmoldof(Vmregion,p,t,n,x)
859 #define strdup(s) vmstrdup(Vmregion,s)