Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libpp/pplib.h
1808 views
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 <[email protected]> *
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
do switch(n) \
430
{ default : memcpy(to,fr,n); to += n; fr += n; break; \
431
case 7 : *to++ = *fr++; \
432
case 6 : *to++ = *fr++; \
433
case 5 : *to++ = *fr++; \
434
case 4 : *to++ = *fr++; \
435
case 3 : *to++ = *fr++; \
436
case 2 : *to++ = *fr++; \
437
case 1 : *to++ = *fr++; \
438
case 0 : break; \
439
} while (0)
440
441
#define NEWDIRECTIVE (-1)
442
443
#undef dirname
444
#undef error
445
446
#define dirname(x) ppkeyname(x,1)
447
#define error pperror
448
#define keyname(x) ppkeyname(x,0)
449
#define nextframe(m,p) (m->next=m+(p-(char*)m+sizeof(struct ppmacstk)-1)/sizeof(struct ppmacstk)+1)
450
#define popframe(m) (m=m->prev)
451
#define pptokchr(c) pptokstr(NiL,(c))
452
#define pushcontrol() do { if (pp.control++ >= pp.maxcon) ppnest(); } while (0)
453
#define pushframe(m) (m->next->prev=m,m=m->next)
454
#define setmode(m,v) ppset(&pp.mode,m,v)
455
#define setoption(m,v) ppset(&pp.option,m,v)
456
#define setstate(m,v) ppset(&pp.state,m,v)
457
#define tracing (error_info.trace<0)
458
459
#define ppgetfile(x) ((struct ppfile*)hashlook(pp.filtab,x,HASH_LOOKUP,NiL))
460
#define ppsetfile(x) ((struct ppfile*)hashlook(pp.filtab,x,HASH_CREATE|HASH_SIZE(sizeof(struct ppfile)),NiL))
461
462
#define ppkeyget(t,n) (struct ppsymkey*)hashlook(t,n,HASH_LOOKUP,NiL)
463
#define ppkeyref(t,n) (struct ppsymkey*)hashlook(t,n,HASH_LOOKUP|HASH_INTERNAL,NiL)
464
#define ppkeyset(t,n) (struct ppsymkey*)hashlook(t,n,HASH_CREATE|HASH_SIZE(sizeof(struct ppsymkey)),NiL)
465
466
#define MARK '@' /* internal mark */
467
#define ARGOFFSET '1' /* macro arg mark offset */
468
469
#define STRAPP(p,v,r) do{r=(v);while((*p++)=(*r++));}while(0)
470
#define STRCOPY(p,v,r) do{r=(v);while((*p++)=(*r++));p--;}while(0)
471
#define STRCOPY2(p,r) do{while((*p++)=(*r++));p--;}while(0)
472
473
#define SETFILE(p,v) (p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'F',(long)v,MARK))
474
#define SETLINE(p,v) (p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'L',(long)v,MARK))
475
476
#define peekchr() (*pp.in->nextchr)
477
#define ungetchr(c) (*--pp.in->nextchr=(c))
478
479
#define MAXID 255 /* maximum identifier size */
480
#define MAXTOKEN PPTOKSIZ /* maximum token size */
481
#define MAXFORMALS 64 /* maximum number macro formals */
482
#define MAXHIDDEN 8 /* ppline if hidden>=MAXHIDDEN */
483
#define DEFMACSTACK (MAXFORMALS*32*32)/* default macstack size */
484
485
#define FSM_COMPATIBILITY 1 /* compatibility mode */
486
#define FSM_IDADD 2 /* add to identifer set */
487
#define FSM_IDDEL 3 /* delete from identifer set */
488
#define FSM_INIT 4 /* initilize */
489
#define FSM_MACRO 5 /* add new macro */
490
#define FSM_OPSPACE 6 /* handle <binop><space>= */
491
#define FSM_PLUSPLUS 7 /* C++ lexical analysis */
492
#define FSM_QUOTADD 8 /* add to quote set */
493
#define FSM_QUOTDEL 9 /* delete from quote set */
494
495
#define IN_TOP 01 /* top level -- directives ok */
496
497
#define IN_BUFFER (2|IN_TOP) /* buffer of lines */
498
#define IN_COPY 2 /* macro arg (copied) */
499
#define IN_EXPAND 4 /* macro arg (expanded) */
500
#define IN_FILE (4|IN_TOP) /* file */
501
#define IN_INIT (6|IN_TOP) /* initialization IN_BUFFER */
502
#define IN_MACRO 8 /* macro text */
503
#define IN_MULTILINE (8|IN_TOP) /* multi-line macro text */
504
#define IN_QUOTE 10 /* "..." macro arg (copied) */
505
#define IN_RESCAN (10|IN_TOP) /* directive rescan buffer */
506
#define IN_SQUOTE 12 /* '...' macro arg (copied) */
507
#define IN_STRING 14 /* string */
508
509
#define INC_CLEAR ((struct ppsymbol*)0)
510
#define INC_IGNORE ((struct ppsymbol*)pp.addbuf)
511
#define INC_TEST ((struct ppsymbol*)pp.catbuf)
512
513
#define INC_BOUND(n) (1<<(n))
514
#define INC_MEMBER(n) (1<<((n)+INC_MAX))
515
#define INC_PREFIX 0
516
#define INC_LOCAL 1
517
#define INC_STANDARD 2
518
#define INC_VENDOR 3
519
#define INC_MAX 4
520
#define INC_SELF (1<<(2*INC_MAX+0))
521
#define INC_EXISTS (1<<(2*INC_MAX+1))
522
#define INC_LISTED (1<<(2*INC_MAX+2))
523
#define INC_MAPALL (1<<(2*INC_MAX+3))
524
#define INC_MAPHOSTED (1<<(2*INC_MAX+4))
525
#define INC_MAPNOHOSTED (1<<(2*INC_MAX+5))
526
#define INC_MAPNOLOCAL (1<<(2*INC_MAX+6))
527
#define INC_HOSTED (1<<(2*INC_MAX+7))
528
529
#define TYPE_ARCHIVE (1<<0)
530
#define TYPE_BUFFER (1<<1)
531
#define TYPE_CHECKPOINT (1<<2)
532
#define TYPE_DIRECTORY (1<<3)
533
#define TYPE_HOSTED (1<<4)
534
#define TYPE_INCLUDE (1<<5)
535
#define TYPE_VENDOR (1<<6)
536
537
#define TOK_BUILTIN (1<<0) /* last token was #( */
538
#define TOK_FORMAL (1<<1) /* last token was arg formal id */
539
#define TOK_ID (1<<2) /* last token was identifier */
540
#define TOK_TOKCAT (1<<3) /* last token was ## */
541
542
#define HADELSE (1<<0) /* already had else part */
543
#define KEPT (1<<1) /* already kept part of block */
544
#define SKIP (1<<2) /* skip this block */
545
#define BLOCKBITS 3 /* block flag bits */
546
547
#define SETIFBLOCK(p) (*(p)=(*((p)-1)&SKIP)|((long)error_info.line<<BLOCKBITS))
548
#define GETIFLINE(p) ((*(p)>>BLOCKBITS)&((1L<<(sizeof(long)*CHAR_BIT-BLOCKBITS))-1))
549
550
#define PUSH(t,p) \
551
do \
552
{ \
553
count(push); \
554
if (!pp.in->next) \
555
{ \
556
pp.in->next = newof(0, struct ppinstk, 1, 0); \
557
pp.in->next->prev = pp.in; \
558
} \
559
p = pp.in = pp.in->next; \
560
p->type = t; \
561
p->flags = 0; \
562
} while (0)
563
564
#define PUSH_BUFFER(f,p,n) \
565
pppush(IN_BUFFER,f,p,n)
566
567
#define PUSH_COPY(p,n) \
568
do \
569
{ \
570
register struct ppinstk* cur; \
571
PUSH(IN_COPY, cur); \
572
cur->line = error_info.line; \
573
error_info.line = n; \
574
cur->nextchr = p; \
575
cur->prev->symbol->flags &= ~SYM_DISABLED; \
576
debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
577
} while (0)
578
579
#define PUSH_EXPAND(p,n) \
580
do \
581
{ \
582
register struct ppinstk* cur; \
583
PUSH(IN_EXPAND, cur); \
584
cur->line = error_info.line; \
585
error_info.line = n; \
586
cur->prev->symbol->flags &= ~SYM_DISABLED; \
587
cur->buffer = cur->nextchr = ppexpand(p); \
588
if (!(cur->prev->symbol->flags & SYM_MULTILINE)) \
589
cur->prev->symbol->flags |= SYM_DISABLED; \
590
debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
591
} while (0)
592
593
#define PUSH_FILE(f,d) \
594
pppush(IN_FILE,f,NiL,d)
595
596
#define PUSH_INIT(f,p) \
597
pppush(IN_INIT,f,p,1)
598
599
#define PUSH_MACRO(p) \
600
do \
601
{ \
602
register struct ppinstk* cur; \
603
PUSH(IN_MACRO, cur); \
604
cur->symbol = p; \
605
cur->nextchr = p->macro->value; \
606
p->flags |= SYM_DISABLED; \
607
if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \
608
pp.state &= ~NEWLINE; \
609
debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
610
} while (0)
611
612
#define PUSH_TUPLE(p,v) \
613
do \
614
{ \
615
register struct ppinstk* cur; \
616
PUSH(IN_MACRO, cur); \
617
cur->symbol = p; \
618
cur->nextchr = v; \
619
p->flags |= SYM_DISABLED; \
620
pp.state &= ~NEWLINE; \
621
debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
622
} while (0)
623
624
#define PUSH_MULTILINE(p) \
625
do \
626
{ \
627
register struct ppinstk* cur; \
628
register int n; \
629
PUSH(IN_MULTILINE, cur); \
630
cur->symbol = p; \
631
cur->flags |= IN_defguard|IN_endguard|IN_noguard; \
632
pushcontrol(); \
633
cur->control = pp.control; \
634
*pp.control = 0; \
635
cur->file = error_info.file; \
636
n = strlen(error_info.file) + strlen(((struct ppsymbol*)p)->name) + 24; \
637
error_info.file = cur->buffer = newof(0, char, n, 0); \
638
sfsprintf(error_info.file, n, "%s:%s,%d", cur->file, p->name, error_info.line); \
639
cur->line = error_info.line; \
640
error_info.line = 1; \
641
cur->nextchr = p->macro->value; \
642
if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \
643
pp.state &= ~NEWLINE; \
644
debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
645
} while (0)
646
647
#define PUSH_QUOTE(p,n) \
648
do \
649
{ \
650
register struct ppinstk* cur; \
651
PUSH(IN_QUOTE, cur); \
652
cur->nextchr = p; \
653
pp.state |= QUOTE; \
654
cur->line = error_info.line; \
655
error_info.line = n; \
656
debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
657
} while (0)
658
659
#define PUSH_RESCAN(p) \
660
pppush(IN_RESCAN,NiL,p,0)
661
662
#define PUSH_SQUOTE(p,n) \
663
do \
664
{ \
665
register struct ppinstk* cur; \
666
PUSH(IN_SQUOTE, cur); \
667
cur->nextchr = p; \
668
pp.state |= SQUOTE; \
669
cur->line = error_info.line; \
670
error_info.line = n; \
671
debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
672
} while (0)
673
674
#define PUSH_STRING(p) \
675
do \
676
{ \
677
register struct ppinstk* cur; \
678
PUSH(IN_STRING, cur); \
679
cur->nextchr = p; \
680
if (pp.state & DISABLE) cur->flags |= IN_disable; \
681
debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
682
} while (0)
683
684
#define PUSH_LINE(p) \
685
do \
686
{ \
687
register struct ppinstk* cur; \
688
PUSH(IN_STRING, cur); \
689
cur->nextchr = p; \
690
pp.state |= DISABLE|NOSPACE|PASSEOF|STRIP; \
691
debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
692
} while (0)
693
694
#define POP_LINE() \
695
do \
696
{ \
697
debug((-7, "POP in=%s", ppinstr(pp.in))); \
698
pp.in = pp.in->prev; \
699
pp.state &= ~(DISABLE|NOSPACE|PASSEOF|STRIP); \
700
} while (0)
701
702
struct ppcontext /* pp context */
703
{
704
_PP_CONTEXT_PUBLIC_
705
_PP_CONTEXT_PRIVATE_
706
};
707
708
struct ppfile /* include file info */
709
{
710
HASH_HEADER; /* this is a hash bucket too */
711
struct ppsymbol* guard; /* guard symbol */
712
struct ppfile* bound[INC_MAX]; /* include bindings */
713
int flags; /* INC_* flags */
714
};
715
716
#if CHECKPOINT
717
718
struct ppindex /* checkpoint include index */
719
{
720
struct ppindex* next; /* next in list */
721
struct ppfile* file; /* include file */
722
unsigned long begin; /* beginning output offset */
723
unsigned long end; /* ending output offset */
724
};
725
726
#endif
727
728
struct ppsymkey /* pun for SYM_KEYWORD lex val */
729
{
730
struct ppsymbol sym; /* symbol as usual */
731
int lex; /* lex value for SYM_KEYWORD */
732
};
733
734
#if PROTOMAIN && PROTO_STANDALONE
735
736
#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
737
#define NiL 0
738
#define NoP(x) (&x,1)
739
#else
740
#define NiL ((char*)0)
741
#define NoP(x)
742
#endif
743
744
#define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
745
746
#define _PP_DELAY_ #
747
748
_PP_DELAY_ ifdef __STDC__
749
750
_PP_DELAY_ include <stdlib.h>
751
_PP_DELAY_ include <unistd.h>
752
_PP_DELAY_ include <time.h>
753
_PP_DELAY_ include <string.h>
754
755
_PP_DELAY_ else
756
757
_PP_DELAY_ define size_t int
758
759
extern void* realloc(void*, size_t);
760
extern void* calloc(size_t, size_t);
761
extern char* ctime(time_t*);
762
extern void free(void*);
763
764
_PP_DELAY_ ifndef O_RDONLY
765
766
extern int access(const char*, int);
767
extern int close(int);
768
extern int creat(const char*, int);
769
extern void exit(int);
770
extern int link(const char*, const char*);
771
extern int open(const char*, int, ...);
772
extern int read(int, void*, int);
773
extern time_t time(time_t*);
774
extern int unlink(const char*);
775
extern int write(int, const void*, int);
776
777
_PP_DELAY_ endif
778
779
_PP_DELAY_ endif
780
781
#else
782
783
/*
784
* library implementation globals
785
*/
786
787
#define ppassert _pp_assert
788
#define ppbuiltin _pp_builtin
789
#define ppcall _pp_call
790
#define ppcontrol _pp_control
791
#define ppdump _pp_dump
792
#define ppexpand _pp_expand
793
#define ppexpr _pp_expr
794
#define ppfsm _pp_fsm
795
#define ppinmap _pp_inmap
796
#define ppinstr _pp_instr
797
#define ppkeyname _pp_keyname
798
#define pplexmap _pp_lexmap
799
#define pplexstr _pp_lexstr
800
#define ppload _pp_load
801
#define ppmodestr _pp_modestr
802
#define ppmultiple _pp_multiple
803
#define ppnest _pp_nest
804
#define ppoption _pp_option
805
#define ppoptionstr _pp_optionstr
806
#define pppclose _pp_pclose
807
#define pppdrop _pp_pdrop
808
#define pppopen _pp_popen
809
#define pppread _pp_pread
810
#define pppredargs _pp_predargs
811
#define pppush _pp_push
812
#define pprefmac _pp_refmac
813
#define ppsearch _pp_search
814
#define ppset _pp_set
815
#define ppstatestr _pp_statestr
816
#define pptokstr _pp_tokstr
817
#define pptrace _pp_trace
818
819
#endif
820
821
extern void ppassert(int, char*, char*);
822
extern void ppbuiltin(void);
823
extern int ppcall(struct ppsymbol*, int);
824
extern int ppcontrol(void);
825
extern void ppdump(void);
826
extern char* ppexpand(char*);
827
extern long ppexpr(int*);
828
extern void ppfsm(int, char*);
829
extern char* ppinstr(struct ppinstk*);
830
extern char* ppkeyname(int, int);
831
extern char* pplexstr(int);
832
extern void ppload(char*);
833
extern void ppmapinclude(char*, char*);
834
extern char* ppmodestr(long);
835
extern int ppmultiple(struct ppfile*, struct ppsymbol*);
836
extern void ppnest(void);
837
extern int ppoption(char*);
838
extern char* ppoptionstr(long);
839
extern void pppclose(char*);
840
extern int pppdrop(char*);
841
extern char* pppopen(char*, int, char*, char*, char*, char*, int);
842
extern int pppread(char*);
843
extern int pppredargs(void);
844
extern void pppush(int, char*, char*, int);
845
extern struct ppsymbol* pprefmac(char*, int);
846
extern int ppsearch(char*, int, int);
847
extern int ppset(long*, long, int);
848
extern char* ppstatestr(long);
849
extern char* pptokstr(char*, int);
850
extern void pptrace(int);
851
852
#if _std_malloc
853
854
#include <vmalloc.h>
855
856
#undef free
857
#define free(p) vmfree(Vmregion,(void*)p)
858
#undef newof
859
#define newof(p,t,n,x) vmnewof(Vmregion,p,t,n,x)
860
#undef oldof
861
#define oldof(p,t,n,x) vmoldof(Vmregion,p,t,n,x)
862
#undef strdup
863
#define strdup(s) vmstrdup(Vmregion,s)
864
865
#endif
866
867
#endif
868
869