📄 gcc.c
字号:
{ /* Find a mapping that applies to this option. */ for (j = 0; j < sizeof (option_map) / sizeof (option_map[0]); j++) { int optlen = strlen (option_map[j].name); int arglen = strlen (argv[i]); int complen = arglen > optlen ? optlen : arglen; char *arginfo = option_map[j].arg_info; if (arginfo == 0) arginfo = ""; if (!strncmp (argv[i], option_map[j].name, complen)) { char *arg = 0; if (arglen < optlen) { for (k = j + 1; k < sizeof (option_map) / sizeof (option_map[0]); k++) if (strlen (option_map[k].name) >= arglen && !strncmp (argv[i], option_map[k].name, arglen)) { error ("Ambiguous abbreviation %s", argv[i]); break; } if (k != sizeof (option_map) / sizeof (option_map[0])) break; } if (arglen > optlen) { /* If the option has an argument, accept that. */ if (argv[i][optlen] == '=') arg = argv[i] + optlen + 1; /* If this mapping requires extra text at end of name, accept that as "argument". */ else if (index (arginfo, '*') != 0) arg = argv[i] + optlen; /* Otherwise, extra text at end means mismatch. Try other mappings. */ else continue; } else if (index (arginfo, '*') != 0) { error ("Incomplete `%s' option", option_map[j].name); break; } /* Handle arguments. */ if (index (arginfo, 'a') != 0) { if (arg == 0) { if (i + 1 == argc) { error ("Missing argument to `%s' option", option_map[j].name); break; } arg = argv[++i]; } } else if (index (arginfo, '*') != 0) ; else if (index (arginfo, 'o') == 0) { if (arg != 0) error ("Extraneous argument to `%s' option", option_map[j].name); arg = 0; } /* Store the translation as one argv elt or as two. */ if (arg != 0 && index (arginfo, 'j') != 0) newv[newindex++] = concat (option_map[j].equivalent, arg, NULL_PTR); else if (arg != 0) { newv[newindex++] = option_map[j].equivalent; newv[newindex++] = arg; } else newv[newindex++] = option_map[j].equivalent; break; } } i++; } /* Handle old-fashioned options--just copy them through, with their arguments. */ else if (argv[i][0] == '-') { char *p = argv[i] + 1; int c = *p; int nskip = 1; if (SWITCH_TAKES_ARG (c) > (p[1] != 0)) nskip += SWITCH_TAKES_ARG (c) - (p[1] != 0); else if (WORD_SWITCH_TAKES_ARG (p)) nskip += WORD_SWITCH_TAKES_ARG (p); else if ((c == 'B' || c == 'b' || c == 'V' || c == 'x') && p[1] == 0) nskip += 1; else if (! strcmp (p, "Xlinker")) nskip += 1; /* Watch out for an option at the end of the command line that is missing arguments, and avoid skipping past the end of the command line. */ if (nskip + i > argc) nskip = argc - i; while (nskip > 0) { newv[newindex++] = argv[i++]; nskip--; } } else /* Ordinary operands, or +e options. */ newv[newindex++] = argv[i++]; } newv[newindex] = 0; *argvp = newv; *argcp = newindex;}char *my_strerror(e) int e;{#ifdef HAVE_STRERROR return strerror(e);#else static char buffer[30]; if (!e) return "cannot access"; if (e > 0 && e < sys_nerr) return sys_errlist[e]; sprintf (buffer, "Unknown error %d", e); return buffer;#endif}static char *skip_whitespace (p) char *p;{ while (1) { /* A fully-blank line is a delimiter in the SPEC file and shouldn't be considered whitespace. */ if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n') return p + 1; else if (*p == '\n' || *p == ' ' || *p == '\t') p++; else if (*p == '#') { while (*p != '\n') p++; p++; } else break; } return p;}/* Structure to keep track of the specs that have been defined so far. These are accessed using %(specname) or %[specname] in a compiler or link spec. */struct spec_list{ /* The following 2 fields must be first */ /* to allow EXTRA_SPECS to be initialized */ char *name; /* name of the spec. */ char *ptr; /* available ptr if no static pointer */ /* The following fields are not initialized */ /* by EXTRA_SPECS */ char **ptr_spec; /* pointer to the spec itself. */ struct spec_list *next; /* Next spec in linked list. */ int name_len; /* length of the name */ int alloc_p; /* whether string was allocated */};#define INIT_STATIC_SPEC(NAME,PTR) \{ NAME, NULL_PTR, PTR, (struct spec_list *)0, sizeof (NAME)-1, 0 }/* List of statically defined specs */static struct spec_list static_specs[] = { INIT_STATIC_SPEC ("asm", &asm_spec), INIT_STATIC_SPEC ("asm_final", &asm_final_spec), INIT_STATIC_SPEC ("cpp", &cpp_spec), INIT_STATIC_SPEC ("cc1", &cc1_spec), INIT_STATIC_SPEC ("cc1plus", &cc1plus_spec), INIT_STATIC_SPEC ("endfile", &endfile_spec), INIT_STATIC_SPEC ("link", &link_spec), INIT_STATIC_SPEC ("lib", &lib_spec), INIT_STATIC_SPEC ("libgcc", &libgcc_spec), INIT_STATIC_SPEC ("startfile", &startfile_spec), INIT_STATIC_SPEC ("switches_need_spaces", &switches_need_spaces), INIT_STATIC_SPEC ("signed_char", &signed_char_spec), INIT_STATIC_SPEC ("predefines", &cpp_predefines), INIT_STATIC_SPEC ("cross_compile", &cross_compile), INIT_STATIC_SPEC ("version", &compiler_version), INIT_STATIC_SPEC ("multilib", &multilib_select), INIT_STATIC_SPEC ("multilib_defaults", &multilib_defaults), INIT_STATIC_SPEC ("multilib_extra", &multilib_extra), INIT_STATIC_SPEC ("multilib_matches", &multilib_matches),};#ifdef EXTRA_SPECS /* additional specs needed */static struct spec_list extra_specs[] = { EXTRA_SPECS };#endif/* List of dynamically allocates specs that have been defined so far. */static struct spec_list *specs = (struct spec_list *)0;/* Initialize the specs lookup routines. */static voidinit_spec (){ struct spec_list *next = (struct spec_list *)0; struct spec_list *sl = (struct spec_list *)0; int i; if (specs) return; /* already initialized */ if (verbose_flag) fprintf (stderr, "Using builtin specs.\n");#ifdef EXTRA_SPECS for (i = (sizeof (extra_specs) / sizeof (extra_specs[0])) - 1; i >= 0; i--) { sl = &extra_specs[i]; sl->next = next; sl->name_len = strlen (sl->name); sl->ptr_spec = &sl->ptr; next = sl; }#endif for (i = (sizeof (static_specs) / sizeof (static_specs[0])) - 1; i >= 0; i--) { sl = &static_specs[i]; sl->next = next; next = sl; } specs = sl;}/* Change the value of spec NAME to SPEC. If SPEC is empty, then the spec is removed; If the spec starts with a + then SPEC is added to the end of the current spec. */static voidset_spec (name, spec) char *name; char *spec;{ struct spec_list *sl; char *old_spec; int name_len = strlen (name); int i; /* If this is the first call, initialize the statically allocated specs */ if (!specs) { struct spec_list *next = (struct spec_list *)0; for (i = (sizeof (static_specs) / sizeof (static_specs[0])) - 1; i >= 0; i--) { sl = &static_specs[i]; sl->next = next; next = sl; } specs = sl; } /* See if the spec already exists */ for (sl = specs; sl; sl = sl->next) if (name_len == sl->name_len && !strcmp (sl->name, name)) break; if (!sl) { /* Not found - make it */ sl = (struct spec_list *) xmalloc (sizeof (struct spec_list)); sl->name = save_string (name, strlen (name)); sl->name_len = name_len; sl->ptr_spec = &sl->ptr; sl->alloc_p = 0; *(sl->ptr_spec) = ""; sl->next = specs; specs = sl; } old_spec = *(sl->ptr_spec); *(sl->ptr_spec) = ((spec[0] == '+' && isspace (spec[1])) ? concat (old_spec, spec + 1, NULL_PTR) : save_string (spec, strlen (spec)));#ifdef DEBUG_SPECS if (verbose_flag) fprintf (stderr, "Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));#endif /* Free the old spec */ if (old_spec && sl->alloc_p) free (old_spec); sl->alloc_p = 1;}/* Accumulate a command (program name and args), and run it. *//* Vector of pointers to arguments in the current line of specifications. */static char **argbuf;/* Number of elements allocated in argbuf. */static int argbuf_length;/* Number of elements in argbuf currently in use (containing args). */static int argbuf_index;/* This is the list of suffixes and codes (%g/%u/%U) and the associated temp file. Used only if MKTEMP_EACH_FILE. */static struct temp_name { char *suffix; /* suffix associated with the code. */ int length; /* strlen (suffix). */ int unique; /* Indicates whether %g or %u/%U was used. */ char *filename; /* associated filename. */ int filename_length; /* strlen (filename). */ struct temp_name *next;} *temp_names;/* Number of commands executed so far. */static int execution_count;/* Number of commands that exited with a signal. */static int signal_count;/* Name with which this program was invoked. */static char *programname;/* Structures to keep track of prefixes to try when looking for files. */struct prefix_list{ char *prefix; /* String to prepend to the path. */ struct prefix_list *next; /* Next in linked list. */ int require_machine_suffix; /* Don't use without machine_suffix. */ /* 2 means try both machine_suffix and just_machine_suffix. */ int *used_flag_ptr; /* 1 if a file was found with this prefix. */};struct path_prefix{ struct prefix_list *plist; /* List of prefixes to try */ int max_len; /* Max length of a prefix in PLIST */ char *name; /* Name of this list (used in config stuff) */};/* List of prefixes to try when looking for executables. */static struct path_prefix exec_prefixes = { 0, 0, "exec" };/* List of prefixes to try when looking for startup (crt0) files. */static struct path_prefix startfile_prefixes = { 0, 0, "startfile" };/* List of prefixes to try when looking for include files. */static struct path_prefix include_prefixes = { 0, 0, "include" };/* Suffix to attach to directories searched for commands. This looks like `MACHINE/VERSION/'. */static char *machine_suffix = 0;/* Suffix to attach to directories searched for commands. This is just `MACHINE/'. */static char *just_machine_suffix = 0;/* Adjusted value of GCC_EXEC_PREFIX envvar. */static char *gcc_exec_prefix;/* Default prefixes to attach to command names. */#ifdef CROSS_COMPILE /* Don't use these prefixes for a cross compiler. */#undef MD_EXEC_PREFIX#undef MD_STARTFILE_PREFIX#undef MD_STARTFILE_PREFIX_1#endif#ifndef STANDARD_EXEC_PREFIX#define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-lib/"#endif /* !defined STANDARD_EXEC_PREFIX */static char *standard_exec_prefix = STANDARD_EXEC_PREFIX;static char *standard_exec_prefix_1 = "/usr/lib/gcc/";#ifdef MD_EXEC_PREFIX
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -