📄 gcc.c
字号:
char *part1; char **args; int valid;};static struct switchstr *switches;static int n_switches;struct infile{ char *name; char *language;};/* Also a vector of input files specified. */static struct infile *infiles;static int n_infiles;/* And a vector of corresponding output files is made up later. */static char **outfiles;/* Create the vector `switches' and its contents. Store its length in `n_switches'. */static voidprocess_command (argc, argv) int argc; char **argv;{ register int i; char *temp; char *spec_lang = 0; int last_language_n_infiles; gcc_exec_prefix = getenv ("GCC_EXEC_PREFIX"); n_switches = 0; n_infiles = 0; /* Default for -V is our version number, ending at first space. */ spec_version = save_string (version_string, strlen (version_string)); for (temp = spec_version; *temp && *temp != ' '; temp++); if (*temp) *temp = '\0'; /* Set up the default search paths. */ if (gcc_exec_prefix == 0) gcc_exec_prefix = standard_exec_prefix; add_prefix (&exec_prefix, gcc_exec_prefix, 0, 0, NULL_PTR); add_prefix (&startfile_prefix, gcc_exec_prefix, 0, 0, NULL_PTR); /* COMPILER_PATH and LIBRARY_PATH have values that are lists of directory names with colons. */ temp = getenv ("COMPILER_PATH"); if (temp) { char *startp, *endp; char *nstore = (char *) alloca (strlen (temp) + 3); startp = endp = temp; while (1) { if (*endp == PATH_SEPARATOR || *endp == 0) { strncpy (nstore, startp, endp-startp); if (endp == startp) { strcpy (nstore, "./"); } else if (endp[-1] != '/') { nstore[endp-startp] = '/'; nstore[endp-startp+1] = 0; } else nstore[endp-startp] = 0; add_prefix (&exec_prefix, nstore, 0, 0, NULL_PTR); if (*endp == 0) break; endp = startp = endp + 1; } else endp++; } } temp = getenv ("LIBRARY_PATH"); if (temp) { char *startp, *endp; char *nstore = (char *) alloca (strlen (temp) + 3); startp = endp = temp; while (1) { if (*endp == PATH_SEPARATOR || *endp == 0) { strncpy (nstore, startp, endp-startp); if (endp == startp) { strcpy (nstore, "./"); } else if (endp[-1] != '/') { nstore[endp-startp] = '/'; nstore[endp-startp+1] = 0; } else nstore[endp-startp] = 0; add_prefix (&startfile_prefix, nstore, 0, 0, NULL_PTR); /* Make separate list of dirs that came from LIBRARY_PATH. */ add_prefix (&library_prefix, nstore, 0, 0, NULL_PTR); if (*endp == 0) break; endp = startp = endp + 1; } else endp++; } } /* Use LPATH like LIBRARY_PATH (for the CMU build program). */ temp = getenv ("LPATH"); if (temp) { char *startp, *endp; char *nstore = (char *) alloca (strlen (temp) + 3); startp = endp = temp; while (1) { if (*endp == PATH_SEPARATOR || *endp == 0) { strncpy (nstore, startp, endp-startp); if (endp == startp) { strcpy (nstore, "./"); } else if (endp[-1] != '/') { nstore[endp-startp] = '/'; nstore[endp-startp+1] = 0; } else nstore[endp-startp] = 0; add_prefix (&startfile_prefix, nstore, 0, 0, NULL_PTR); /* Make separate list of dirs that came from LIBRARY_PATH. */ add_prefix (&library_prefix, nstore, 0, 0, NULL_PTR); if (*endp == 0) break; endp = startp = endp + 1; } else endp++; } } /* Scan argv twice. Here, the first time, just count how many switches there will be in their vector, and how many input files in theirs. Here we also parse the switches that cc itself uses (e.g. -v). */ for (i = 1; i < argc; i++) { if (! strcmp (argv[i], "-dumpspecs")) { printf ("*asm:\n%s\n\n", asm_spec); printf ("*asm_final:\n%s\n\n", asm_final_spec); printf ("*cpp:\n%s\n\n", cpp_spec); printf ("*cc1:\n%s\n\n", cc1_spec); printf ("*cc1plus:\n%s\n\n", cc1plus_spec); printf ("*endfile:\n%s\n\n", endfile_spec); printf ("*link:\n%s\n\n", link_spec); printf ("*lib:\n%s\n\n", lib_spec); printf ("*startfile:\n%s\n\n", startfile_spec); printf ("*switches_need_spaces:\n%s\n\n", switches_need_spaces); printf ("*signed_char:\n%s\n\n", signed_char_spec); printf ("*predefines:\n%s\n\n", cpp_predefines); printf ("*cross_compile:\n%d\n\n", cross_compile); exit (0); } else if (! strcmp (argv[i], "-dumpversion")) { printf ("%s\n", version_string); exit (0); } else if (! strcmp (argv[i], "-print-libgcc-file-name")) { print_libgcc_file_name = 1; } else if (! strcmp (argv[i], "-Xlinker")) { /* Pass the argument of this option to the linker when we link. */ if (i + 1 == argc) fatal ("argument to `-Xlinker' is missing"); n_linker_options++; if (!linker_options) linker_options = (char **) xmalloc (n_linker_options * sizeof (char **)); else linker_options = (char **) xrealloc (linker_options, n_linker_options * sizeof (char **)); linker_options[n_linker_options - 1] = argv[++i]; } else if (! strncmp (argv[i], "-Wl,", 4)) { int prev, j; /* Pass the rest of this option to the linker when we link. */ n_linker_options++; if (!linker_options) linker_options = (char **) xmalloc (n_linker_options * sizeof (char **)); else linker_options = (char **) xrealloc (linker_options, n_linker_options * sizeof (char **)); /* Split the argument at commas. */ prev = 4; for (j = 4; argv[i][j]; j++) if (argv[i][j] == ',') { linker_options[n_linker_options - 1] = save_string (argv[i] + prev, j - prev); n_linker_options++; linker_options = (char **) xrealloc (linker_options, n_linker_options * sizeof (char **)); prev = j + 1; } /* Record the part after the last comma. */ linker_options[n_linker_options - 1] = argv[i] + prev; } else if (! strncmp (argv[i], "-Wa,", 4)) { int prev, j; /* Pass the rest of this option to the assembler. */ n_assembler_options++; if (!assembler_options) assembler_options = (char **) xmalloc (n_assembler_options * sizeof (char **)); else assembler_options = (char **) xrealloc (assembler_options, n_assembler_options * sizeof (char **)); /* Split the argument at commas. */ prev = 4; for (j = 4; argv[i][j]; j++) if (argv[i][j] == ',') { assembler_options[n_assembler_options - 1] = save_string (argv[i] + prev, j - prev); n_assembler_options++; assembler_options = (char **) xrealloc (assembler_options, n_assembler_options * sizeof (char **)); prev = j + 1; } /* Record the part after the last comma. */ assembler_options[n_assembler_options - 1] = argv[i] + prev; } else if (argv[i][0] == '+' && argv[i][1] == 'e') /* Compensate for the +e options to the C++ front-end. */ n_switches++; else if (argv[i][0] == '-' && argv[i][1] != 0 && argv[i][1] != 'l') { register char *p = &argv[i][1]; register int c = *p; switch (c) { case 'b': if (p[1] == 0 && i + 1 == argc) fatal ("argument to `-b' is missing"); if (p[1] == 0) spec_machine = argv[++i]; else spec_machine = p + 1; break; case 'B': { int *temp = (int *) xmalloc (sizeof (int)); char *value; if (p[1] == 0 && i + 1 == argc) fatal ("argument to `-B' is missing"); if (p[1] == 0) value = argv[++i]; else value = p + 1; add_prefix (&exec_prefix, value, 1, 0, temp); add_prefix (&startfile_prefix, value, 1, 0, temp); } break; case 'v': /* Print our subcommands and print versions. */ n_switches++; /* If they do anything other than exactly `-v', don't set verbose_flag; rather, continue on to give the error. */ if (p[1] != 0) break; verbose_flag++; break; case 'V': if (p[1] == 0 && i + 1 == argc) fatal ("argument to `-V' is missing"); if (p[1] == 0) spec_version = argv[++i]; else spec_version = p + 1; break; case 's': if (!strcmp (p, "save-temps")) { save_temps_flag = 1; n_switches++; break; } default: n_switches++; if (SWITCH_TAKES_ARG (c) > (p[1] != 0)) i += SWITCH_TAKES_ARG (c) - (p[1] != 0); else if (WORD_SWITCH_TAKES_ARG (p)) i += WORD_SWITCH_TAKES_ARG (p); } } else n_infiles++; } /* Set up the search paths before we go looking for config files. */ /* These come before the md prefixes so that we will find gcc's subcommands (such as cpp) rather than those of the host system. */ /* Use 2 as fourth arg meaning try just the machine as a suffix, as well as trying the machine and the version. */ add_prefix (&exec_prefix, standard_exec_prefix, 0, 2, NULL_PTR); add_prefix (&exec_prefix, standard_exec_prefix_1, 0, 2, NULL_PTR); add_prefix (&startfile_prefix, standard_exec_prefix, 0, 1, NULL_PTR); add_prefix (&startfile_prefix, standard_exec_prefix_1, 0, 1, NULL_PTR); /* More prefixes are enabled in main, after we read the specs file and determine whether this is cross-compilation or not. */ /* Then create the space for the vectors and scan again. */ switches = ((struct switchstr *) xmalloc ((n_switches + 1) * sizeof (struct switchstr))); infiles = (struct infile *) xmalloc ((n_infiles + 1) * sizeof (struct infile)); n_switches = 0; n_infiles = 0; last_language_n_infiles = -1; /* This, time, copy the text of each switch and store a pointer to the copy in the vector of switches. Store all the infiles in their vector. */ for (i = 1; i < argc; i++) { /* Just skip the switches that were handled by the preceding loop. */ if (!strcmp (argv[i], "-Xlinker")) i++; else if (! strncmp (argv[i], "-Wl,", 4)) ; else if (! strncmp (argv[i], "-Wa,", 4)) ; else if (! strcmp (argv[i], "-print-libgcc-file-name")) ; else if (argv[i][0] == '+' && argv[i][1] == 'e') { /* Compensate for the +e options to the C++ front-end; they're there simply for cfront call-compatability. We do some magic in default_compilers to pass them down properly. Note we deliberately start at the `+' here, to avoid passing -e0 or -e1 down into the linker. */ switches[n_switches].part1 = &argv[i][0]; switches[n_switches].args = 0; switches[n_switches].valid = 0; n_switches++; } else if (argv[i][0] == '-' && argv[i][1] != 0 && argv[i][1] != 'l') { register char *p = &argv[i][1]; register int c = *p; if (c == 'B' || c == 'b' || c == 'V') { /* Skip a separate arg, if any. */ if (p[1] == 0) i++; continue; } if (c == 'x') { if (p[1] == 0 && i + 1 == argc) fatal ("argument to `-x' is missing"); if (p[1] == 0) spec_lang = argv[++i]; else spec_lang = p + 1; if (! strcmp (spec_lang, "none")) /* Suppress the warning if -xnone comes after the last input file, because alternate command interfaces like g++ might find it useful to place -xnone after each input file. */ spec_lang = 0; else last_language_n_infiles = n_infiles; continue; } switches[n_switches].part1 = p; /* Deal with option arguments in separate argv elements. */ if ((SWITCH_TAKES_ARG (c) > (p[1] != 0)) || WORD_SWITCH_TAKES_ARG (p)) { int j = 0; int n_args = WORD_SWITCH_TAKES_ARG (p); if (n_args == 0) { /* Count only the option arguments in separate argv elements. */ n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0); } if (i + n_args >= argc) fatal ("argument to `-%s' is missing", p); switches[n_switches].args = (char **) xmalloc ((n_args + 1) * sizeof (char *)); while (j < n_args) switches[n_switches].args[j++] = argv[++i]; /* Null-terminate the vector. */ sw
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -