public inbox for sid@sourceware.org
 help / color / mirror / Atom feed
* patch for location-independence
@ 2001-11-13 13:24 Geoffrey Keating
  2001-11-13 13:49 ` Frank Ch. Eigler
  2001-11-21 13:33 ` Geoffrey Keating
  0 siblings, 2 replies; 4+ messages in thread
From: Geoffrey Keating @ 2001-11-13 13:24 UTC (permalink / raw)
  To: sid


The attached patch causes SID to look at argv[0] to determine its
location, so that the installed sid tree can be moved anywhere and
there is no need to set SID_EXEC_PREFIX (to run the sid executable,
at least).

OK to commit?

-- 
Geoff Keating <geoffk@redhat.com>

===File ~/patches/sid-relocate.patch========================
Index: sid/include/ChangeLog
2001-11-19  Geoffrey Keating  <geoffk@redhat.com>

	* sidmiscutil.h (argv0): New variable.
	(make_relative_prefix): New function.
	(sid_file_search_path): Determine default SID_EXEC_PREFIX from
	argv[0].
	* configure.in: Define SID_PREFIX as $prefix.
	* configure: Regenerate.
	* sidconfutil.in: Dummy SID_PREFIX declaration.

Index: sid/main/dynamic/ChangeLog
2001-11-19  Geoffrey Keating  <geoffk@redhat.com>

	* mainDynamic.cxx (sidutil::argv0): Define.

Index: sid/include/configure.in
===================================================================
RCS file: /cvs/cvsfiles/devo/sid/include/configure.in,v
retrieving revision 1.10
diff -p -u -p -r1.10 configure.in
--- configure.in	2001/03/26 19:18:38	1.10
+++ configure.in	2001/11/20 05:26:27
@@ -66,5 +66,7 @@ else
 fi
 AC_DEFINE_UNQUOTED(SID_EXEC_PREFIX,"$sid_exec_prefix",[Define to build-time exec-prefix])
 
+AC_DEFINE_UNQUOTED(SID_PREFIX,"$prefix",[Define to build-time prefix])
+
 dnl Outputs
 AC_OUTPUT(Makefile)
Index: sid/include/sidconfutil.in
===================================================================
RCS file: /cvs/cvsfiles/devo/sid/include/sidconfutil.in,v
retrieving revision 1.4
diff -p -u -p -r1.4 sidconfutil.in
--- sidconfutil.in	2001/03/26 19:18:38	1.4
+++ sidconfutil.in	2001/11/20 05:26:27
@@ -36,3 +36,6 @@
 /* Define to build-time exec-prefix */
 #undef SID_EXEC_PREFIX
 
+/* Define to build-time prefix */
+#undef SID_PREFIX
+
Index: sid/include/sidmiscutil.h
===================================================================
RCS file: /cvs/cvsfiles/devo/sid/include/sidmiscutil.h,v
retrieving revision 1.19
diff -p -u -p -r1.19 sidmiscutil.h
--- sidmiscutil.h	2001/05/25 15:12:54	1.19
+++ sidmiscutil.h	2001/11/20 05:26:27
@@ -20,10 +20,14 @@
 #ifdef __CYGWIN__
 #include <sys/cygwin.h>
 #endif
+#include <unistd.h>
 
 
 namespace sidutil
 {
+  // argv[0] passed to the main program.
+  extern char *argv0;
+
   // Instances of this class template function as bidirectional lookup
   // tables (bijections) for mapping objects to each other by value.
   template <class Obj1, class Obj2>
@@ -310,6 +314,111 @@ namespace sidutil
     }
 
 
+  /* 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.  */
+
+  inline std::string *
+  make_relative_prefix (const std::string &progname, 
+			const std::string &bin_prefix, 
+			const std::string &prefix)
+  {
+    std::vector<std::string> prog_dirs = tokenize (progname, "/");
+
+    /* 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_dirs.size() == 1)
+      {
+	char *path = getenv ("PATH");
+	
+	if (path)
+	  {
+	    std::vector<std::string> paths = tokenize (path, ":");
+	    std::vector<std::string>::iterator i;
+	    
+	    for (i = paths.begin();
+		 i != paths.end();
+		 i++)
+	      {
+		std::string s = *i;
+		if (s == "")
+		  s = '.';
+		if (s[s.length()-1] != '/')
+		  s += '/';
+		s += progname;
+		if (! access (s.c_str (), X_OK))
+		  break;
+#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
+		s += HOST_EXECUTABLE_SUFFIX;
+		if (! access (s.c_str (), X_OK))
+		  break;
+#endif
+	      }
+	  
+	    if (i == paths.end())
+	      return NULL;
+	  
+	    prog_dirs = tokenize (*i, "/");
+	  }
+      } else {
+	/* Remove the program name from comparison of directory names.  */
+	prog_dirs.pop_back ();
+      }
+    
+    std::vector<std::string> bin_dirs = tokenize (bin_prefix, "/");
+
+    /* Determine if the program is installed in the standard location, and if
+       so, we don't need to specify relative directories.  */
+    if (prog_dirs == bin_dirs)
+      return new std::string (prefix);
+
+    std::vector<std::string> prefix_dirs = tokenize (prefix, "/");
+
+    /* Find how many directories are in common between bin_prefix & prefix.  */
+    std::vector<std::string>::iterator bin_common, pfx_common;
+    for (bin_common = bin_dirs.begin(), pfx_common = prefix_dirs.begin();
+	 bin_common != bin_dirs.end() && pfx_common != prefix_dirs.end();
+	 bin_common++, pfx_common++)
+      if (*bin_common != *pfx_common)
+	break;
+    
+    /* If there are no common directories, there can be no relative prefix.  */
+    if (bin_common == bin_dirs.begin ())
+      return NULL;
+  
+    std::string result = "";
+
+    /* Build up the pathnames in argv[0].  */
+    for (std::vector<std::string>::iterator i = prog_dirs.begin ();
+	 i != prog_dirs.end ();
+	 i++)
+      {
+	result += *i;
+	result += '/';
+      }
+
+    /* Now build up the ..'s.  */
+    for (; bin_common != bin_dirs.end (); bin_common++)
+      result += "../";
+  
+    /* Put in directories to move over to prefix.  */
+    for (; pfx_common != prefix_dirs.end (); pfx_common++)
+      {
+	result += *pfx_common;
+	result += '/';
+      }
+    
+    return new std::string(result);
+  }
+
   // Return a vector of directory names, where the SID_LIBRARY_PATH
   // and SID_EXEC_PREFIX environment variables are pointing.  Convert
   // all paths to POSIX form on Cygwin.
@@ -337,14 +446,31 @@ namespace sidutil
 	  sep = conv_fn;
       }
 #endif
-    if (!sep) sep = SID_EXEC_PREFIX; // build-time configuration
-    // We really just want to get to pkgdatadir, which is $prefix/share
-    // Guess exec-prefix == prefix
-    std::string pkglibdir1 = std::string(sep) + std::string("/share");
-    search_directories.push_back (pkglibdir1);
-    // Guess exec-prefix == prefix/H-HOST
-    std::string pkglibdir2 = std::string(sep) + std::string("/../share");
-    search_directories.push_back (pkglibdir2);
+    if (sep)
+      {
+	// We really just want to get to pkgdatadir, which is $prefix/share
+	// Guess exec-prefix == prefix
+	std::string pkglibdir1 = std::string(sep) + std::string("/share");
+	search_directories.push_back (pkglibdir1);
+	// Guess exec-prefix == prefix/H-HOST
+	std::string pkglibdir2 = std::string(sep) + std::string("/../share");
+	search_directories.push_back (pkglibdir2);
+      }
+    else
+      {
+	// Guess from argv[0].
+	std::string *path;
+	path = make_relative_prefix (argv0, SID_EXEC_PREFIX "/bin",
+				     SID_PREFIX "/share");
+	if (path)
+	  {
+	    search_directories.push_back (*path);
+	    delete path;
+	  }
+	else
+	  // Fall back to build-time configuration.
+	  search_directories.push_back (SID_PREFIX "/share");
+      }
 
     return search_directories;
   }
Index: sid/main/dynamic/mainDynamic.cxx
===================================================================
RCS file: /cvs/cvsfiles/devo/sid/main/dynamic/mainDynamic.cxx,v
retrieving revision 1.23
diff -p -u -p -r1.23 mainDynamic.cxx
--- mainDynamic.cxx	2001/10/05 19:57:06	1.23
+++ mainDynamic.cxx	2001/11/20 05:26:27
@@ -35,6 +35,9 @@ static void sid_pre_run () {}
 static void sid_post_run () {}
 
 
+namespace sidutil {
+  char *argv0;
+}
 
 void
 version ()
@@ -68,6 +71,8 @@ main(int argc, char* argv[])
   vector< pair<bool,string> > config_items;
   bool dry_run_p = false;
   string config_file;
+
+  argv0 = argv[0];
 
   if (argc == 1)
     {
============================================================

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

* Re: patch for location-independence
  2001-11-13 13:24 patch for location-independence Geoffrey Keating
@ 2001-11-13 13:49 ` Frank Ch. Eigler
  2001-11-21 13:59   ` Frank Ch. Eigler
  2001-11-21 13:33 ` Geoffrey Keating
  1 sibling, 1 reply; 4+ messages in thread
From: Frank Ch. Eigler @ 2001-11-13 13:49 UTC (permalink / raw)
  To: Geoffrey Keating; +Cc: sid

[-- Attachment #1: Type: text/plain, Size: 1322 bytes --]

Hi -

On Wed, Nov 21, 2001 at 01:33:47PM -0800, Geoffrey Keating wrote:
: The attached patch causes SID to look at argv[0] to determine its
: location, so that the installed sid tree can be moved anywhere and
: there is no need to set SID_EXEC_PREFIX (to run the sid executable,
: at least).
: 
: OK to commit?

Thank you for giving this a try, however, I have a few
reservations though about the propriety of this approach.

For one thing, global variables such as sidutil::argv0[] are
generally unwelcome in sid, among other reasons for interfering
with shared library mechanisms.  For another, it is necessary to
use systematic C++ namespace prefixing on ~all the identifiers;
testing with gcc 3.0+ helps uncover problems like that.  The code
also does too much (all) work anew for each file search.

It would be better to put this logic into sid/main/mainDynamic.cxx
itself; if getenv(SID_EXEC_PREFIX) is unset, it could endavour to
compute a plausible value and put it into the environment.  (It could
do the same to a hypothetical SID_PREFIX while at it.)  The sidutil
code could then go unchanged, or even simplified.

Does this make sense?

(I wonder too to what extent the code in question was begat by gcc;
sid is (C) Red Hat, not (C) FSF; is there a reason for concern?)

- FChE

[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

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

* patch for location-independence
  2001-11-13 13:24 patch for location-independence Geoffrey Keating
  2001-11-13 13:49 ` Frank Ch. Eigler
@ 2001-11-21 13:33 ` Geoffrey Keating
  1 sibling, 0 replies; 4+ messages in thread
From: Geoffrey Keating @ 2001-11-21 13:33 UTC (permalink / raw)
  To: sid

The attached patch causes SID to look at argv[0] to determine its
location, so that the installed sid tree can be moved anywhere and
there is no need to set SID_EXEC_PREFIX (to run the sid executable,
at least).

OK to commit?

-- 
Geoff Keating <geoffk@redhat.com>

===File ~/patches/sid-relocate.patch========================
Index: sid/include/ChangeLog
2001-11-19  Geoffrey Keating  <geoffk@redhat.com>

	* sidmiscutil.h (argv0): New variable.
	(make_relative_prefix): New function.
	(sid_file_search_path): Determine default SID_EXEC_PREFIX from
	argv[0].
	* configure.in: Define SID_PREFIX as $prefix.
	* configure: Regenerate.
	* sidconfutil.in: Dummy SID_PREFIX declaration.

Index: sid/main/dynamic/ChangeLog
2001-11-19  Geoffrey Keating  <geoffk@redhat.com>

	* mainDynamic.cxx (sidutil::argv0): Define.

Index: sid/include/configure.in
===================================================================
RCS file: /cvs/cvsfiles/devo/sid/include/configure.in,v
retrieving revision 1.10
diff -p -u -p -r1.10 configure.in
--- configure.in	2001/03/26 19:18:38	1.10
+++ configure.in	2001/11/20 05:26:27
@@ -66,5 +66,7 @@ else
 fi
 AC_DEFINE_UNQUOTED(SID_EXEC_PREFIX,"$sid_exec_prefix",[Define to build-time exec-prefix])
 
+AC_DEFINE_UNQUOTED(SID_PREFIX,"$prefix",[Define to build-time prefix])
+
 dnl Outputs
 AC_OUTPUT(Makefile)
Index: sid/include/sidconfutil.in
===================================================================
RCS file: /cvs/cvsfiles/devo/sid/include/sidconfutil.in,v
retrieving revision 1.4
diff -p -u -p -r1.4 sidconfutil.in
--- sidconfutil.in	2001/03/26 19:18:38	1.4
+++ sidconfutil.in	2001/11/20 05:26:27
@@ -36,3 +36,6 @@
 /* Define to build-time exec-prefix */
 #undef SID_EXEC_PREFIX
 
+/* Define to build-time prefix */
+#undef SID_PREFIX
+
Index: sid/include/sidmiscutil.h
===================================================================
RCS file: /cvs/cvsfiles/devo/sid/include/sidmiscutil.h,v
retrieving revision 1.19
diff -p -u -p -r1.19 sidmiscutil.h
--- sidmiscutil.h	2001/05/25 15:12:54	1.19
+++ sidmiscutil.h	2001/11/20 05:26:27
@@ -20,10 +20,14 @@
 #ifdef __CYGWIN__
 #include <sys/cygwin.h>
 #endif
+#include <unistd.h>
 
 
 namespace sidutil
 {
+  // argv[0] passed to the main program.
+  extern char *argv0;
+
   // Instances of this class template function as bidirectional lookup
   // tables (bijections) for mapping objects to each other by value.
   template <class Obj1, class Obj2>
@@ -310,6 +314,111 @@ namespace sidutil
     }
 
 
+  /* 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.  */
+
+  inline std::string *
+  make_relative_prefix (const std::string &progname, 
+			const std::string &bin_prefix, 
+			const std::string &prefix)
+  {
+    std::vector<std::string> prog_dirs = tokenize (progname, "/");
+
+    /* 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_dirs.size() == 1)
+      {
+	char *path = getenv ("PATH");
+	
+	if (path)
+	  {
+	    std::vector<std::string> paths = tokenize (path, ":");
+	    std::vector<std::string>::iterator i;
+	    
+	    for (i = paths.begin();
+		 i != paths.end();
+		 i++)
+	      {
+		std::string s = *i;
+		if (s == "")
+		  s = '.';
+		if (s[s.length()-1] != '/')
+		  s += '/';
+		s += progname;
+		if (! access (s.c_str (), X_OK))
+		  break;
+#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
+		s += HOST_EXECUTABLE_SUFFIX;
+		if (! access (s.c_str (), X_OK))
+		  break;
+#endif
+	      }
+	  
+	    if (i == paths.end())
+	      return NULL;
+	  
+	    prog_dirs = tokenize (*i, "/");
+	  }
+      } else {
+	/* Remove the program name from comparison of directory names.  */
+	prog_dirs.pop_back ();
+      }
+    
+    std::vector<std::string> bin_dirs = tokenize (bin_prefix, "/");
+
+    /* Determine if the program is installed in the standard location, and if
+       so, we don't need to specify relative directories.  */
+    if (prog_dirs == bin_dirs)
+      return new std::string (prefix);
+
+    std::vector<std::string> prefix_dirs = tokenize (prefix, "/");
+
+    /* Find how many directories are in common between bin_prefix & prefix.  */
+    std::vector<std::string>::iterator bin_common, pfx_common;
+    for (bin_common = bin_dirs.begin(), pfx_common = prefix_dirs.begin();
+	 bin_common != bin_dirs.end() && pfx_common != prefix_dirs.end();
+	 bin_common++, pfx_common++)
+      if (*bin_common != *pfx_common)
+	break;
+    
+    /* If there are no common directories, there can be no relative prefix.  */
+    if (bin_common == bin_dirs.begin ())
+      return NULL;
+  
+    std::string result = "";
+
+    /* Build up the pathnames in argv[0].  */
+    for (std::vector<std::string>::iterator i = prog_dirs.begin ();
+	 i != prog_dirs.end ();
+	 i++)
+      {
+	result += *i;
+	result += '/';
+      }
+
+    /* Now build up the ..'s.  */
+    for (; bin_common != bin_dirs.end (); bin_common++)
+      result += "../";
+  
+    /* Put in directories to move over to prefix.  */
+    for (; pfx_common != prefix_dirs.end (); pfx_common++)
+      {
+	result += *pfx_common;
+	result += '/';
+      }
+    
+    return new std::string(result);
+  }
+
   // Return a vector of directory names, where the SID_LIBRARY_PATH
   // and SID_EXEC_PREFIX environment variables are pointing.  Convert
   // all paths to POSIX form on Cygwin.
@@ -337,14 +446,31 @@ namespace sidutil
 	  sep = conv_fn;
       }
 #endif
-    if (!sep) sep = SID_EXEC_PREFIX; // build-time configuration
-    // We really just want to get to pkgdatadir, which is $prefix/share
-    // Guess exec-prefix == prefix
-    std::string pkglibdir1 = std::string(sep) + std::string("/share");
-    search_directories.push_back (pkglibdir1);
-    // Guess exec-prefix == prefix/H-HOST
-    std::string pkglibdir2 = std::string(sep) + std::string("/../share");
-    search_directories.push_back (pkglibdir2);
+    if (sep)
+      {
+	// We really just want to get to pkgdatadir, which is $prefix/share
+	// Guess exec-prefix == prefix
+	std::string pkglibdir1 = std::string(sep) + std::string("/share");
+	search_directories.push_back (pkglibdir1);
+	// Guess exec-prefix == prefix/H-HOST
+	std::string pkglibdir2 = std::string(sep) + std::string("/../share");
+	search_directories.push_back (pkglibdir2);
+      }
+    else
+      {
+	// Guess from argv[0].
+	std::string *path;
+	path = make_relative_prefix (argv0, SID_EXEC_PREFIX "/bin",
+				     SID_PREFIX "/share");
+	if (path)
+	  {
+	    search_directories.push_back (*path);
+	    delete path;
+	  }
+	else
+	  // Fall back to build-time configuration.
+	  search_directories.push_back (SID_PREFIX "/share");
+      }
 
     return search_directories;
   }
Index: sid/main/dynamic/mainDynamic.cxx
===================================================================
RCS file: /cvs/cvsfiles/devo/sid/main/dynamic/mainDynamic.cxx,v
retrieving revision 1.23
diff -p -u -p -r1.23 mainDynamic.cxx
--- mainDynamic.cxx	2001/10/05 19:57:06	1.23
+++ mainDynamic.cxx	2001/11/20 05:26:27
@@ -35,6 +35,9 @@ static void sid_pre_run () {}
 static void sid_post_run () {}
 
 
+namespace sidutil {
+  char *argv0;
+}
 
 void
 version ()
@@ -68,6 +71,8 @@ main(int argc, char* argv[])
   vector< pair<bool,string> > config_items;
   bool dry_run_p = false;
   string config_file;
+
+  argv0 = argv[0];
 
   if (argc == 1)
     {
============================================================

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

* Re: patch for location-independence
  2001-11-13 13:49 ` Frank Ch. Eigler
@ 2001-11-21 13:59   ` Frank Ch. Eigler
  0 siblings, 0 replies; 4+ messages in thread
From: Frank Ch. Eigler @ 2001-11-21 13:59 UTC (permalink / raw)
  To: Geoffrey Keating; +Cc: sid

Hi -

On Wed, Nov 21, 2001 at 01:33:47PM -0800, Geoffrey Keating wrote:
: The attached patch causes SID to look at argv[0] to determine its
: location, so that the installed sid tree can be moved anywhere and
: there is no need to set SID_EXEC_PREFIX (to run the sid executable,
: at least).
: 
: OK to commit?

Thank you for giving this a try, however, I have a few
reservations though about the propriety of this approach.

For one thing, global variables such as sidutil::argv0[] are
generally unwelcome in sid, among other reasons for interfering
with shared library mechanisms.  For another, it is necessary to
use systematic C++ namespace prefixing on ~all the identifiers;
testing with gcc 3.0+ helps uncover problems like that.  The code
also does too much (all) work anew for each file search.

It would be better to put this logic into sid/main/mainDynamic.cxx
itself; if getenv(SID_EXEC_PREFIX) is unset, it could endavour to
compute a plausible value and put it into the environment.  (It could
do the same to a hypothetical SID_PREFIX while at it.)  The sidutil
code could then go unchanged, or even simplified.

Does this make sense?

(I wonder too to what extent the code in question was begat by gcc;
sid is (C) Red Hat, not (C) FSF; is there a reason for concern?)

- FChE
-- 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE7/CO2VZbdDOm/ZT0RAgcgAJ9Fwi8yubKZiLo1WrPfeXfd9lApQwCfeXUx
IGZUl0CSNjv4+GKD00ga0l0=
=vjpK
-----END PGP SIGNATURE-----

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

end of thread, other threads:[~2001-11-21 21:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-11-13 13:24 patch for location-independence Geoffrey Keating
2001-11-13 13:49 ` Frank Ch. Eigler
2001-11-21 13:59   ` Frank Ch. Eigler
2001-11-21 13:33 ` Geoffrey 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).