cccp.c

来自「GCC编译器源代码」· C语言 代码 · 共 2,126 行 · 第 1/5 页

C
2,126
字号
/* Nonzero means inhibit macroexpansion of what seem to be   assertion tests, in rescan.  For #if.  */static int assertions_flag;/* `struct directive' defines one #-directive, including how to handle it.  */#define DO_PROTO PROTO((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *))struct directive {  int length;			/* Length of name */  int (*func) DO_PROTO;	/* Function to handle directive */  char *name;			/* Name of directive */  enum node_type type;		/* Code which describes which directive.  */};#define IS_INCLUDE_DIRECTIVE_TYPE(t) (T_INCLUDE <= (t) && (t) <= T_IMPORT)/* These functions are declared to return int instead of void since they   are going to be placed in the table and some old compilers have trouble with   pointers to functions returning void.  */static int do_assert DO_PROTO;static int do_define DO_PROTO;static int do_elif DO_PROTO;static int do_else DO_PROTO;static int do_endif DO_PROTO;static int do_error DO_PROTO;static int do_ident DO_PROTO;static int do_if DO_PROTO;static int do_include DO_PROTO;static int do_line DO_PROTO;static int do_pragma DO_PROTO;#ifdef SCCS_DIRECTIVEstatic int do_sccs DO_PROTO;#endifstatic int do_unassert DO_PROTO;static int do_undef DO_PROTO;static int do_warning DO_PROTO;static int do_xifdef DO_PROTO;/* Here is the actual list of #-directives, most-often-used first.  */static struct directive directive_table[] = {  {  6, do_define, "define", T_DEFINE},  {  2, do_if, "if", T_IF},  {  5, do_xifdef, "ifdef", T_IFDEF},  {  6, do_xifdef, "ifndef", T_IFNDEF},  {  5, do_endif, "endif", T_ENDIF},  {  4, do_else, "else", T_ELSE},  {  4, do_elif, "elif", T_ELIF},  {  4, do_line, "line", T_LINE},  {  7, do_include, "include", T_INCLUDE},  { 12, do_include, "include_next", T_INCLUDE_NEXT},  {  6, do_include, "import", T_IMPORT},  {  5, do_undef, "undef", T_UNDEF},  {  5, do_error, "error", T_ERROR},  {  7, do_warning, "warning", T_WARNING},#ifdef SCCS_DIRECTIVE  {  4, do_sccs, "sccs", T_SCCS},#endif  {  6, do_pragma, "pragma", T_PRAGMA},  {  5, do_ident, "ident", T_IDENT},  {  6, do_assert, "assert", T_ASSERT},  {  8, do_unassert, "unassert", T_UNASSERT},  {  -1, 0, "", T_UNUSED},};/* When a directive handler is called,   this points to the # (or the : of the %:) that started the directive.  */U_CHAR *directive_start;/* table to tell if char can be part of a C identifier.  */U_CHAR is_idchar[256];/* table to tell if char can be first char of a c identifier.  */U_CHAR is_idstart[256];/* table to tell if c is horizontal space.  */static U_CHAR is_hor_space[256];/* table to tell if c is horizontal or vertical space.  */U_CHAR is_space[256];/* names of some characters */static char *char_name[256];#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)  static int errors = 0;			/* Error counter for exit code *//* Name of output file, for error messages.  */static char *out_fname;/* Stack of conditionals currently in progress   (including both successful and failing conditionals).  */struct if_stack {  struct if_stack *next;	/* for chaining to the next stack frame */  char *fname;		/* copied from input when frame is made */  int lineno;			/* similarly */  int if_succeeded;		/* true if a leg of this if-group				    has been passed through rescan */  U_CHAR *control_macro;	/* For #ifndef at start of file,				   this is the macro name tested.  */  enum node_type type;		/* type of last directive seen in this group */};typedef struct if_stack IF_STACK_FRAME;static IF_STACK_FRAME *if_stack = NULL;/* Buffer of -M output.  */static char *deps_buffer;/* Number of bytes allocated in above.  */static int deps_allocated_size;/* Number of bytes used.  */static int deps_size;/* Number of bytes since the last newline.  */static int deps_column;/* Nonzero means -I- has been seen,   so don't look for #include "foo" the source-file directory.  */static int ignore_srcdir;static int safe_read PROTO((int, char *, int));static void safe_write PROTO((int, char *, int));int main PROTO((int, char **));static void path_include PROTO((char *));static U_CHAR *index0 PROTO((U_CHAR *, int, size_t));static void trigraph_pcp PROTO((FILE_BUF *));static void newline_fix PROTO((U_CHAR *));static void name_newline_fix PROTO((U_CHAR *));static char *get_lintcmd PROTO((U_CHAR *, U_CHAR *, U_CHAR **, int *, int *));static void rescan PROTO((FILE_BUF *, int));static FILE_BUF expand_to_temp_buffer PROTO((U_CHAR *, U_CHAR *, int, int));static int handle_directive PROTO((FILE_BUF *, FILE_BUF *));static struct tm *timestamp PROTO((void));static void special_symbol PROTO((HASHNODE *, FILE_BUF *));static int is_system_include PROTO((char *));static char *base_name PROTO((char *));static int absolute_filename PROTO((char *));static size_t simplify_filename PROTO((char *));static char *read_filename_string PROTO((int, FILE *));static struct file_name_map *read_name_map PROTO((char *));static int open_include_file PROTO((char *, struct file_name_list *, U_CHAR *, struct include_file **));static char *remap_include_file PROTO((char *, struct file_name_list *));static int lookup_ino_include PROTO((struct include_file *));static void finclude PROTO((int, struct include_file *, FILE_BUF *, int, struct file_name_list *));static void record_control_macro PROTO((struct include_file *, U_CHAR *));static char *check_precompiled PROTO((int, struct stat *, char *, char **));static int check_preconditions PROTO((char *));static void pcfinclude PROTO((U_CHAR *, U_CHAR *, U_CHAR *, FILE_BUF *));static void pcstring_used PROTO((HASHNODE *));static void write_output PROTO((void));static void pass_thru_directive PROTO((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *));static MACRODEF create_definition PROTO((U_CHAR *, U_CHAR *, FILE_BUF *));static int check_macro_name PROTO((U_CHAR *, char *));static int compare_defs PROTO((DEFINITION *, DEFINITION *));static int comp_def_part PROTO((int, U_CHAR *, int, U_CHAR *, int, int));static DEFINITION *collect_expansion  PROTO((U_CHAR *, U_CHAR *, int, struct arglist *));int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));static int compare_token_lists PROTO((struct arglist *, struct arglist *));static struct arglist *read_token_list PROTO((U_CHAR **, U_CHAR *, int *));static void free_token_list PROTO((struct arglist *));static ASSERTION_HASHNODE *assertion_install PROTO((U_CHAR *, int, int));static ASSERTION_HASHNODE *assertion_lookup PROTO((U_CHAR *, int, int));static void delete_assertion PROTO((ASSERTION_HASHNODE *));static void do_once PROTO((void));static HOST_WIDE_INT eval_if_expression PROTO((U_CHAR *, int));static void conditional_skip PROTO((FILE_BUF *, int, enum node_type, U_CHAR *, FILE_BUF *));static void skip_if_group PROTO((FILE_BUF *, int, FILE_BUF *));static void validate_else PROTO((U_CHAR *, U_CHAR *));static U_CHAR *skip_to_end_of_comment PROTO((FILE_BUF *, int *, int));static U_CHAR *skip_quoted_string PROTO((U_CHAR *, U_CHAR *, int, int *, int *, int *));static char *quote_string PROTO((char *, char *));static U_CHAR *skip_paren_group PROTO((FILE_BUF *));/* Last arg to output_line_directive.  */enum file_change_code {same_file, enter_file, leave_file};static void output_line_directive PROTO((FILE_BUF *, FILE_BUF *, int, enum file_change_code));static void macroexpand PROTO((HASHNODE *, FILE_BUF *));struct argdata;static char *macarg PROTO((struct argdata *, int));static U_CHAR *macarg1 PROTO((U_CHAR *, U_CHAR *, int *, int *, int *, int));static int discard_comments PROTO((U_CHAR *, int, int));static int change_newlines PROTO((U_CHAR *, int));char *my_strerror PROTO((int));void error PRINTF_PROTO_1((char *, ...));static void verror PROTO((char *, va_list));static void error_from_errno PROTO((char *));void warning PRINTF_PROTO_1((char *, ...));static void vwarning PROTO((char *, va_list));static void error_with_line PRINTF_PROTO_2((int, char *, ...));static void verror_with_line PROTO((int, char *, va_list));static void vwarning_with_line PROTO((int, char *, va_list));static void warning_with_line PRINTF_PROTO_2((int, char *, ...));void pedwarn PRINTF_PROTO_1((char *, ...));void pedwarn_with_line PRINTF_PROTO_2((int, char *, ...));static void pedwarn_with_file_and_line PRINTF_PROTO_3((char *, int, char *, ...));static void print_containing_files PROTO((void));static int line_for_error PROTO((int));static int grow_outbuf PROTO((FILE_BUF *, int));static HASHNODE *install PROTO((U_CHAR *, int, enum node_type, char *, int));HASHNODE *lookup PROTO((U_CHAR *, int, int));static void delete_macro PROTO((HASHNODE *));static int hashf PROTO((U_CHAR *, int, int));static void dump_single_macro PROTO((HASHNODE *, FILE *));static void dump_all_macros PROTO((void));static void dump_defn_1 PROTO((U_CHAR *, int, int, FILE *));static void dump_arg_n PROTO((DEFINITION *, int, FILE *));static void initialize_char_syntax PROTO((void));static void initialize_builtins PROTO((FILE_BUF *, FILE_BUF *));static void make_definition PROTO((char *, FILE_BUF *));static void make_undef PROTO((char *, FILE_BUF *));static void make_assertion PROTO((char *, char *));static struct file_name_list *new_include_prefix PROTO((struct file_name_list *, char *, char *, char *));static void append_include_chain PROTO((struct file_name_list *, struct file_name_list *));static int quote_string_for_make PROTO((char *, char *));static void deps_output PROTO((char *, int));static void fatal PRINTF_PROTO_1((char *, ...)) __attribute__ ((noreturn));void fancy_abort PROTO((void)) __attribute__ ((noreturn));static void perror_with_name PROTO((char *));static void pfatal_with_name PROTO((char *)) __attribute__ ((noreturn));static void pipe_closed PROTO((int)) __attribute__ ((noreturn));static void memory_full PROTO((void)) __attribute__ ((noreturn));GENERIC_PTR xmalloc PROTO((size_t));static GENERIC_PTR xrealloc PROTO((GENERIC_PTR, size_t));static GENERIC_PTR xcalloc PROTO((size_t, size_t));static char *savestring PROTO((char *));/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,   retrying if necessary.  If MAX_READ_LEN is defined, read at most   that bytes at a time.  Return a negative value if an error occurs,   otherwise return the actual number of bytes read,   which must be LEN unless end-of-file was reached.  */static intsafe_read (desc, ptr, len)     int desc;     char *ptr;     int len;{  int left, rcount, nchars;  left = len;  while (left > 0) {    rcount = left;#ifdef MAX_READ_LEN    if (rcount > MAX_READ_LEN)      rcount = MAX_READ_LEN;#endif    nchars = read (desc, ptr, rcount);    if (nchars < 0)      {#ifdef EINTR	if (errno == EINTR)	  continue;#endif	return nchars;      }    if (nchars == 0)      break;    ptr += nchars;    left -= nchars;  }  return len - left;}/* Write LEN bytes at PTR to descriptor DESC,   retrying if necessary, and treating any real error as fatal.   If MAX_WRITE_LEN is defined, write at most that many bytes at a time.  */static voidsafe_write (desc, ptr, len)     int desc;     char *ptr;     int len;{  int wcount, written;  while (len > 0) {    wcount = len;#ifdef MAX_WRITE_LEN    if (wcount > MAX_WRITE_LEN)      wcount = MAX_WRITE_LEN;#endif    written = write (desc, ptr, wcount);    if (written < 0)      {#ifdef EINTR	if (errno == EINTR)	  continue;#endif	pfatal_with_name (out_fname);      }    ptr += written;    len -= written;  }}intmain (argc, argv)     int argc;     char **argv;{  struct stat st;  char *in_fname;  char *cp;  int f, i;  FILE_BUF *fp;  char **pend_files = (char **) xmalloc (argc * sizeof (char *));  char **pend_defs = (char **) xmalloc (argc * sizeof (char *));  char **pend_undefs = (char **) xmalloc (argc * sizeof (char *));  char **pend_assertions = (char **) xmalloc (argc * sizeof (char *));  char **pend_includes = (char **) xmalloc (argc * sizeof (char *));  /* Record the option used with each element of pend_assertions.     This is preparation for supporting more than one option for making     an assertion.  */  char **pend_assertion_options = (char **) xmalloc (argc * sizeof (char *));  int inhibit_predefs = 0;  int no_standard_includes = 0;  int no_standard_cplusplus_includes = 0;  int missing_newline = 0;  /* Non-0 means don't output the preprocessed program.  */  int inhibit_output = 0;  /* Non-0 means -v, so print the full set of include dirs.  */  int verbose = 0;  /* File name which deps are being written to.     This is 0 if deps are being written to stdout.  */  char *deps_file = 0;  /* Fopen file mode to open deps_file with.  */  char *deps_mode = "a";  /* Stream on which to print the dependency information.  */  FILE *deps_stream = 0;  /* Target-name to write with the dependency information.  */  char *deps_target = 0;#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)  /* Get rid of any avoidable limit on stack size.  */  {    struct rlimit rlim;    /* Set the stack limit huge so that alloca (particularly stringtab       in dbxread.c) does not fail.  */    getrlimit (RLIMIT_STACK, &rlim);    rlim.rlim_cur = rlim.rlim_max;    setrlimit (RLIMIT_STACK, &rlim);  }#endif#ifdef SIGPIPE  signal (SIGPIPE, pipe_closed);#endif  progname = base_name (argv[0]);#ifdef VMS  {    /* Remove extension from PROGNAME.  */    char *p;    char *s = progname = savestring (progname);    if ((p = rindex (s, ';')) != 0) *p = '\0';	/* strip version number */    if ((p = rindex (s, '.')) != 0		/* strip type iff ".exe" */	&& (p[1] == 'e' || p[1] == 'E')	&& (p[2] == 'x' || p[2] == 'X')	&& (p[3] == 'e' || p[3] == 'E')	&& !p[4])      *p = '\0';  }#endif  in_fname = NULL;  out_fname = NULL;  /* Initialize is_idchar.  */  initialize_char_syntax ();  no_line_directives = 0;  no_trigraphs = 1;  dump_macros = dump_none;  no_output = 0;  cplusplus = 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?