⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cccp.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* C Compatible Compiler Preprocessor (CCCP)Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.                    Written by Paul Rubin, June 1986		    Adapted to ANSI C, Richard Stallman, Jan 1987This program is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 1, or (at your option) anylater version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve what you give them.   Help stamp out software-hoarding!  */typedef unsigned char U_CHAR;#ifdef EMACS#define NO_SHORTNAMES#include "../src/config.h"#ifdef open#undef open#undef read#undef write#endif /* open */#endif /* EMACS */#ifndef EMACS#include "config.h"#endif /* not EMACS */#ifndef CC_INCLUDE_DIR#define CC_INCLUDE_DIR "/usr/include"#endif#ifndef STDC_VALUE#define STDC_VALUE 1#endif/* In case config.h defines these.  */#undef bcopy#undef bzero#undef bcmp#include <sys/types.h>#include <sys/stat.h>#include <ctype.h>#include <stdio.h>#include <signal.h>#ifndef VMS#include <sys/file.h>#ifndef USG#include <sys/time.h>		/* for __DATE__ and __TIME__ */#include <sys/resource.h>#else#define index strchr#define rindex strrchr#include <time.h>#include <fcntl.h>#endif /* USG */#endif /* not VMS */  /* VMS-specific definitions */#ifdef VMS#include <time.h>#include <errno.h>		/* This defines "errno" properly */#include <perror.h>		/* This defines sys_errlist/sys_nerr properly */#include <descrip.h>#define O_RDONLY	0	/* Open arg for Read/Only  */#define O_WRONLY	1	/* Open arg for Write/Only */#define read(fd,buf,size)	VAX11_C_read(fd,buf,size)#define write(fd,buf,size)	VAX11_C_write(fd,buf,size)#ifdef __GNUC__#define BSTRING			/* VMS/GCC supplies the bstring routines */#endif /* __GNUC__ */#endif /* VMS */#ifndef O_RDONLY#define O_RDONLY 0#endif #define max(a,b) ((a) > (b) ? (a) : (b))#ifndef S_ISREG#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)#endif/* External declarations.  */void bcopy (), bzero ();int bcmp ();extern char *getenv ();extern char *version_string;/* Forward declarations.  */struct directive;struct file_buf;struct arglist;struct argdata;int do_define (), do_line (), do_include (), do_undef (), do_error (),  do_pragma (), do_if (), do_xifdef (), do_else (),  do_elif (), do_endif (), do_sccs (), do_once ();struct hashnode *install ();struct hashnode *lookup ();char *xmalloc (), *xrealloc (), *xcalloc (), *savestring ();void fatal (), fancy_abort (), pfatal_with_name (), perror_with_name ();void macroexpand ();void dump_all_macros ();void conditional_skip ();void skip_if_group ();void output_line_command ();/* Last arg to output_line_command.  */enum file_change_code {same_file, enter_file, leave_file};int grow_outbuf ();int handle_directive ();void memory_full ();U_CHAR *macarg1 ();char *macarg ();U_CHAR *skip_to_end_of_comment ();U_CHAR *skip_quoted_string ();#ifndef FATAL_EXIT_CODE#define FATAL_EXIT_CODE 33	/* gnu cc command understands this */#endif#ifndef SUCCESS_EXIT_CODE#define SUCCESS_EXIT_CODE 0	/* 0 means success on Unix.  */#endif/* Name under which this program was invoked.  */char *progname;/* Nonzero means handle C++ comment syntax and use   extra default include directories for C++.  */int cplusplus;/* Current maximum length of directory names in the search path   for include files.  (Altered as we get more of them.)  */int max_include_len;/* Nonzero means copy comments into the output file.  */int put_out_comments = 0;/* Nonzero means don't process the ANSI trigraph sequences.  */int no_trigraphs = 0;/* Nonzero means print the names of included files rather than   the preprocessed output.  1 means just the #include "...",   2 means #include <...> as well.  */int print_deps = 0;/* Nonzero means don't output line number information.  */int no_line_commands;/* Nonzero means inhibit output of the preprocessed text   and instead output the definitions of all user-defined macros   in a form suitable for use as input to cccp.  */int dump_macros;/* Nonzero means give all the error messages the ANSI standard requires.  */int pedantic;/* Nonzero means don't print warning messages.  -w.  */int inhibit_warnings = 0;/* Nonzero means warn if slash-star appears in a comment.  */int warn_comments;/* Nonzero means warn if there are any trigraphs.  */int warn_trigraphs;/* Nonzero means try to imitate old fashioned non-ANSI preprocessor.  */int traditional;/* Nonzero causes output not to be done,   but directives such as #define that have side effects   are still obeyed.  */int no_output;/* I/O buffer structure.   The `fname' field is nonzero for source files and #include files   and for the dummy text used for -D and -U.   It is zero for rescanning results of macro expansion   and for expanding macro arguments.  */#define INPUT_STACK_MAX 200struct file_buf {  char *fname;  int lineno;  int length;  U_CHAR *buf;  U_CHAR *bufp;  /* Macro that this level is the expansion of.     Included so that we can reenable the macro     at the end of this level.  */  struct hashnode *macro;  /* Value of if_stack at start of this file.     Used to prohibit unmatched #endif (etc) in an include file.  */  struct if_stack *if_stack;  /* Object to be freed at end of input at this level.  */  U_CHAR *free_ptr;} instack[INPUT_STACK_MAX];/* Current nesting level of input sources.   `instack[indepth]' is the level currently being read.  */int indepth = -1;#define CHECK_DEPTH(code) \  if (indepth >= (INPUT_STACK_MAX - 1))					\    {									\      error_with_line (line_for_error (instack[indepth].lineno),	\		       "macro or #include recursion too deep");		\      code;								\    }/* Current depth in #include directives that use <...>.  */int system_include_depth = 0;typedef struct file_buf FILE_BUF;/* The output buffer.  Its LENGTH field is the amount of room allocated   for the buffer, not the number of chars actually present.  To get   that, subtract outbuf.buf from outbuf.bufp. */#define OUTBUF_SIZE 10	/* initial size of output buffer */FILE_BUF outbuf;/* Grow output buffer OBUF points at   so it can hold at least NEEDED more chars.  */#define check_expand(OBUF, NEEDED)  \  (((OBUF)->length - ((OBUF)->bufp - (OBUF)->buf) <= (NEEDED))   \   ? grow_outbuf ((OBUF), (NEEDED)) : 0)struct file_name_list  {    struct file_name_list *next;    char *fname;  };/* #include "file" looks in source file dir, then stack. *//* #include <file> just looks in the stack. *//* -I directories are added to the end, then the defaults are added. */struct file_name_list include_defaults[] =  {#ifndef VMS    { &include_defaults[1], GCC_INCLUDE_DIR },    { &include_defaults[2], CC_INCLUDE_DIR },    { 0, "/usr/local/include" }#else    { &include_defaults[1], "GNU_CC_INCLUDE:" },       /* GNU includes */    { &include_defaults[2], "SYS$SYSROOT:[SYSLIB.]" }, /* VAX-11 "C" includes */    { 0, "." }	/* This makes normal VMS filespecs work OK. The "." forces */		/* the file through hack_vms_include_specification */#endif /* VMS */  };/* These are used instead of the above, for C++.  */struct file_name_list cplusplus_include_defaults[] =  {#ifndef VMS    /* Pick up GNU C++ specific include files.  */    { &cplusplus_include_defaults[1], GPLUSPLUS_INCLUDE_DIR },    /* Use GNU CC specific header files.  */    { &cplusplus_include_defaults[2], GCC_INCLUDE_DIR },    { 0, CC_INCLUDE_DIR }#else    { &cplusplus_include_defaults[1], "GNU_GXX_INCLUDE:" },    { &cplusplus_include_defaults[2], "GNU_CC_INCLUDE:" },    /* VAX-11 C includes */    { &cplusplus_include_defaults[3], "SYS$SYSROOT:[SYSLIB.]" },    { 0, "." }	/* This makes normal VMS filespecs work OK */#endif /* VMS */  };struct file_name_list *include = 0;	/* First dir to search */	/* First dir to search for <file> */struct file_name_list *first_bracket_include = 0;struct file_name_list *last_include = 0;	/* Last in chain *//* List of included files that contained #once.  */struct file_name_list *dont_repeat_files = 0;/* List of other included files.  */struct file_name_list *all_include_files = 0;/* Structure allocated for every #define.  For a simple replacement   such as   	#define foo bar ,   nargs = -1, the `pattern' list is null, and the expansion is just   the replacement text.  Nargs = 0 means a functionlike macro with no args,   e.g.,       #define getchar() getc (stdin) .   When there are args, the expansion is the replacement text with the   args squashed out, and the reflist is a list describing how to   build the output from the input: e.g., "3 chars, then the 1st arg,   then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg".   The chars here come from the expansion.  Whatever is left of the   expansion after the last arg-occurrence is copied after that arg.   Note that the reflist can be arbitrarily long---   its length depends on the number of times the arguments appear in   the replacement text, not how many args there are.  Example:   #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and   pattern list     { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }   where (x, y) means (nchars, argno). */typedef struct definition DEFINITION;struct definition {  int nargs;  int length;			/* length of expansion string */  U_CHAR *expansion;  struct reflist {    struct reflist *next;    char stringify;		/* nonzero if this arg was preceded by a				   # operator. */    char raw_before;		/* Nonzero if a ## operator before arg. */    char raw_after;		/* Nonzero if a ## operator after arg. */    int nchars;			/* Number of literal chars to copy before				   this arg occurrence.  */    int argno;			/* Number of arg to substitute (origin-0) */  } *pattern;  /* Names of macro args, concatenated in reverse order     with comma-space between them.     The only use of this is that we warn on redefinition     if this differs between the old and new definitions.  */  U_CHAR *argnames;};/* different kinds of things that can appear in the value field   of a hash node.  Actually, this may be useless now. */union hashval {  int ival;  char *cpval;  DEFINITION *defn;};/* The structure of a node in the hash table.  The hash table   has entries for all tokens defined by #define commands (type T_MACRO),   plus some special tokens like __LINE__ (these each have their own   type, and the appropriate code is run when that type of node is seen.   It does not contain control words like "#define", which are recognized   by a separate piece of code. *//* different flavors of hash nodes --- also used in keyword table */enum node_type { T_DEFINE = 1,	/* the `#define' keyword */ T_INCLUDE,	/* the `#include' keyword */ T_IFDEF,	/* the `#ifdef' keyword */ T_IFNDEF,	/* the `#ifndef' keyword */ T_IF,		/* the `#if' keyword */ T_ELSE,	/* `#else' */ T_PRAGMA,	/* `#pragma' */ T_ELIF,	/* `#else' */ T_UNDEF,	/* `#undef' */ T_LINE,	/* `#line' */ T_ERROR,	/* `#error' */ T_ENDIF,	/* `#endif' */ T_SCCS,	/* `#sccs', used on system V.  */ T_IDENT,	/* `#ident', used on system V.  */ T_SPECLINE,	/* special symbol `__LINE__' */ T_DATE,	/* `__DATE__' */ T_FILE,	/* `__FILE__' */ T_BASE_FILE,	/* `__BASE_FILE__' */ T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */ T_VERSION,	/* `__VERSION__' */ T_TIME,	/* `__TIME__' */ T_CONST,	/* Constant value, used by `__STDC__' */ T_MACRO,	/* macro defined by `#define' */ T_DISABLED,	/* macro temporarily turned off for rescan */ T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */ T_UNUSED	/* Used for something not defined.  */ };struct hashnode {  struct hashnode *next;	/* double links for easy deletion */  struct hashnode *prev;  struct hashnode **bucket_hdr;	/* also, a back pointer to this node's hash				   chain is kept, in case the node is the head				   of the chain and gets deleted. */  enum node_type type;		/* type of special token */  int length;			/* length of token, for quick comparison */  U_CHAR *name;			/* the actual name */  union hashval value;		/* pointer to expansion, or whatever */};typedef struct hashnode HASHNODE;/* Some definitions for the hash table.  The hash function MUST be   computed as shown in hashf () below.  That is because the rescan   loop computes the hash value `on the fly' for most tokens,   in order to avoid the overhead of a lot of procedure calls to   the hashf () function.  Hashf () only exists for the sake of   politeness, for use when speed isn't so important. */#define HASHSIZE 1403HASHNODE *hashtab[HASHSIZE];#define HASHSTEP(old, c) ((old << 2) + c)#define MAKE_POS(v) (v & ~0x80000000) /* make number positive *//* Symbols to predefine.  */#ifdef CPP_PREDEFINESchar *predefs = CPP_PREDEFINES;#elsechar *predefs = "";#endif/* `struct directive' defines one #-directive, including how to handle it.  */struct directive {  int length;			/* Length of name */  int (*func)();		/* Function to handle directive */  char *name;			/* Name of directive */  enum node_type type;		/* Code which describes which directive. */  char angle_brackets;		/* Nonzero => <...> is special.  */  char traditional_comments;	/* Nonzero: keep comments if -traditional.  */  char pass_thru;		/* Copy preprocessed directive to output file.  */};/* Here is the actual list of #-directives, most-often-used first.  */struct directive directive_table[] = {  {  6, do_define, "define", T_DEFINE, 0, 1},  {  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, 1},  {  5, do_undef, "undef", T_UNDEF},  {  5, do_error, "error", T_ERROR},#ifdef SCCS_DIRECTIVE  {  4, do_sccs, "sccs", T_SCCS},#endif  {  6, do_pragma, "pragma", T_PRAGMA, 0, 0, 1},  {  -1, 0, "", T_UNUSED},};/* 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.  */U_CHAR is_hor_space[256];/* table to tell if c is horizontal or vertical space.  */U_CHAR is_space[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)  int errors = 0;			/* Error counter for exit code *//* Zero means dollar signs are punctuation.   -$ stores 0; -traditional, stores 1.  Default is 1 for VMS, 0 otherwise.   This must be 0 for correct processing of this ANSI C program:	#define foo(a) #a	#define lose(b) foo(b)

⌨️ 快捷键说明

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