From 4839dd4f8b6ba2b66a662c9ceda9d98732ee43e7 Mon Sep 17 00:00:00 2001
From: Marcus Comstedt <marcus@mc.pp.se>
Date: Sun, 2 Sep 2001 03:36:14 +0200
Subject: [PATCH] Relocatable dumped modules TNG.  Fully optional and actually
 working.  :)

Rev: bin/install.pike:1.79
Rev: lib/master.pike.in:1.169
Rev: lib/modules/Calendar.pmod/Events.pmod:1.10
Rev: lib/modules/Calendar.pmod/TZnames.pmod:1.10
Rev: lib/modules/Calendar.pmod/Timezone.pmod:1.22
Rev: src/Makefile.in:1.271
Rev: src/configure.in:1.545
Rev: src/dumpmodule.pike:1.22
---
 bin/install.pike                        |  2 ++
 lib/master.pike.in                      | 46 ++++++++++++++++++++++++-
 lib/modules/Calendar.pmod/Events.pmod   |  4 +--
 lib/modules/Calendar.pmod/TZnames.pmod  |  2 +-
 lib/modules/Calendar.pmod/Timezone.pmod |  2 +-
 src/Makefile.in                         | 17 +++++----
 src/configure.in                        | 11 +++++-
 src/dumpmodule.pike                     | 31 +++++++++++++----
 8 files changed, 95 insertions(+), 20 deletions(-)

diff --git a/bin/install.pike b/bin/install.pike
index e0b115f4b9..f1fd795560 100644
--- a/bin/install.pike
+++ b/bin/install.pike
@@ -1008,6 +1008,8 @@ void make_master(string dest, string master, string lib_prefix)
   status("Finalizing",master);
   string master_data=Stdio.read_file(master);
   master_data=replace(master_data,"�lib_prefix�",replace(lib_prefix,"\\","\\\\"));
+  if((vars->PIKE_MODULE_RELOC||"") != "")
+    master_data=replace(master_data,"#undef PIKE_MODULE_RELOC","#define PIKE_MODULE_RELOC 1");
   Stdio.write_file(combine_path(vars->TMP_LIBDIR,"master.pike"),master_data);
   status("Finalizing",master,"done");
 }
diff --git a/lib/master.pike.in b/lib/master.pike.in
index 1c109078c0..7b8ddea6d5 100644
--- a/lib/master.pike.in
+++ b/lib/master.pike.in
@@ -1,6 +1,6 @@
 /* -*- Pike -*-
  *	
- * $Id: master.pike.in,v 1.168 2001/08/31 07:18:19 hubbe Exp $
+ * $Id: master.pike.in,v 1.169 2001/09/02 01:36:13 marcus Exp $
  * 
  * Master-file for Pike.
  *
@@ -33,6 +33,8 @@ constant out_of_date_warning = OUT_OF_DATE_WARNING;
 #define PIKE_WARNINGS 0
 #endif /* PIKE_WARNINGS */
 
+#undef PIKE_MODULE_RELOC
+
 /*
  * Functions begin here.
  */
@@ -53,6 +55,41 @@ string fakeroot(string s)
 #define fakeroot(X) X
 #endif
 
+#ifdef PIKE_MODULE_RELOC
+string relocate_module(string s)
+{
+  if(s[..1]=="/$" && (s+"/")[..20] == "/${PIKE_MODULE_PATH}/") {
+    string tmp = s[21..];
+    foreach(pike_module_path, string path) {
+      string s2 = fakeroot(sizeof(tmp)? combine_path(path, tmp) : path);
+      if(master_file_stat(s2))
+	return s2;
+    }
+  }
+  return fakeroot(s);
+}
+
+string unrelocate_module(string s)
+{
+  if(s[..1]=="/$" && (s+"/")[..20] == "/${PIKE_MODULE_PATH}/")
+    return s;
+
+  foreach(pike_module_path, string path)
+    if(s == path)
+      return "/${PIKE_MODULE_PATH}";
+    else {
+      string s2 = combine_path(path, "");
+      if(s[..sizeof(s2)-1] == s2)
+	return "/${PIKE_MODULE_PATH}/"+s[sizeof(s2)..];
+    }
+  return s;
+}
+#ifdef fakeroot
+#undef fakeroot
+#endif
+#define fakeroot relocate_module
+#endif
+
 
 //! @appears is_absolute_path
 //! Check if a path @[p] is fully qualified (ie not relative).
@@ -392,6 +429,10 @@ static program low_findprog(string pname,
   }
 #endif
 
+#ifdef PIKE_MODULE_RELOC
+  fname = unrelocate_module(fname);
+#endif
+
 #ifdef PIKE_AUTORELOAD
   if(!autoreload_on || load_time[fname]>=time())
 #endif
@@ -1683,6 +1724,9 @@ mixed get_inhibit_compile_errors()
 static private function(string:string) _trim_file_name_cb=0;
 string trim_file_name(string s)
 {
+#ifdef PIKE_MODULE_RELOC
+  s = relocate_module(s);
+#endif
   if(getenv("LONG_PIKE_ERRORS")) return s;
   if(getenv("SHORT_PIKE_ERRORS")) return BASENAME(s);
 
diff --git a/lib/modules/Calendar.pmod/Events.pmod b/lib/modules/Calendar.pmod/Events.pmod
index 77dfc741ae..70b053776b 100644
--- a/lib/modules/Calendar.pmod/Events.pmod
+++ b/lib/modules/Calendar.pmod/Events.pmod
@@ -12,7 +12,7 @@ constant wd2n=(["Mon":1,"Tue":2,"Wed":3,"Thu":4,"Fri":5,"Sat":6,"Sun":7]);
 
 void read_all_data()
 {
-   all_data=Stdio.read_bytes(
+   all_data=master()->master_read_file(
       combine_path(__FILE__,"../events/regional"));
 }
 
@@ -171,7 +171,7 @@ mapping made_namedays=([]);
 
 string read_all_namedays()
 {
-   return Stdio.read_bytes(
+   return master()->master_read_file(
       combine_path(__FILE__,"../events/namedays"));
 }
 
diff --git a/lib/modules/Calendar.pmod/TZnames.pmod b/lib/modules/Calendar.pmod/TZnames.pmod
index 7b89f936f8..b77a3d8bd5 100644
--- a/lib/modules/Calendar.pmod/TZnames.pmod
+++ b/lib/modules/Calendar.pmod/TZnames.pmod
@@ -31,7 +31,7 @@ static string raw_zone_tab=0;
 string _zone_tab()
 {
    return raw_zone_tab ||
-      (raw_zone_tab = Stdio.read_bytes(
+      (raw_zone_tab = master()->master_read_file(
 	 combine_path(__FILE__,"..","tzdata/zone.tab")));
 }
 
diff --git a/lib/modules/Calendar.pmod/Timezone.pmod b/lib/modules/Calendar.pmod/Timezone.pmod
index 1a66c049c7..684c29d0fe 100644
--- a/lib/modules/Calendar.pmod/Timezone.pmod
+++ b/lib/modules/Calendar.pmod/Timezone.pmod
@@ -1041,7 +1041,7 @@ class Runtime_timezone_compiler
 	 map(files,
 	     lambda(string fn)
 	     {
-		return Stdio.read_bytes(base_path+fn) ||
+		return master()->master_read_file(base_path+fn) ||
 		   (error("Failed to open file %O\n",base_path+fn), "");
 	     })*"\n";
    }
diff --git a/src/Makefile.in b/src/Makefile.in
index 09f5fe8045..08387f8c37 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.in,v 1.270 2001/07/20 12:44:50 grubba Exp $
+# $Id: Makefile.in,v 1.271 2001/09/02 01:36:14 marcus Exp $
 #
 
 # This line is needed on some machines.
@@ -99,6 +99,7 @@ RUNPIKE=$(DEFAULT_RUNPIKE)
 USE_TPIKE=$(TMP_BUILDDIR)/precompile.sh
 USE_PIKE=@PIKE@ $(PIKEOPTS)
 RUNTPIKE=$(@RUNTPIKE@)
+PIKE_MODULE_RELOC=@PIKE_MODULE_RELOC@
 
 MAKE_FLAGS=
 
@@ -371,14 +372,14 @@ install: pike hilfe pike-module aclocal
 	TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" \
 	SRCDIR="$(SRCDIR)" prefix="$(prefix)" MANDIR_SRC="$(MANDIR_SRC)" \
 	man_prefix="$(man_prefix)" pike_name=$(pike_name) \
-	fakeroot="$(buildroot)"
+	fakeroot="$(buildroot)" PIKE_MODULE_RELOC="$(PIKE_MODULE_RELOC)"
 
 install_interactive: pike hilfe pike-module aclocal
 	@$(RUNPIKE) $(TMP_BINDIR)/install.pike --interactive \
 	exec_prefix="$(exec_prefix)"  prefix=$(prefix) \
 	TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" \
 	SRCDIR="$(SRCDIR)" MANDIR_SRC="$(MANDIR_SRC)" \
-	fakeroot="$(buildroot)"
+	fakeroot="$(buildroot)" PIKE_MODULE_RELOC="$(PIKE_MODULE_RELOC)"
 
 # tidy up a bit
 tidy:
@@ -441,10 +442,10 @@ just_verify: module_testsuites testsuite master-stamp
 
 tinstall: aclocal master-stamp aclocal
 	-rm -rf test-install
-	$(RUNPIKE) $(TMP_BINDIR)/install.pike $(INSTALLARGS) pike_name="test-pike" lib_prefix="$(lib_prefix)" TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" SRCDIR="$(SRCDIR)" prefix="./test-install" MANDIR_SRC="$(MANDIR_SRC)" man_prefix="$(man_prefix)" fakeroot="$(buildroot)"
+	$(RUNPIKE) $(TMP_BINDIR)/install.pike $(INSTALLARGS) pike_name="test-pike" lib_prefix="$(lib_prefix)" TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" SRCDIR="$(SRCDIR)" prefix="./test-install" MANDIR_SRC="$(MANDIR_SRC)" man_prefix="$(man_prefix)" fakeroot="$(buildroot)" PIKE_MODULE_RELOC="$(PIKE_MODULE_RELOC)"
 
 just-tinstall: aclocal master-stamp aclocal
-	$(RUNPIKE) $(TMP_BINDIR)/install.pike $(INSTALLARGS) pike_name="test-pike" lib_prefix="$(lib_prefix)" TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" SRCDIR="$(SRCDIR)" prefix="./test-install" MANDIR_SRC="$(MANDIR_SRC)" man_prefix="$(man_prefix)" fakeroot="$(buildroot)"
+	$(RUNPIKE) $(TMP_BINDIR)/install.pike $(INSTALLARGS) pike_name="test-pike" lib_prefix="$(lib_prefix)" TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" SRCDIR="$(SRCDIR)" prefix="./test-install" MANDIR_SRC="$(MANDIR_SRC)" man_prefix="$(man_prefix)" fakeroot="$(buildroot)" PIKE_MODULE_RELOC="$(PIKE_MODULE_RELOC)"
 
 
 verify: module_testsuites testsuite tinstall
@@ -500,8 +501,10 @@ lib: Makefile
 
 master.pike: $(LIBDIR_SRC)/master.pike.in Makefile
 	t="$$PIKE_PATH_TRANSLATE"; if test "x$$t" = "x"; then t=s,x,x,; else :; fi; \
+	if test "x$(PIKE_MODULE_RELOC)" = "x"; then u=s,x,x,; else u='s/^#undef PIKE_MODULE_RELOC/#define PIKE_MODULE_RELOC 1/'; fi; \
 	sed -e 's!�lib_prefix�!'"`echo "$(TMP_LIBDIR)" | sed -e "$$t"`"'!' <$(LIBDIR_SRC)/master.pike.in \
-	  | sed -e 's!�share_prefix�!'"`echo "$(LIBDIR_SRC)" | sed -e "$$t"`"'!' >master.pike
+	  | sed -e 's!�share_prefix�!'"`echo "$(LIBDIR_SRC)" | sed -e "$$t"`"'!' \
+	  | sed -e "$$u" >master.pike
 
 # Want master.pike up-to-date, but yet there's no dependency on the
 # that file. Works like the .h_src.h target.
@@ -551,7 +554,7 @@ bin_export: aclocal
 	exec_prefix="$(exec_prefix)" lib_prefix="$(lib_prefix)" \
 	TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" \
 	SRCDIR="$(SRCDIR)" prefix="$(prefix)" MANDIR_SRC="$(MANDIR_SRC)" \
-	man_prefix="$(man_prefix)" pike_name=$(pike_name)
+	man_prefix="$(man_prefix)" pike_name=$(pike_name) PIKE_MODULE_RELOC="$(PIKE_MODULE_RELOC)"
 	@case " $(CC)" in \
 	  *\ rnt*) \
 	    $(MAKE) $(MAKE_FLAGS) uncompress_header ;\
diff --git a/src/configure.in b/src/configure.in
index 5fb1805877..81ea40b1d9 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1,4 +1,4 @@
-AC_REVISION("$Id: configure.in,v 1.544 2001/08/29 16:11:03 mast Exp $")
+AC_REVISION("$Id: configure.in,v 1.545 2001/09/02 01:36:14 marcus Exp $")
 AC_INIT(interpret.c)
 AC_CONFIG_HEADER(machine.h)
 
@@ -884,6 +884,7 @@ AC_ARG_WITH(root,              [  --with-root=path                 specify a cro
     ;;
   esac
 ],[with_root=""])
+AC_ARG_WITH(relocatable_dumped_modules, [  --with-relocatable-dumped-modules     make dumped modules relocatable],[with_relocatable_dumped_modules=yes],[])
 AC_ARG_WITH(dynamic_modules,   [  --without-dynamic-modules        link modules statically],[],[])
 AC_ARG_WITH(static_linking,    [  --with-static-linking            link statically, if possible],[with_static_linking=yes],[])
 AC_ARG_WITH(include-path,[  --with-include-path    A list of paths to search for include files.])
@@ -1052,6 +1053,13 @@ if test "x$with_thread_trace" = "xyes"; then
   AC_DEFINE(THREAD_TRACE)
 else :; fi
 
+if test "x$with_relocatable_dumped_modules" = xyes; then
+  PIKE_MODULE_RELOC=1
+else
+  PIKE_MODULE_RELOC=""
+fi
+AC_SUBST(PIKE_MODULE_RELOC)
+
 
 #
 # Allow --with(out)-debug to toggle both cdebug and rtldebug, but
@@ -5770,6 +5778,7 @@ PAD_FEATURE([debug])$with_debug
 PAD_FEATURE([dmalloc])$with_dmalloc
 PAD_FEATURE([rtldebug])$with_rtldebug
 PAD_FEATURE([mmx])$with_mmx$mmx_reason
+PAD_FEATURE([module reloc])${with_relocatable_dumped_modules:-no}
 EOF
 
 touch confdefs.h 2>/dev/null
diff --git a/src/dumpmodule.pike b/src/dumpmodule.pike
index 28cfaa8e2e..323bb7d990 100755
--- a/src/dumpmodule.pike
+++ b/src/dumpmodule.pike
@@ -18,19 +18,27 @@ Tools.Install.ProgressBar progress_bar;
 
 mapping function_names=([]);
 
-class __Codec
+static string fixup_path(string x)
 {
-  string last_id;
-
-  static string fixup_path(string x)
-  {
+  if(master()->relocate_module) {
     foreach(master()->pike_module_path, string path) {
       path = combine_path(path, "");
       if(x[..sizeof(path)-1] == path)
-	return "mpath:"+x[sizeof(path)..];
+	return "/${PIKE_MODULE_PATH}/"+x[sizeof(path)..];
+    }
+    /* This is necessary to find compat modules... */
+    foreach(master()->pike_module_path, string path) {
+      path = combine_path(path, "..", "");
+      if(x[..sizeof(path)-1] == path)
+	return "/${PIKE_MODULE_PATH}/../"+x[sizeof(path)..];
     }
-    return x;
   }
+  return x;
+}
+
+class __Codec
+{
+  string last_id;
 
   string nameof(mixed x)
   {
@@ -234,6 +242,15 @@ class Handler
     }
 }
 
+program compile_file(string file, object|void handler)
+{
+  if(master()->relocate_module) {
+    string s = master()->master_read_file(file);
+    return master()->compile_string(s,fixup_path(file), handler);
+  } else
+    return master()->compile_file(file, handler);
+}
+
 void dumpit(string file)
 {
   if(logfile)
-- 
GitLab