/****************************************************************************** * FREXXWARE * ---------------------------------------------------------------------------- * * Project: Frexx C Preprocessor * $Source: /home/user/start/cpp/RCS/cppadd.h,v $ * $Revision: 1.5 $ * $Date: 1994/01/24 09:38:12 $ * $Author: start $ * $State: Exp $ * $Locker: start $ * * ---------------------------------------------------------------------------- * $Log: cppadd.h,v $ * Revision 1.5 1994/01/24 09:38:12 start * Added the 'rightconcat' in the global structure. * * Revision 1.4 1993/12/06 13:51:20 start * A lot of new stuff (too much to mention) * * Revision 1.3 1993/11/29 14:01:13 start * New features added * * Revision 1.2 1993/11/11 07:16:39 start * New stuff * * Revision 1.1 1993/11/03 09:15:59 start * Initial revision * * *****************************************************************************/ /********************************************************************** * * cppadd.h * * Prototypes and structures added by Daniel Stenberg. * *******/ #include #include "memory.h" struct Global { /* * Commonly used global variables: * line is the current input line number. * wrongline is set in many places when the actual output * line is out of sync with the numbering, e.g, * when expanding a macro with an embedded newline. * * tokenbuf holds the last identifier scanned (which might * be a candidate for macro expansion). * errors is the running cpp error counter. * infile is the head of a linked list of input files (extended by * #include and macros being expanded). infile always points * to the current file/macro. infile->parent to the includer, * etc. infile->fd is NULL if this input stream is a macro. */ int line; /* Current line number */ int wrongline; /* Force #line to compiler */ char *tokenbuf; /* Buffer for current input token */ char *functionname; /* Buffer for current function */ int funcline; /* Line number of current function */ int tokenbsize; /* Allocated size of tokenbuf, */ /* not counting zero at end. */ int errors; /* cpp error counter */ FILEINFO *infile; /* Current input file */ #if DEBUG int debug; /* TRUE if debugging now */ #endif /* * This counter is incremented when a macro expansion is initiated. * If it exceeds a built-in value, the expansion stops -- this tests * for a runaway condition: * #define X Y * #define Y X * X * This can be disabled by falsifying rec_recover. (Nothing does this * currently: it is a hook for an eventual invocation flag.) */ int recursion; /* Infinite recursion counter */ int rec_recover; /* Unwind recursive macros */ /* * instring is set TRUE when a string is scanned. It modifies the * behavior of the "get next character" routine, causing all characters * to be passed to the caller (except ). Note especially that * comments and \ are not removed from the source. (This * prevents cpp output lines from being arbitrarily long). * * inmacro is set by #define -- it absorbs comments and converts * form-feed and vertical-tab to space, but returns \ * to the caller. Strictly speaking, this is a bug as \ * shouldn't delimit tokens, but we'll worry about that some other * time -- it is more important to prevent infinitly long output lines. * * instring and inmarcor are parameters to the get() routine which * were made global for speed. */ int instring; /* TRUE if scanning string */ int inmacro; /* TRUE if #defining a macro */ /* * work[] and workp are used to store one piece of text in a temporay * buffer. To initialize storage, set workp = work. To store one * character, call save(c); (This will fatally exit if there isn't * room.) To terminate the string, call save(EOS). Note that * the work buffer is used by several subroutines -- be sure your * data won't be overwritten. The extra byte in the allocation is * needed for string formal replacement. */ char work[NWORK + 1]; /* Work buffer */ char *workp; /* Work buffer pointer */ /* * keepcomments is set TRUE by the -C option. If TRUE, comments * are written directly to the output stream. This is needed if * the output from cpp is to be passed to lint (which uses commands * embedded in comments). cflag contains the permanent state of the * -C flag. keepcomments is always falsified when processing #control * commands and when compilation is supressed by a false #if * * If eflag is set, CPP returns "success" even if non-fatal errors * were detected. * * If nflag is non-zero, no symbols are predefined except __LINE__. * __FILE__, and __DATE__. If nflag > 1, absolutely no symbols * are predefined. */ char keepcomments; /* Write out comments flag */ char cflag; /* -C option (keep comments) */ char eflag; /* -E option (never fail) */ char nflag; /* -N option (no predefines) */ char wflag; /* -W option (write #defines) */ /* * ifstack[] holds information about nested #if's. It is always * accessed via *ifptr. The information is as follows: * WAS_COMPILING state of compiling flag at outer level. * ELSE_SEEN set TRUE when #else seen to prevent 2nd #else. * TRUE_SEEN set TRUE when #if or #elif succeeds * ifstack[0] holds the compiling flag. It is TRUE if compilation * is currently enabled. Note that this must be initialized TRUE. */ char ifstack[BLK_NEST]; /* #if information */ char *ifptr; /* -> current ifstack[] */ /* * incdir[] stores the -i directories (and the system-specific * #include <...> directories. */ char *incdir[NINCLUDE]; /* -i directories */ char **incend; /* -> free space in incdir[] */ /* * include[] stores the -X and -x files. */ char *include[NINCLUDE]; char includeshow[NINCLUDE]; /* show it or not! */ char included; /* * This is the table used to predefine target machine and operating * system designators. It may need hacking for specific circumstances. * Note: it is not clear that this is part of the Ansi Standard. * The -B option supresses preset definitions. */ char *preset[5]; /* names defined at cpp start */ /* * The value of these predefined symbols must be recomputed whenever * they are evaluated. The order must not be changed. */ char *magic[5]; /* Note: order is important */ /* * This is the variable saying if Cpp should remove C++ style comments from * the output. Default is... TRUE, yes, pronto, do it!!! */ char cplusplus; char *sharpfilename; /* * parm[], parmp, and parlist[] are used to store #define() argument * lists. nargs contains the actual number of parameters stored. */ char parm[NPARMWORK + 1]; /* define param work buffer */ char *parmp; /* Free space in parm */ char *parlist[LASTPARM]; /* -> start of each parameter */ int nargs; /* Parameters for this macro */ DEFBUF *macro; /* Catches start of infinite macro */ DEFBUF *symtab[SBSIZE]; /* Symbol table queue headers */ int evalue; /* Current value from evallex() */ char *(*input)(char *, int, void *); /* Input function */ char *first_file; /* Preprocessed file. */ void *userdata; /* Data sent to input function */ void (*output)(int, void *); /* output function */ void (*error)(void *, char *, va_list); /* error function */ char linelines; char warnillegalcpp; /* warn for illegal preprocessor instructions? */ char outputLINE; /* output 'line' in #line instructions */ char showversion; /* display version */ char showincluded; /* display included files */ char showbalance; /* display paren balance */ char showspace; /* display all whitespaces as they are */ char comment; /* TRUE if a comment just has been written to output */ char *spacebuf; /* Buffer to store whitespaces in if -H */ long chpos; /* Number of whitespaces in buffer */ char nestcomments; /* Allow nested comments */ char warnnestcomments; /* Warn at nested comments */ char warnnoinclude; /* Warn at missing include file */ char outputfile; /* output the main file */ char out; /* should we output anything now? */ char rightconcat; /* should the right part of a concatenation be avaluated before the concat (TRUE) or after (FALSE) */ char *initialfunc; /* file to include first in all functions */ char *excludedinit[20]; /* functions (names) excluded from the initfunc */ int excluded; char outputfunctions; /* output all discovered functions to stderr! */ char webmode; /* WWW process mode */ }; typedef enum { ERROR_STRING_MUST_BE_IF, ERROR_STRING_MAY_NOT_FOLLOW_ELSE, ERROR_ERROR, ERROR_PREPROC_FAILURE, ERROR_MISSING_ARGUMENT, ERROR_INCLUDE_SYNTAX, ERROR_DEFINE_SYNTAX, ERROR_REDEFINE, ERROR_ILLEGAL_UNDEF, ERROR_RECURSIVE_MACRO, ERROR_EOF_IN_ARGUMENT, ERROR_MISPLACED_CONSTANT, ERROR_IF_OVERFLOW, ERROR_ILLEGAL_IF_LINE, ERROR_OPERATOR, ERROR_EXPR_OVERFLOW, ERROR_UNBALANCED_PARENS, ERROR_MISPLACED, ERROR_STRING_IN_IF, ERROR_DEFINED_SYNTAX, ERROR_ILLEGAL_ASSIGN, ERROR_ILLEGAL_BACKSLASH, ERROR_SIZEOF_SYNTAX, ERROR_SIZEOF_UNKNOWN, ERROR_SIZEOF_ILLEGAL_TYPE, ERROR_SIZEOF_NO_TYPE, ERROR_UNTERMINATED_STRING, ERROR_EOF_IN_COMMENT, ERROR_IFDEF_DEPTH, ERROR_ILLEGAL_CHARACTER, ERROR_ILLEGAL_CHARACTER2, ERROR_SIZEOF_BUG, ERROR_IF_OPERAND, ERROR_STRANG_CHARACTER, ERROR_STRANG_CHARACTER2, BORDER_ERROR_WARN, /* below this number: errors, above: warnings */ WARN_CONTROL_LINE_IN_MACRO, WARN_ILLEGAL_COMMAND, WARN_UNEXPECTED_TEXT_IGNORED, WARN_TOO_FEW_VALUES_TO_SIZEOF, WARN_TOO_MANY_VALUES_TO_SIZEOF, WARN_NOT_DEFINED, WARN_INTERNAL_ERROR, WARN_MACRO_NEEDS_ARGUMENTS, WARN_WRONG_NUMBER_ARGUMENTS, WARN_DIVISION_BY_ZERO, WARN_ILLEGAL_OCTAL, WARN_MULTIBYTE_NOT_PORTABLE, WARN_CANNOT_OPEN_INCLUDE, WARN_BRACKET_DEPTH, WARN_PAREN_DEPTH, WARN_BRACE_DEPTH, WARN_NESTED_COMMENT, BORDER_WARN_FATAL, /* below this number: warnings, above: fatals */ FATAL_TOO_MANY_NESTINGS, FATAL_FILENAME_BUFFER_OVERFLOW, FATAL_TOO_MANY_INCLUDE_DIRS, FATAL_TOO_MANY_INCLUDE_FILES, FATAL_TOO_MANY_ARGUMENTS_MACRO, FATAL_MACRO_AREA_OVERFLOW, FATAL_ILLEGAL_MACRO, FATAL_TOO_MANY_ARGUMENTS_EXPANSION, FATAL_OUT_OF_SPACE_IN_ARGUMENT, FATAL_WORK_AREA_OVERFLOW, FATAL_WORK_BUFFER_OVERFLOW, FATAL_OUT_OF_MEMORY, FATAL_TOO_MUCH_PUSHBACK } ErrorCode; /********************************************************************** * RETURN CODES: *********************************************************************/ typedef enum { FPP_OK, FPP_OUT_OF_MEMORY, FPP_TOO_MANY_NESTED_STATEMENTS, FPP_FILENAME_BUFFER_OVERFLOW, FPP_NO_INCLUDE, FPP_OPEN_ERROR, FPP_TOO_MANY_ARGUMENTS, FPP_WORK_AREA_OVERFLOW, FPP_ILLEGAL_MACRO, FPP_EOF_IN_MACRO, FPP_OUT_OF_SPACE_IN_MACRO_EXPANSION, FPP_ILLEGAL_CHARACTER, FPP_CANT_USE_STRING_IN_IF, FPP_BAD_IF_DEFINED_SYNTAX, FPP_IF_ERROR, FPP_SIZEOF_ERROR, FPP_UNTERMINATED_STRING, FPP_TOO_MANY_INCLUDE_DIRS, FPP_TOO_MANY_INCLUDE_FILES, FPP_INTERNAL_ERROR, FPP_LAST_ERROR } ReturnCode; /* Nasty defines to make them appear as three different functions! */ #define cwarn cerror #define cfatal cerror /********************************************************************** * PROTOTYPES: *********************************************************************/ int PREFIX fppPreProcess(REG(a0) struct fppTag *); void Freemem(void *); void Error(struct Global *, char *, ...); void Putchar(struct Global *, int); void Putstring(struct Global *, char *); void Putint(struct Global *, int); char *savestring(struct Global *, char *); ReturnCode addfile(struct Global *, FILE *, char *); int catenate(struct Global *, ReturnCode *); void cerror(struct Global *, ErrorCode, ...); ReturnCode control(struct Global *, int *); ReturnCode dodefine(struct Global *); int dooptions(struct Global *, struct fppTag *); void doundef(struct Global *); void dumpparm(char *); ReturnCode expand(struct Global *, DEFBUF *); int get(struct Global *); ReturnCode initdefines(struct Global *); void outdefines(struct Global *); ReturnCode save(struct Global *, int); void scanid(struct Global *, int); ReturnCode scannumber(struct Global *, int, ReturnCode(*)(struct Global *, int)); ReturnCode scanstring(struct Global *, int, ReturnCode(*)(struct Global *, int)); void unget(struct Global *); ReturnCode ungetstring(struct Global *, char *); ReturnCode eval(struct Global *, int *); #ifdef DEBUG_EVAL void dumpstack(OPTAB[NEXP], register OPTAB *, int [NEXP], register int *); #endif void skipnl(struct Global *); int skipws(struct Global *); ReturnCode macroid(struct Global *, int *); ReturnCode getfile(struct Global *, int, char *, FILEINFO **); DEFBUF *lookid(struct Global *, int ); DEFBUF *defendel(struct Global *, char *, int); #if DEBUG void dumpdef(char *); void dumpadef(char *, register DEFBUF *); #endif ReturnCode openfile(struct Global *,char *); int cget(struct Global *); void deldefines(struct Global *); char *Getmem(struct Global *, int); ReturnCode openinclude(struct Global *, char *, int); ReturnCode expstuff(struct Global *, char *, char *);