pplib.h revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Copyright (c) 1986-2007 AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* by AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * preprocessor library private definitions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the first definitions control optional code -- 0 disables
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CHECKPOINT 1 /* checkpoint preprocessed files */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define COMPATIBLE 1 /* enable COMPATIBILITY related code */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MACKEYARGS _BLD_DEBUG /* name=value macro formals and actuals */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the lower tests are transient
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_CLASSIC (1<<0) /* classic to prototyped */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_EXTERNALIZE (1<<2) /* static fun() => extern fun() */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_INCLUDE (1<<5) /* <prototyped.h> instead */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_INITIALIZED (1<<6) /* internal initialization */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_LINESYNC (1<<7) /* force standalone line syncs */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_NOPRAGMA (1<<8) /* delete pragma prototyped */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_PLUSPLUS (1<<10) /* extern () -> extern (...) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_RETAIN (1<<11) /* defines retained after close */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SEARCH_HOSTED (1<<0) /* search hosted dirs only */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SEARCH_INCLUDE (1<<2) /* ppsearch for include */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SEARCH_VENDOR (1<<3) /* search vendor dirs only */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_defguard (1<<1) /* did multiple include check */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_endguard (1<<3) /* did multiple include check */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_flush (1<<6) /* flush stdout on file_refill()*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_ignoreline (1<<8) /* ignore #line until file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_newline (1<<9) /* newline at end of last fill */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_noguard (1<<10) /* no multiple include guard */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_static (1<<13) /* static buffer - don't free */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_tokens (1L<<15)/* non-space tokens encountered */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef char* (*PPBUILTIN)(char*, const char*, const char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef void (*PPCOMMENT)(const char*, const char*, const char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef void (*PPINCREF)(const char*, const char*, int, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef void (*PPLINESYNC)(int, const char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef void (*PPMACREF)(struct ppsymbol*, const char*, int, int, unsigned long);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef int (*PPOPTARG)(int, int, const char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef void (*PPPRAGMA)(const char*, const char*, const char*, const char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppinstk* next; /* next frame (for allocation) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppmacstk* next; /* next frame (for allocation) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SAMEID(a,b) ((a)->st_ino==(unsigned long)(b)->st_ino&&(a)->st_dev==(unsigned long)(b)->st_dev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SAVEID(a,b) ((a)->st_ino=(unsigned long)(b)->st_ino,(a)->st_dev=(unsigned long)(b)->st_dev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_CONTEXT_PRIVATE_ /* ppglobals private context */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppindex* firstindex; /* first include index entry */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppindex* lastindex; /* last include index entry */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char c; /* arg C state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char ignoresrc; /* arg ignore source state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char initialized; /* arg initialized state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_GLOBALS_PRIVATE_ /* ppglobals private additions */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* the rest are implicitly initialized */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* include; /* saved path of last #include */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppmember* member; /* include archive member data */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppmacstk* macp; /* top of macro actual stack */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppdirs* found; /* last successful ppsearch dir */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_SYMBOL_PRIVATE_ /* ppsymbol private additions */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_MACRO_PRIVATE_ /* ppmacro private additions */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define formkeys args.key /* formal keyword argument list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_MACRO_PRIVATE_ /* ppmacro private additions */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_DIRS_PRIVATE_ /* ppdirs private additions */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char c; /* files here are C language */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char index; /* prefix,local,standard index */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * DEBUG is encoded with the following bits
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PANIC (ERROR_PANIC|ERROR_SOURCE|ERROR_SYSTEM),__FILE__,__LINE__
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define message(x) do { if (tracing) error x; } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * note that MEMCPY advances the associated pointers
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do switch(n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { default : memcpy(to,fr,n); to += n; fr += n; break; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0 : break; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define nextframe(m,p) (m->next=m+(p-(char*)m+sizeof(struct ppmacstk)-1)/sizeof(struct ppmacstk)+1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pushcontrol() do { if (pp.control++ >= pp.maxcon) ppnest(); } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define setmode(m,v) ((v)?(pp.mode|=(m)):(pp.mode&=~(m)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define setoption(m,v) ((v)?(pp.option|=(m)):(pp.option&=~(m)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define setstate(s,v) ((v)?(pp.state|=(s)):(pp.state&=~(s)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppgetfile(x) ((struct ppfile*)hashlook(pp.filtab,x,HASH_LOOKUP,NiL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppsetfile(x) ((struct ppfile*)hashlook(pp.filtab,x,HASH_CREATE|HASH_SIZE(sizeof(struct ppfile)),NiL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppkeyget(t,n) (struct ppsymkey*)hashlook(t,n,HASH_LOOKUP,NiL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppkeyref(t,n) (struct ppsymkey*)hashlook(t,n,HASH_LOOKUP|HASH_INTERNAL,NiL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppkeyset(t,n) (struct ppsymkey*)hashlook(t,n,HASH_CREATE|HASH_SIZE(sizeof(struct ppsymkey)),NiL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define STRAPP(p,v,r) do{r=(v);while((*p++)=(*r++));}while(0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define STRCOPY(p,v,r) do{r=(v);while((*p++)=(*r++));p--;}while(0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define STRCOPY2(p,r) do{while((*p++)=(*r++));p--;}while(0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SETFILE(p,v) (p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'F',(long)v,MARK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SETLINE(p,v) (p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'L',(long)v,MARK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAXFORMALS 64 /* maximum number macro formals */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DEFMACSTACK (MAXFORMALS*32*32)/* default macstack size */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_INIT (6|IN_TOP) /* initialization IN_BUFFER */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_MULTILINE (8|IN_TOP) /* multi-line macro text */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_RESCAN (10|IN_TOP) /* directive rescan buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TOK_FORMAL (1<<1) /* last token was arg formal id */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SETIFBLOCK(p) (*(p)=(*((p)-1)&SKIP)|((long)error_info.line<<BLOCKBITS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define GETIFLINE(p) ((*(p)>>BLOCKBITS)&((1L<<(sizeof(long)*CHAR_BIT-BLOCKBITS))-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH(t,p) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_BUFFER(f,p,n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_COPY(p,n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_EXPAND(p,n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_FILE(f,d) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_INIT(f,p) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_TUPLE(p,v) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strlen(error_info.file) + strlen(((struct ppsymbol*)p)->name) + 24; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.file = cur->buffer = newof(0, char, n, 0); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(error_info.file, n, "%s:%s,%d", cur->file, p->name, error_info.line); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_QUOTE(p,n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_SQUOTE(p,n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NiL ((char*)0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void free(void*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int access(const char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int close(int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int creat(const char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void exit(int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int link(const char*, const char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int open(const char*, int, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int read(int, void*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int unlink(const char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int write(int, const void*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * library implementation globals
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void ppassert(int, char*, char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void ppbuiltin(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int ppcontrol(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void ppdump(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* ppexpand(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern long ppexpr(int*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void ppfsm(int, char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* ppkeyname(int, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* pplexstr(int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void ppload(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void ppmapinclude(char*, char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* ppmodestr(long);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int ppmultiple(struct ppfile*, struct ppsymbol*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void ppnest(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int ppoption(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* ppoptionstr(long);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void pppclose(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int pppdrop(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* pppopen(char*, int, char*, char*, char*, char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int pppread(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int pppredargs(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void pppush(int, char*, char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int ppsearch(char*, int, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* ppstatestr(long);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* pptokstr(char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void pptrace(int);