/************************************************************************/ /* */ /* File: pp.h */ /* */ /* Header file for PP. */ /* */ /* Written by: */ /* Gary Oliver */ /* 3420 NW Elmwood Dr. */ /* PO Box 826 */ /* Corvallis, Oregon 97339 */ /* (503)758-5549 */ /* Maintained by: */ /* Kirk Bailey */ /* Logical Systems */ /* P.O. Box 1702 */ /* Corvallis, OR 97339 */ /* (503)753-9051 */ /* */ /* This program is hereby placed in the public domain. In */ /* contrast to other claims of "public domain", this means no */ /* copyright is claimed and you may do anything you like with PP, */ /* including selling it! As a gesture of courtesy, please retain */ /* the authorship information in the source code and */ /* documentation. */ /* */ /************************************************************************/ #define VERSION "Logical Systems Version 96.1" /* Version info */ #ifdef MAIN #define EXTERN /* Inside main() routine, make internal */ #define I_BRZERO ={0} #define I_ZERO =0 #else /* !MAIN */ #define EXTERN extern /* Define for creating external refs */ #define I_BRZERO #define I_ZERO #endif /* MAIN */ /* Define TRUE and FALSE if not already defined */ #ifndef TRUE #define TRUE 1 #endif /* TRUE */ #ifndef FALSE #define FALSE 0 #endif /* FALSE */ /* * Define AND and OR as logical "and" and "or", or boolean if the * preprocessor being used to compile PP doesn't support "&&" and "||" in * preprocessor directives (at least one version of Lattice for instance). */ #define AND && #define OR || /* * If the value of PP is FALSE, this program may be run through * the original QC compiler without parameterized macro expansion. * After a version is built, recompile with PP as TRUE to make * things run more efficiently (ctype.h, for example.) */ #define PP TRUE /* TRUE if to depend upon PP features */ #define DEBUG FALSE /* TRUE if to include debug code */ /* * The host system the preprocessor will be running on. Note that this * choice implies both the host operating system and the specific "C" * compiler used to compile PP. Note that not all combinations have * been (recently), tested! */ #define H_BSD 1 /* BSD 4.X UNIX */ #define H_CPM 2 /* QC Z80 native compiler under CP/M */ #define H_MPW 3 /* MPW on Mac's */ #define H_MSDOS 4 /* MSC or Borland "C" on MS-DOS */ #define H_UNIX 5 /* AT+T System 5 UNIX */ #define H_VMS 6 /* DEC VAX VMS */ #define H_XENIX 7 /* Microsoft XENIX */ #define HOST H_MSDOS /* * The target system for which the preprocessor is generating code. Note * that this choice implies both the target "operating system" (if any), * and the target processor. In particular, this choice affects which * symbols PP predefines. Note that not all combinations have been * (recently), tested! */ #define T_BSD 1 /* BSD 4.X UNIX */ #define T_MPW 2 /* MPW "C" on Mac's */ #define T_QC 3 /* QC "C" */ #define T_QCX 4 /* QCX "C" cross compiler */ #define T_TCX 5 /* TCX "C" cross compiler */ #define T_UNIX 6 /* AT+T System 5 UNIX */ #define T_VMS 7 /* DEC VAX VMS */ #define T_XENIX 8 /* Microsoft XENIX */ #define TARGET T_TCX #if ((HOST == H_BSD) OR (HOST == H_UNIX) OR (HOST == H_XENIX)) #define STDERR stderr #else /* ! (H_BSD OR H_UNIX OR H_XENIX) */ #define STDERR stdout #endif /* H_BSD OR H_UNIX OR H_XENIX */ #if HOST != H_MPW #define VERBOSE TRUE /* TRUE to make verbose by default */ #else /* MPW */ #define VERBOSE FALSE /* TRUE to make verbose by default */ #endif /* HOST != H_MPW */ #if HOST == H_CPM #include /* Standard stuff */ #include #if PP #include /* Character types */ #endif /* PP */ #define EVALINT int /* For QC: evaluate using ints */ #define PP_SYSIO /* Defined if to use direct I/O routines*/ #define BUFFERSIZE 512 /* Disk buffer size */ #define OUTBUFSIZE 2048 /* Output buffer size */ #define strchr index /* ANSI C defs */ #define strrchr rindex #define DFLT_PATH "A0" /* Enables -I code */ #define PATHFILE "path.ppi" /* Location of path info */ #define ENDFILE (0x1A) /* CP/M End of file character */ #define BDOS_SELDISK 14 /* Bdos select disk function */ #define BDOS_GETDISK 25 /* Bdos get disk function */ #define BDOS_USER 32 /* Bdos get/set user function */ #endif /* HOST == H_CPM */ #if HOST != H_CPM #define ENV_PATH "PPINC" /* Env. variable for include path */ #if HOST == H_MSDOS #define DFLT_PATH "/include" /* Default include location */ #else /* ! H_MSDOS */ #if HOST == H_VMS #define DFLT_PATH "crel$include:" /* Default include location */ #else /* !H_VMS */ #ifndef DFLT_PATH /* If MAKEFILE doesn't override */ #define DFLT_PATH "/usr/include" /* Default include location */ #endif /* !defined(DFLT_PATH) */ #endif /* HOST == H_VMS */ #endif /* HOST == MS_DOS */ #define PP_SYSIO /* Defined if to use direct I/O routines*/ #if HOST == H_BSD #include #define BUFFERSIZE BLKDEV_IOSIZE /* 2K bytes Ultrix2.2/SunOS4.0 */ #else /* ! H_BSD */ #define BUFFERSIZE 512 /* Disk buffer size */ #endif /* HOST == H_BSD */ #include /* Standard I/O info */ #include /* Standard library info */ #include #include /* Char type info */ #if HOST == H_XENIX #include /* Need for 'time_t' */ #endif /* HOST == H_XENIX */ #if HOST == H_MPW #define SLASHCHAR ':' #define SLASHSTR ":" #else /* ! H_MPW */ #define SLASHCHAR '/' #if HOST == H_VMS #define SLASHSTR "" #else /* ! H_VMS */ #define SLASHSTR "/" #endif /* HOST == H_VMS */ #include /* System time info */ #endif /* HOST == H_MPW */ #if HOST == H_BSD /* Berkeley 4.x */ #include #define strchr index #define strrchr rindex #define memmov bcopy /* Used move memory routine */ #endif /* HOST == H_BSD */ #endif /* HOST != H_CPM */ #define PATHPUNC ';' /* Include file path separator */ #if (HOST!=H_BSD)AND(HOST!=H_MPW)AND(HOST!=H_UNIX)AND(HOST!=H_XENIX) #define IGNORE_CR /* Defined if to ignore CR's */ #endif /* !H_BSD AND !H_MPW AND !H_UNIX AND !H_XENIX */ #ifndef EVALINT #define EVALINT long /* Default values in eval are longs */ #endif /* EVALINT */ /* * Character type. */ #define C_L 0x01 /* Letter (A-Zz-z) */ #define C_D 0x02 /* Digit (0-9) */ #define C_X 0x04 /* Hex digit (0-9 a-f|A-F) */ #define C_W 0x08 /* White space (ht, sp, etc.) */ /* 0x10 Not used */ #define C_C 0x20 /* Special processing inside gchbuf() */ #define C_M 0x40 /* A META token (see gettoken()) */ #define C_N 0x80 /* A NUL (no output) */ #if PP #define istype(c,v) ((typetab+1)[(c)]&(v)) extern int gchfile(); #else /* !PP */ extern int istype(); #endif /* PP */ #ifdef MAIN char typetab[] = { (char) (C_C|C_N), /* EOF */ 0, 0, 0, 0, /* ^@ ^A ^B ^C */ 0, 0, 0, 0, /* ^D ^E ^F ^G */ 0, C_W, C_C, 0, /* ^H ^I ^J ^K */ #if HOST == H_MPW C_W, C_C, 0, 0, /* ^L ^M ^N ^O */ #else /* ! H_MPW */ C_W, C_W|C_C, 0, 0, /* ^L ^M ^N ^O */ #endif /* HOST == H_MPW */ 0, 0, 0, 0, /* ^P ^Q ^R ^S */ 0, 0, 0, 0, /* ^T ^U ^V ^W */ #if HOST == H_CPM 0, 0, C_C, 0, /* ^X ^Y ^Z ESC*/ #else /* ! H_CPM */ 0, 0, 0, 0, /* ^X ^Y ^Z ESC*/ #endif /* HOST == H_CPM */ 0, 0, 0, 0, /* FS GS RS VS */ C_W, 0, 0, 0, /* Sp ! " # */ 0, 0, 0, 0, /* $ % & ' */ 0, 0, 0, 0, /* ( ) * + */ 0, 0, 0, 0, /* , - . / */ C_D|C_X, C_D|C_X, C_D|C_X, C_D|C_X, /* 0 1 2 3 */ C_D|C_X, C_D|C_X, C_D|C_X, C_D|C_X, /* 4 5 6 7 */ C_D|C_X, C_D|C_X, 0, 0, /* 8 9 : ; */ 0, 0, 0, 0, /* < = > ? */ 0, C_L|C_X, C_L|C_X, C_L|C_X, /* @ A B C */ C_L|C_X, C_L|C_X, C_L|C_X, C_L, /* D E F G */ C_L, C_L, C_L, C_L, /* H I J K */ C_L, C_L, C_L, C_L, /* L M N O */ C_L, C_L, C_L, C_L, /* P Q R S */ C_L, C_L, C_L, C_L, /* T U V W */ C_L, C_L, C_L, 0, /* X Y Z [ */ C_C, 0, 0, C_L, /* \ ] ^ _ */ 0, C_L|C_X, C_L|C_X, C_L|C_X, /* ` a b c */ C_L|C_X, C_L|C_X, C_L|C_X, C_L, /* d e f g */ C_L, C_L, C_L, C_L, /* h i j k */ C_L, C_L, C_L, C_L, /* l m n o */ C_L, C_L, C_L, C_L, /* p q r s */ C_L, C_L, C_L, C_L, /* t u v w */ C_L, C_L, C_L, 0, /* x y z { */ 0, 0, 0, 0, /* | } ~ Rub*/ /* Special token chars 0x80 - 0x?? */ (char) (C_M|C_N), /* END_MACRO token */ (char) (C_M|C_N), /* END_ARG token */ (char) (C_M|C_N), /* TOGGLE_EXPAND */ (char) (C_M|C_N), /* __LINE__ token */ (char) (C_M|C_N), /* __FILE__ token */ (char) (C_M|C_N), /* __TIME__ token */ (char) (C_M|C_N), /* __DATE__ token */ (char) (C_M|C_N), /* __NOW__ token */ (char) (C_M|C_N), /* __NEXT__ token */ (char) (C_M|C_N) /* __PREV__ token */ }; #else extern char typetab[]; #endif /* MAIN */ #define EQUAL 0 /* Value returned by strcmp if equal */ /* * Token types from gettoken() */ #define LETTER 'a' /* (letter | '_') letter* digit* */ #define NUMBER '0' /* (digit | '.' | letter) digit+ */ #define DIRECTIVE_CHAR '#' /* Defines a PP directive */ #define END_MACRO 0x80 /* Marks end of macro in pushback */ #define TOGGLE_EXPAND 0x81 /* Marks edges of previously expanded */ #define END_ARG 0x82 /* Marks end of argument macro scope */ #define LINE_TOKEN 0x83 /* Return the Line number */ #define FILE_TOKEN 0x84 /* Return the File name */ #define TIME_TOKEN 0x85 /* Return the system time */ #define DATE_TOKEN 0x86 /* Return the system date */ #define NOW_TOKEN 0x87 /* Return the last result of NEXT_TOKEN */ #define NEXT_TOKEN 0x88 /* Return a unique unsigned number */ #define PREV_TOKEN 0x89 /* Return previous unique unsigned # */ /* * Flag parameter to "gettoken()". */ #define GT_STR 0x0001 /* gettoken() returns whole strings */ #define GT_ANGLE 0x0003 /* GT_STR plus returns whole <>'s */ #if HOST == H_CPM #define FILENAMESIZE 20 #else /* ! H_CPM */ #if HOST == H_BSD #define FILENAMESIZE MAXPATHLEN #else /* ! H_BSD */ #define FILENAMESIZE 80 /* Long enough until we find better */ #endif /* HOST == H_BSD */ #endif /* HOST == H_CPM */ #define FILESTACKSIZE 14 /* Max depth of #include */ #define MACROSIZE 4000 /* Max length of #define */ #define TOKENSIZE 510 /* Max token length */ #define NUMBUCKETS 64 /* # of buckets (power of 2) */ #define IFSTACKSIZE 32 /* #ifxx nesting */ #define PUSHBACKSIZE TOKENSIZE /* Pushback buffer */ #define EVALBUFSIZE TOKENSIZE /* Buffer size in doif() */ #define MESSAGEBUFSIZE TOKENSIZE /* Buffer size in #pragma mess */ #define PRAGBUFSIZE TOKENSIZE /* Room for pragma line */ /* * Pushback buffer */ EXTERN struct pbbuf *Pbbufp I_ZERO; EXTERN struct pbbuf *Pbbuf I_ZERO; struct pbbuf { char pb_type; #define PB_CHAR 0 /* pb_val.pb_char is character */ #define PB_STRING 1 /* pb_val.pb_str is ptr to string */ #define PB_TOS 2 /* Top of pushback buffer stack */ union { char *pb_str; int pb_char; } pb_val; }; EXTERN FILE *Output I_ZERO; /* Output file */ struct file { int f_line; /* Line number */ #if HOST == H_CPM /* Path names for #includes */ int f_disk; /* Disk number */ int f_user; /* User number (< 0 if default) */ #endif /* HOST == H_CPM */ #ifdef PP_SYSIO /* If to use direct I/O system calls? */ int f_fd; /* A file descriptor */ #else /* !PP_SYSIO */ FILE *f_file;/* FILE pointer */ #endif /* PP_SYSIO */ char *f_bufp;/* Pointer into buffer */ int f_bufc; /* Number of chars left */ int f_eof; /* Flag that's non-zero if in last blk */ char f_lasteol; /* TRUE if last char was EOL */ char f_buf[BUFFERSIZE]; /* Buffer for file */ char f_name[FILENAMESIZE + 1]; /* File name */ }; /* * Define static vars that are a bit more efficient to access. */ EXTERN int Bufc I_ZERO; /* Current file char count */ EXTERN char *Bufp I_ZERO; /* Current file char ptr */ EXTERN int Lasteol I_ZERO; /* True if last char processed was EOL */ EXTERN int LLine I_ZERO; /* Last line number */ EXTERN int (*Nextch)(); /* Next char function */ #define nextch (*Nextch) /* Macro to rd chars via Nextch */ EXTERN struct file *Filestack[FILESTACKSIZE + 1] I_BRZERO; EXTERN int Filelevel I_ZERO; /* Include level */ EXTERN int Do_name I_ZERO; /* True to put name on #line */ EXTERN char Outfile[FILENAMESIZE + 1] I_BRZERO; EXTERN char Token[TOKENSIZE + 1] I_BRZERO; /* Token buffer */ EXTERN unsigned int Tokenline I_ZERO; /* Line # token began */ EXTERN unsigned int Tokenfile I_ZERO; /* File # token began */ EXTERN int Lastnl I_ZERO; /* Last token processed was \n */ /* * Macro proto pointers. */ struct symtab { struct symtab *s_link;/* Next in list for this chain */ char disable;/* TRUE to disable recognition for now */ char *s_body;/* Body of definition */ struct param *s_params; /* List of parameters */ char s_name[1]; /* Name is appended to structure*/ }; struct param { struct param *p_link;/* Next in list */ char p_flags;/* Flags: */ #define PF_RQUOTES 0x01 /* Remove "" chars from parameter */ #define PF_PNLINES 0x02 /* Preserve '\n' char in parameter */ char p_name[1]; /* Name is appended to struct */ }; /* * Predefined symbol entry. */ struct ppdir { char *pp_name; /* #function name */ char pp_ifif; /* FALSE if ! to do on false #if*/ void (*pp_func)(); /* Address of function */ int pp_arg; /* Argument to function */ }; /* * Predefined symbols. */ #define YES TRUE #define NO FALSE #define EMPTY 0 /* Catch-all for non-used field */ /* * Alphabetically ordered. */ #if (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) extern void doasm(); #endif /* (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) */ extern void dodefine(); extern void doelse(); extern void doendif(); extern void doerror(); extern void doif(); extern void doifs(); extern void doinclude(); extern void doline(); extern void dopragma(); extern void doundef(); #ifdef MAIN /* If in main() module */ struct ppdir pptab[] = { /* Directive Do within Procedure Arg to */ /* name FALSE #ifxx name function */ /* -------------- ----------- ---------- -------- */ #if (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) {"asm", NO, doasm, TRUE }, #endif /* (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) */ {"define", NO, dodefine, FALSE }, {"elif", YES, doelse, TRUE }, {"else", YES, doelse, FALSE }, #if (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) {"endasm", NO, doasm, FALSE }, #endif /* (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) */ {"endif", YES, doendif, EMPTY }, {"error", NO, doerror, EMPTY }, {"if", YES, doif, EMPTY }, {"ifdef", YES, doifs, TRUE }, {"ifndef", YES, doifs, FALSE }, {"include", NO, doinclude, EMPTY }, {"line", NO, doline, EMPTY }, {"undef", NO, doundef, EMPTY }, {"pragma", YES, dopragma, EMPTY }, {NULL} /* The end */ }; #if (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) extern void pragasm(); #endif /* (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX)*/ extern void pragendm(); extern void pragerror(); extern void pragmsg(); extern void pragopt(); extern void pragvalue(); /* * Pragma keyword table. */ struct ppdir pragtab[] = { /* Keyword Do within Procedure Arg to */ /* name FALSE #ifxx name function */ /* ------------------ ----------- ---------- -------- */ {"arg_string", NO, pragopt, EMPTY }, #if (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) {"asm", NO, pragasm, TRUE }, {"asm_expand", NO, pragopt, EMPTY }, #endif /* (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) */ {"comment_recurse",NO, pragopt, EMPTY }, {"define", NO, dodefine, FALSE }, {"elif", YES, doelse, TRUE }, {"else", YES, doelse, FALSE }, #if (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) {"endasm", NO, pragasm, FALSE }, #endif /* (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) */ {"endif", YES, doendif, EMPTY }, {"endmacro", NO, pragendm, EMPTY }, {"error", NO, pragerror, FALSE }, {"if", YES, doif, EMPTY }, {"ifdef", YES, doifs, TRUE }, {"ifndef", YES, doifs, FALSE }, {"macro", NO, dodefine, TRUE }, {"macro_rescan",NO, pragopt, EMPTY }, {"macro_stack", NO, pragopt, EMPTY }, {"message", NO, pragmsg, EMPTY }, {"trigraph", NO, pragopt, EMPTY }, {"undef", NO, doundef, EMPTY }, {"value", NO, pragvalue, EMPTY }, {NULL} /* The end */ }; #else /* !MAIN */ extern struct ppdir pptab[]; extern struct ppdir pragtab[]; #endif /* MAIN */ EXTERN int A_astring I_ZERO; /* TRUE/args in strings */ EXTERN int A_crecurse I_ZERO; /* TRUE/comments nest */ EXTERN int A_eolcomment I_ZERO; /* TRUE/eol comments OK */ EXTERN int A_rescan I_ZERO;/* TRUE/direct. from macro's */ EXTERN int A_stack I_ZERO; /* TRUE/macro def's stack */ EXTERN int A_trigraph I_ZERO; /* TRUE/trigraphs active*/ EXTERN struct symtab *Macros[NUMBUCKETS] I_BRZERO; /* Ptr/macro chains*/ EXTERN int Nsyms I_ZERO; /* Number of symbols in table */ EXTERN int Maxsyms I_ZERO; /* Max number of symbols used */ #define NO_PARAMS (struct param *)NULL /* For sbind of 0 params*/ struct ifstk { char i_state;/* The ifstack state: */ #define IFTRUE 0 /* True - include code within #ifxx */ #define IFFALSE 1 /* False - no code within #ifxx */ #define IFNEVER 2 /* Treat as false forever after */ char i_else; /* True if encountered an #else */ }; EXTERN struct ifstk Ifstack[IFSTACKSIZE + 1] I_BRZERO; EXTERN int Iflevel I_ZERO; /* Index into Ifstack */ EXTERN int Ifstate I_ZERO; /* Current state of #if */ #if DEBUG EXTERN int Debug I_ZERO; /* -z flag */ #endif /* DEBUG */ EXTERN int Lineopt;/* True if producing #line directives */ #define LINE_EXP 1 /* If to expand to #line directives */ #define LINE_ABR 2 /* If to abbreviate to # n "file" */ EXTERN int Outline I_ZERO; /* Line # of current output file*/ EXTERN int Errors I_ZERO; /* Total errors detected */ EXTERN int Eflag I_ZERO; /* True if to ignore errors */ #if DEBUG EXTERN int Stats I_ZERO; /* True to print stats at end */ #endif /* DEBUG */ EXTERN char Date[12] I_BRZERO; /* Date str for __DATE__*/ EXTERN char _Time[9] I_BRZERO; /* Time str for __TIME__*/ EXTERN unsigned int Unique I_ZERO; /* Unique # for __NOW__/__NEXT__*/ EXTERN int Verbose I_ZERO; /* True to print verbose mess */ #if (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) EXTERN int Do_asm I_ZERO; /* True if in asm/endasm body */ EXTERN int Macexpand I_ZERO; /* True/macro expand on */ EXTERN int Asmexpand I_ZERO; /* Set Macexpand in asm */ #endif /* (TARGET == T_QC) OR (TARGET == T_QCX) OR (TARGET == T_TCX) */ #define NIPATHS 10 /* Up to 10 -i pathnames */ EXTERN char *Ipath[NIPATHS+1] I_BRZERO; /* -i path list */ EXTERN int Ipcnt I_ZERO; /* Count of -i parameters */ #if HOST == H_CPM EXTERN int Orig_user I_ZERO; /* Original user */ EXTERN int Orig_disk I_ZERO; /* Original disk */ #endif /* HOST == H_CPM */ /* * End of pp.h */