+/* #include types. */
+enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE};
+
+typedef struct toklist toklist;
+struct toklist
+{
+ cpp_token *first;
+ cpp_token *limit;
+};
+
+typedef struct cpp_context cpp_context;
+struct cpp_context
+{
+ /* Doubly-linked list. */
+ cpp_context *next, *prev;
+
+ /* Contexts other than the base context are contiguous tokens.
+ e.g. macro expansions, expanded argument tokens. */
+ struct toklist list;
+
+ /* For a macro context, these are the macro and its arguments. */
+ cpp_macro *macro;
+};
+
+struct lexer_state
+{
+ /* Nonzero if first token on line is CPP_HASH. */
+ unsigned char in_directive;
+
+ /* True if we are skipping a failed conditional group. */
+ unsigned char skipping;
+
+ /* Nonzero if in a directive that takes angle-bracketed headers. */
+ unsigned char angled_headers;
+
+ /* Nonzero to save comments. Turned off if discard_comments, and in
+ all directives apart from #define. */
+ unsigned char save_comments;
+
+ /* If nonzero the next token is at the beginning of the line. */
+ unsigned char next_bol;
+
+ /* Nonzero if we're mid-comment. */
+ unsigned char lexing_comment;
+
+ /* Nonzero if lexing __VA_ARGS__ is valid. */
+ unsigned char va_args_ok;
+
+ /* Nonzero if lexing poisoned identifiers is valid. */
+ unsigned char poisoned_ok;
+
+ /* Nonzero to prevent macro expansion. */
+ unsigned char prevent_expansion;
+
+ /* Nonzero when parsing arguments to a function-like macro. */
+ unsigned char parsing_args;
+
+ /* Nonzero when in a # NUMBER directive. */
+ unsigned char line_extension;
+};
+
+/* Special nodes - identifiers with predefined significance. */
+struct spec_nodes
+{
+ cpp_hashnode *n_L; /* L"str" */
+ cpp_hashnode *n_defined; /* defined operator */
+ cpp_hashnode *n_true; /* C++ keyword true */
+ cpp_hashnode *n_false; /* C++ keyword false */
+ cpp_hashnode *n__Pragma; /* _Pragma operator */
+ cpp_hashnode *n__STRICT_ANSI__; /* STDC_0_IN_SYSTEM_HEADERS */
+ cpp_hashnode *n__CHAR_UNSIGNED__; /* plain char is unsigned */
+ cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */
+};
+
+struct cpp_buffer
+{
+ const unsigned char *cur; /* current position */
+ const unsigned char *rlimit; /* end of valid data */
+ const unsigned char *line_base; /* start of current line */
+ cppchar_t read_ahead; /* read ahead character */
+ cppchar_t extra_char; /* extra read-ahead for long tokens. */
+
+ struct cpp_reader *pfile; /* Owns this buffer. */
+ struct cpp_buffer *prev;
+
+ const unsigned char *buf; /* entire buffer */
+
+ /* Filename specified with #line command. */
+ const char *nominal_fname;
+
+ /* Pointer into the include table. Used for include_next and
+ to record control macros. */
+ struct include_file *inc;
+
+ /* Value of if_stack at start of this file.
+ Used to prohibit unmatched #endif (etc) in an include file. */
+ struct if_stack *if_stack;
+
+ /* Token column position adjustment owing to tabs in whitespace. */
+ unsigned int col_adjust;
+
+ /* The line of the buffer that we return to after a #include.
+ Strictly this is redundant, since it can be calculated from the
+ line maps, but it is clearest to save it here. */
+ unsigned int return_to_line;
+
+ /* Contains PREV_WHITE and/or AVOID_LPASTE. */
+ unsigned char saved_flags;
+
+ /* Because of the way the lexer works, -Wtrigraphs can sometimes
+ warn twice for the same trigraph. This helps prevent that. */
+ const unsigned char *last_Wtrigraphs;
+
+ /* True if we have already warned about C++ comments in this file.
+ The warning happens only for C89 extended mode with -pedantic on,
+ or for -Wtraditional, and only once per file (otherwise it would
+ be far too noisy). */
+ unsigned char warned_cplusplus_comments;
+
+ /* True if we don't process trigraphs and escaped newlines. True
+ for preprocessed input, command line directives, and _Pragma
+ buffers. */
+ unsigned char from_stage3;
+
+ /* 1 = system header file, 2 = C system header file used for C++. */
+ unsigned char sysp;
+
+ /* Nonzero means we have printed (while error reporting) a list of
+ containing files that matches the current status. */
+ unsigned char include_stack_listed;
+
+ /* Nonzero means that the directory to start searching for ""
+ include files has been calculated and stored in "dir" below. */
+ unsigned char search_cached;
+
+ /* At EOF, a buffer is automatically popped. If RETURN_AT_EOF is
+ true, a CPP_EOF token is then returned. Otherwise, the next
+ token from the enclosing buffer is returned. */
+ bool return_at_eof;
+
+ /* Buffer type. */
+ ENUM_BITFIELD (cpp_buffer_type) type : 8;
+
+ /* The directory of the this buffer's file. Its NAME member is not
+ allocated, so we don't need to worry about freeing it. */
+ struct search_path dir;
+};
+
+/* A cpp_reader encapsulates the "state" of a pre-processor run.
+ Applying cpp_get_token repeatedly yields a stream of pre-processor
+ tokens. Usually, there is only one cpp_reader object active. */
+
+struct cpp_reader