da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Copyright (c) 1986-2009 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * preprocessor library private definitions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef _PPLIB_H
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PPLIB_H
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the first definitions control optional code -- 0 disables
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef ARCHIVE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ARCHIVE 1 /* -I can specify header archives */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef CATSTRINGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CATSTRINGS 1 /* concatenate adjacent strings */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef CHECKPOINT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CHECKPOINT 1 /* checkpoint preprocessed files */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef COMPATIBLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define COMPATIBLE 1 /* enable COMPATIBILITY related code */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MACKEYARGS _BLD_DEBUG /* name=value macro formals and actuals */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef POOL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define POOL 1 /* enable loop on input,output,error */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef PROTOTYPE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTOTYPE 1 /* enable ppproto code */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TRUNCLENGTH 8 /* default TRUNCATE length */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _BLD_DEBUG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef DEBUG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DEBUG (TRACE_message|TRACE_count|TRACE_debug)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef DEBUG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DEBUG (TRACE_message)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the lower tests are transient
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TEST_count (1L<<24)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TEST_hashcount (1L<<25)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TEST_hashdump (1L<<26)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TEST_hit (1L<<27)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TEST_noinit (1L<<28)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TEST_nonoise (1L<<29)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TEST_noproto (1L<<30)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TEST_INVERT (1L<<31)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_CLASSIC (1<<0) /* classic to prototyped */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_DISABLE (1<<1) /* disable conversion */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_EXTERNALIZE (1<<2) /* static fun() => extern fun() */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_FORCE (1<<3) /* force even if no magic */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_HEADER (1<<4) /* header defines too */
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_PASS (1<<9) /* pass blocks if no magic */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_PLUSPLUS (1<<10) /* extern () -> extern (...) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_RETAIN (1<<11) /* defines retained after close */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_TEST (1<<12) /* enable test code */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PROTO_USER (1<<13) /* first user flag */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SEARCH_EXISTS 0 /* ppsearch for existence */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SEARCH_HOSTED (1<<0) /* search hosted dirs only */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SEARCH_IGNORE (1<<1) /* ignore if not found */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SEARCH_INCLUDE (1<<2) /* ppsearch for include */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SEARCH_VENDOR (1<<3) /* search vendor dirs only */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SEARCH_USER (1<<4) /* first user flag */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define STYLE_gnu (1<<0) /* gnu style args */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_c (1<<0) /* C language file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_defguard (1<<1) /* did multiple include check */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_disable (1<<2) /* saved state&DISABLE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_endguard (1<<3) /* did multiple include check */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_eof (1<<4) /* reached EOF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_expand (1<<5) /* ppexpand buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_flush (1<<6) /* flush stdout on file_refill()*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_hosted (1<<7) /* saved mode&HOSTED */
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_prototype (1<<11) /* ppproto() input */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_regular (1<<12) /* regular input file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_static (1<<13) /* static buffer - don't free */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_sync (1<<14) /* line sync required on pop */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_tokens (1L<<15)/* non-space tokens encountered */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define OPT_GLOBAL (1<<0) /* pp: pass optional */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define OPT_PASS (1<<1) /* pass on */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct ppsymbol;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct ppindex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
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
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct ppinstk /* input stream stack frame */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* nextchr; /* next input char (first elt) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppinstk* next; /* next frame (for allocation) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppinstk* prev; /* previous frame */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long* control; /* control block level */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* buffer; /* buffer base pointer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* file; /* saved file name */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* prefix; /* directory prefix */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppsymbol* symbol; /* macro info */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if CHECKPOINT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppindex* index; /* checkpoint include index */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int buflen; /* buffer count */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int line; /* saved line number */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int vendor; /* saved pp.vendor */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short fd; /* file descriptor */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short hide; /* hide index (from pp.hide) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short flags; /* IN_[a-z]* flags */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char type; /* input type */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct ppkeyarg /* pp macro keyword arg info */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* name; /* keyword arg name */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* value; /* keyword arg value */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct pplist /* string list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* value; /* string value */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pplist* next; /* next in list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct oplist /* queue op until PP_INIT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int op; /* PP_* op */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* value; /* op value */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct oplist* next; /* next op */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct pphide /* hidden symbol info */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppmacro* macro; /* saved macro info */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long flags; /* saved symbol flags if macro */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int level; /* nesting level */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct ppmacstk /* macro invocation stack frame */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppmacstk* next; /* next frame (for allocation) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppmacstk* prev; /* previous frame */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int line; /* line number of first arg */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* arg[1]; /* arg text pointers */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct ppmember /* archive member pun on ppfile */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppdirs* archive; /* archive holding file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long offset; /* data offset */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long size; /* data size */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct counter /* monitoring counters */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int candidate; /* macro candidates */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int function; /* function macros */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int macro; /* macro hits */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int pplex; /* pplex() calls */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int push; /* input stream pushes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int terminal; /* terminal states */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int token; /* emitted tokens */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct pptuple /* tuple macro */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pptuple* nomatch; /* nomatch tuple */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pptuple* match; /* match tuple */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char token[1]; /* matching token */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct ppfileid /* physical file id */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long st_dev; /* dev */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long st_ino; /* ino */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct pathid /* physical file name and id */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* path; /* file path */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppfileid id; /* file id */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
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
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_CONTEXT_PRIVATE_ /* ppglobals private context */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppcontext* context; /* current context */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long state; /* pp state flags */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long mode; /* uncoupled pp state flags */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long option; /* option flags */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long test; /* implementation tests */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* sp; /* FILEDEPS output stream */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long flags; /* PP_FILEDEPS flags */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } filedeps; /* FILEDEPS info */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppdirs* firstdir; /* first include dir */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppdirs* lastdir; /* last include dir */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int hide; /* current include hide index */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int column; /* FILEDEPS column */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int pending; /* ppline() pending output */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* firstfile; /* ppline() first file */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* lastfile; /* ppline() most recent file */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* ignore; /* include ignore list file */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* probe; /* ppdefault probe key */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Hash_table_t* filtab; /* file name hash table */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Hash_table_t* prdtab; /* predicate hash table */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* date; /* start date string */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* time; /* start time string */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* maps; /* directive maps */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long ro_state; /* readonly state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long ro_mode; /* readonly mode */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long ro_option; /* readonly option */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pathid cdir; /* arg C dir */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pathid hostdir; /* arg host dir */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* ppdefault; /* arg default info file */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppindex* firstindex; /* first include index entry */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppindex* lastindex; /* last include index entry */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct oplist* firstop; /* first arg op */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct oplist* lastop; /* last arg op */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct oplist* firsttx; /* first text file */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct oplist* lasttx; /* last text file */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char arg_file; /* arg file index */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char arg_mode; /* arg mode */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char arg_style; /* arg style */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char c; /* arg C state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char hosted; /* arg hosted state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char ignoresrc; /* arg ignore source state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char initialized; /* arg initialized state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char standalone; /* arg standalone state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char spare_1; /* padding spare */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_GLOBALS_PRIVATE_ /* ppglobals private additions */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* checkpoint; /* checkpoint version */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int constack; /* pp.control size */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppinstk* in; /* input stream stack pointer */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* addp; /* addbuf pointer */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* args; /* predicate args */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* addbuf; /* ADD buffer */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* catbuf; /* catenation buffer */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* hdrbuf; /* HEADEREXPAND buffer */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* hidebuf; /* pp:hide buffer */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* path; /* full path of last #include */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* tmpbuf; /* very temporary buffer */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* valbuf; /* builtin macro value buffer */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* optflags; /* OPT_* flags indexed by X_* */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int lastout; /* last output char */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* the rest are implicitly initialized */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* include; /* saved path of last #include */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* prefix; /* current directory prefix */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppmember* member; /* include archive member data */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int hidden; /* hidden newline count */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int hiding; /* number of symbols in hiding */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int level; /* pplex() recursion level */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int input; /* pool input */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int output; /* pool output */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } pool; /* loop on input,output,error */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long ro_state; /* original pp.ro_state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long ro_mode; /* original pp.ro_mode */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long ro_option; /* original pp.ro_option */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int on; /* PP_RESET enabled */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Hash_table_t* symtab; /* original pp.symtab scope */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } reset; /* PP_RESET state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int truncate; /* identifier truncation length */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppmacstk* macp; /* top of macro actual stack */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* maxmac; /* maximum size of macro stack */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* mactop; /* top of current macro frame */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* toknxt; /* '\0' of pp.token */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long* control; /* control block flags pointer */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long* maxcon; /* max control block frame */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct oplist* chop; /* include prefix chop list */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppfile* insert; /* inserted line sync file */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppfile* original; /* original include name */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppdirs* found; /* last successful ppsearch dir */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int vendor; /* vendor includes only */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Hash_table_t* dirtab; /* directive hash table */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Hash_table_t* strtab; /* string hash table */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PPBUILTIN builtin; /* builtin macro handler */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PPCOMMENT comment; /* pass along comments */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PPINCREF incref; /* include file push/return */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PPLINESYNC linesync; /* pass along line sync info */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PPLINESYNC olinesync; /* original linesync value */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PPMACREF macref; /* called on macro def/ref */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PPOPTARG optarg; /* unknown option arg handler */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PPPRAGMA pragma; /* pass along unknown pragmas */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct counter counter; /* monitoring counters */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char funbuf[256]; /* last __FUNCTION__ */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_SYMBOL_PRIVATE_ /* ppsymbol private additions */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pphide* hidden; /* hidden symbol info */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_MACRO_PRIVATE_ /* ppmacro private additions */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pptuple* tuple; /* tuple macro */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin union \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* formal; /* normal formals list */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppkeyarg* key; /* keyword formals table */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } args; /* macro args info */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int size; /* body size */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define formals args.formal /* formal argument list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define formkeys args.key /* formal keyword argument list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_MACRO_PRIVATE_ /* ppmacro private additions */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pptuple* tuple; /* tuple macro */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* formals; /* formal argument list */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int size; /* body size */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
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 unsigned char type; /* dir type */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin union \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* buffer; /* TYPE_BUFFER buffer */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* sp; /* archive stream */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppdirs* subdir; /* subdir list */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } info; /* type info */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppfileid id; /* directory id */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !PROTOMAIN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <error.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef newof
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "pp.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "ppdef.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "ppkey.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef setstate /* random clash! */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * DEBUG is encoded with the following bits
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TRACE_message 01
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TRACE_count 02
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TRACE_debug 04
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG && !lint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PANIC (ERROR_PANIC|ERROR_SOURCE|ERROR_SYSTEM),__FILE__,__LINE__
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PANIC ERROR_PANIC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG & TRACE_count
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define count(x) pp.counter.x++
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define count(x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG & TRACE_message
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define message(x) do { if (tracing) error x; } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define message(x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG & TRACE_debug
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define debug(x) do { if (tracing) error x; } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define debug(x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * note that MEMCPY advances the associated pointers
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MEMCPY(to,fr,n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do switch(n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { default : memcpy(to,fr,n); to += n; fr += n; break; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 7 : *to++ = *fr++; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 6 : *to++ = *fr++; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 5 : *to++ = *fr++; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 4 : *to++ = *fr++; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 3 : *to++ = *fr++; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 2 : *to++ = *fr++; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 1 : *to++ = *fr++; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0 : break; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NEWDIRECTIVE (-1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef dirname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef error
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define dirname(x) ppkeyname(x,1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define error pperror
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define keyname(x) ppkeyname(x,0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define nextframe(m,p) (m->next=m+(p-(char*)m+sizeof(struct ppmacstk)-1)/sizeof(struct ppmacstk)+1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define popframe(m) (m=m->prev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pptokchr(c) pptokstr(NiL,(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pushcontrol() do { if (pp.control++ >= pp.maxcon) ppnest(); } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pushframe(m) (m->next->prev=m,m=m->next)
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 tracing (error_info.trace<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
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
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
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MARK '@' /* internal mark */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ARGOFFSET '1' /* macro arg mark offset */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
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
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
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define peekchr() (*pp.in->nextchr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ungetchr(c) (*--pp.in->nextchr=(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAXID 255 /* maximum identifier size */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAXTOKEN PPTOKSIZ /* maximum token size */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAXFORMALS 64 /* maximum number macro formals */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAXHIDDEN 8 /* ppline if hidden>=MAXHIDDEN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DEFMACSTACK (MAXFORMALS*32*32)/* default macstack size */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FSM_COMPATIBILITY 1 /* compatibility mode */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FSM_IDADD 2 /* add to identifer set */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FSM_IDDEL 3 /* delete from identifer set */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FSM_INIT 4 /* initilize */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FSM_MACRO 5 /* add new macro */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FSM_OPSPACE 6 /* handle <binop><space>= */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FSM_PLUSPLUS 7 /* C++ lexical analysis */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FSM_QUOTADD 8 /* add to quote set */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FSM_QUOTDEL 9 /* delete from quote set */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_TOP 01 /* top level -- directives ok */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_BUFFER (2|IN_TOP) /* buffer of lines */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_COPY 2 /* macro arg (copied) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_EXPAND 4 /* macro arg (expanded) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_FILE (4|IN_TOP) /* file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_INIT (6|IN_TOP) /* initialization IN_BUFFER */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_MACRO 8 /* macro text */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_MULTILINE (8|IN_TOP) /* multi-line macro text */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_QUOTE 10 /* "..." macro arg (copied) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_RESCAN (10|IN_TOP) /* directive rescan buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_SQUOTE 12 /* '...' macro arg (copied) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define IN_STRING 14 /* string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_CLEAR ((struct ppsymbol*)0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_IGNORE ((struct ppsymbol*)pp.addbuf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_TEST ((struct ppsymbol*)pp.catbuf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_BOUND(n) (1<<(n))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_MEMBER(n) (1<<((n)+INC_MAX))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_PREFIX 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_LOCAL 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_STANDARD 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_VENDOR 3
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_MAX 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_SELF (1<<(2*INC_MAX+0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_EXISTS (1<<(2*INC_MAX+1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_LISTED (1<<(2*INC_MAX+2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_MAPALL (1<<(2*INC_MAX+3))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_MAPHOSTED (1<<(2*INC_MAX+4))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_MAPNOHOSTED (1<<(2*INC_MAX+5))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_MAPNOLOCAL (1<<(2*INC_MAX+6))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INC_HOSTED (1<<(2*INC_MAX+7))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TYPE_ARCHIVE (1<<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TYPE_BUFFER (1<<1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TYPE_CHECKPOINT (1<<2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TYPE_DIRECTORY (1<<3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TYPE_HOSTED (1<<4)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TYPE_INCLUDE (1<<5)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TYPE_VENDOR (1<<6)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TOK_BUILTIN (1<<0) /* last token was #( */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TOK_FORMAL (1<<1) /* last token was arg formal id */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TOK_ID (1<<2) /* last token was identifier */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TOK_TOKCAT (1<<3) /* last token was ## */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define HADELSE (1<<0) /* already had else part */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define KEPT (1<<1) /* already kept part of block */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SKIP (1<<2) /* skip this block */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define BLOCKBITS 3 /* block flag bits */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
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
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH(t,p) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count(push); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!pp.in->next) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.in->next = newof(0, struct ppinstk, 1, 0); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.in->next->prev = pp.in; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = pp.in = pp.in->next; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->type = t; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->flags = 0; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_BUFFER(f,p,n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pppush(IN_BUFFER,f,p,n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_COPY(p,n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppinstk* cur; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH(IN_COPY, cur); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->line = error_info.line; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line = n; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->nextchr = p; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->prev->symbol->flags &= ~SYM_DISABLED; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_EXPAND(p,n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppinstk* cur; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH(IN_EXPAND, cur); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->line = error_info.line; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line = n; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->prev->symbol->flags &= ~SYM_DISABLED; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->buffer = cur->nextchr = ppexpand(p); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cur->prev->symbol->flags & SYM_MULTILINE)) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->prev->symbol->flags |= SYM_DISABLED; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_FILE(f,d) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pppush(IN_FILE,f,NiL,d)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_INIT(f,p) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pppush(IN_INIT,f,p,1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_MACRO(p) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppinstk* cur; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH(IN_MACRO, cur); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->symbol = p; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->nextchr = p->macro->value; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->flags |= SYM_DISABLED; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NEWLINE; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_TUPLE(p,v) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppinstk* cur; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH(IN_MACRO, cur); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->symbol = p; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->nextchr = v; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->flags |= SYM_DISABLED; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NEWLINE; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_MULTILINE(p) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppinstk* cur; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH(IN_MULTILINE, cur); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->symbol = p; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->flags |= IN_defguard|IN_endguard|IN_noguard; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pushcontrol(); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->control = pp.control; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.control = 0; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->file = error_info.file; \
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 cur->line = error_info.line; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line = 1; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->nextchr = p->macro->value; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NEWLINE; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_QUOTE(p,n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppinstk* cur; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH(IN_QUOTE, cur); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->nextchr = p; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= QUOTE; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->line = error_info.line; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line = n; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_RESCAN(p) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pppush(IN_RESCAN,NiL,p,0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_SQUOTE(p,n) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppinstk* cur; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH(IN_SQUOTE, cur); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->nextchr = p; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= SQUOTE; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->line = error_info.line; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line = n; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_STRING(p) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppinstk* cur; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH(IN_STRING, cur); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->nextchr = p; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.state & DISABLE) cur->flags |= IN_disable; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PUSH_LINE(p) \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppinstk* cur; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH(IN_STRING, cur); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cur->nextchr = p; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= DISABLE|NOSPACE|PASSEOF|STRIP; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define POP_LINE() \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-7, "POP in=%s", ppinstr(pp.in))); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.in = pp.in->prev; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~(DISABLE|NOSPACE|PASSEOF|STRIP); \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct ppcontext /* pp context */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin _PP_CONTEXT_PUBLIC_
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin _PP_CONTEXT_PRIVATE_
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct ppfile /* include file info */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin HASH_HEADER; /* this is a hash bucket too */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppsymbol* guard; /* guard symbol */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppfile* bound[INC_MAX]; /* include bindings */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int flags; /* INC_* flags */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if CHECKPOINT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct ppindex /* checkpoint include index */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppindex* next; /* next in list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppfile* file; /* include file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long begin; /* beginning output offset */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long end; /* ending output offset */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct ppsymkey /* pun for SYM_KEYWORD lex val */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppsymbol sym; /* symbol as usual */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int lex; /* lex value for SYM_KEYWORD */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if PROTOMAIN && PROTO_STANDALONE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NiL 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NoP(x) (&x,1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NiL ((char*)0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NoP(x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _PP_DELAY_ #
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_PP_DELAY_ ifdef __STDC__
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_PP_DELAY_ include <stdlib.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_PP_DELAY_ include <unistd.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_PP_DELAY_ include <time.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_PP_DELAY_ include <string.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_PP_DELAY_ else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_PP_DELAY_ define size_t int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void* realloc(void*, size_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void* calloc(size_t, size_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* ctime(time_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void free(void*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_PP_DELAY_ ifndef O_RDONLY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
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 time_t time(time_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int unlink(const char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int write(int, const void*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_PP_DELAY_ endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_PP_DELAY_ endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * library implementation globals
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppassert _pp_assert
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppbuiltin _pp_builtin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppcall _pp_call
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppcontrol _pp_control
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppdump _pp_dump
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppexpand _pp_expand
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppexpr _pp_expr
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppfsm _pp_fsm
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppinmap _pp_inmap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppinstr _pp_instr
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppkeyname _pp_keyname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pplexmap _pp_lexmap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pplexstr _pp_lexstr
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppload _pp_load
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppmodestr _pp_modestr
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppmultiple _pp_multiple
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppnest _pp_nest
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppoption _pp_option
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppoptionstr _pp_optionstr
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pppclose _pp_pclose
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pppdrop _pp_pdrop
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pppopen _pp_popen
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pppread _pp_pread
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pppredargs _pp_predargs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pppush _pp_push
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pprefmac _pp_refmac
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppsearch _pp_search
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ppstatestr _pp_statestr
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pptokstr _pp_tokstr
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pptrace _pp_trace
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void ppassert(int, char*, char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void ppbuiltin(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int ppcall(struct ppsymbol*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int ppcontrol(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void ppdump(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* ppexpand(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern long ppexpr(int*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void ppfsm(int, char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* ppinstr(struct ppinstk*);
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 struct ppsymbol* pprefmac(char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int ppsearch(char*, int, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* ppstatestr(long);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* pptokstr(char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void pptrace(int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _std_malloc
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <vmalloc.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef free
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define free(p) vmfree(Vmregion,(void*)p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef newof
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define newof(p,t,n,x) vmnewof(Vmregion,p,t,n,x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef oldof
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define oldof(p,t,n,x) vmoldof(Vmregion,p,t,n,x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef strdup
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define strdup(s) vmstrdup(Vmregion,s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif