blob: 4f0a7092dfbe4a55a5ac4f61d6be81032832ada6 [file] [log] [blame]
/*
* (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