cccp.c

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

C
2,126
字号
  /* Initialize output buffer */  outbuf.buf = (U_CHAR *) xmalloc (OUTBUF_SIZE);  outbuf.bufp = outbuf.buf;  outbuf.length = OUTBUF_SIZE;  /* Do partial setup of input buffer for the sake of generating     early #line directives (when -g is in effect).  */  fp = &instack[++indepth];  if (in_fname == NULL)    in_fname = "";  fp->nominal_fname = fp->fname = in_fname;  fp->lineno = 0;  /* In C++, wchar_t is a distinct basic type, and we can expect     __wchar_t to be defined by cc1plus.  */  if (cplusplus)    wchar_type = "__wchar_t";  /* Install __LINE__, etc.  Must follow initialize_char_syntax     and option processing.  */  initialize_builtins (fp, &outbuf);  /* Do standard #defines and assertions     that identify system and machine type.  */  if (!inhibit_predefs) {    char *p = (char *) alloca (strlen (predefs) + 1);    strcpy (p, predefs);    while (*p) {      char *q;      while (*p == ' ' || *p == '\t')	p++;      /* Handle -D options.  */       if (p[0] == '-' && p[1] == 'D') {	q = &p[2];	while (*p && *p != ' ' && *p != '\t')	  p++;	if (*p != 0)	  *p++= 0;	if (debug_output)	  output_line_directive (fp, &outbuf, 0, same_file);	make_definition (q, &outbuf);	while (*p == ' ' || *p == '\t')	  p++;      } else if (p[0] == '-' && p[1] == 'A') {	/* Handle -A options (assertions).  */ 	char *assertion;	char *past_name;	char *value;	char *past_value;	char *termination;	int save_char;	assertion = &p[2];	past_name = assertion;	/* Locate end of name.  */	while (*past_name && *past_name != ' '	       && *past_name != '\t' && *past_name != '(')	  past_name++;	/* Locate `(' at start of value.  */	value = past_name;	while (*value && (*value == ' ' || *value == '\t'))	  value++;	if (*value++ != '(')	  abort ();	while (*value && (*value == ' ' || *value == '\t'))	  value++;	past_value = value;	/* Locate end of value.  */	while (*past_value && *past_value != ' '	       && *past_value != '\t' && *past_value != ')')	  past_value++;	termination = past_value;	while (*termination && (*termination == ' ' || *termination == '\t'))	  termination++;	if (*termination++ != ')')	  abort ();	if (*termination && *termination != ' ' && *termination != '\t')	  abort ();	/* Temporarily null-terminate the value.  */	save_char = *termination;	*termination = '\0';	/* Install the assertion.  */	make_assertion ("-A", assertion);	*termination = (char) save_char;	p = termination;	while (*p == ' ' || *p == '\t')	  p++;      } else {	abort ();      }    }  }  /* Now handle the command line options.  */  /* Do -U's, -D's and -A's in the order they were seen.  */  for (i = 1; i < argc; i++) {    if (pend_undefs[i]) {      if (debug_output)        output_line_directive (fp, &outbuf, 0, same_file);      make_undef (pend_undefs[i], &outbuf);    }    if (pend_defs[i]) {      if (debug_output)        output_line_directive (fp, &outbuf, 0, same_file);      make_definition (pend_defs[i], &outbuf);    }    if (pend_assertions[i])      make_assertion (pend_assertion_options[i], pend_assertions[i]);  }  done_initializing = 1;  { /* Read the appropriate environment variable and if it exists       replace include_defaults with the listed path.  */    char *epath = 0;    switch ((objc << 1) + cplusplus)      {      case 0:	epath = getenv ("C_INCLUDE_PATH");	break;      case 1:	epath = getenv ("CPLUS_INCLUDE_PATH");	break;      case 2:	epath = getenv ("OBJC_INCLUDE_PATH");	break;      case 3:	epath = getenv ("OBJCPLUS_INCLUDE_PATH");	break;      }    /* If the environment var for this language is set,       add to the default list of include directories.  */    if (epath) {      int num_dirs;      char *startp, *endp;      for (num_dirs = 1, startp = epath; *startp; startp++)	if (*startp == PATH_SEPARATOR)	  num_dirs++;      include_defaults	= (struct default_include *) xmalloc ((num_dirs					       * sizeof (struct default_include))					      + sizeof (include_defaults_array));      startp = endp = epath;      num_dirs = 0;      while (1) {	char c = *endp++;	if (c == PATH_SEPARATOR || !c) {	  endp[-1] = 0;	  include_defaults[num_dirs].fname	    = startp == endp ? "." : savestring (startp);	  endp[-1] = c;	  include_defaults[num_dirs].component = 0;	  include_defaults[num_dirs].cplusplus = cplusplus;	  include_defaults[num_dirs].cxx_aware = 1;	  num_dirs++;	  if (!c)	    break;	  startp = endp;	}      }      /* Put the usual defaults back in at the end.  */      bcopy ((char *) include_defaults_array,	     (char *) &include_defaults[num_dirs],	     sizeof (include_defaults_array));    }  }  append_include_chain (before_system, last_before_system);  first_system_include = before_system;  /* Unless -fnostdinc,     tack on the standard include file dirs to the specified list */  if (!no_standard_includes) {    struct default_include *p = include_defaults;    char *specd_prefix = include_prefix;    char *default_prefix = savestring (GCC_INCLUDE_DIR);    int default_len = 0;    /* Remove the `include' from /usr/local/lib/gcc.../include.  */    if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {      default_len = strlen (default_prefix) - 7;      default_prefix[default_len] = 0;    }    /* Search "translated" versions of GNU directories.       These have /usr/local/lib/gcc... replaced by specd_prefix.  */    if (specd_prefix != 0 && default_len != 0)      for (p = include_defaults; p->fname; p++) {	/* Some standard dirs are only for C++.  */	if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) {	  /* Does this dir start with the prefix?  */	  if (!strncmp (p->fname, default_prefix, default_len)) {	    /* Yes; change prefix and add to search list.  */	    struct file_name_list *new	      = new_include_prefix (NULL_PTR, NULL_PTR, specd_prefix,				    p->fname + default_len);	    if (new) {	      new->c_system_include_path = !p->cxx_aware;	      append_include_chain (new, new);	      if (first_system_include == 0)		first_system_include = new;	    }	  }	}      }    /* Search ordinary names for GNU include directories.  */    for (p = include_defaults; p->fname; p++) {      /* Some standard dirs are only for C++.  */      if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) {	struct file_name_list *new	  = new_include_prefix (NULL_PTR, p->component, "", p->fname);	if (new) {	  new->c_system_include_path = !p->cxx_aware;	  append_include_chain (new, new);	  if (first_system_include == 0)	    first_system_include = new;	}      }    }  }  /* Tack the after_include chain at the end of the include chain.  */  append_include_chain (after_include, last_after_include);  if (first_system_include == 0)    first_system_include = after_include;  /* With -v, print the list of dirs to search.  */  if (verbose) {    struct file_name_list *p;    fprintf (stderr, "#include \"...\" search starts here:\n");    for (p = include; p; p = p->next) {      if (p == first_bracket_include)	fprintf (stderr, "#include <...> search starts here:\n");      if (!p->fname[0])	fprintf (stderr, " .\n");      else if (!strcmp (p->fname, "/") || !strcmp (p->fname, "//"))	fprintf (stderr, " %s\n", p->fname);      else	/* Omit trailing '/'.  */	fprintf (stderr, " %.*s\n", (int) strlen (p->fname) - 1, p->fname);    }    fprintf (stderr, "End of search list.\n");  }  /* -MG doesn't select the form of output and must be specified with one of     -M or -MM.  -MG doesn't make sense with -MD or -MMD since they don't     inhibit compilation.  */  if (print_deps_missing_files && (print_deps == 0 || !inhibit_output))    fatal ("-MG must be specified with one of -M or -MM");  /* Either of two environment variables can specify output of deps.     Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",     where OUTPUT_FILE is the file to write deps info to     and DEPS_TARGET is the target to mention in the deps.  */  if (print_deps == 0      && (getenv ("SUNPRO_DEPENDENCIES") != 0	  || getenv ("DEPENDENCIES_OUTPUT") != 0)) {    char *spec = getenv ("DEPENDENCIES_OUTPUT");    char *s;    char *output_file;    if (spec == 0) {      spec = getenv ("SUNPRO_DEPENDENCIES");      print_deps = 2;    }    else      print_deps = 1;    s = spec;    /* Find the space before the DEPS_TARGET, if there is one.  */    /* This should use index.  (mrs) */    while (*s != 0 && *s != ' ') s++;    if (*s != 0) {      deps_target = s + 1;      output_file = xmalloc (s - spec + 1);      bcopy (spec, output_file, s - spec);      output_file[s - spec] = 0;    }    else {      deps_target = 0;      output_file = spec;    }          deps_file = output_file;    deps_mode = "a";  }  /* For -M, print the expected object file name     as the target of this Make-rule.  */  if (print_deps) {    deps_allocated_size = 200;    deps_buffer = xmalloc (deps_allocated_size);    deps_buffer[0] = 0;    deps_size = 0;    deps_column = 0;    if (deps_target) {      deps_output (deps_target, ':');    } else if (*in_fname == 0) {      deps_output ("-", ':');    } else {      char *p, *q;      int len;      q = base_name (in_fname);      /* Copy remainder to mungable area.  */      p = (char *) alloca (strlen(q) + 8);      strcpy (p, q);      /* Output P, but remove known suffixes.  */      len = strlen (p);      q = p + len;      if (len >= 2	  && p[len - 2] == '.'	  && index("cCsSm", p[len - 1]))	q = p + (len - 2);      else if (len >= 3	       && p[len - 3] == '.'	       && p[len - 2] == 'c'	       && p[len - 1] == 'c')	q = p + (len - 3);      else if (len >= 4	       && p[len - 4] == '.'	       && p[len - 3] == 'c'	       && p[len - 2] == 'x'	       && p[len - 1] == 'x')	q = p + (len - 4);      else if (len >= 4	       && p[len - 4] == '.'	       && p[len - 3] == 'c'	       && p[len - 2] == 'p'	       && p[len - 1] == 'p')	q = p + (len - 4);      /* Supply our own suffix.  */      strcpy (q, OBJECT_SUFFIX);      deps_output (p, ':');      deps_output (in_fname, ' ');    }  }  /* Scan the -imacros files before the main input.     Much like #including them, but with no_output set     so that only their macro definitions matter.  */  no_output++; no_record_file++;  for (i = 1; i < argc; i++)    if (pend_files[i]) {      struct include_file *inc;      int fd = open_include_file (pend_files[i], NULL_PTR, NULL_PTR, &inc);      if (fd < 0) {	perror_with_name (pend_files[i]);	return FATAL_EXIT_CODE;      }      finclude (fd, inc, &outbuf, 0, NULL_PTR);    }  no_output--; no_record_file--;  /* Copy the entire contents of the main input file into     the stacked input buffer previously allocated for it.  */  /* JF check for stdin */  if (in_fname == NULL || *in_fname == 0) {    in_fname = "";    f = 0;  } else if ((f = open (in_fname, O_RDONLY, 0666)) < 0)    goto perror;  if (fstat (f, &st) != 0)    pfatal_with_name (in_fname);  fp->nominal_fname = fp->fname = in_fname;  fp->lineno = 1;  fp->system_header_p = 0;  /* JF all this is mine about reading pipes and ttys */  if (! S_ISREG (st.st_mode)) {    /* Read input from a file that is not a normal disk file.       We cannot preallocate a buffer with the correct size,       so we must read in the file a piece at the time and make it bigger.  */    int size;    int bsize;    int cnt;    if (S_ISDIR (st.st_mode))      fatal ("Input file `%s' is a directory", in_fname);    bsize = 2000;    size = 0;    fp->buf = (U_CHAR *) xmalloc (bsize + 2);    for (;;) {      cnt = safe_read (f, (char *) fp->buf + size, bsize - size);      if (cnt < 0) goto perror;	/* error! */      size += cnt;      if (size != bsize) break;	/* End of file */      bsize *= 2;      fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);    }    fp->length = size;  } else {    /* Read a file whose size we can determine in advance.       For the sake of VMS, st.st_size is just an upper bound.  */    size_t s = (size_t) st.st_size;    if (s != st.st_size || s + 2 < s)      memory_full ();    fp->buf = (U_CHAR *) xmalloc (s + 2);    fp->length = safe_read (f, (char *) fp->buf, s);    if (fp->length < 0) goto perror;  }  fp->bufp = fp->buf;  fp->if_stack = if_stack;  /* Make sure data ends with a newline.  And put a null after it.  */  if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')      /* Backslash-newline at end is not good enough.  */      || (fp->length > 1 && fp->buf[fp->lengt

⌨️ 快捷键说明

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