This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH[libiberty] for Re: Mainline: C++ include files not found!


On Thu, Feb 20, 2003 at 04:12:47PM -0500, DJ Delorie wrote:
> 
> > My initial reluctance was that readlink isn't guaranteed to give us
> > something that we can append to the dirname and access.  And I'd
> > need to drag in both stat and readlink, and some bits for
> > HOST_EXECUTABLE_SUFFIX that I'm not entirely sure of.
> 
> I had at one point written a semi-portable canonicalize_file_name()
> that did all that, but the reason I wrote it went away, so I dropped
> it.
> 
> > Would you rather I add this, or can we leave it until someone needs
> > this on DJGPP?
> 
> It will work well enough on DJGPP without it, so I wouldn't bother.
> 
> > Optionally returning filename seems risky to me, personally.
> 
> I'm thinking that most uses of this function will call it once at
> program startup and not even need to free the malloc'd pointer.  I
> guess it doesn't matter either way.

make_relative_prefix actually wants to free it.

> > You've got a good point on the xmalloc thing.  How about use malloc
> > and return NULL on allocation failure?  And strdup instead of
> > xstrdup.
> 
> That would be better.

Here it is with cleanups.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2003-02-20  Daniel Jacobowitz  <drow at mvista dot com>

	* libiberty.h (lrealpath): Add declaration.

2003-02-20  Daniel Jacobowitz  <drow at mvista dot com>

	* Makefile.in (CFILES): Add lrealpath.c.
	(REQUIRED_OFILES): Add lrealpath.o.
	(lrealpath.o): Add rule.
	* aclocal.m4 (libiberty_NEED_DECLARATION): Add.
	* configure.in: Add realpath and canonicalize_file_name to
	checkfuncs and AC_CHECK_FUNCS.  Use libiberty_NEED_DECLARATION
	for canonicalize_file_name.
	* lrealpath.c: New file.
	* make-relative-prefix.c: Update documentation.
	(make_relative_prefix): Simplify.  Use lbasename and lrealpath.
	* config.in: Regenerated.
	* configure: Regenerated.
	* functions.texi: Regenerated.

Index: include/libiberty.h
===================================================================
RCS file: /big/fsf/rsync/gcc-cvs/gcc/include/libiberty.h,v
retrieving revision 1.31
diff -u -p -r1.31 libiberty.h
--- include/libiberty.h	24 Nov 2002 06:54:38 -0000	1.31
+++ include/libiberty.h	20 Feb 2003 16:46:16 -0000
@@ -85,6 +85,10 @@ extern char *basename ();
 
 extern const char *lbasename PARAMS ((const char *));
 
+/* A well-defined realpath () that is always compiled in.  */
+
+extern char *lrealpath PARAMS ((const char *));
+
 /* Concatenate an arbitrary number of strings.  You must pass NULL as
    the last argument of this function, to terminate the list of
    strings.  Allocates memory using xmalloc.  */
Index: libiberty/Makefile.in
===================================================================
RCS file: /big/fsf/rsync/gcc-cvs/gcc/libiberty/Makefile.in,v
retrieving revision 1.85
diff -u -p -r1.85 Makefile.in
--- libiberty/Makefile.in	30 Jan 2003 19:02:11 -0000	1.85
+++ libiberty/Makefile.in	20 Feb 2003 17:21:34 -0000
@@ -137,6 +137,7 @@ CFILES = alloca.c argv.c asprintf.c atex
 	hashtab.c hex.c							\
 	index.c insque.c						\
 	lbasename.c							\
+	lrealpath.c							\
 	make-relative-prefix.c						\
 	make-temp-file.c md5.c memchr.c memcmp.c memcpy.c memmove.c	\
 	 memset.c mkstemps.c						\
@@ -165,6 +166,7 @@ REQUIRED_OFILES = regex.o cplus-dem.o cp
 	getopt.o getopt1.o getpwd.o getruntime.o			\
 	hashtab.o hex.o							\
 	lbasename.o							\
+	lrealpath.o							\
 	make-relative-prefix.o						\
 	make-temp-file.o						\
 	objalloc.o obstack.o						\
@@ -443,6 +445,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
+lrealpath.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.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
Index: libiberty/aclocal.m4
===================================================================
RCS file: /big/fsf/rsync/gcc-cvs/gcc/libiberty/aclocal.m4,v
retrieving revision 1.5
diff -u -p -r1.5 aclocal.m4
--- libiberty/aclocal.m4	31 Dec 2001 23:23:49 -0000	1.5
+++ libiberty/aclocal.m4	20 Feb 2003 20:41:52 -0000
@@ -87,6 +87,35 @@ then AC_DEFINE(NEED_DECLARATION_ERRNO, 1
 fi
 ])
 
+dnl See whether we need a declaration for a function.
+AC_DEFUN(libiberty_NEED_DECLARATION,
+[AC_MSG_CHECKING([whether $1 must be declared])
+AC_CACHE_VAL(libiberty_cv_decl_needed_$1,
+[AC_TRY_COMPILE([
+#include "confdefs.h"
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif],
+[char *(*pfn) = (char *(*)) $1],
+libiberty_cv_decl_needed_$1=no, libiberty_cv_decl_needed_$1=yes)])
+AC_MSG_RESULT($libiberty_cv_decl_needed_$1)
+if test $libiberty_cv_decl_needed_$1 = yes; then
+  AC_DEFINE([NEED_DECLARATION_]translit($1, [a-z], [A-Z]), 1,
+            [Define if $1 is not declared in system header files.])
+fi
+])dnl
+
 # FIXME: We temporarily define our own version of AC_PROG_CC.  This is
 # copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS.  We
 # are probably using a cross compiler, which will not be able to fully
Index: libiberty/configure.in
===================================================================
RCS file: /big/fsf/rsync/gcc-cvs/gcc/libiberty/configure.in,v
retrieving revision 1.55
diff -u -p -r1.55 configure.in
--- libiberty/configure.in	30 Jan 2003 19:02:12 -0000	1.55
+++ libiberty/configure.in	20 Feb 2003 17:22:48 -0000
@@ -207,6 +207,7 @@ funcs="$funcs waitpid"
 vars="sys_errlist sys_nerr sys_siglist"
 
 checkfuncs="getrusage on_exit psignal strerror strsignal sysconf times sbrk gettimeofday"
+checkfuncs="$checkfuncs realpath canonicalize_file_name"
 
 # These are neither executed nor required, but they help keep
 # autoheader happy without adding a bunch of text to acconfig.h.
@@ -218,6 +219,7 @@ if test "x" = "y"; then
   AC_CHECK_FUNCS(strtod strtol strtoul tmpnam vasprintf vfprintf vprintf)
   AC_CHECK_FUNCS(vsprintf waitpid getrusage on_exit psignal strerror strsignal)
   AC_CHECK_FUNCS(sysconf times sbrk gettimeofday ffs)
+  AC_CHECK_FUNCS(realpath canonicalize_file_name)
   AC_DEFINE(HAVE_SYS_ERRLIST, 1, [Define if you have the sys_errlist variable.])
   AC_DEFINE(HAVE_SYS_NERR,    1, [Define if you have the sys_nerr variable.])
   AC_DEFINE(HAVE_SYS_SIGLIST, 1, [Define if you have the sys_siglist variable.])
@@ -424,6 +426,7 @@ if test -z "${setobjs}"; then
     fi
   done
   AC_CHECK_FUNCS($checkfuncs)
+  libiberty_NEED_DECLARATION(canonicalize_file_name)
 fi
 
 # Figure out which version of pexecute to use.
Index: libiberty/lrealpath.c
===================================================================
RCS file: libiberty/lrealpath.c
diff -N libiberty/lrealpath.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libiberty/lrealpath.c	20 Feb 2003 20:44:03 -0000
@@ -0,0 +1,128 @@
+/* Libiberty realpath.  Like realpath, but more consistent behavior.
+   Based on gdb_realpath from GDB.
+
+   Copyright 2003 Free Software Foundation, Inc.
+
+   This file is part of the libiberty library.
+
+   This program 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 of the License, or
+   (at your option) any later version.
+
+   This program 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 this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/*
+
+ at deftypefn Replacement {const char*} lrealpath (const char * at var{name})
+
+Given a pointer to a string containing a pathname, returns a canonical
+version of the filename.  Symlinks will be resolved, and ``.'' and ``..''
+components will be simplified.  The returned value will be allocated using
+ at code{malloc}, or @code{NULL} will be returned on a memory allocation error.
+
+ at end deftypefn
+
+*/
+
+#include "config.h"
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+/* On GNU libc systems the declaration is only visible with _GNU_SOURCE.  */
+#if defined(HAVE_CANONICALIZE_FILE_NAME) \
+    && defined(NEED_DECLARATION_CANONICALIZE_FILE_NAME)
+extern char *canonicalize_file_name (const char *);
+#endif
+
+#if defined(HAVE_REALPATH)
+# if defined (PATH_MAX)
+#  define REALPATH_LIMIT PATH_MAX
+# else
+#  if defined (MAXPATHLEN)
+#   define REALPATH_LIMIT MAXPATHLEN
+#  endif
+# endif
+#endif
+
+char *
+lrealpath (filename)
+     const char *filename;
+{
+  /* Method 1: The system has a compile time upper bound on a filename
+     path.  Use that and realpath() to canonicalize the name.  This is
+     the most common case.  Note that, if there isn't a compile time
+     upper bound, you want to avoid realpath() at all costs.  */
+#if defined(REALPATH_LIMIT)
+  {
+    char buf[REALPATH_LIMIT];
+    const char *rp = realpath (filename, buf);
+    if (rp == NULL)
+      rp = filename;
+    return strdup (rp);
+  }
+#endif /* REALPATH_LIMIT */
+
+  /* Method 2: The host system (i.e., GNU) has the function
+     canonicalize_file_name() which malloc's a chunk of memory and
+     returns that, use that.  */
+#if defined(HAVE_CANONICALIZE_FILE_NAME)
+  {
+    char *rp = canonicalize_file_name (filename);
+    if (rp == NULL)
+      return strdup (filename);
+    else
+      return rp;
+  }
+#endif
+
+  /* Method 3: Now we're getting desperate!  The system doesn't have a
+     compile time buffer size and no alternative function.  Query the
+     OS, using pathconf(), for the buffer limit.  Care is needed
+     though, some systems do not limit PATH_MAX (return -1 for
+     pathconf()) making it impossible to pass a correctly sized buffer
+     to realpath() (it could always overflow).  On those systems, we
+     skip this.  */
+#if defined (HAVE_REALPATH) && defined (HAVE_UNISTD_H)
+  {
+    /* Find out the max path size.  */
+    long path_max = pathconf ("/", _PC_PATH_MAX);
+    if (path_max > 0)
+      {
+	/* PATH_MAX is bounded.  */
+	char *buf, *rp, *ret;
+	buf = malloc (path_max);
+	if (buf == NULL)
+	  return NULL;
+	rp = realpath (filename, buf);
+	ret = strdup (rp ? rp : filename);
+	free (buf);
+	return ret;
+      }
+  }
+#endif
+
+  /* This system is a lost cause, just duplicate the filename.  */
+  return strdup (filename);
+}
Index: libiberty/make-relative-prefix.c
===================================================================
RCS file: /big/fsf/rsync/gcc-cvs/gcc/libiberty/make-relative-prefix.c,v
retrieving revision 1.3
diff -u -p -r1.3 make-relative-prefix.c
--- libiberty/make-relative-prefix.c	4 Dec 2002 01:57:27 -0000	1.3
+++ libiberty/make-relative-prefix.c	20 Feb 2003 20:45:22 -0000
@@ -23,16 +23,25 @@ Software Foundation, 59 Temple Place - S
 
 @deftypefn Extension {const char*} make_relative_prefix (const char * at var{progname}, const char * at var{bin_prefix}, const char * at 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/}.
+Given three paths @var{progname}, @var{bin_prefix}, @var{prefix},
+return the path that is in the same position relative to
+ at var{progname}'s directory as @var{prefix} is relative to
+ at var{bin_prefix} dot   That is, a string starting with the directory
+portion of @var{progname}, followed by a relative pathname of the
+difference between @var{bin_prefix} and @var{prefix}.
+
+If @var{progname} does not contain any directory separators,
+ at code{make_relative_prefix} will search @env{PATH} to find a program
+named @var{progname}.  Also, if @var{progname} is a symbolic link,
+the symbolic link will be resolved.
+
+For example, if @var{bin_prefix} is @code{/alpha/beta/gamma/gcc/delta},
+ at var{prefix} is @code{/alpha/beta/gamma/omega/}, and @var{progname} is
+ at code{/red/green/blue/gcc}, then this function will return
+ at code{/red/green/blue/../../omega/}.
 
-The return value is normally allocated via @code{malloc}.  If no relative prefix
-can be found, return @code{NULL}.
+The return value is normally allocated via @code{malloc}.  If no
+relative prefix can be found, return @code{NULL}.
 
 @end deftypefn
 
@@ -223,19 +232,14 @@ make_relative_prefix (progname, bin_pref
   int prog_num, bin_num, prefix_num;
   int i, n, common;
   int needed_len;
-  char *ret, *ptr;
+  char *ret, *ptr, *full_progname = NULL;
 
   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)
+  if (lbasename (progname) == progname)
     {
       char *temp;
 
@@ -278,14 +282,7 @@ make_relative_prefix (progname, bin_pref
 #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;
 		    }
 
@@ -298,6 +295,16 @@ make_relative_prefix (progname, bin_pref
 	    }
 	}
     }
+
+  full_progname = lrealpath (progname);
+  if (full_progname == NULL)
+    return NULL;
+
+  prog_dirs = split_directories (full_progname, &prog_num);
+  bin_dirs = split_directories (bin_prefix, &bin_num);
+  free (full_progname);
+  if (bin_dirs == NULL || prog_dirs == NULL)
+    return NULL;
 
   /* Remove the program name from comparison of directory names.  */
   prog_num--;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]