summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2023-11-08 21:46:48 (GMT)
committerdgp <dgp@users.sourceforge.net>2023-11-08 21:46:48 (GMT)
commitb50cf76d6fd8274a93a5d041ec2a568a549293fe (patch)
tree79e3d6baef970fdc15aff094cd8e6683a6fa0555
parentef791b806773a49297d64bbac8da4dc89cf4e6f8 (diff)
downloadtcl-b50cf76d6fd8274a93a5d041ec2a568a549293fe.zip
tcl-b50cf76d6fd8274a93a5d041ec2a568a549293fe.tar.gz
tcl-b50cf76d6fd8274a93a5d041ec2a568a549293fe.tar.bz2
In the zipfs archive initialization, use Tcl_SetPreInitScript() to equip
the creation of every interp by the Tcl library with the knowledge of where in the archive the script library is to be found. This is the **documented example usage** for Tcl_SetPreInitScript. POSTSCRIPT: Moved to development branch. Still needs some verification.
-rw-r--r--generic/tclZipfs.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c
index 842d51a..4d95973 100644
--- a/generic/tclZipfs.c
+++ b/generic/tclZipfs.c
@@ -91,6 +91,17 @@ static const z_crc_t* crc32tab;
#define ZIPFS_VOLUME_LEN 9
#define ZIPFS_APP_MOUNT ZIPFS_VOLUME "app"
#define ZIPFS_ZIP_MOUNT ZIPFS_VOLUME "lib/tcl"
+
+#define ZIPFS_SCRIPT_PREFIX "set ::tcl_library "
+#define ZIPFS_TCL_LIBRARY_1 ZIPFS_APP_MOUNT "/tcl_library"
+#define ZIPFS_INIT_SCRIPT_1 ZIPFS_SCRIPT_PREFIX ZIPFS_TCL_LIBRARY_1
+
+#define ZIPFS_TCL_LIBRARY_2 ZIPFS_ZIP_MOUNT
+#define ZIPFS_INIT_SCRIPT_2 ZIPFS_SCRIPT_PREFIX ZIPFS_TCL_LIBRARY_2
+
+#define ZIPFS_TCL_LIBRARY_3 ZIPFS_ZIP_MOUNT "/tcl_library"
+#define ZIPFS_INIT_SCRIPT_3 ZIPFS_SCRIPT_PREFIX ZIPFS_TCL_LIBRARY_3
+
#define ZIPFS_FALLBACK_ENCODING "cp437"
/*
@@ -313,6 +324,7 @@ static const char pwrot[17] =
"\x10\x90\x50\xD0\x30\xB0\x70\xF0";
static const char *zipfs_literal_tcl_library = NULL;
+static const char *zipfs_init_script = NULL;
/* Function prototypes */
@@ -4231,6 +4243,28 @@ ScriptLibrarySetup(
Tcl_Obj *libDirObj = Tcl_NewStringObj(dirName, -1);
Tcl_Obj *subDirObj, *searchPathObj;
+ /*
+ * We know where the init.tcl is located in the attached script library
+ * archive. Use a pre-init script to tell every Tcl interp as it gets
+ * created where that is, so none of them need to construct and then
+ * iterate through some search path. That's the literal documented
+ * purpose of Tcl_SetPreInitScript(). Use it.
+ *
+ * TODO: Examine why we need so many variations and eliminate as many
+ * as possible.
+ */
+
+ if (0 == strcmp(zipfs_literal_tcl_library, ZIPFS_TCL_LIBRARY_1)) {
+ zipfs_init_script = ZIPFS_INIT_SCRIPT_1;
+ } else if (0 == strcmp(zipfs_literal_tcl_library, ZIPFS_TCL_LIBRARY_2)) {
+ zipfs_init_script = ZIPFS_INIT_SCRIPT_2;
+ } else if (0 == strcmp(zipfs_literal_tcl_library, ZIPFS_TCL_LIBRARY_3)) {
+ zipfs_init_script = ZIPFS_INIT_SCRIPT_3;
+ }
+ if (zipfs_init_script) {
+ Tcl_SetPreInitScript(zipfs_init_script);
+ }
+
TclNewLiteralStringObj(subDirObj, "encoding");
Tcl_IncrRefCount(subDirObj);
TclNewObj(searchPathObj);
@@ -4268,13 +4302,12 @@ TclZipfs_TclLibrary(void)
* Look for the library file system within the executable.
*/
- vfsInitScript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",
- -1);
+ vfsInitScript = Tcl_NewStringObj(ZIPFS_TCL_LIBRARY_1 "/init.tcl", -1);
Tcl_IncrRefCount(vfsInitScript);
found = Tcl_FSAccess(vfsInitScript, F_OK);
Tcl_DecrRefCount(vfsInitScript);
if (found == TCL_OK) {
- zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library";
+ zipfs_literal_tcl_library = ZIPFS_TCL_LIBRARY_1;
return ScriptLibrarySetup(zipfs_literal_tcl_library);
}
@@ -6283,22 +6316,21 @@ ZipfsAppHookFindTclInit(
return TCL_ERROR;
}
- TclNewLiteralStringObj(vfsInitScript, ZIPFS_ZIP_MOUNT "/init.tcl");
+ TclNewLiteralStringObj(vfsInitScript, ZIPFS_TCL_LIBRARY_2 "/init.tcl");
Tcl_IncrRefCount(vfsInitScript);
found = Tcl_FSAccess(vfsInitScript, F_OK);
Tcl_DecrRefCount(vfsInitScript);
if (found == 0) {
- zipfs_literal_tcl_library = ZIPFS_ZIP_MOUNT;
+ zipfs_literal_tcl_library = ZIPFS_TCL_LIBRARY_2;
return TCL_OK;
}
- TclNewLiteralStringObj(vfsInitScript,
- ZIPFS_ZIP_MOUNT "/tcl_library/init.tcl");
+ TclNewLiteralStringObj(vfsInitScript, ZIPFS_TCL_LIBRARY_3 "/init.tcl");
Tcl_IncrRefCount(vfsInitScript);
found = Tcl_FSAccess(vfsInitScript, F_OK);
Tcl_DecrRefCount(vfsInitScript);
if (found == 0) {
- zipfs_literal_tcl_library = ZIPFS_ZIP_MOUNT "/tcl_library";
+ zipfs_literal_tcl_library = ZIPFS_TCL_LIBRARY_3;
return TCL_OK;
}
@@ -6415,12 +6447,12 @@ TclZipfs_AppHook(
if (!zipfs_literal_tcl_library) {
TclNewLiteralStringObj(vfsInitScript,
- ZIPFS_APP_MOUNT "/tcl_library/init.tcl");
+ ZIPFS_TCL_LIBRARY_1 "/init.tcl");
Tcl_IncrRefCount(vfsInitScript);
found = Tcl_FSAccess(vfsInitScript, F_OK);
Tcl_DecrRefCount(vfsInitScript);
if (found == TCL_OK) {
- zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library";
+ zipfs_literal_tcl_library = ZIPFS_TCL_LIBRARY_1;
return version;
}
}
@@ -6449,7 +6481,7 @@ TclZipfs_AppHook(
TclZipfs_TclLibrary();
TclNewLiteralStringObj(vfsInitScript,
- ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl");
+ ZIPFS_TCL_LIBRARY_3 "install.tcl");
Tcl_IncrRefCount(vfsInitScript);
if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) {
Tcl_SetStartupScript(vfsInitScript, NULL);
@@ -6472,12 +6504,12 @@ TclZipfs_AppHook(
}
/* Set Tcl Encodings */
TclNewLiteralStringObj(vfsInitScript,
- ZIPFS_APP_MOUNT "/tcl_library/init.tcl");
+ ZIPFS_TCL_LIBRARY_1 "/init.tcl");
Tcl_IncrRefCount(vfsInitScript);
found = Tcl_FSAccess(vfsInitScript, F_OK);
Tcl_DecrRefCount(vfsInitScript);
if (found == TCL_OK) {
- zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library";
+ zipfs_literal_tcl_library = ZIPFS_TCL_LIBRARY_1;
return version;
}
}