public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Add make_relative_prefix to libiberty
@ 2002-11-18  9:39 Daniel Jacobowitz
  2002-11-18 11:44 ` DJ Delorie
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2002-11-18  9:39 UTC (permalink / raw)
  To: gcc-patches; +Cc: dj

This is something I've been needing for a while.  I'm about to add some
relocation support to GNU LD, and it needs the same make_relative_prefix
logic that GCC does.  So I'd like to move make_relative_prefix from gcc.c to
libiberty.  Is this reasonable?  OK to commit?

The functions in this patch are copied verbatim from gcc/gcc.c (3.4-bib),
with two exceptions:
 - A bug fix involving n vs. bin_num which I've posted to this list several
times as part of other patches, still awaiting review.
 - An init_obstack call in make_relative_prefix now that we no longer have
GCC's global obstack for temporary strings.

(The patch is against b-i-b, sorry - it applies to HEAD also except for the
removal of an unused variable std_loc_p on b-i-b.  I'm asking that this
patch be considered for HEAD, so that I can use it in src/.)

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2002-11-18  Daniel Jacobowitz  <drow@mvista.com>

	* libiberty.h (make_relative_prefix): Add prototype.

2002-11-18  Daniel Jacobowitz  <drow@mvista.com>

	* gcc.c (make_relative_prefix): Remove.
	(free_split_directores, split_directories): Remove.

2002-11-18  Daniel Jacobowitz  <drow@mvista.com>

	* Makefile.in: Add make-relative-prefix.c.
	* make-relative-prefix.c: New file.

Index: libiberty/Makefile.in
===================================================================
RCS file: /cvs/src/src/libiberty/Makefile.in,v
retrieving revision 1.37
diff -u -p -r1.37 Makefile.in
--- libiberty/Makefile.in	23 Sep 2002 12:08:57 -0000	1.37
+++ libiberty/Makefile.in	18 Nov 2002 17:25:25 -0000
@@ -135,6 +135,7 @@ CFILES = alloca.c argv.c asprintf.c atex
 	hashtab.c hex.c							\
 	index.c insque.c						\
 	lbasename.c							\
+	make-relative-prefix.c						\
 	make-temp-file.c md5.c memchr.c memcmp.c memcpy.c memmove.c	\
 	 memset.c mkstemps.c						\
 	objalloc.c obstack.c						\
@@ -159,6 +160,7 @@ REQUIRED_OFILES = regex.o cplus-dem.o cp
 	getopt.o getopt1.o getpwd.o getruntime.o			\
 	hashtab.o hex.o							\
 	lbasename.o							\
+	make-relative-prefix.o						\
 	make-temp-file.o						\
 	objalloc.o obstack.o						\
 	partition.o pexecute.o						\
@@ -432,6 +434,8 @@ hashtab.o: config.h $(INCDIR)/ansidecl.h
 hex.o: $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
 lbasename.o: $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
 	$(INCDIR)/safe-ctype.h
+make-relative-prefix.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
+	$(INCDIR)/obstack.h
 make-temp-file.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
 md5.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/md5.h
 memchr.o: $(INCDIR)/ansidecl.h
Index: libiberty/make-relative-prefix.c
===================================================================
RCS file: libiberty/make-relative-prefix.c
diff -N libiberty/make-relative-prefix.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libiberty/make-relative-prefix.c	18 Nov 2002 17:25:25 -0000
@@ -0,0 +1,329 @@
+/* Relative (relocatable) prefix support.
+   Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/*
+
+@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, const char *@var{bin_prefix}, const char *@var{prefix})
+
+Given pointers to the @code{argv[0]}, the default installation directory
+for this program, and the default location of another directory, this function
+returns the path to the other directory assuming the installation tree has moved
+from @var{bin_prefix} to the new location of @var{progname}.
+
+@end deftypefn
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ansidecl.h"
+#include "libiberty.h"
+#include "obstack.h"
+
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#endif
+
+#ifndef DIR_SEPARATOR
+#  define DIR_SEPARATOR '/'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) \
+    || defined (__DJGPP__) || defined (__OS2__)
+#  define HAVE_DOS_BASED_FILE_SYSTEM
+#  define HOST_EXECUTABLE_SUFFIX ".exe"
+#  ifndef DIR_SEPARATOR_2 
+#    define DIR_SEPARATOR_2 '\\'
+#  endif
+#  define PATH_SEPARATOR ';'
+#else
+#  define PATH_SEPARATOR ':'
+#endif
+
+#ifndef DIR_SEPARATOR_2
+#  define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else
+#  define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif
+
+#define DIR_UP ".."
+
+static char *save_string PARAMS ((const char *, int));
+static char **split_directories	PARAMS ((const char *, int *));
+static void free_split_directories PARAMS ((char **));
+
+static char *
+save_string (s, len)
+     const char *s;
+     int len;
+{
+  char *result = xmalloc (len + 1);
+
+  memcpy (result, s, len);
+  result[len] = 0;
+  return result;
+}
+
+/* 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;
+  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)
+    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.  */
+
+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;
+  int i, n, common;
+  struct obstack obstack;
+
+  init_obstack (&obstack);
+
+  prog_dirs = split_directories (progname, &prog_num);
+  bin_dirs = split_directories (bin_prefix, &bin_num);
+
+  /* If there is no full pathname, try to find the program by checking in each
+     of the directories specified in the PATH environment variable.  */
+  if (prog_num == 1)
+    {
+      char *temp;
+
+      temp = getenv ("PATH");
+      if (temp)
+	{
+	  char *startp, *endp, *nstore;
+	  size_t prefixlen = strlen (temp) + 1;
+	  if (prefixlen < 2)
+	    prefixlen = 2;
+
+	  nstore = (char *) alloca (prefixlen + strlen (progname) + 1);
+
+	  startp = endp = temp;
+	  while (1)
+	    {
+	      if (*endp == PATH_SEPARATOR || *endp == 0)
+		{
+		  if (endp == startp)
+		    {
+		      nstore[0] = '.';
+		      nstore[1] = DIR_SEPARATOR;
+		      nstore[2] = '\0';
+		    }
+		  else
+		    {
+		      strncpy (nstore, startp, endp - startp);
+		      if (! IS_DIR_SEPARATOR (endp[-1]))
+			{
+			  nstore[endp - startp] = DIR_SEPARATOR;
+			  nstore[endp - startp + 1] = 0;
+			}
+		      else
+			nstore[endp - startp] = 0;
+		    }
+		  strcat (nstore, progname);
+		  if (! access (nstore, X_OK)
+#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
+                      || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK)
+#endif
+		      )
+		    {
+		      free_split_directories (prog_dirs);
+		      progname = nstore;
+		      prog_dirs = split_directories (progname, &prog_num);
+		      break;
+		    }
+
+		  if (*endp == 0)
+		    break;
+		  endp = startp = endp + 1;
+		}
+	      else
+		endp++;
+	    }
+	}
+    }
+
+  /* Remove the program name from comparison of directory names.  */
+  prog_num--;
+
+  /* Determine if the compiler is installed in the standard location, and if
+     so, we don't need to specify relative directories.  Also, if argv[0]
+     doesn't contain any directory specifiers, there is not much we can do.  */
+  if (prog_num == bin_num)
+    {
+      for (i = 0; i < bin_num; i++)
+	{
+	  if (strcmp (prog_dirs[i], bin_dirs[i]) != 0)
+	    break;
+	}
+
+      if (prog_num <= 0 || i == bin_num)
+	{
+	  free_split_directories (prog_dirs);
+	  free_split_directories (bin_dirs);
+	  prog_dirs = bin_dirs = (char **) 0;
+	  return NULL;
+	}
+    }
+
+  prefix_dirs = split_directories (prefix, &prefix_num);
+
+  /* Find how many directories are in common between bin_prefix & prefix.  */
+  n = (prefix_num < bin_num) ? prefix_num : bin_num;
+  for (common = 0; common < n; common++)
+    {
+      if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0)
+	break;
+    }
+
+  /* If there are no common directories, there can be no relative prefix.  */
+  if (common == 0)
+    {
+      free_split_directories (prog_dirs);
+      free_split_directories (bin_dirs);
+      free_split_directories (prefix_dirs);
+      return NULL;
+    }
+
+  /* Build up the pathnames in argv[0].  */
+  for (i = 0; i < prog_num; i++)
+    obstack_grow (&obstack, prog_dirs[i], strlen (prog_dirs[i]));
+
+  /* Now build up the ..'s.  */
+  for (i = common; i < bin_num; i++)
+    {
+      obstack_grow (&obstack, DIR_UP, sizeof (DIR_UP) - 1);
+      obstack_1grow (&obstack, DIR_SEPARATOR);
+    }
+
+  /* Put in directories to move over to prefix.  */
+  for (i = common; i < prefix_num; i++)
+    obstack_grow (&obstack, prefix_dirs[i], strlen (prefix_dirs[i]));
+
+  free_split_directories (prog_dirs);
+  free_split_directories (bin_dirs);
+  free_split_directories (prefix_dirs);
+
+  obstack_1grow (&obstack, '\0');
+  return obstack_finish (&obstack);
+}
Index: include/libiberty.h
===================================================================
RCS file: /cvs/src/src/include/libiberty.h,v
retrieving revision 1.18
diff -u -p -r1.18 libiberty.h
--- include/libiberty.h	20 Sep 2002 00:21:58 -0000	1.18
+++ include/libiberty.h	18 Nov 2002 17:26:10 -0000
@@ -145,6 +145,11 @@ extern char * getpwd PARAMS ((void));
 
 extern long get_run_time PARAMS ((void));
 
+/* Generate a relocated path to some installation directory.  */
+
+extern char *make_relative_prefix PARAMS ((const char *, const char *,
+					   const char *));
+
 /* Choose a temporary directory to use for scratch files.  */
 
 extern char *choose_temp_base PARAMS ((void)) ATTRIBUTE_MALLOC;
Index: gcc/gcc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcc.c,v
retrieving revision 1.336.4.10
diff -u -p -r1.336.4.10 gcc.c
--- gcc/gcc.c	21 Oct 2002 17:51:57 -0000	1.336.4.10
+++ gcc/gcc.c	18 Nov 2002 17:33:01 -0000
@@ -277,11 +281,6 @@ static struct rusage rus, prus;
 struct path_prefix;
 
 static void init_spec		PARAMS ((void));
-#ifndef VMS
-static char **split_directories	PARAMS ((const char *, int *));
-static void free_split_directories PARAMS ((char **));
-static char *make_relative_prefix PARAMS ((const char *, const char *, const char *));
-#endif /* VMS */
 static void store_arg		PARAMS ((const char *, int, int));
 static char *load_specs		PARAMS ((const char *));
 static void read_specs		PARAMS ((const char *, int));
@@ -2306,244 +2307,6 @@ putenv_from_prefixes (paths, 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;
-  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)
-    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;
-  int i, n, common;
-
-  prog_dirs = split_directories (progname, &prog_num);
-  bin_dirs = split_directories (bin_prefix, &bin_num);
-
-  /* If there is no full pathname, try to find the program by checking in each
-     of the directories specified in the PATH environment variable.  */
-  if (prog_num == 1)
-    {
-      char *temp;
-
-      GET_ENVIRONMENT (temp, "PATH");
-      if (temp)
-	{
-	  char *startp, *endp, *nstore;
-	  size_t prefixlen = strlen (temp) + 1;
-	  if (prefixlen < 2)
-	    prefixlen = 2;
-
-	  nstore = (char *) alloca (prefixlen + strlen (progname) + 1);
-
-	  startp = endp = temp;
-	  while (1)
-	    {
-	      if (*endp == PATH_SEPARATOR || *endp == 0)
-		{
-		  if (endp == startp)
-		    {
-		      nstore[0] = '.';
-		      nstore[1] = DIR_SEPARATOR;
-		      nstore[2] = '\0';
-		    }
-		  else
-		    {
-		      strncpy (nstore, startp, endp - startp);
-		      if (! IS_DIR_SEPARATOR (endp[-1]))
-			{
-			  nstore[endp - startp] = DIR_SEPARATOR;
-			  nstore[endp - startp + 1] = 0;
-			}
-		      else
-			nstore[endp - startp] = 0;
-		    }
-		  strcat (nstore, progname);
-		  if (! access (nstore, X_OK)
-#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
-                      || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK)
-#endif
-		      )
-		    {
-		      free_split_directories (prog_dirs);
-		      progname = nstore;
-		      prog_dirs = split_directories (progname, &prog_num);
-		      break;
-		    }
-
-		  if (*endp == 0)
-		    break;
-		  endp = startp = endp + 1;
-		}
-	      else
-		endp++;
-	    }
-	}
-    }
-
-  /* Remove the program name from comparison of directory names.  */
-  prog_num--;
-
-  /* Determine if the compiler is installed in the standard location, and if
-     so, we don't need to specify relative directories.  Also, if argv[0]
-     doesn't contain any directory specifiers, there is not much we can do.  */
-  if (prog_num == bin_num)
-    {
-      for (i = 0; i < bin_num; i++)
-	{
-	  if (strcmp (prog_dirs[i], bin_dirs[i]) != 0)
-	    break;
-	}
-
-      if (prog_num <= 0 || i == bin_num)
-	{
-	  free_split_directories (prog_dirs);
-	  free_split_directories (bin_dirs);
-	  prog_dirs = bin_dirs = (char **) 0;
-	  return NULL;
-	}
-    }
-
-  prefix_dirs = split_directories (prefix, &prefix_num);
-
-  /* Find how many directories are in common between bin_prefix & prefix.  */
-  n = (prefix_num < bin_num) ? prefix_num : bin_num;
-  for (common = 0; common < n; common++)
-    {
-      if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0)
-	break;
-    }
-
-  /* If there are no common directories, there can be no relative prefix.  */
-  if (common == 0)
-    {
-      free_split_directories (prog_dirs);
-      free_split_directories (bin_dirs);
-      free_split_directories (prefix_dirs);
-      return NULL;
-    }
-
-  /* Build up the pathnames in argv[0].  */
-  for (i = 0; i < prog_num; i++)
-    obstack_grow (&obstack, prog_dirs[i], strlen (prog_dirs[i]));
-
-  /* Now build up the ..'s.  */
-  for (i = common; i < n; i++)
-    {
-      obstack_grow (&obstack, DIR_UP, sizeof (DIR_UP) - 1);
-      obstack_1grow (&obstack, DIR_SEPARATOR);
-    }
-
-  /* Put in directories to move over to prefix.  */
-  for (i = common; i < prefix_num; i++)
-    obstack_grow (&obstack, prefix_dirs[i], strlen (prefix_dirs[i]));
-
-  free_split_directories (prog_dirs);
-  free_split_directories (bin_dirs);
-  free_split_directories (prefix_dirs);
-
-  obstack_1grow (&obstack, '\0');
-  return obstack_finish (&obstack);
-}
-#endif /* VMS */
-\f
 /* Check whether NAME can be accessed in MODE.  This is like access,
    except that it never considers directories to be executable.  */
 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Add make_relative_prefix to libiberty
  2002-11-18  9:39 Add make_relative_prefix to libiberty Daniel Jacobowitz
@ 2002-11-18 11:44 ` DJ Delorie
  2002-11-18 16:24   ` Daniel Jacobowitz
  0 siblings, 1 reply; 8+ messages in thread
From: DJ Delorie @ 2002-11-18 11:44 UTC (permalink / raw)
  To: drow; +Cc: gcc-patches


> 2002-11-18  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* libiberty.h (make_relative_prefix): Add prototype.
> 
> 2002-11-18  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* Makefile.in: Add make-relative-prefix.c.
> 	* make-relative-prefix.c: New file.

You're creating an obstack which will become impossible to clean up
after.  Please just call malloc (not xmalloc).  Return NULL on
allocation failure.  Please note the allocation rules in the header.
Please regenerate the documentation from the source.  Please check for
valid (i.e. non-NULL arguments).  The comment "Determine if the
compiler is installed in the standard location" would no longer be
appropriate.  You may not call xmalloc or friends from any of these
functions, you must instead signal an allocation error to the
application somehow.

You have also changed the copyright terms (GPL -> LGPL).  Do you have
the FSF's permission to do so?

> 2002-11-18  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* gcc.c (make_relative_prefix): Remove.
> 	(free_split_directores, split_directories): Remove.

I can't approve the gcc changes, of course.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Add make_relative_prefix to libiberty
  2002-11-18 11:44 ` DJ Delorie
@ 2002-11-18 16:24   ` Daniel Jacobowitz
  2002-11-18 16:52     ` DJ Delorie
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2002-11-18 16:24 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc-patches

Does it show that I haven't patched libiberty before?  Thanks for the
patience.

On Mon, Nov 18, 2002 at 02:44:38PM -0500, DJ Delorie wrote:
> 
> > 2002-11-18  Daniel Jacobowitz  <drow@mvista.com>
> > 
> > 	* libiberty.h (make_relative_prefix): Add prototype.
> > 
> > 2002-11-18  Daniel Jacobowitz  <drow@mvista.com>
> > 
> > 	* Makefile.in: Add make-relative-prefix.c.
> > 	* make-relative-prefix.c: New file.
> 
> You're creating an obstack which will become impossible to clean up
> after.  Please just call malloc (not xmalloc).  Return NULL on
> allocation failure.  Please note the allocation rules in the header.

The problem is that this function makes use of growable obstacks. 
Unfortunately obstacks by default abort on allocation failure... I've
rewritten it to use malloc.

Which header?  I do not see allocation rules, just a list of how
different functions in libiberty allocate memory.  A number of them use
xmalloc to do it.  Much simpler for an initialization function like
this one.

> Please regenerate the documentation from the source.

Done.

>  Please check for
> valid (i.e. non-NULL arguments).

Done.  I'm of the glibc school of mind on this (if my interface says
"takes a string" and you give me NULL, it's your own fault) but it's
easy enough.

>  The comment "Determine if the
> compiler is installed in the standard location" would no longer be
> appropriate.

Thanks, updated.

>  You may not call xmalloc or friends from any of these
> functions, you must instead signal an allocation error to the
> application somehow.

By returning NULL in this case.

> You have also changed the copyright terms (GPL -> LGPL).  Do you have
> the FSF's permission to do so?

No.  It was just me being sloppy; I apologize.  I copied the wrong
copyright notice; I think I grabbed it from lbasename.  Since I see a
number of GPL source files in libiberty, I assume that there is no
problem with adding a GPL'd source file to the libiberty directory?

Revised patch attached (actually against HEAD this time); retested on
i386-debian-linux-gnu x. sh4-elf. Have I missed anything?

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2002-11-18  Daniel Jacobowitz  <drow@mvista.com>

	* libiberty.h (make_relative_prefix): Add prototype.

2002-11-18  Daniel Jacobowitz  <drow@mvista.com>

	* Makefile.in: Add make-relative-prefix.c.
	* make-relative-prefix.c: New file.
	* functions.texi: Rebuilt.

2002-11-18  Daniel Jacobowitz  <drow@mvista.com>

	* gcc.c (make_relative_prefix, split_directories)
	(free_split_directories): Removed.

Index: gcc/gcc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcc.c,v
retrieving revision 1.344
diff -u -p -r1.344 gcc.c
--- gcc/gcc.c	14 Oct 2002 07:15:38 -0000	1.344
+++ gcc/gcc.c	19 Nov 2002 00:18:23 -0000
@@ -267,11 +267,6 @@ static struct rusage rus, prus;
 struct path_prefix;
 
 static void init_spec		PARAMS ((void));
-#ifndef VMS
-static char **split_directories	PARAMS ((const char *, int *));
-static void free_split_directories PARAMS ((char **));
-static char *make_relative_prefix PARAMS ((const char *, const char *, const char *));
-#endif /* VMS */
 static void store_arg		PARAMS ((const char *, int, int));
 static char *load_specs		PARAMS ((const char *));
 static void read_specs		PARAMS ((const char *, int));
@@ -2249,246 +2244,6 @@ putenv_from_prefixes (paths, 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;
-  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)
-    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);
-
-  /* If there is no full pathname, try to find the program by checking in each
-     of the directories specified in the PATH environment variable.  */
-  if (prog_num == 1)
-    {
-      char *temp;
-
-      GET_ENVIRONMENT (temp, "PATH");
-      if (temp)
-	{
-	  char *startp, *endp, *nstore;
-	  size_t prefixlen = strlen (temp) + 1;
-	  if (prefixlen < 2)
-	    prefixlen = 2;
-
-	  nstore = (char *) alloca (prefixlen + strlen (progname) + 1);
-
-	  startp = endp = temp;
-	  while (1)
-	    {
-	      if (*endp == PATH_SEPARATOR || *endp == 0)
-		{
-		  if (endp == startp)
-		    {
-		      nstore[0] = '.';
-		      nstore[1] = DIR_SEPARATOR;
-		      nstore[2] = '\0';
-		    }
-		  else
-		    {
-		      strncpy (nstore, startp, endp - startp);
-		      if (! IS_DIR_SEPARATOR (endp[-1]))
-			{
-			  nstore[endp - startp] = DIR_SEPARATOR;
-			  nstore[endp - startp + 1] = 0;
-			}
-		      else
-			nstore[endp - startp] = 0;
-		    }
-		  strcat (nstore, progname);
-		  if (! access (nstore, X_OK)
-#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
-                      || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK)
-#endif
-		      )
-		    {
-		      free_split_directories (prog_dirs);
-		      progname = nstore;
-		      prog_dirs = split_directories (progname, &prog_num);
-		      break;
-		    }
-
-		  if (*endp == 0)
-		    break;
-		  endp = startp = endp + 1;
-		}
-	      else
-		endp++;
-	    }
-	}
-    }
-
-  /* Remove the program name from comparison of directory names.  */
-  prog_num--;
-
-  /* Determine if the compiler is installed in the standard location, and if
-     so, we don't need to specify relative directories.  Also, if argv[0]
-     doesn't contain any directory specifiers, there is not much we can do.  */
-  std_loc_p = 0;
-  if (prog_num == bin_num)
-    {
-      for (i = 0; i < bin_num; i++)
-	{
-	  if (strcmp (prog_dirs[i], bin_dirs[i]) != 0)
-	    break;
-	}
-
-      if (prog_num <= 0 || i == bin_num)
-	{
-	  std_loc_p = 1;
-	  free_split_directories (prog_dirs);
-	  free_split_directories (bin_dirs);
-	  prog_dirs = bin_dirs = (char **) 0;
-	  return NULL;
-	}
-    }
-
-  prefix_dirs = split_directories (prefix, &prefix_num);
-
-  /* Find how many directories are in common between bin_prefix & prefix.  */
-  n = (prefix_num < bin_num) ? prefix_num : bin_num;
-  for (common = 0; common < n; common++)
-    {
-      if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0)
-	break;
-    }
-
-  /* If there are no common directories, there can be no relative prefix.  */
-  if (common == 0)
-    {
-      free_split_directories (prog_dirs);
-      free_split_directories (bin_dirs);
-      free_split_directories (prefix_dirs);
-      return NULL;
-    }
-
-  /* Build up the pathnames in argv[0].  */
-  for (i = 0; i < prog_num; i++)
-    obstack_grow (&obstack, prog_dirs[i], strlen (prog_dirs[i]));
-
-  /* Now build up the ..'s.  */
-  for (i = common; i < n; i++)
-    {
-      obstack_grow (&obstack, DIR_UP, sizeof (DIR_UP) - 1);
-      obstack_1grow (&obstack, DIR_SEPARATOR);
-    }
-
-  /* Put in directories to move over to prefix.  */
-  for (i = common; i < prefix_num; i++)
-    obstack_grow (&obstack, prefix_dirs[i], strlen (prefix_dirs[i]));
-
-  free_split_directories (prog_dirs);
-  free_split_directories (bin_dirs);
-  free_split_directories (prefix_dirs);
-
-  obstack_1grow (&obstack, '\0');
-  return obstack_finish (&obstack);
-}
-#endif /* VMS */
 \f
 /* Check whether NAME can be accessed in MODE.  This is like access,
    except that it never considers directories to be executable.  */
Index: include/libiberty.h
===================================================================
RCS file: /cvs/gcc/gcc/include/libiberty.h,v
retrieving revision 1.29
diff -u -p -r1.29 libiberty.h
--- include/libiberty.h	20 Sep 2002 00:21:54 -0000	1.29
+++ include/libiberty.h	19 Nov 2002 00:18:25 -0000
@@ -145,6 +145,11 @@ extern char * getpwd PARAMS ((void));
 
 extern long get_run_time PARAMS ((void));
 
+/* Generate a relocated path to some installation directory.  */
+
+extern char *make_relative_prefix PARAMS ((const char *, const char *,
+					   const char *));
+
 /* Choose a temporary directory to use for scratch files.  */
 
 extern char *choose_temp_base PARAMS ((void)) ATTRIBUTE_MALLOC;
Index: libiberty/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/Makefile.in,v
retrieving revision 1.77
diff -u -p -r1.77 Makefile.in
--- libiberty/Makefile.in	23 Sep 2002 03:52:51 -0000	1.77
+++ libiberty/Makefile.in	19 Nov 2002 00:18:25 -0000
@@ -135,6 +135,7 @@ CFILES = alloca.c argv.c asprintf.c atex
 	hashtab.c hex.c							\
 	index.c insque.c						\
 	lbasename.c							\
+	make-relative-prefix.c						\
 	make-temp-file.c md5.c memchr.c memcmp.c memcpy.c memmove.c	\
 	 memset.c mkstemps.c						\
 	objalloc.c obstack.c						\
@@ -159,6 +160,7 @@ REQUIRED_OFILES = regex.o cplus-dem.o cp
 	getopt.o getopt1.o getpwd.o getruntime.o			\
 	hashtab.o hex.o							\
 	lbasename.o							\
+	make-relative-prefix.o						\
 	make-temp-file.o						\
 	objalloc.o obstack.o						\
 	partition.o pexecute.o						\
@@ -432,6 +434,8 @@ hashtab.o: config.h $(INCDIR)/ansidecl.h
 hex.o: $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
 lbasename.o: $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
 	$(INCDIR)/safe-ctype.h
+make-relative-prefix.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
+	$(INCDIR)/obstack.h
 make-temp-file.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
 md5.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/md5.h
 memchr.o: $(INCDIR)/ansidecl.h
Index: libiberty/functions.texi
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/functions.texi,v
retrieving revision 1.8
diff -u -p -r1.8 functions.texi
--- libiberty/functions.texi	28 Mar 2002 04:04:20 -0000	1.8
+++ libiberty/functions.texi	19 Nov 2002 00:18:25 -0000
@@ -276,7 +276,7 @@ itself.
 
 @end deftypefn
 
-@c getruntime.c:78
+@c getruntime.c:82
 @deftypefn Replacement long get_run_time (void)
 
 Returns the time used so far, in microseconds.  If possible, this is
@@ -322,11 +322,12 @@ between calls to @code{getpwd}.
 
 Initializes the array mapping the current character set to
 corresponding hex values.  This function must be called before any
-call to @code{hex_p} or @code{hex_value}.
+call to @code{hex_p} or @code{hex_value}.  If you fail to call it, a
+default ASCII-based table will normally be used on ASCII systems.
 
 @end deftypefn
 
-@c hex.c:33
+@c hex.c:34
 @deftypefn Extension int hex_p (int @var{c})
 
 Evaluates to non-zero if the given character is a valid hex character,
@@ -335,7 +336,7 @@ or zero if it is not.  Note that the val
 
 @end deftypefn
 
-@c hex.c:41
+@c hex.c:42
 @deftypefn Extension int hex_value (int @var{c})
 
 Returns the numeric equivalent of the given character when interpreted
@@ -388,6 +389,16 @@ strings for particular input.
 
 In particular, the empty string returns the same empty string,
 and a path ending in @code{/} returns the empty string after it.
+
+@end deftypefn
+
+@c make-relative-prefix.c:24
+@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, const char *@var{bin_prefix}, const char *@var{prefix})
+
+Given pointers to the @code{argv[0]}, the default installation directory
+for this program, and the default location of another directory, this function
+returns the path to the other directory assuming the installation tree has moved
+from @var{bin_prefix} to the new location of @var{progname}.
 
 @end deftypefn
 
Index: libiberty/make-relative-prefix.c
===================================================================
RCS file: libiberty/make-relative-prefix.c
diff -N libiberty/make-relative-prefix.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libiberty/make-relative-prefix.c	19 Nov 2002 00:18:25 -0000
@@ -0,0 +1,381 @@
+/* Relative (relocatable) prefix support.
+   Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+/*
+
+@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, const char *@var{bin_prefix}, const char *@var{prefix})
+
+Given pointers to the @code{argv[0]}, the default installation directory
+for this program, and the default location of another directory, this function
+returns the path to the other directory assuming the installation tree has moved
+from @var{bin_prefix} to the new location of @var{progname}.
+
+@end deftypefn
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <string.h>
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#endif
+
+#ifndef DIR_SEPARATOR
+#  define DIR_SEPARATOR '/'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) \
+    || defined (__DJGPP__) || defined (__OS2__)
+#  define HAVE_DOS_BASED_FILE_SYSTEM
+#  define HOST_EXECUTABLE_SUFFIX ".exe"
+#  ifndef DIR_SEPARATOR_2 
+#    define DIR_SEPARATOR_2 '\\'
+#  endif
+#  define PATH_SEPARATOR ';'
+#else
+#  define PATH_SEPARATOR ':'
+#endif
+
+#ifndef DIR_SEPARATOR_2
+#  define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else
+#  define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif
+
+#define DIR_UP ".."
+
+static char *save_string PARAMS ((const char *, int));
+static char **split_directories	PARAMS ((const char *, int *));
+static void free_split_directories PARAMS ((char **));
+
+static char *
+save_string (s, len)
+     const char *s;
+     int len;
+{
+  char *result = malloc (len + 1);
+
+  memcpy (result, s, len);
+  result[len] = 0;
+  return result;
+}
+
+/* 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 **) malloc (sizeof (char *) * (num_dirs + 2));
+  if (dirs == NULL)
+    return NULL;
+
+  /* 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);
+      if (dirs[num_dirs - 1] == NULL)
+	{
+	  free (dirs);
+	  return NULL;
+	}
+      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);
+	  if (dirs[num_dirs - 1] == NULL)
+	    {
+	      dirs[num_dirs] = NULL;
+	      free_split_directories (dirs);
+	      return NULL;
+	    }
+	  q = p;
+	}
+    }
+
+  if (p - 1 - q > 0)
+    dirs[num_dirs++] = save_string (q, p - 1 - q);
+  dirs[num_dirs] = NULL;
+
+  if (dirs[num_dirs - 1] == NULL)
+    {
+      free_split_directories (dirs);
+      return NULL;
+    }
+
+  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)
+    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.  */
+
+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;
+  int i, n, common;
+  int needed_len;
+  char *ret, *ptr;
+
+  if (progname == NULL || bin_prefix == NULL || prefix == NULL)
+    return NULL;
+
+  prog_dirs = split_directories (progname, &prog_num);
+  bin_dirs = split_directories (bin_prefix, &bin_num);
+  if (bin_dirs == NULL || prog_dirs == NULL)
+    return NULL;
+
+  /* If there is no full pathname, try to find the program by checking in each
+     of the directories specified in the PATH environment variable.  */
+  if (prog_num == 1)
+    {
+      char *temp;
+
+      temp = getenv ("PATH");
+      if (temp)
+	{
+	  char *startp, *endp, *nstore;
+	  size_t prefixlen = strlen (temp) + 1;
+	  if (prefixlen < 2)
+	    prefixlen = 2;
+
+	  nstore = (char *) alloca (prefixlen + strlen (progname) + 1);
+
+	  startp = endp = temp;
+	  while (1)
+	    {
+	      if (*endp == PATH_SEPARATOR || *endp == 0)
+		{
+		  if (endp == startp)
+		    {
+		      nstore[0] = '.';
+		      nstore[1] = DIR_SEPARATOR;
+		      nstore[2] = '\0';
+		    }
+		  else
+		    {
+		      strncpy (nstore, startp, endp - startp);
+		      if (! IS_DIR_SEPARATOR (endp[-1]))
+			{
+			  nstore[endp - startp] = DIR_SEPARATOR;
+			  nstore[endp - startp + 1] = 0;
+			}
+		      else
+			nstore[endp - startp] = 0;
+		    }
+		  strcat (nstore, progname);
+		  if (! access (nstore, X_OK)
+#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
+                      || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK)
+#endif
+		      )
+		    {
+		      free_split_directories (prog_dirs);
+		      progname = nstore;
+		      prog_dirs = split_directories (progname, &prog_num);
+		      if (prog_dirs == NULL)
+			{
+			  free_split_directories (bin_dirs);
+			  return NULL;
+			}
+		      break;
+		    }
+
+		  if (*endp == 0)
+		    break;
+		  endp = startp = endp + 1;
+		}
+	      else
+		endp++;
+	    }
+	}
+    }
+
+  /* Remove the program name from comparison of directory names.  */
+  prog_num--;
+
+  /* If we are still installed in the standard location, we don't need to
+     specify relative directories.  Also, if argv[0] still doesn't contain
+     any directory specifiers after the search above, then there is not much
+     we can do.  */
+  if (prog_num == bin_num)
+    {
+      for (i = 0; i < bin_num; i++)
+	{
+	  if (strcmp (prog_dirs[i], bin_dirs[i]) != 0)
+	    break;
+	}
+
+      if (prog_num <= 0 || i == bin_num)
+	{
+	  free_split_directories (prog_dirs);
+	  free_split_directories (bin_dirs);
+	  prog_dirs = bin_dirs = (char **) 0;
+	  return NULL;
+	}
+    }
+
+  prefix_dirs = split_directories (prefix, &prefix_num);
+  if (prefix_dirs == NULL)
+    {
+      free_split_directories (prog_dirs);
+      free_split_directories (bin_dirs);
+      return NULL;
+    }
+
+  /* Find how many directories are in common between bin_prefix & prefix.  */
+  n = (prefix_num < bin_num) ? prefix_num : bin_num;
+  for (common = 0; common < n; common++)
+    {
+      if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0)
+	break;
+    }
+
+  /* If there are no common directories, there can be no relative prefix.  */
+  if (common == 0)
+    {
+      free_split_directories (prog_dirs);
+      free_split_directories (bin_dirs);
+      free_split_directories (prefix_dirs);
+      return NULL;
+    }
+
+  /* Two passes: first figure out the size of the result string, and
+     then construct it.  */
+  needed_len = 0;
+  for (i = 0; i < prog_num; i++)
+    needed_len += strlen (prog_dirs[i]);
+  needed_len += sizeof (DIR_UP) * (bin_num - common);
+  for (i = common; i < prefix_num; i++)
+    needed_len += strlen (prefix_dirs[i]);
+  needed_len += 1; /* Trailing NUL.  */
+
+  ret = (char *) malloc (needed_len);
+  if (ret == NULL)
+    return NULL;
+
+  /* Build up the pathnames in argv[0].  */
+  for (i = 0; i < prog_num; i++)
+    strcat (ret, prog_dirs[i]);
+
+  /* Now build up the ..'s.  */
+  ptr = ret + strlen(ret);
+  for (i = common; i < bin_num; i++)
+    {
+      strcpy (ptr, DIR_UP);
+      ptr += sizeof (DIR_UP) - 1;
+      *(ptr++) = DIR_SEPARATOR;
+    }
+  *ptr = '\0';
+
+  /* Put in directories to move over to prefix.  */
+  for (i = common; i < prefix_num; i++)
+    strcat (ret, prefix_dirs[i]);
+
+  free_split_directories (prog_dirs);
+  free_split_directories (bin_dirs);
+  free_split_directories (prefix_dirs);
+
+  return ret;
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Add make_relative_prefix to libiberty
  2002-11-18 16:24   ` Daniel Jacobowitz
@ 2002-11-18 16:52     ` DJ Delorie
  2002-11-18 17:33       ` Daniel Jacobowitz
  0 siblings, 1 reply; 8+ messages in thread
From: DJ Delorie @ 2002-11-18 16:52 UTC (permalink / raw)
  To: drow; +Cc: gcc-patches


> Which header?  I do not see allocation rules, just a list of how
> different functions in libiberty allocate memory.  A number of them use
> xmalloc to do it.  Much simpler for an initialization function like
> this one.

All I'm looking for is a short note in the header where the
declaration is (like "return value must be free'd by caller").

> > You have also changed the copyright terms (GPL -> LGPL).  Do you have
> > the FSF's permission to do so?
> 
> No.  It was just me being sloppy; I apologize.  I copied the wrong
> copyright notice; I think I grabbed it from lbasename.  Since I see a
> number of GPL source files in libiberty, I assume that there is no
> problem with adding a GPL'd source file to the libiberty directory?

Depends.  If this function is primarily for GPL'd applications, I
don't see a problem.  We've had cases where we want the "GPL plus
exception" for libstdc++, but I don't think this is the case.  but we
can't change it anyway, so we might as well keep it GPL.

> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 2, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING.  If not, write to the Free
> +Software Foundation, 59 Temple Place - Suite 330, Boston, MA
> +02111-1307, USA.  */

Obviously, we shouldn't use "GCC" here ;-)

> +/*
> +
> +@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, const char *@var{bin_prefix}, const char *@var{prefix})
> +
> +Given pointers to the @code{argv[0]}, the default installation directory
> +for this program, and the default location of another directory, this function
> +returns the path to the other directory assuming the installation tree has moved
> +from @var{bin_prefix} to the new location of @var{progname}.

Hmmm.. could we add a note about the rv's allocation here?

And the big comment above make_relative_prefix itself has the text
which should go here.  That's basically what I did when I did the
original set of docs - just resyntaxed the comments into texinfo.

> +#include "ansidecl.h"
> +#include "libiberty.h"

The Makefile still has dependencies on obstack.h

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Add make_relative_prefix to libiberty
  2002-11-18 16:52     ` DJ Delorie
@ 2002-11-18 17:33       ` Daniel Jacobowitz
  2002-11-18 17:47         ` DJ Delorie
  2002-11-22  7:37         ` Daniel Jacobowitz
  0 siblings, 2 replies; 8+ messages in thread
From: Daniel Jacobowitz @ 2002-11-18 17:33 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc-patches

On Mon, Nov 18, 2002 at 07:52:51PM -0500, DJ Delorie wrote:
> 
> > Which header?  I do not see allocation rules, just a list of how
> > different functions in libiberty allocate memory.  A number of them use
> > xmalloc to do it.  Much simpler for an initialization function like
> > this one.
> 
> All I'm looking for is a short note in the header where the
> declaration is (like "return value must be free'd by caller").

Oh, I see.

> > > You have also changed the copyright terms (GPL -> LGPL).  Do you have
> > > the FSF's permission to do so?
> > 
> > No.  It was just me being sloppy; I apologize.  I copied the wrong
> > copyright notice; I think I grabbed it from lbasename.  Since I see a
> > number of GPL source files in libiberty, I assume that there is no
> > problem with adding a GPL'd source file to the libiberty directory?
> 
> Depends.  If this function is primarily for GPL'd applications, I
> don't see a problem.  We've had cases where we want the "GPL plus
> exception" for libstdc++, but I don't think this is the case.  but we
> can't change it anyway, so we might as well keep it GPL.
> 
> > +This file is part of GCC.
> > +
> > +GCC is free software; you can redistribute it and/or modify it under
> > +the terms of the GNU General Public License as published by the Free
> > +Software Foundation; either version 2, or (at your option) any later
> > +version.
> > +
> > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> > +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> > +for more details.
> > +
> > +You should have received a copy of the GNU General Public License
> > +along with GCC; see the file COPYING.  If not, write to the Free
> > +Software Foundation, 59 Temple Place - Suite 330, Boston, MA
> > +02111-1307, USA.  */
> 
> Obviously, we shouldn't use "GCC" here ;-)

Just quoting :)  Should all the rest of the files in libiberty be
updated to say they belong to libiberty?  There's one from GDB
(floatformat), one from GNU C Library (regex.c; that one's actually
mastered elsewhere IIRC?), and several from GNU CC or GNU C Compiler.

> > +/*
> > +
> > +@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, const char *@var{bin_prefix}, const char *@var{prefix})
> > +
> > +Given pointers to the @code{argv[0]}, the default installation directory
> > +for this program, and the default location of another directory, this function
> > +returns the path to the other directory assuming the installation tree has moved
> > +from @var{bin_prefix} to the new location of @var{progname}.
> 
> Hmmm.. could we add a note about the rv's allocation here?
> 
> And the big comment above make_relative_prefix itself has the text
> which should go here.  That's basically what I did when I did the
> original set of docs - just resyntaxed the comments into texinfo.

Okie.

> > +#include "ansidecl.h"
> > +#include "libiberty.h"
> 
> The Makefile still has dependencies on obstack.h

Fixed.  While I was at it, I updated the docs and big comment to be
actually _accurate_.  If you work through the example that's been
sitting there for a while, you'll notice it doesn't make much sense...

Updated with your corrections.  If this is OK with DJ, would a GCC
maintainer please approve the move out of gcc.c?

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2002-11-18  Daniel Jacobowitz  <drow@mvista.com>

	* libiberty.h (make_relative_prefix): Add prototype.

2002-11-18  Daniel Jacobowitz  <drow@mvista.com>

	* Makefile.in: Add make-relative-prefix.c.
	* make-relative-prefix.c: New file.
	* functions.texi: Rebuilt.

2002-11-18  Daniel Jacobowitz  <drow@mvista.com>

	* gcc.c (make_relative_prefix, split_directories)
	(free_split_directories): Removed.

Index: gcc/gcc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcc.c,v
retrieving revision 1.344
diff -u -p -r1.344 gcc.c
--- gcc/gcc.c	14 Oct 2002 07:15:38 -0000	1.344
+++ gcc/gcc.c	19 Nov 2002 01:30:22 -0000
@@ -267,11 +267,6 @@ static struct rusage rus, prus;
 struct path_prefix;
 
 static void init_spec		PARAMS ((void));
-#ifndef VMS
-static char **split_directories	PARAMS ((const char *, int *));
-static void free_split_directories PARAMS ((char **));
-static char *make_relative_prefix PARAMS ((const char *, const char *, const char *));
-#endif /* VMS */
 static void store_arg		PARAMS ((const char *, int, int));
 static char *load_specs		PARAMS ((const char *));
 static void read_specs		PARAMS ((const char *, int));
@@ -2249,246 +2244,6 @@ putenv_from_prefixes (paths, 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;
-  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)
-    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);
-
-  /* If there is no full pathname, try to find the program by checking in each
-     of the directories specified in the PATH environment variable.  */
-  if (prog_num == 1)
-    {
-      char *temp;
-
-      GET_ENVIRONMENT (temp, "PATH");
-      if (temp)
-	{
-	  char *startp, *endp, *nstore;
-	  size_t prefixlen = strlen (temp) + 1;
-	  if (prefixlen < 2)
-	    prefixlen = 2;
-
-	  nstore = (char *) alloca (prefixlen + strlen (progname) + 1);
-
-	  startp = endp = temp;
-	  while (1)
-	    {
-	      if (*endp == PATH_SEPARATOR || *endp == 0)
-		{
-		  if (endp == startp)
-		    {
-		      nstore[0] = '.';
-		      nstore[1] = DIR_SEPARATOR;
-		      nstore[2] = '\0';
-		    }
-		  else
-		    {
-		      strncpy (nstore, startp, endp - startp);
-		      if (! IS_DIR_SEPARATOR (endp[-1]))
-			{
-			  nstore[endp - startp] = DIR_SEPARATOR;
-			  nstore[endp - startp + 1] = 0;
-			}
-		      else
-			nstore[endp - startp] = 0;
-		    }
-		  strcat (nstore, progname);
-		  if (! access (nstore, X_OK)
-#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
-                      || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK)
-#endif
-		      )
-		    {
-		      free_split_directories (prog_dirs);
-		      progname = nstore;
-		      prog_dirs = split_directories (progname, &prog_num);
-		      break;
-		    }
-
-		  if (*endp == 0)
-		    break;
-		  endp = startp = endp + 1;
-		}
-	      else
-		endp++;
-	    }
-	}
-    }
-
-  /* Remove the program name from comparison of directory names.  */
-  prog_num--;
-
-  /* Determine if the compiler is installed in the standard location, and if
-     so, we don't need to specify relative directories.  Also, if argv[0]
-     doesn't contain any directory specifiers, there is not much we can do.  */
-  std_loc_p = 0;
-  if (prog_num == bin_num)
-    {
-      for (i = 0; i < bin_num; i++)
-	{
-	  if (strcmp (prog_dirs[i], bin_dirs[i]) != 0)
-	    break;
-	}
-
-      if (prog_num <= 0 || i == bin_num)
-	{
-	  std_loc_p = 1;
-	  free_split_directories (prog_dirs);
-	  free_split_directories (bin_dirs);
-	  prog_dirs = bin_dirs = (char **) 0;
-	  return NULL;
-	}
-    }
-
-  prefix_dirs = split_directories (prefix, &prefix_num);
-
-  /* Find how many directories are in common between bin_prefix & prefix.  */
-  n = (prefix_num < bin_num) ? prefix_num : bin_num;
-  for (common = 0; common < n; common++)
-    {
-      if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0)
-	break;
-    }
-
-  /* If there are no common directories, there can be no relative prefix.  */
-  if (common == 0)
-    {
-      free_split_directories (prog_dirs);
-      free_split_directories (bin_dirs);
-      free_split_directories (prefix_dirs);
-      return NULL;
-    }
-
-  /* Build up the pathnames in argv[0].  */
-  for (i = 0; i < prog_num; i++)
-    obstack_grow (&obstack, prog_dirs[i], strlen (prog_dirs[i]));
-
-  /* Now build up the ..'s.  */
-  for (i = common; i < n; i++)
-    {
-      obstack_grow (&obstack, DIR_UP, sizeof (DIR_UP) - 1);
-      obstack_1grow (&obstack, DIR_SEPARATOR);
-    }
-
-  /* Put in directories to move over to prefix.  */
-  for (i = common; i < prefix_num; i++)
-    obstack_grow (&obstack, prefix_dirs[i], strlen (prefix_dirs[i]));
-
-  free_split_directories (prog_dirs);
-  free_split_directories (bin_dirs);
-  free_split_directories (prefix_dirs);
-
-  obstack_1grow (&obstack, '\0');
-  return obstack_finish (&obstack);
-}
-#endif /* VMS */
 \f
 /* Check whether NAME can be accessed in MODE.  This is like access,
    except that it never considers directories to be executable.  */
Index: include/libiberty.h
===================================================================
RCS file: /cvs/gcc/gcc/include/libiberty.h,v
retrieving revision 1.29
diff -u -p -r1.29 libiberty.h
--- include/libiberty.h	20 Sep 2002 00:21:54 -0000	1.29
+++ include/libiberty.h	19 Nov 2002 01:30:23 -0000
@@ -145,6 +145,12 @@ extern char * getpwd PARAMS ((void));
 
 extern long get_run_time PARAMS ((void));
 
+/* Generate a relocated path to some installation directory.  Allocates
+   return value using malloc.  */
+
+extern char *make_relative_prefix PARAMS ((const char *, const char *,
+					   const char *));
+
 /* Choose a temporary directory to use for scratch files.  */
 
 extern char *choose_temp_base PARAMS ((void)) ATTRIBUTE_MALLOC;
Index: libiberty/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/Makefile.in,v
retrieving revision 1.77
diff -u -p -r1.77 Makefile.in
--- libiberty/Makefile.in	23 Sep 2002 03:52:51 -0000	1.77
+++ libiberty/Makefile.in	19 Nov 2002 01:30:24 -0000
@@ -135,6 +135,7 @@ CFILES = alloca.c argv.c asprintf.c atex
 	hashtab.c hex.c							\
 	index.c insque.c						\
 	lbasename.c							\
+	make-relative-prefix.c						\
 	make-temp-file.c md5.c memchr.c memcmp.c memcpy.c memmove.c	\
 	 memset.c mkstemps.c						\
 	objalloc.c obstack.c						\
@@ -159,6 +160,7 @@ REQUIRED_OFILES = regex.o cplus-dem.o cp
 	getopt.o getopt1.o getpwd.o getruntime.o			\
 	hashtab.o hex.o							\
 	lbasename.o							\
+	make-relative-prefix.o						\
 	make-temp-file.o						\
 	objalloc.o obstack.o						\
 	partition.o pexecute.o						\
@@ -432,6 +434,7 @@ hashtab.o: config.h $(INCDIR)/ansidecl.h
 hex.o: $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
 lbasename.o: $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
 	$(INCDIR)/safe-ctype.h
+make-relative-prefix.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
 make-temp-file.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
 md5.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/md5.h
 memchr.o: $(INCDIR)/ansidecl.h
Index: libiberty/functions.texi
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/functions.texi,v
retrieving revision 1.8
diff -u -p -r1.8 functions.texi
--- libiberty/functions.texi	28 Mar 2002 04:04:20 -0000	1.8
+++ libiberty/functions.texi	19 Nov 2002 01:30:24 -0000
@@ -276,7 +276,7 @@ itself.
 
 @end deftypefn
 
-@c getruntime.c:78
+@c getruntime.c:82
 @deftypefn Replacement long get_run_time (void)
 
 Returns the time used so far, in microseconds.  If possible, this is
@@ -322,11 +322,12 @@ between calls to @code{getpwd}.
 
 Initializes the array mapping the current character set to
 corresponding hex values.  This function must be called before any
-call to @code{hex_p} or @code{hex_value}.
+call to @code{hex_p} or @code{hex_value}.  If you fail to call it, a
+default ASCII-based table will normally be used on ASCII systems.
 
 @end deftypefn
 
-@c hex.c:33
+@c hex.c:34
 @deftypefn Extension int hex_p (int @var{c})
 
 Evaluates to non-zero if the given character is a valid hex character,
@@ -335,7 +336,7 @@ or zero if it is not.  Note that the val
 
 @end deftypefn
 
-@c hex.c:41
+@c hex.c:42
 @deftypefn Extension int hex_value (int @var{c})
 
 Returns the numeric equivalent of the given character when interpreted
@@ -388,6 +389,22 @@ strings for particular input.
 
 In particular, the empty string returns the same empty string,
 and a path ending in @code{/} returns the empty string after it.
+
+@end deftypefn
+
+@c make-relative-prefix.c:24
+@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, const char *@var{bin_prefix}, const char *@var{prefix})
+
+Given three strings @var{progname}, @var{bin_prefix}, @var{prefix}, return a string
+that gets to @var{prefix} starting with the directory portion of @var{progname} and
+a relative pathname of the difference between @var{bin_prefix} and @var{prefix}.
+
+For example, if @var{bin_prefix} is @code{/alpha/beta/gamma/gcc/delta}, @var{prefix}
+is @code{/alpha/beta/gamma/omega/}, and @var{progname} is @code{/red/green/blue/gcc},
+then this function will return @code{/red/green/blue/../../omega/}.
+
+The return value is normally allocated via @code{malloc}.  If no relative prefix
+can be found, return @code{NULL}.
 
 @end deftypefn
 
Index: libiberty/make-relative-prefix.c
===================================================================
RCS file: libiberty/make-relative-prefix.c
diff -N libiberty/make-relative-prefix.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libiberty/make-relative-prefix.c	19 Nov 2002 01:30:24 -0000
@@ -0,0 +1,387 @@
+/* Relative (relocatable) prefix support.
+   Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of libiberty.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+/*
+
+@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, const char *@var{bin_prefix}, const char *@var{prefix})
+
+Given three strings @var{progname}, @var{bin_prefix}, @var{prefix}, return a string
+that gets to @var{prefix} starting with the directory portion of @var{progname} and
+a relative pathname of the difference between @var{bin_prefix} and @var{prefix}.
+
+For example, if @var{bin_prefix} is @code{/alpha/beta/gamma/gcc/delta}, @var{prefix}
+is @code{/alpha/beta/gamma/omega/}, and @var{progname} is @code{/red/green/blue/gcc},
+then this function will return @code{/red/green/blue/../../omega/}.
+
+The return value is normally allocated via @code{malloc}.  If no relative prefix
+can be found, return @code{NULL}.
+
+@end deftypefn
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <string.h>
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#endif
+
+#ifndef DIR_SEPARATOR
+#  define DIR_SEPARATOR '/'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) \
+    || defined (__DJGPP__) || defined (__OS2__)
+#  define HAVE_DOS_BASED_FILE_SYSTEM
+#  define HOST_EXECUTABLE_SUFFIX ".exe"
+#  ifndef DIR_SEPARATOR_2 
+#    define DIR_SEPARATOR_2 '\\'
+#  endif
+#  define PATH_SEPARATOR ';'
+#else
+#  define PATH_SEPARATOR ':'
+#endif
+
+#ifndef DIR_SEPARATOR_2
+#  define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else
+#  define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif
+
+#define DIR_UP ".."
+
+static char *save_string PARAMS ((const char *, int));
+static char **split_directories	PARAMS ((const char *, int *));
+static void free_split_directories PARAMS ((char **));
+
+static char *
+save_string (s, len)
+     const char *s;
+     int len;
+{
+  char *result = malloc (len + 1);
+
+  memcpy (result, s, len);
+  result[len] = 0;
+  return result;
+}
+
+/* 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 **) malloc (sizeof (char *) * (num_dirs + 2));
+  if (dirs == NULL)
+    return NULL;
+
+  /* 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);
+      if (dirs[num_dirs - 1] == NULL)
+	{
+	  free (dirs);
+	  return NULL;
+	}
+      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);
+	  if (dirs[num_dirs - 1] == NULL)
+	    {
+	      dirs[num_dirs] = NULL;
+	      free_split_directories (dirs);
+	      return NULL;
+	    }
+	  q = p;
+	}
+    }
+
+  if (p - 1 - q > 0)
+    dirs[num_dirs++] = save_string (q, p - 1 - q);
+  dirs[num_dirs] = NULL;
+
+  if (dirs[num_dirs - 1] == NULL)
+    {
+      free_split_directories (dirs);
+      return NULL;
+    }
+
+  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)
+    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.  */
+
+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;
+  int i, n, common;
+  int needed_len;
+  char *ret, *ptr;
+
+  if (progname == NULL || bin_prefix == NULL || prefix == NULL)
+    return NULL;
+
+  prog_dirs = split_directories (progname, &prog_num);
+  bin_dirs = split_directories (bin_prefix, &bin_num);
+  if (bin_dirs == NULL || prog_dirs == NULL)
+    return NULL;
+
+  /* If there is no full pathname, try to find the program by checking in each
+     of the directories specified in the PATH environment variable.  */
+  if (prog_num == 1)
+    {
+      char *temp;
+
+      temp = getenv ("PATH");
+      if (temp)
+	{
+	  char *startp, *endp, *nstore;
+	  size_t prefixlen = strlen (temp) + 1;
+	  if (prefixlen < 2)
+	    prefixlen = 2;
+
+	  nstore = (char *) alloca (prefixlen + strlen (progname) + 1);
+
+	  startp = endp = temp;
+	  while (1)
+	    {
+	      if (*endp == PATH_SEPARATOR || *endp == 0)
+		{
+		  if (endp == startp)
+		    {
+		      nstore[0] = '.';
+		      nstore[1] = DIR_SEPARATOR;
+		      nstore[2] = '\0';
+		    }
+		  else
+		    {
+		      strncpy (nstore, startp, endp - startp);
+		      if (! IS_DIR_SEPARATOR (endp[-1]))
+			{
+			  nstore[endp - startp] = DIR_SEPARATOR;
+			  nstore[endp - startp + 1] = 0;
+			}
+		      else
+			nstore[endp - startp] = 0;
+		    }
+		  strcat (nstore, progname);
+		  if (! access (nstore, X_OK)
+#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
+                      || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK)
+#endif
+		      )
+		    {
+		      free_split_directories (prog_dirs);
+		      progname = nstore;
+		      prog_dirs = split_directories (progname, &prog_num);
+		      if (prog_dirs == NULL)
+			{
+			  free_split_directories (bin_dirs);
+			  return NULL;
+			}
+		      break;
+		    }
+
+		  if (*endp == 0)
+		    break;
+		  endp = startp = endp + 1;
+		}
+	      else
+		endp++;
+	    }
+	}
+    }
+
+  /* Remove the program name from comparison of directory names.  */
+  prog_num--;
+
+  /* If we are still installed in the standard location, we don't need to
+     specify relative directories.  Also, if argv[0] still doesn't contain
+     any directory specifiers after the search above, then there is not much
+     we can do.  */
+  if (prog_num == bin_num)
+    {
+      for (i = 0; i < bin_num; i++)
+	{
+	  if (strcmp (prog_dirs[i], bin_dirs[i]) != 0)
+	    break;
+	}
+
+      if (prog_num <= 0 || i == bin_num)
+	{
+	  free_split_directories (prog_dirs);
+	  free_split_directories (bin_dirs);
+	  prog_dirs = bin_dirs = (char **) 0;
+	  return NULL;
+	}
+    }
+
+  prefix_dirs = split_directories (prefix, &prefix_num);
+  if (prefix_dirs == NULL)
+    {
+      free_split_directories (prog_dirs);
+      free_split_directories (bin_dirs);
+      return NULL;
+    }
+
+  /* Find how many directories are in common between bin_prefix & prefix.  */
+  n = (prefix_num < bin_num) ? prefix_num : bin_num;
+  for (common = 0; common < n; common++)
+    {
+      if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0)
+	break;
+    }
+
+  /* If there are no common directories, there can be no relative prefix.  */
+  if (common == 0)
+    {
+      free_split_directories (prog_dirs);
+      free_split_directories (bin_dirs);
+      free_split_directories (prefix_dirs);
+      return NULL;
+    }
+
+  /* Two passes: first figure out the size of the result string, and
+     then construct it.  */
+  needed_len = 0;
+  for (i = 0; i < prog_num; i++)
+    needed_len += strlen (prog_dirs[i]);
+  needed_len += sizeof (DIR_UP) * (bin_num - common);
+  for (i = common; i < prefix_num; i++)
+    needed_len += strlen (prefix_dirs[i]);
+  needed_len += 1; /* Trailing NUL.  */
+
+  ret = (char *) malloc (needed_len);
+  if (ret == NULL)
+    return NULL;
+
+  /* Build up the pathnames in argv[0].  */
+  for (i = 0; i < prog_num; i++)
+    strcat (ret, prog_dirs[i]);
+
+  /* Now build up the ..'s.  */
+  ptr = ret + strlen(ret);
+  for (i = common; i < bin_num; i++)
+    {
+      strcpy (ptr, DIR_UP);
+      ptr += sizeof (DIR_UP) - 1;
+      *(ptr++) = DIR_SEPARATOR;
+    }
+  *ptr = '\0';
+
+  /* Put in directories to move over to prefix.  */
+  for (i = common; i < prefix_num; i++)
+    strcat (ret, prefix_dirs[i]);
+
+  free_split_directories (prog_dirs);
+  free_split_directories (bin_dirs);
+  free_split_directories (prefix_dirs);
+
+  return ret;
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Add make_relative_prefix to libiberty
  2002-11-18 17:33       ` Daniel Jacobowitz
@ 2002-11-18 17:47         ` DJ Delorie
  2002-11-22  7:37         ` Daniel Jacobowitz
  1 sibling, 0 replies; 8+ messages in thread
From: DJ Delorie @ 2002-11-18 17:47 UTC (permalink / raw)
  To: drow; +Cc: gcc-patches


> Just quoting :)  Should all the rest of the files in libiberty be
> updated to say they belong to libiberty?  There's one from GDB
> (floatformat), one from GNU C Library (regex.c; that one's actually
> mastered elsewhere IIRC?), and several from GNU CC or GNU C Compiler.

The regex files *were* mastered in glibc, but glibc changed to a
completely different implementation.  So far I haven't gotten around
to fixing the commentary.

Yeah, all the files should say libiberty, but we can deal with them
individually as time permits.  No excuse to do it wrong this time,
though.

> Updated with your corrections.  If this is OK with DJ, would a GCC
> maintainer please approve the move out of gcc.c?

> 2002-11-18  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* libiberty.h (make_relative_prefix): Add prototype.
> 
> 2002-11-18  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* Makefile.in: Add make-relative-prefix.c.
> 	* make-relative-prefix.c: New file.
> 	* functions.texi: Rebuilt.
> 
> 2002-11-18  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* gcc.c (make_relative_prefix, split_directories)
> 	(free_split_directories): Removed.

The libiberty parts are OK.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Add make_relative_prefix to libiberty
  2002-11-18 17:33       ` Daniel Jacobowitz
  2002-11-18 17:47         ` DJ Delorie
@ 2002-11-22  7:37         ` Daniel Jacobowitz
  2002-11-22 11:33           ` Geoff Keating
  1 sibling, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2002-11-22  7:37 UTC (permalink / raw)
  To: gcc-patches; +Cc: DJ Delorie

Ping.  DJ approved the libiberty parts of this patch; I'd like to
commit it so that I can make ld and gdb use it, but it needs to go in
with the GCC bits.

On Mon, Nov 18, 2002 at 08:34:38PM -0500, Daniel Jacobowitz wrote:
> On Mon, Nov 18, 2002 at 07:52:51PM -0500, DJ Delorie wrote:
> > 
> > > Which header?  I do not see allocation rules, just a list of how
> > > different functions in libiberty allocate memory.  A number of them use
> > > xmalloc to do it.  Much simpler for an initialization function like
> > > this one.
> > 
> > All I'm looking for is a short note in the header where the
> > declaration is (like "return value must be free'd by caller").
> 
> Oh, I see.
> 
> > > > You have also changed the copyright terms (GPL -> LGPL).  Do you have
> > > > the FSF's permission to do so?
> > > 
> > > No.  It was just me being sloppy; I apologize.  I copied the wrong
> > > copyright notice; I think I grabbed it from lbasename.  Since I see a
> > > number of GPL source files in libiberty, I assume that there is no
> > > problem with adding a GPL'd source file to the libiberty directory?
> > 
> > Depends.  If this function is primarily for GPL'd applications, I
> > don't see a problem.  We've had cases where we want the "GPL plus
> > exception" for libstdc++, but I don't think this is the case.  but we
> > can't change it anyway, so we might as well keep it GPL.
> > 
> > > +This file is part of GCC.
> > > +
> > > +GCC is free software; you can redistribute it and/or modify it under
> > > +the terms of the GNU General Public License as published by the Free
> > > +Software Foundation; either version 2, or (at your option) any later
> > > +version.
> > > +
> > > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> > > +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > > +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> > > +for more details.
> > > +
> > > +You should have received a copy of the GNU General Public License
> > > +along with GCC; see the file COPYING.  If not, write to the Free
> > > +Software Foundation, 59 Temple Place - Suite 330, Boston, MA
> > > +02111-1307, USA.  */
> > 
> > Obviously, we shouldn't use "GCC" here ;-)
> 
> Just quoting :)  Should all the rest of the files in libiberty be
> updated to say they belong to libiberty?  There's one from GDB
> (floatformat), one from GNU C Library (regex.c; that one's actually
> mastered elsewhere IIRC?), and several from GNU CC or GNU C Compiler.
> 
> > > +/*
> > > +
> > > +@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, const char *@var{bin_prefix}, const char *@var{prefix})
> > > +
> > > +Given pointers to the @code{argv[0]}, the default installation directory
> > > +for this program, and the default location of another directory, this function
> > > +returns the path to the other directory assuming the installation tree has moved
> > > +from @var{bin_prefix} to the new location of @var{progname}.
> > 
> > Hmmm.. could we add a note about the rv's allocation here?
> > 
> > And the big comment above make_relative_prefix itself has the text
> > which should go here.  That's basically what I did when I did the
> > original set of docs - just resyntaxed the comments into texinfo.
> 
> Okie.
> 
> > > +#include "ansidecl.h"
> > > +#include "libiberty.h"
> > 
> > The Makefile still has dependencies on obstack.h
> 
> Fixed.  While I was at it, I updated the docs and big comment to be
> actually _accurate_.  If you work through the example that's been
> sitting there for a while, you'll notice it doesn't make much sense...
> 
> Updated with your corrections.  If this is OK with DJ, would a GCC
> maintainer please approve the move out of gcc.c?
> 
> -- 
> Daniel Jacobowitz
> MontaVista Software                         Debian GNU/Linux Developer
> 
> 2002-11-18  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* libiberty.h (make_relative_prefix): Add prototype.
> 
> 2002-11-18  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* Makefile.in: Add make-relative-prefix.c.
> 	* make-relative-prefix.c: New file.
> 	* functions.texi: Rebuilt.
> 
> 2002-11-18  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* gcc.c (make_relative_prefix, split_directories)
> 	(free_split_directories): Removed.
> 
> Index: gcc/gcc.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/gcc.c,v
> retrieving revision 1.344
> diff -u -p -r1.344 gcc.c
> --- gcc/gcc.c	14 Oct 2002 07:15:38 -0000	1.344
> +++ gcc/gcc.c	19 Nov 2002 01:30:22 -0000
> @@ -267,11 +267,6 @@ static struct rusage rus, prus;
>  struct path_prefix;
>  
>  static void init_spec		PARAMS ((void));
> -#ifndef VMS
> -static char **split_directories	PARAMS ((const char *, int *));
> -static void free_split_directories PARAMS ((char **));
> -static char *make_relative_prefix PARAMS ((const char *, const char *, const char *));
> -#endif /* VMS */
>  static void store_arg		PARAMS ((const char *, int, int));
>  static char *load_specs		PARAMS ((const char *));
>  static void read_specs		PARAMS ((const char *, int));
> @@ -2249,246 +2244,6 @@ putenv_from_prefixes (paths, 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;
> -  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)
> -    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);
> -
> -  /* If there is no full pathname, try to find the program by checking in each
> -     of the directories specified in the PATH environment variable.  */
> -  if (prog_num == 1)
> -    {
> -      char *temp;
> -
> -      GET_ENVIRONMENT (temp, "PATH");
> -      if (temp)
> -	{
> -	  char *startp, *endp, *nstore;
> -	  size_t prefixlen = strlen (temp) + 1;
> -	  if (prefixlen < 2)
> -	    prefixlen = 2;
> -
> -	  nstore = (char *) alloca (prefixlen + strlen (progname) + 1);
> -
> -	  startp = endp = temp;
> -	  while (1)
> -	    {
> -	      if (*endp == PATH_SEPARATOR || *endp == 0)
> -		{
> -		  if (endp == startp)
> -		    {
> -		      nstore[0] = '.';
> -		      nstore[1] = DIR_SEPARATOR;
> -		      nstore[2] = '\0';
> -		    }
> -		  else
> -		    {
> -		      strncpy (nstore, startp, endp - startp);
> -		      if (! IS_DIR_SEPARATOR (endp[-1]))
> -			{
> -			  nstore[endp - startp] = DIR_SEPARATOR;
> -			  nstore[endp - startp + 1] = 0;
> -			}
> -		      else
> -			nstore[endp - startp] = 0;
> -		    }
> -		  strcat (nstore, progname);
> -		  if (! access (nstore, X_OK)
> -#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
> -                      || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK)
> -#endif
> -		      )
> -		    {
> -		      free_split_directories (prog_dirs);
> -		      progname = nstore;
> -		      prog_dirs = split_directories (progname, &prog_num);
> -		      break;
> -		    }
> -
> -		  if (*endp == 0)
> -		    break;
> -		  endp = startp = endp + 1;
> -		}
> -	      else
> -		endp++;
> -	    }
> -	}
> -    }
> -
> -  /* Remove the program name from comparison of directory names.  */
> -  prog_num--;
> -
> -  /* Determine if the compiler is installed in the standard location, and if
> -     so, we don't need to specify relative directories.  Also, if argv[0]
> -     doesn't contain any directory specifiers, there is not much we can do.  */
> -  std_loc_p = 0;
> -  if (prog_num == bin_num)
> -    {
> -      for (i = 0; i < bin_num; i++)
> -	{
> -	  if (strcmp (prog_dirs[i], bin_dirs[i]) != 0)
> -	    break;
> -	}
> -
> -      if (prog_num <= 0 || i == bin_num)
> -	{
> -	  std_loc_p = 1;
> -	  free_split_directories (prog_dirs);
> -	  free_split_directories (bin_dirs);
> -	  prog_dirs = bin_dirs = (char **) 0;
> -	  return NULL;
> -	}
> -    }
> -
> -  prefix_dirs = split_directories (prefix, &prefix_num);
> -
> -  /* Find how many directories are in common between bin_prefix & prefix.  */
> -  n = (prefix_num < bin_num) ? prefix_num : bin_num;
> -  for (common = 0; common < n; common++)
> -    {
> -      if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0)
> -	break;
> -    }
> -
> -  /* If there are no common directories, there can be no relative prefix.  */
> -  if (common == 0)
> -    {
> -      free_split_directories (prog_dirs);
> -      free_split_directories (bin_dirs);
> -      free_split_directories (prefix_dirs);
> -      return NULL;
> -    }
> -
> -  /* Build up the pathnames in argv[0].  */
> -  for (i = 0; i < prog_num; i++)
> -    obstack_grow (&obstack, prog_dirs[i], strlen (prog_dirs[i]));
> -
> -  /* Now build up the ..'s.  */
> -  for (i = common; i < n; i++)
> -    {
> -      obstack_grow (&obstack, DIR_UP, sizeof (DIR_UP) - 1);
> -      obstack_1grow (&obstack, DIR_SEPARATOR);
> -    }
> -
> -  /* Put in directories to move over to prefix.  */
> -  for (i = common; i < prefix_num; i++)
> -    obstack_grow (&obstack, prefix_dirs[i], strlen (prefix_dirs[i]));
> -
> -  free_split_directories (prog_dirs);
> -  free_split_directories (bin_dirs);
> -  free_split_directories (prefix_dirs);
> -
> -  obstack_1grow (&obstack, '\0');
> -  return obstack_finish (&obstack);
> -}
> -#endif /* VMS */
>  \f
>  /* Check whether NAME can be accessed in MODE.  This is like access,
>     except that it never considers directories to be executable.  */
> Index: include/libiberty.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/include/libiberty.h,v
> retrieving revision 1.29
> diff -u -p -r1.29 libiberty.h
> --- include/libiberty.h	20 Sep 2002 00:21:54 -0000	1.29
> +++ include/libiberty.h	19 Nov 2002 01:30:23 -0000
> @@ -145,6 +145,12 @@ extern char * getpwd PARAMS ((void));
>  
>  extern long get_run_time PARAMS ((void));
>  
> +/* Generate a relocated path to some installation directory.  Allocates
> +   return value using malloc.  */
> +
> +extern char *make_relative_prefix PARAMS ((const char *, const char *,
> +					   const char *));
> +
>  /* Choose a temporary directory to use for scratch files.  */
>  
>  extern char *choose_temp_base PARAMS ((void)) ATTRIBUTE_MALLOC;
> Index: libiberty/Makefile.in
> ===================================================================
> RCS file: /cvs/gcc/gcc/libiberty/Makefile.in,v
> retrieving revision 1.77
> diff -u -p -r1.77 Makefile.in
> --- libiberty/Makefile.in	23 Sep 2002 03:52:51 -0000	1.77
> +++ libiberty/Makefile.in	19 Nov 2002 01:30:24 -0000
> @@ -135,6 +135,7 @@ CFILES = alloca.c argv.c asprintf.c atex
>  	hashtab.c hex.c							\
>  	index.c insque.c						\
>  	lbasename.c							\
> +	make-relative-prefix.c						\
>  	make-temp-file.c md5.c memchr.c memcmp.c memcpy.c memmove.c	\
>  	 memset.c mkstemps.c						\
>  	objalloc.c obstack.c						\
> @@ -159,6 +160,7 @@ REQUIRED_OFILES = regex.o cplus-dem.o cp
>  	getopt.o getopt1.o getpwd.o getruntime.o			\
>  	hashtab.o hex.o							\
>  	lbasename.o							\
> +	make-relative-prefix.o						\
>  	make-temp-file.o						\
>  	objalloc.o obstack.o						\
>  	partition.o pexecute.o						\
> @@ -432,6 +434,7 @@ hashtab.o: config.h $(INCDIR)/ansidecl.h
>  hex.o: $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
>  lbasename.o: $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
>  	$(INCDIR)/safe-ctype.h
> +make-relative-prefix.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
>  make-temp-file.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
>  md5.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/md5.h
>  memchr.o: $(INCDIR)/ansidecl.h
> Index: libiberty/functions.texi
> ===================================================================
> RCS file: /cvs/gcc/gcc/libiberty/functions.texi,v
> retrieving revision 1.8
> diff -u -p -r1.8 functions.texi
> --- libiberty/functions.texi	28 Mar 2002 04:04:20 -0000	1.8
> +++ libiberty/functions.texi	19 Nov 2002 01:30:24 -0000
> @@ -276,7 +276,7 @@ itself.
>  
>  @end deftypefn
>  
> -@c getruntime.c:78
> +@c getruntime.c:82
>  @deftypefn Replacement long get_run_time (void)
>  
>  Returns the time used so far, in microseconds.  If possible, this is
> @@ -322,11 +322,12 @@ between calls to @code{getpwd}.
>  
>  Initializes the array mapping the current character set to
>  corresponding hex values.  This function must be called before any
> -call to @code{hex_p} or @code{hex_value}.
> +call to @code{hex_p} or @code{hex_value}.  If you fail to call it, a
> +default ASCII-based table will normally be used on ASCII systems.
>  
>  @end deftypefn
>  
> -@c hex.c:33
> +@c hex.c:34
>  @deftypefn Extension int hex_p (int @var{c})
>  
>  Evaluates to non-zero if the given character is a valid hex character,
> @@ -335,7 +336,7 @@ or zero if it is not.  Note that the val
>  
>  @end deftypefn
>  
> -@c hex.c:41
> +@c hex.c:42
>  @deftypefn Extension int hex_value (int @var{c})
>  
>  Returns the numeric equivalent of the given character when interpreted
> @@ -388,6 +389,22 @@ strings for particular input.
>  
>  In particular, the empty string returns the same empty string,
>  and a path ending in @code{/} returns the empty string after it.
> +
> +@end deftypefn
> +
> +@c make-relative-prefix.c:24
> +@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, const char *@var{bin_prefix}, const char *@var{prefix})
> +
> +Given three strings @var{progname}, @var{bin_prefix}, @var{prefix}, return a string
> +that gets to @var{prefix} starting with the directory portion of @var{progname} and
> +a relative pathname of the difference between @var{bin_prefix} and @var{prefix}.
> +
> +For example, if @var{bin_prefix} is @code{/alpha/beta/gamma/gcc/delta}, @var{prefix}
> +is @code{/alpha/beta/gamma/omega/}, and @var{progname} is @code{/red/green/blue/gcc},
> +then this function will return @code{/red/green/blue/../../omega/}.
> +
> +The return value is normally allocated via @code{malloc}.  If no relative prefix
> +can be found, return @code{NULL}.
>  
>  @end deftypefn
>  
> Index: libiberty/make-relative-prefix.c
> ===================================================================
> RCS file: libiberty/make-relative-prefix.c
> diff -N libiberty/make-relative-prefix.c
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ libiberty/make-relative-prefix.c	19 Nov 2002 01:30:24 -0000
> @@ -0,0 +1,387 @@
> +/* Relative (relocatable) prefix support.
> +   Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
> +   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
> +
> +This file is part of libiberty.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 2, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING.  If not, write to the Free
> +Software Foundation, 59 Temple Place - Suite 330, Boston, MA
> +02111-1307, USA.  */
> +
> +/*
> +
> +@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, const char *@var{bin_prefix}, const char *@var{prefix})
> +
> +Given three strings @var{progname}, @var{bin_prefix}, @var{prefix}, return a string
> +that gets to @var{prefix} starting with the directory portion of @var{progname} and
> +a relative pathname of the difference between @var{bin_prefix} and @var{prefix}.
> +
> +For example, if @var{bin_prefix} is @code{/alpha/beta/gamma/gcc/delta}, @var{prefix}
> +is @code{/alpha/beta/gamma/omega/}, and @var{progname} is @code{/red/green/blue/gcc},
> +then this function will return @code{/red/green/blue/../../omega/}.
> +
> +The return value is normally allocated via @code{malloc}.  If no relative prefix
> +can be found, return @code{NULL}.
> +
> +@end deftypefn
> +
> +*/
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#ifdef HAVE_STDLIB_H
> +#include <stdlib.h>
> +#endif
> +#ifdef HAVE_UNISTD_H
> +#include <unistd.h>
> +#endif
> +
> +#include <string.h>
> +
> +#include "ansidecl.h"
> +#include "libiberty.h"
> +
> +#ifndef R_OK
> +#define R_OK 4
> +#define W_OK 2
> +#define X_OK 1
> +#endif
> +
> +#ifndef DIR_SEPARATOR
> +#  define DIR_SEPARATOR '/'
> +#endif
> +
> +#if defined (_WIN32) || defined (__MSDOS__) \
> +    || defined (__DJGPP__) || defined (__OS2__)
> +#  define HAVE_DOS_BASED_FILE_SYSTEM
> +#  define HOST_EXECUTABLE_SUFFIX ".exe"
> +#  ifndef DIR_SEPARATOR_2 
> +#    define DIR_SEPARATOR_2 '\\'
> +#  endif
> +#  define PATH_SEPARATOR ';'
> +#else
> +#  define PATH_SEPARATOR ':'
> +#endif
> +
> +#ifndef DIR_SEPARATOR_2
> +#  define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
> +#else
> +#  define IS_DIR_SEPARATOR(ch) \
> +	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
> +#endif
> +
> +#define DIR_UP ".."
> +
> +static char *save_string PARAMS ((const char *, int));
> +static char **split_directories	PARAMS ((const char *, int *));
> +static void free_split_directories PARAMS ((char **));
> +
> +static char *
> +save_string (s, len)
> +     const char *s;
> +     int len;
> +{
> +  char *result = malloc (len + 1);
> +
> +  memcpy (result, s, len);
> +  result[len] = 0;
> +  return result;
> +}
> +
> +/* 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 **) malloc (sizeof (char *) * (num_dirs + 2));
> +  if (dirs == NULL)
> +    return NULL;
> +
> +  /* 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);
> +      if (dirs[num_dirs - 1] == NULL)
> +	{
> +	  free (dirs);
> +	  return NULL;
> +	}
> +      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);
> +	  if (dirs[num_dirs - 1] == NULL)
> +	    {
> +	      dirs[num_dirs] = NULL;
> +	      free_split_directories (dirs);
> +	      return NULL;
> +	    }
> +	  q = p;
> +	}
> +    }
> +
> +  if (p - 1 - q > 0)
> +    dirs[num_dirs++] = save_string (q, p - 1 - q);
> +  dirs[num_dirs] = NULL;
> +
> +  if (dirs[num_dirs - 1] == NULL)
> +    {
> +      free_split_directories (dirs);
> +      return NULL;
> +    }
> +
> +  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)
> +    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.  */
> +
> +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;
> +  int i, n, common;
> +  int needed_len;
> +  char *ret, *ptr;
> +
> +  if (progname == NULL || bin_prefix == NULL || prefix == NULL)
> +    return NULL;
> +
> +  prog_dirs = split_directories (progname, &prog_num);
> +  bin_dirs = split_directories (bin_prefix, &bin_num);
> +  if (bin_dirs == NULL || prog_dirs == NULL)
> +    return NULL;
> +
> +  /* If there is no full pathname, try to find the program by checking in each
> +     of the directories specified in the PATH environment variable.  */
> +  if (prog_num == 1)
> +    {
> +      char *temp;
> +
> +      temp = getenv ("PATH");
> +      if (temp)
> +	{
> +	  char *startp, *endp, *nstore;
> +	  size_t prefixlen = strlen (temp) + 1;
> +	  if (prefixlen < 2)
> +	    prefixlen = 2;
> +
> +	  nstore = (char *) alloca (prefixlen + strlen (progname) + 1);
> +
> +	  startp = endp = temp;
> +	  while (1)
> +	    {
> +	      if (*endp == PATH_SEPARATOR || *endp == 0)
> +		{
> +		  if (endp == startp)
> +		    {
> +		      nstore[0] = '.';
> +		      nstore[1] = DIR_SEPARATOR;
> +		      nstore[2] = '\0';
> +		    }
> +		  else
> +		    {
> +		      strncpy (nstore, startp, endp - startp);
> +		      if (! IS_DIR_SEPARATOR (endp[-1]))
> +			{
> +			  nstore[endp - startp] = DIR_SEPARATOR;
> +			  nstore[endp - startp + 1] = 0;
> +			}
> +		      else
> +			nstore[endp - startp] = 0;
> +		    }
> +		  strcat (nstore, progname);
> +		  if (! access (nstore, X_OK)
> +#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
> +                      || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK)
> +#endif
> +		      )
> +		    {
> +		      free_split_directories (prog_dirs);
> +		      progname = nstore;
> +		      prog_dirs = split_directories (progname, &prog_num);
> +		      if (prog_dirs == NULL)
> +			{
> +			  free_split_directories (bin_dirs);
> +			  return NULL;
> +			}
> +		      break;
> +		    }
> +
> +		  if (*endp == 0)
> +		    break;
> +		  endp = startp = endp + 1;
> +		}
> +	      else
> +		endp++;
> +	    }
> +	}
> +    }
> +
> +  /* Remove the program name from comparison of directory names.  */
> +  prog_num--;
> +
> +  /* If we are still installed in the standard location, we don't need to
> +     specify relative directories.  Also, if argv[0] still doesn't contain
> +     any directory specifiers after the search above, then there is not much
> +     we can do.  */
> +  if (prog_num == bin_num)
> +    {
> +      for (i = 0; i < bin_num; i++)
> +	{
> +	  if (strcmp (prog_dirs[i], bin_dirs[i]) != 0)
> +	    break;
> +	}
> +
> +      if (prog_num <= 0 || i == bin_num)
> +	{
> +	  free_split_directories (prog_dirs);
> +	  free_split_directories (bin_dirs);
> +	  prog_dirs = bin_dirs = (char **) 0;
> +	  return NULL;
> +	}
> +    }
> +
> +  prefix_dirs = split_directories (prefix, &prefix_num);
> +  if (prefix_dirs == NULL)
> +    {
> +      free_split_directories (prog_dirs);
> +      free_split_directories (bin_dirs);
> +      return NULL;
> +    }
> +
> +  /* Find how many directories are in common between bin_prefix & prefix.  */
> +  n = (prefix_num < bin_num) ? prefix_num : bin_num;
> +  for (common = 0; common < n; common++)
> +    {
> +      if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0)
> +	break;
> +    }
> +
> +  /* If there are no common directories, there can be no relative prefix.  */
> +  if (common == 0)
> +    {
> +      free_split_directories (prog_dirs);
> +      free_split_directories (bin_dirs);
> +      free_split_directories (prefix_dirs);
> +      return NULL;
> +    }
> +
> +  /* Two passes: first figure out the size of the result string, and
> +     then construct it.  */
> +  needed_len = 0;
> +  for (i = 0; i < prog_num; i++)
> +    needed_len += strlen (prog_dirs[i]);
> +  needed_len += sizeof (DIR_UP) * (bin_num - common);
> +  for (i = common; i < prefix_num; i++)
> +    needed_len += strlen (prefix_dirs[i]);
> +  needed_len += 1; /* Trailing NUL.  */
> +
> +  ret = (char *) malloc (needed_len);
> +  if (ret == NULL)
> +    return NULL;
> +
> +  /* Build up the pathnames in argv[0].  */
> +  for (i = 0; i < prog_num; i++)
> +    strcat (ret, prog_dirs[i]);
> +
> +  /* Now build up the ..'s.  */
> +  ptr = ret + strlen(ret);
> +  for (i = common; i < bin_num; i++)
> +    {
> +      strcpy (ptr, DIR_UP);
> +      ptr += sizeof (DIR_UP) - 1;
> +      *(ptr++) = DIR_SEPARATOR;
> +    }
> +  *ptr = '\0';
> +
> +  /* Put in directories to move over to prefix.  */
> +  for (i = common; i < prefix_num; i++)
> +    strcat (ret, prefix_dirs[i]);
> +
> +  free_split_directories (prog_dirs);
> +  free_split_directories (bin_dirs);
> +  free_split_directories (prefix_dirs);
> +
> +  return ret;
> +}
> 

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Add make_relative_prefix to libiberty
  2002-11-22  7:37         ` Daniel Jacobowitz
@ 2002-11-22 11:33           ` Geoff Keating
  0 siblings, 0 replies; 8+ messages in thread
From: Geoff Keating @ 2002-11-22 11:33 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: DJ Delorie, gcc-patches


> Ping.  DJ approved the libiberty parts of this patch; I'd like to
> commit it so that I can make ld and gdb use it, but it needs to go in
> with the GCC bits.

The gcc.c part is OK.

-- 
- Geoffrey Keating <geoffk@geoffk.org>

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2002-11-22 19:33 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-11-18  9:39 Add make_relative_prefix to libiberty Daniel Jacobowitz
2002-11-18 11:44 ` DJ Delorie
2002-11-18 16:24   ` Daniel Jacobowitz
2002-11-18 16:52     ` DJ Delorie
2002-11-18 17:33       ` Daniel Jacobowitz
2002-11-18 17:47         ` DJ Delorie
2002-11-22  7:37         ` Daniel Jacobowitz
2002-11-22 11:33           ` Geoff Keating

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).