📄 cccp.c
字号:
p = (char *) getenv ("CPATH"); if (p != 0 && ! no_standard_includes) path_include (p); /* Now that dollars_in_ident is known, initialize is_idchar. */ initialize_char_syntax (); /* 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; /* 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_command (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_command (fp, &outbuf, 0, same_file); make_undef (pend_undefs[i], &outbuf); } if (pend_defs[i]) { if (debug_output) output_line_command (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) { char *nstore = (char *) alloca (strlen (epath) + 2); 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) { /* Handle cases like c:/usr/lib:d:/gcc/lib */ if ((*endp == PATH_SEPARATOR#if 0 /* Obsolete, now that we use semicolons as the path separator. */#ifdef __MSDOS__ && (endp-startp != 1 || !isalpha (*startp))#endif#endif ) || *endp == 0) { strncpy (nstore, startp, endp-startp); if (endp == startp) strcpy (nstore, "."); else nstore[endp-startp] = '\0'; include_defaults[num_dirs].fname = savestring (nstore); include_defaults[num_dirs].cplusplus = cplusplus; num_dirs++; if (*endp == '\0') break; endp = startp = endp + 1; } else endp++; } /* Put the usual defaults back in at the end. */ bcopy (include_defaults_array, &include_defaults[num_dirs], sizeof (include_defaults_array)); } } first_system_include = 0; /* 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 = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); int this_len = strlen (specd_prefix) + strlen (p->fname) - default_len; char *str = (char *) xmalloc (this_len + 1); strcpy (str, specd_prefix); strcat (str, p->fname + default_len); new->fname = str; new->control_macro = 0; 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 = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); new->control_macro = 0; new->fname = p->fname; 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; /* 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++; for (i = 1; i < argc; i++) if (pend_files[i]) { int fd = open (pend_files[i], O_RDONLY, 0666); if (fd < 0) { perror_with_name (pend_files[i]); return FAILURE_EXIT_CODE; } finclude (fd, pend_files[i], &outbuf, 0, NULL_PTR); } no_output--; /* 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; /* 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 = (char *) 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; } /* For -M, print the expected object file name as the target of this Make-rule. */ if (print_deps) { deps_allocated_size = 200; deps_buffer = (char *) xmalloc (deps_allocated_size); deps_buffer[0] = 0; deps_size = 0; deps_column = 0; if (deps_target) { deps_output (deps_target, 0); deps_output (":", 0); } else if (*in_fname == 0) deps_output ("-: ", 0); else { int len; char *p = in_fname; char *p1 = p; /* Discard all directory prefixes from P. */ while (*p1) { if (*p1 == '/') p = p1 + 1; p1++; } /* Output P, but remove known suffixes. */ len = strlen (p); if (p[len - 2] == '.' && p[len - 1] == 'c') deps_output (p, len - 2); else if (p[len - 2] == '.' && p[len - 1] == 'C') deps_output (p, len - 2); else if (p[len - 3] == '.' && p[len - 2] == 'c' && p[len - 1] == 'c') deps_output (p, len - 3); else if (p[len - 2] == '.' && p[len - 1] == 's') deps_output (p, len - 2); else if (p[len - 2] == '.' && p[len - 1] == 'S') deps_output (p, len - 2); else if (p[len - 2] == '.' && p[len - 1] == 'm') deps_output (p, len - 2); else deps_output (p, 0); /* Supply our own suffix. */#ifndef VMS deps_output (".o : ", 0);#else deps_output (".obj : ", 0);#endif deps_output (in_fname, 0); deps_output (" ", 0); } } file_size_and_mode (f, &st_mode, &st_size); 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_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; U_CHAR *bufp; bsize = 2000; size = 0; fp->buf = (U_CHAR *) xmalloc (bsize + 2); bufp = fp->buf; for (;;) { cnt = read (f, bufp, bsize - size); if (cnt < 0) goto perror; /* error! */ if (cnt == 0) break; /* End of file */ size += cnt; bufp += cnt; if (bsize == size) { /* Buffer is full! */ bsize *= 2; fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2); bufp = fp->buf + size; /* May have moved */ } } fp->length = size; } else { /* Read a file whose size we can determine in advance. For the sake of VMS, st_size is just an upper bound. */ long i; fp->length = 0; fp->buf = (U_CHAR *) xmalloc (st_size + 2); while (st_size > 0) { i = read (f, fp->buf + fp->length, st_size); if (i <= 0) { if (i == 0) break; goto perror; } fp->length += i; st_size -= i; } } 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->length - 2] == '\\')) { fp->buf[fp->length++] = '\n'; missing_newline = 1; } fp->buf[fp->length] = '\0'; /* Unless inhibited, convert trigraphs in the input. */ if (!no_trigraphs) trigraph_pcp (fp); /* Now that we know the input file is valid, open the output. */ if (!out_fname || !strcmp (out_fname, "")) out_fname = "stdout"; else if (! freopen (out_fname, "w", stdout)) pfatal_with_name (out_fname); output_line_command (fp, &outbuf, 0, same_file); /* Scan the -include files before the main input. */ for (i = 1; i < argc; i++) if (pend_includes[i]) { int fd = open (pend_includes[i], O_RDONLY, 0666); if (fd < 0) { perror_with_name (pend_includes[i]); return FAILURE_EXIT_CODE; } finclude (fd, pend_includes[i], &outbuf, 0, NULL_PTR); } /* Scan the input, processing macros and directives. */ rescan (&outbuf, 0); if (pedantic && missing_newline) pedwarn ("file does not end in newline"); /* Now we have processed the entire input Write whichever kind of output has been requested. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -