316 lines · 8.1 KB · C
RawDownload
/* * (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	512enum {	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_BUFvoid 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_MMAPFILE *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