📄 gcc.c
字号:
for (temp = failure_delete_queue; temp; temp = temp->next) delete_if_ordinary (temp->name);}static voidclear_failure_queue (){ failure_delete_queue = 0;}/* Routine to add variables to the environment. We do this to pass the pathname of the gcc driver, and the directories search to the collect2 program, which is being run as ld. This way, we can be sure of executing the right compiler when collect2 wants to build constructors and destructors. Since the environment variables we use come from an obstack, we don't have to worry about allocating space for them. */#ifndef HAVE_PUTENVvoidputenv (str) char *str;{#ifndef VMS /* nor about VMS */ extern char **environ; char **old_environ = environ; char **envp; int num_envs = 0; int name_len = 1; int str_len = strlen (str); char *p = str; int ch; while ((ch = *p++) != '\0' && ch != '=') name_len++; if (!ch) abort (); /* Search for replacing an existing environment variable, and count the number of total environment variables. */ for (envp = old_environ; *envp; envp++) { num_envs++; if (!strncmp (str, *envp, name_len)) { *envp = str; return; } } /* Add a new environment variable */ environ = (char **) xmalloc (sizeof (char *) * (num_envs+2)); *environ = str; bcopy ((char *) old_environ, (char *) (environ + 1), sizeof (char *) * (num_envs+1));#endif /* VMS */}#endif /* HAVE_PUTENV *//* Build a list of search directories from PATHS. PREFIX is a string to prepend to the list. If CHECK_DIR_P is non-zero we ensure the directory exists. This is used mostly by putenv_from_prefixes so we use `collect_obstack'. It is also used by the --print-search-dirs flag. */static char *build_search_list (paths, prefix, check_dir_p) struct path_prefix *paths; char *prefix; int check_dir_p;{ int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0; int just_suffix_len = (just_machine_suffix) ? strlen (just_machine_suffix) : 0; int first_time = TRUE; struct prefix_list *pprefix; obstack_grow (&collect_obstack, prefix, strlen (prefix)); for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next) { int len = strlen (pprefix->prefix); if (machine_suffix && (! check_dir_p || is_directory (pprefix->prefix, machine_suffix, 0))) { if (!first_time) obstack_1grow (&collect_obstack, PATH_SEPARATOR); first_time = FALSE; obstack_grow (&collect_obstack, pprefix->prefix, len); obstack_grow (&collect_obstack, machine_suffix, suffix_len); } if (just_machine_suffix && pprefix->require_machine_suffix == 2 && (! check_dir_p || is_directory (pprefix->prefix, just_machine_suffix, 0))) { if (! first_time) obstack_1grow (&collect_obstack, PATH_SEPARATOR); first_time = FALSE; obstack_grow (&collect_obstack, pprefix->prefix, len); obstack_grow (&collect_obstack, just_machine_suffix, just_suffix_len); } if (! pprefix->require_machine_suffix) { if (! first_time) obstack_1grow (&collect_obstack, PATH_SEPARATOR); first_time = FALSE; obstack_grow (&collect_obstack, pprefix->prefix, len); } } obstack_1grow (&collect_obstack, '\0'); return obstack_finish (&collect_obstack);}/* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables for collect. */static voidputenv_from_prefixes (paths, env_var) struct path_prefix *paths; char *env_var;{ putenv (build_search_list (paths, env_var, 1));}/* Search for NAME using the prefix list PREFIXES. MODE is passed to access to check permissions. Return 0 if not found, otherwise return its name, allocated with malloc. */static char *find_a_file (pprefix, name, mode) struct path_prefix *pprefix; char *name; int mode;{ char *temp; char *file_suffix = ((mode & X_OK) != 0 ? EXECUTABLE_SUFFIX : ""); struct prefix_list *pl; int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1; if (machine_suffix) len += strlen (machine_suffix); temp = xmalloc (len); /* Determine the filename to execute (special case for absolute paths). */ if (*name == '/' || *name == DIR_SEPARATOR /* Check for disk name on MS-DOS-based systems. */ || (DIR_SEPARATOR == '\\' && name[1] == ':' && (name[2] == DIR_SEPARATOR || name[2] == '/'))) { if (access (name, mode)) { strcpy (temp, name); return temp; } } else for (pl = pprefix->plist; pl; pl = pl->next) { if (machine_suffix) { /* Some systems have a suffix for executable files. So try appending that first. */ if (file_suffix[0] != 0) { strcpy (temp, pl->prefix); strcat (temp, machine_suffix); strcat (temp, name); strcat (temp, file_suffix); if (access (temp, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; return temp; } } /* Now try just the name. */ strcpy (temp, pl->prefix); strcat (temp, machine_suffix); strcat (temp, name); if (access (temp, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; return temp; } } /* Certain prefixes are tried with just the machine type, not the version. This is used for finding as, ld, etc. */ if (just_machine_suffix && pl->require_machine_suffix == 2) { /* Some systems have a suffix for executable files. So try appending that first. */ if (file_suffix[0] != 0) { strcpy (temp, pl->prefix); strcat (temp, just_machine_suffix); strcat (temp, name); strcat (temp, file_suffix); if (access (temp, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; return temp; } } strcpy (temp, pl->prefix); strcat (temp, just_machine_suffix); strcat (temp, name); if (access (temp, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; return temp; } } /* Certain prefixes can't be used without the machine suffix when the machine or version is explicitly specified. */ if (! pl->require_machine_suffix) { /* Some systems have a suffix for executable files. So try appending that first. */ if (file_suffix[0] != 0) { strcpy (temp, pl->prefix); strcat (temp, name); strcat (temp, file_suffix); if (access (temp, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; return temp; } } strcpy (temp, pl->prefix); strcat (temp, name); if (access (temp, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; return temp; } } } free (temp); return 0;}/* Add an entry for PREFIX in PLIST. If FIRST is set, it goes at the start of the list, otherwise it goes at the end. If WARN is nonzero, we will warn if no file is found through this prefix. WARN should point to an int which will be set to 1 if this entry is used. COMPONENT is the value to be passed to update_path. REQUIRE_MACHINE_SUFFIX is 1 if this prefix can't be used without the complete value of machine_suffix. 2 means try both machine_suffix and just_machine_suffix. */static voidadd_prefix (pprefix, prefix, component, first, require_machine_suffix, warn) struct path_prefix *pprefix; char *prefix; char *component; int first; int require_machine_suffix; int *warn;{ struct prefix_list *pl, **prev; int len; if (! first && pprefix->plist) { for (pl = pprefix->plist; pl->next; pl = pl->next) ; prev = &pl->next; } else prev = &pprefix->plist; /* Keep track of the longest prefix */ prefix = update_path (prefix, component); len = strlen (prefix); if (len > pprefix->max_len) pprefix->max_len = len; pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list)); pl->prefix = save_string (prefix, len); pl->require_machine_suffix = require_machine_suffix; pl->used_flag_ptr = warn; if (warn) *warn = 0; if (*prev) pl->next = *prev; else pl->next = (struct prefix_list *) 0; *prev = pl;}/* Print warnings for any prefixes in the list PPREFIX that were not used. */static voidunused_prefix_warnings (pprefix) struct path_prefix *pprefix;{ struct prefix_list *pl = pprefix->plist; while (pl) { if (pl->used_flag_ptr != 0 && !*pl->used_flag_ptr) { if (pl->require_machine_suffix && machine_suffix) error ("file path prefix `%s%s' never used", pl->prefix, machine_suffix); else error ("file path prefix `%s' never used", pl->prefix); /* Prevent duplicate warnings. */ *pl->used_flag_ptr = 1; } pl = pl->next; }}/* Get rid of all prefixes built up so far in *PLISTP. */static voidfree_path_prefix (pprefix) struct path_prefix *pprefix;{ struct prefix_list *pl = pprefix->plist; struct prefix_list *temp; while (pl) { temp = pl; pl = pl->next; free (temp->prefix); free ((char *) temp); } pprefix->plist = (struct prefix_list *) 0;}/* Execute the command specified by the arguments on the current line of spec. When using pipes, this includes several piped-together commands with `|' between them. Return 0 if successful, -1 if failed. */static intexecute (){ int i; int n_commands; /* # of command. */ char *string; struct command { char *prog; /* program name. */ char **argv; /* vector of args. */ int pid; /* pid of process for this command. */ }; struct command *commands; /* each command buffer with above info. */ /* Count # of piped commands. */ for (n_commands = 1, i = 0; i < argbuf_index; i++) if (strcmp (argbuf[i], "|") == 0) n_commands++; /* Get storage for each command. */ commands = (struct command *) alloca (n_commands * sizeof (struct command)); /* Split argbuf into its separate piped processes, and record info about each one. Also search for the programs that are to be run. */ commands[0].prog = argbuf[0]; /* first command. */ commands[0].argv = &argbuf[0]; string = find_a_file (&exec_prefixes, commands[0].prog, X_OK); if (string) commands[0].argv[0] = string; for (n_commands = 1, i = 0; i < argbuf_index; i++) if (strcmp (argbuf[i], "|") == 0) { /* each command. */#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__)) || defined (OS2) || defined (VMS) fatal ("-pipe not supported");#endif argbuf[i] = 0; /* termination of command args. */ commands[n_commands].prog = argbuf[i + 1]; commands[n_commands].argv = &argbuf[i + 1]; string = find_a_file (&exec_prefixes, commands[n_commands].prog, X_OK); if (string) commands[n_commands].argv[0] = string; n_commands++; } argbuf[argbuf_index] = 0; /* If -v, print what we are about to do, and maybe query. */ if (verbose_flag) { /* Print each piped command as a separate line. */ for (i = 0; i < n_comma
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -