+ obstack_grow (&collect_obstack, prefix, strlen (prefix));
+ obstack_1grow (&collect_obstack, '=');
+
+ 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 void
+putenv_from_prefixes (paths, env_var)
+ struct path_prefix *paths;
+ const char *env_var;
+{
+ putenv (build_search_list (paths, env_var, 1));
+}
+\f
+#ifndef VMS
+
+/* FIXME: the location independence code for VMS is hairier than this,
+ and hasn't been written. */
+
+/* Split a filename into component directories. */
+
+static char **
+split_directories (name, ptr_num_dirs)
+ const char *name;
+ int *ptr_num_dirs;
+{
+ int num_dirs = 0;
+ char **dirs;
+ const char *p, *q;
+ int ch;
+
+ /* Count the number of directories. Special case MSDOS disk names as part
+ of the initial directory. */
+ p = name;
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ if (name[1] == ':' && IS_DIR_SEPARATOR (name[2]))
+ {
+ p += 3;
+ num_dirs++;
+ }
+#endif /* HAVE_DOS_BASED_FILE_SYSTEM */
+
+ while ((ch = *p++) != '\0')
+ {
+ if (IS_DIR_SEPARATOR (ch))
+ {
+ num_dirs++;
+ while (IS_DIR_SEPARATOR (*p))
+ p++;
+ }
+ }
+
+ dirs = (char **) xmalloc (sizeof (char *) * (num_dirs + 2));
+
+ /* Now copy the directory parts. */
+ num_dirs = 0;
+ p = name;
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ if (name[1] == ':' && IS_DIR_SEPARATOR (name[2]))
+ {
+ dirs[num_dirs++] = save_string (p, 3);
+ p += 3;
+ }
+#endif /* HAVE_DOS_BASED_FILE_SYSTEM */
+
+ q = p;
+ while ((ch = *p++) != '\0')
+ {
+ if (IS_DIR_SEPARATOR (ch))
+ {
+ while (IS_DIR_SEPARATOR (*p))
+ p++;
+
+ dirs[num_dirs++] = save_string (q, p - q);
+ q = p;
+ }
+ }
+
+ if (p - 1 - q > 0)
+ dirs[num_dirs++] = save_string (q, p - 1 - q);
+
+ dirs[num_dirs] = NULL_PTR;
+ if (ptr_num_dirs)
+ *ptr_num_dirs = num_dirs;
+
+ return dirs;
+}
+
+/* Release storage held by split directories. */
+
+static void
+free_split_directories (dirs)
+ char **dirs;
+{
+ int i = 0;
+
+ while (dirs[i] != NULL_PTR)
+ free (dirs[i++]);
+
+ free ((char *) dirs);
+}
+
+/* Given three strings PROGNAME, BIN_PREFIX, PREFIX, return a string that gets
+ to PREFIX starting with the directory portion of PROGNAME and a relative
+ pathname of the difference between BIN_PREFIX and PREFIX.
+
+ For example, if BIN_PREFIX is /alpha/beta/gamma/gcc/delta, PREFIX is
+ /alpha/beta/gamma/omega/, and PROGNAME is /red/green/blue/gcc, then this
+ function will return /red/green/blue/../omega.
+
+ If no relative prefix can be found, return NULL. */
+
+static char *
+make_relative_prefix (progname, bin_prefix, prefix)
+ const char *progname;
+ const char *bin_prefix;
+ const char *prefix;
+{
+ char **prog_dirs, **bin_dirs, **prefix_dirs;
+ int prog_num, bin_num, prefix_num, std_loc_p;
+ int i, n, common;
+
+ prog_dirs = split_directories (progname, &prog_num);
+ bin_dirs = split_directories (bin_prefix, &bin_num);