📄 gcc.c
字号:
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); 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 ""; if (e > 0 && e < sys_nerr) return sys_errlist[e]; sprintf (buffer, "Unknown error %d", e); return buffer;#endif}/* Read compilation specs from a file named FILENAME, replacing the default ones. A suffix which starts with `*' is a definition for one of the machine-specific sub-specs. The "suffix" should be *asm, *cc1, *cpp, *link, *startfile, *signed_char, etc. The corresponding spec is stored in asm_spec, etc., rather than in the `compilers' vector. Anything invalid in the file is a fatal error. */static voidread_specs (filename) char *filename;{ int desc; int readlen; struct stat statbuf; char *buffer; register char *p; if (verbose_flag) fprintf (stderr, "Reading specs from %s\n", filename); /* Open and stat the file. */ desc = open (filename, O_RDONLY, 0); if (desc < 0) pfatal_with_name (filename); if (stat (filename, &statbuf) < 0) pfatal_with_name (filename); /* Read contents of file into BUFFER. */ buffer = xmalloc ((unsigned) statbuf.st_size + 1); readlen = read (desc, buffer, (unsigned) statbuf.st_size); if (readlen < 0) pfatal_with_name (filename); buffer[readlen] = 0; close (desc); /* Scan BUFFER for specs, putting them in the vector. */ p = buffer; while (1) { char *suffix; char *spec; char *in, *out, *p1, *p2; /* Advance P in BUFFER to the next nonblank nocomment line. */ p = skip_whitespace (p); if (*p == 0) break; /* Find the colon that should end the suffix. */ p1 = p; while (*p1 && *p1 != ':' && *p1 != '\n') p1++; /* The colon shouldn't be missing. */ if (*p1 != ':') fatal ("specs file malformed after %d characters", p1 - buffer); /* Skip back over trailing whitespace. */ p2 = p1; while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t')) p2--; /* Copy the suffix to a string. */ suffix = save_string (p, p2 - p); /* Find the next line. */ p = skip_whitespace (p1 + 1); if (p[1] == 0) fatal ("specs file malformed after %d characters", p - buffer); p1 = p; /* Find next blank line. */ while (*p1 && !(*p1 == '\n' && p1[1] == '\n')) p1++; /* Specs end at the blank line and do not include the newline. */ spec = save_string (p, p1 - p); p = p1; /* Delete backslash-newline sequences from the spec. */ in = spec; out = spec; while (*in != 0) { if (in[0] == '\\' && in[1] == '\n') in += 2; else if (in[0] == '#') { while (*in && *in != '\n') in++; } else *out++ = *in++; } *out = 0; if (suffix[0] == '*') { if (! strcmp (suffix, "*link_command")) link_command_spec = spec; else set_spec (suffix + 1, spec); } else { /* Add this pair to the vector. */ compilers = ((struct compiler *) xrealloc (compilers, (n_compilers + 2) * sizeof (struct compiler))); compilers[n_compilers].suffix = suffix; bzero ((char *) compilers[n_compilers].spec, sizeof compilers[n_compilers].spec); compilers[n_compilers].spec[0] = spec; n_compilers++; bzero ((char *) &compilers[n_compilers], sizeof compilers[n_compilers]); } if (*suffix == 0) link_command_spec = spec; } if (link_command_spec == 0) fatal ("spec file has no spec for linking");}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{ char *name; /* Name of the spec. */ char *spec; /* The spec itself. */ struct spec_list *next; /* Next spec in linked list. */};/* List of specs that have been defined so far. */static struct spec_list *specs = (struct spec_list *) 0;/* 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; /* See if the spec already exists */ for (sl = specs; sl; sl = sl->next) if (strcmp (sl->name, name) == 0) break; if (!sl) { /* Not found - make it */ sl = (struct spec_list *) xmalloc (sizeof (struct spec_list)); sl->name = save_string (name, strlen (name)); sl->spec = save_string ("", 0); sl->next = specs; specs = sl; } old_spec = sl->spec; if (name && spec[0] == '+' && isspace (spec[1])) sl->spec = concat (old_spec, spec + 1); else sl->spec = save_string (spec, strlen (spec)); if (! strcmp (name, "asm")) asm_spec = sl->spec; else if (! strcmp (name, "asm_final")) asm_final_spec = sl->spec; else if (! strcmp (name, "cc1")) cc1_spec = sl->spec; else if (! strcmp (name, "cc1plus")) cc1plus_spec = sl->spec; else if (! strcmp (name, "cpp")) cpp_spec = sl->spec; else if (! strcmp (name, "endfile")) endfile_spec = sl->spec; else if (! strcmp (name, "lib")) lib_spec = sl->spec; else if (! strcmp (name, "libgcc")) libgcc_spec = sl->spec; else if (! strcmp (name, "link")) link_spec = sl->spec; else if (! strcmp (name, "predefines")) cpp_predefines = sl->spec; else if (! strcmp (name, "signed_char")) signed_char_spec = sl->spec; else if (! strcmp (name, "startfile")) startfile_spec = sl->spec; else if (! strcmp (name, "switches_need_spaces")) switches_need_spaces = sl->spec; else if (! strcmp (name, "cross_compile")) cross_compile = atoi (sl->spec); else if (! strcmp (name, "multilib")) multilib_select = sl->spec; /* Free the old spec */ if (old_spec) free (old_spec);}/* 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -