| /* |
| * (c) Thomas Pornin 1999, 2000 |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 4. The name of the authors may not be used to endorse or promote |
| * products derived from this software without specific prior written |
| * permission. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
| * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| */ |
| |
| #ifndef UCPP__CPP__ |
| #define UCPP__CPP__ |
| |
| /* |
| * Uncomment the following if you want ucpp to use externally provided |
| * error-reporting functions (ucpp_warning(), ucpp_error() and ucpp_ouch()) |
| */ |
| /* #define NO_UCPP_ERROR_FUNCTIONS */ |
| |
| /* |
| * Tokens (do not change the order unless checking operators_name[] in cpp.c) |
| * |
| * It is important that the token NONE is 0 |
| * Check the STRING_TOKEN macro |
| */ |
| #define CPPERR 512 |
| enum { |
| NONE, /* whitespace */ |
| NEWLINE, /* newline */ |
| COMMENT, /* comment */ |
| NUMBER, /* number constant */ |
| NAME, /* identifier */ |
| BUNCH, /* non-C characters */ |
| PRAGMA, /* a #pragma directive */ |
| CONTEXT, /* new file or #line */ |
| STRING, /* constant "xxx" */ |
| CHAR, /* constant 'xxx' */ |
| SLASH, /* / */ |
| ASSLASH, /* /= */ |
| MINUS, /* - */ |
| MMINUS, /* -- */ |
| ASMINUS, /* -= */ |
| ARROW, /* -> */ |
| PLUS, /* + */ |
| PPLUS, /* ++ */ |
| ASPLUS, /* += */ |
| LT, /* < */ |
| LEQ, /* <= */ |
| LSH, /* << */ |
| ASLSH, /* <<= */ |
| GT, /* > */ |
| GEQ, /* >= */ |
| RSH, /* >> */ |
| ASRSH, /* >>= */ |
| ASGN, /* = */ |
| SAME, /* == */ |
| #ifdef CAST_OP |
| CAST, /* => */ |
| #endif |
| NOT, /* ~ */ |
| NEQ, /* != */ |
| AND, /* & */ |
| LAND, /* && */ |
| ASAND, /* &= */ |
| OR, /* | */ |
| LOR, /* || */ |
| ASOR, /* |= */ |
| PCT, /* % */ |
| ASPCT, /* %= */ |
| STAR, /* * */ |
| ASSTAR, /* *= */ |
| CIRC, /* ^ */ |
| ASCIRC, /* ^= */ |
| LNOT, /* ! */ |
| ASNOT, /* ~= */ |
| LBRA, /* { */ |
| RBRA, /* } */ |
| LBRK, /* [ */ |
| RBRK, /* ] */ |
| LPAR, /* ( */ |
| RPAR, /* ) */ |
| COMMA, /* , */ |
| QUEST, /* ? */ |
| SEMIC, /* ; */ |
| COLON, /* : */ |
| DOT, /* . */ |
| MDOTS, /* ... */ |
| SHARP, /* # */ |
| DSHARP, /* ## */ |
| |
| OPT_NONE, /* optional space to separate tokens in text output */ |
| |
| DIGRAPH_TOKENS, /* there begin digraph tokens */ |
| |
| /* for DIG_*, do not change order, unless checking undig() in cpp.c */ |
| DIG_LBRK, /* <: */ |
| DIG_RBRK, /* :> */ |
| DIG_LBRA, /* <% */ |
| DIG_RBRA, /* %> */ |
| DIG_SHARP, /* %: */ |
| DIG_DSHARP, /* %:%: */ |
| |
| DIGRAPH_TOKENS_END, /* digraph tokens end here */ |
| |
| LAST_MEANINGFUL_TOKEN, /* reserved words will go there */ |
| |
| MACROARG, /* special token for representing macro arguments */ |
| |
| UPLUS = CPPERR, /* unary + */ |
| UMINUS /* unary - */ |
| }; |
| |
| #include <stdio.h> |
| #include <setjmp.h> |
| #include "tune.h" |
| |
| struct token { |
| int type; |
| long line; |
| char *name; |
| }; |
| |
| struct token_fifo { |
| struct token *t; |
| size_t nt, art; |
| }; |
| |
| struct lexer_state { |
| /* input control */ |
| FILE *input; |
| #ifndef NO_UCPP_BUF |
| unsigned char *input_buf; |
| #ifdef UCPP_MMAP |
| int from_mmap; |
| unsigned char *input_buf_sav; |
| #endif |
| #endif |
| unsigned char *input_string; |
| size_t ebuf; |
| size_t pbuf; |
| int lka[2]; |
| int nlka; |
| int macfile; |
| int last; |
| int discard; |
| unsigned long utf8; |
| unsigned char copy_line[COPY_LINE_LENGTH]; |
| int cli; |
| |
| /* output control */ |
| |
| FILE *output; |
| struct token_fifo *output_fifo, *toplevel_of; |
| #ifndef NO_UCPP_BUF |
| unsigned char *output_buf; |
| #endif |
| size_t sbuf; |
| |
| /* token control */ |
| struct token *ctok; |
| struct token *save_ctok; |
| int tknl; |
| int ltwnl; |
| int pending_token; |
| #ifdef INMACRO_FLAG |
| int inmacro; |
| long macro_count; |
| #endif |
| |
| /* lexer options */ |
| long line; |
| long oline; |
| unsigned long flags; |
| long count_trigraphs; |
| struct garbage_fifo *gf; |
| int ifnest; |
| int condnest; |
| int condcomp; |
| int condmet; |
| unsigned long condf[2]; |
| }; |
| |
| /* |
| * Flags for struct lexer_state |
| */ |
| /* warning flags */ |
| #define WARN_STANDARD 0x000001UL /* emit standard warnings */ |
| #define WARN_ANNOYING 0x000002UL /* emit annoying warnings */ |
| #define WARN_TRIGRAPHS 0x000004UL /* warn when trigraphs are used */ |
| #define WARN_TRIGRAPHS_MORE 0x000008UL /* extra-warn for trigraphs */ |
| #define WARN_PRAGMA 0x000010UL /* warn for pragmas in non-lexer mode */ |
| |
| /* error flags */ |
| #define FAIL_SHARP 0x000020UL /* emit errors on rogue '#' */ |
| #define CCHARSET 0x000040UL /* emit errors on non-C characters */ |
| |
| /* emission flags */ |
| #define DISCARD_COMMENTS 0x000080UL /* discard comments from text output */ |
| #define CPLUSPLUS_COMMENTS 0x000100UL /* understand C++-like comments */ |
| #define LINE_NUM 0x000200UL /* emit #line directives in output */ |
| #define GCC_LINE_NUM 0x000400UL /* same as #line, with gcc-syntax */ |
| |
| /* language flags */ |
| #define HANDLE_ASSERTIONS 0x000800UL /* understand assertions */ |
| #define HANDLE_PRAGMA 0x001000UL /* emit PRAGMA tokens in lexer mode */ |
| #define MACRO_VAARG 0x002000UL /* understand macros with '...' */ |
| #define UTF8_SOURCE 0x004000UL /* identifiers are in UTF8 encoding */ |
| #define HANDLE_TRIGRAPHS 0x008000UL /* handle trigraphs */ |
| |
| /* global ucpp behaviour */ |
| #define LEXER 0x010000UL /* behave as a lexer */ |
| #define KEEP_OUTPUT 0x020000UL /* emit the result of preprocessing */ |
| #define COPY_LINE 0x040000UL /* make a copy of the parsed line */ |
| |
| /* internal flags */ |
| #define READ_AGAIN 0x080000UL /* emit again the last token */ |
| #define TEXT_OUTPUT 0x100000UL /* output text */ |
| |
| /* |
| * Public function prototypes |
| */ |
| |
| #ifndef NO_UCPP_BUF |
| void flush_output(struct lexer_state *); |
| #endif |
| |
| void init_assertions(void); |
| int make_assertion(char *); |
| int destroy_assertion(char *); |
| void print_assertions(void); |
| |
| void init_macros(void); |
| int define_macro(struct lexer_state *, char *); |
| int undef_macro(struct lexer_state *, char *); |
| void print_defines(void); |
| |
| void set_init_filename(char *, int); |
| void init_cpp(void); |
| void init_include_path(char *[]); |
| void init_lexer_state(struct lexer_state *); |
| void init_lexer_mode(struct lexer_state *); |
| void free_lexer_state(struct lexer_state *); |
| int lex(struct lexer_state *); |
| int check_cpp_errors(struct lexer_state *); |
| void add_incpath(char *); |
| void init_tables(int); |
| void enter_file(struct lexer_state *, unsigned long); |
| int cpp(struct lexer_state *); |
| |
| #ifdef UCPP_MMAP |
| FILE *fopen_mmap_file(char *); |
| void set_input_file(struct lexer_state *, FILE *); |
| #endif |
| |
| struct stack_context { |
| char *long_name, *name; |
| long line; |
| }; |
| struct stack_context *report_context(void); |
| |
| extern int no_special_macros, system_macros, |
| emit_dependencies, emit_defines, emit_assertions; |
| extern int c99_compliant, c99_hosted; |
| extern FILE *emit_output; |
| extern char *current_filename, *current_long_filename; |
| extern char *operators_name[]; |
| extern struct protect { |
| char *macro; |
| int state; |
| struct found_file *ff; |
| } protect_detect; |
| |
| void ucpp_ouch(char *, ...); |
| void ucpp_error(long, char *, ...); |
| void ucpp_warning(long, char *, ...); |
| |
| extern int *transient_characters; |
| |
| /* |
| * Errors from CPPERR_EOF and above are not real erros, only show-stoppers. |
| * Errors below CPPERR_EOF are real ones. |
| */ |
| #define CPPERR_NEST 900 |
| #define CPPERR_EOF 1000 |
| |
| /* |
| * This macro tells whether the name field of a given token type is |
| * relevant, or not. Irrelevant name field means that it might point |
| * to outerspace. |
| */ |
| #ifdef SEMPER_FIDELIS |
| #define STRING_TOKEN(x) ((x) == NONE || ((x) >= COMMENT && (x) <= CHAR)) |
| #else |
| #define STRING_TOKEN(x) ((x) >= NUMBER && (x) <= CHAR) |
| #endif |
| |
| #endif |