summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/zipfs.n46
-rw-r--r--generic/tclInterp.c1
-rw-r--r--generic/tclTest.c53
-rw-r--r--generic/zipfs.c17
-rw-r--r--tests/nre.test4
5 files changed, 80 insertions, 41 deletions
diff --git a/doc/zipfs.n b/doc/zipfs.n
index d16c047..838a898 100644
--- a/doc/zipfs.n
+++ b/doc/zipfs.n
@@ -15,15 +15,15 @@ zipfs \- Mount and work with ZIP files within Tcl
.nf
\fBpackage require zipfs \fR?\fB1.0\fR?
.sp
-\fB::zipfs::exists\fR \fIfilename\fR
-\fB::zipfs::find\fR \fIdir\fR
-\fB::zipfs::info\fR \fIfilename\fR
-\fB::zipfs::list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR
-\fB::zipfs::mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR
-\fB::zipfs::mkkey\fR \fIpassword\fR
-\fB::zipfs::mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR
-\fB::zipfs::mount\fR \fI?zipfile?\fR \fI?mountpoint?\fR \fI?password?\fR
-\fB::zipfs::unmount\fR \fIzipfile\fR
+\fBzipfs exists\fR \fIfilename\fR
+\fBzipfs find\fR \fIdir\fR
+\fBzipfs info\fR \fIfilename\fR
+\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR
+\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR
+\fBzipfs mkkey\fR \fIpassword\fR
+\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR
+\fBzipfs mount\fR \fI?zipfile?\fR \fI?mountpoint?\fR \fI?password?\fR
+\fBzipfs unmount\fR \fIzipfile\fR
.fi
.BE
.SH DESCRIPTION
@@ -31,18 +31,18 @@ zipfs \- Mount and work with ZIP files within Tcl
The \fBzipfs\fR package provides tcl with the ability to mount
the contents of a zip file as a virtual file system.
.TP
-\fB::zipfs::exists\fR \fIfilename\fR
+\fBzipfs exists\fR \fIfilename\fR
.
Return 1 if the given filename exists in the mounted zipfs and 0 if it does not.
.TP
-\fB::zipfs::find\fR \fIdir\fR
+\fBzipfs find\fR \fIdir\fR
.
Recursively lists files including and below the directory \fIdir\fR.
The result list consists of relative path names starting from the
-given directory. This command is also used by the \fB::zipfs::mkzip\fR
-and \fB::zipfs::mkimg\fR commands.
+given directory. This command is also used by the \fBzipfs mkzip\fR
+and \fBzipfs mkimg\fR commands.
.TP
-\fB::zipfs::info\fR \fIfile\fR
+\fBzipfs info\fR \fIfile\fR
.
Return information about the given file in the mounted zipfs. The information
consists of (1) the name of the ZIP archive file that contains the file,
@@ -54,15 +54,15 @@ Note: querying the mount point gives the start of zip data offset in (4),
which can be used to truncate the zip info off an executable.
.RE
.TP
-\fB::zipfs::list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR
+\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR
.
Return a list of all files in the mounted zipfs. The order of the names
in the list is arbitrary.
.TP
-\fB::zipfs::mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR
+\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR
.
Creates an image (potentially a new executable file) similar to
-\fB::zipfs::mkzip\fR. If the \fIinfile\fR parameter is specified,
+\fBzipfs mkzip\fR. If the \fIinfile\fR parameter is specified,
this file is prepended in front of the ZIP archive, otherwise the file
returned by \fBTcl_NameOfExecutable(3)\fR (i.e. the executable file of
the running process) is used. If the \fIpassword\fR parameter is not empty,
@@ -75,12 +75,12 @@ Caution: highly experimental, not usable on Android, only partially tested
on Linux and Windows.
.RE
.TP
-\fB::zipfs::mkkey\fR \fIpassword\fR
+\fBzipfs mkkey\fR \fIpassword\fR
.
For the clear text \fIpassword\fR argument an obfuscated string version
-is returned with the same format used in the \fB::zipfs::mkimg\fR command.
+is returned with the same format used in the \fBzipfs mkimg\fR command.
.TP
-\fB::zipfs::mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR
+\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR
.
Creates a ZIP archive file named \fIoutfile\fR from the contents of the input
directory \fIindir\fR (contained regular files only) with optional ZIP
@@ -94,9 +94,9 @@ Caution: the choice of the \fIindir\fR parameter
archive's content.
.RE
.TP
-\fB::zipfs::mount ?\fIzipfile\fR? ?\fImountpoint\fR? ?\fIpassword\fR?
+\fBzipfs mount ?\fIzipfile\fR? ?\fImountpoint\fR? ?\fIpassword\fR?
.
-The \fB::zipfs::mount\fR command mounts a ZIP archive file as a VFS.
+The \fBzipfs mount\fR command mounts a ZIP archive file as a VFS.
After this command executes, files contained in \fIzipfile\fR
will appear to Tcl to be regular files at the mount point.
.RS
@@ -106,7 +106,7 @@ With no \fIzipfile\fR, return all zipfile/mount pairs.
If \fImountpoint\fR is specified as an empty string, mount on file path.
.RE
.TP
-\fB::zipfs::unmount \fIzipfile\fR
+\fBzipfs unmount \fIzipfile\fR
.
Unmounts a previously mounted ZIP archive file \fIzipfile\fR.
.SH "SEE ALSO"
diff --git a/generic/tclInterp.c b/generic/tclInterp.c
index 0da5d47..5c94461 100644
--- a/generic/tclInterp.c
+++ b/generic/tclInterp.c
@@ -1882,7 +1882,6 @@ AliasObjCmd(
cmdv = TclStackAlloc(interp, cmdc * sizeof(Tcl_Obj *));
}
- prefv = &aliasPtr->objPtr;
memcpy(cmdv, prefv, (size_t) (prefc * sizeof(Tcl_Obj *)));
memcpy(cmdv+prefc, objv+1, (size_t) ((objc-1) * sizeof(Tcl_Obj *)));
diff --git a/generic/tclTest.c b/generic/tclTest.c
index 5468c56..2ea3016 100644
--- a/generic/tclTest.c
+++ b/generic/tclTest.c
@@ -412,6 +412,12 @@ static int TestNumUtfCharsCmd(ClientData clientData,
static int TestHashSystemHashCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+
+static int NREUnwind_callback(ClientData data[], Tcl_Interp *interp,
+ int result);
+static int TestNREUnwind(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
static int TestNRELevels(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -697,6 +703,8 @@ Tcltest_Init(
NULL);
#endif /* TCL_NO_DEPRECATED */
+ Tcl_CreateObjCommand(interp, "testnreunwind", TestNREUnwind,
+ NULL, NULL);
Tcl_CreateObjCommand(interp, "testnrelevels", TestNRELevels,
NULL, NULL);
Tcl_CreateObjCommand(interp, "testinterpresolver", TestInterpResolverCmd,
@@ -6846,6 +6854,51 @@ TestgetintCmd(
}
static int
+NREUnwind_callback(
+ ClientData data[],
+ Tcl_Interp *interp,
+ int result)
+{
+ int none;
+
+ if (data[0] == INT2PTR(-1)) {
+ TclNRAddCallback(interp, NREUnwind_callback, &none, INT2PTR(-1),
+ INT2PTR(-1), NULL);
+ } else if (data[1] == INT2PTR(-1)) {
+ TclNRAddCallback(interp, NREUnwind_callback, data[0], &none,
+ INT2PTR(-1), NULL);
+ } else if (data[2] == INT2PTR(-1)) {
+ TclNRAddCallback(interp, NREUnwind_callback, data[0], data[1],
+ &none, NULL);
+ } else {
+ Tcl_Obj *idata[3];
+ idata[0] = Tcl_NewIntObj((int) (data[1] - data[0]));
+ idata[1] = Tcl_NewIntObj((int) (data[2] - data[0]));
+ idata[2] = Tcl_NewIntObj((int) ((void *) &none - data[0]));
+ Tcl_SetObjResult(interp, Tcl_NewListObj(3, idata));
+ }
+ return TCL_OK;
+}
+
+static int
+TestNREUnwind(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ /*
+ * Insure that callbacks effectively run at the proper level during the
+ * unwinding of the NRE stack.
+ */
+
+ TclNRAddCallback(interp, NREUnwind_callback, INT2PTR(-1), INT2PTR(-1),
+ INT2PTR(-1), NULL);
+ return TCL_OK;
+}
+
+
+static int
TestNRELevels(
ClientData clientData,
Tcl_Interp *interp,
diff --git a/generic/zipfs.c b/generic/zipfs.c
index 8db1ac1..c5cb65b 100644
--- a/generic/zipfs.c
+++ b/generic/zipfs.c
@@ -4020,28 +4020,11 @@ Zipfs_doInit(Tcl_Interp *interp, int safe)
Unlock();
Tcl_PkgProvide(interp, "zipfs", "1.0");
if (!safe) {
- Tcl_CreateObjCommand(interp, "::zipfs::mount", ZipFSMountObjCmd, 0, 0);
- Tcl_CreateObjCommand(interp, "::zipfs::unmount",
- ZipFSUnmountObjCmd, 0, 0);
- Tcl_CreateObjCommand(interp, "::zipfs::mkkey", ZipFSMkKeyObjCmd, 0, 0);
- Tcl_CreateObjCommand(interp, "::zipfs::mkimg", ZipFSMkImgObjCmd, 0, 0);
- Tcl_CreateObjCommand(interp, "::zipfs::mkzip", ZipFSMkZipObjCmd, 0, 0);
- Tcl_CreateObjCommand(interp, "::zipfs::lmkimg",
- ZipFSLMkImgObjCmd, 0, 0);
- Tcl_CreateObjCommand(interp, "::zipfs::lmkzip",
- ZipFSLMkZipObjCmd, 0, 0);
Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL);
- }
- Tcl_CreateObjCommand(interp, "::zipfs::exists", ZipFSExistsObjCmd, 0, 0);
- Tcl_CreateObjCommand(interp, "::zipfs::info", ZipFSInfoObjCmd, 0, 0);
- Tcl_CreateObjCommand(interp, "::zipfs::list", ZipFSListObjCmd, 0, 0);
- if (!safe) {
Tcl_LinkVar(interp, "::zipfs::wrmax", (char *) &ZipFS.wrmax,
TCL_LINK_INT);
}
-
TclMakeEnsemble(interp, "zipfs", safe ? initSafeMap : initMap);
-
return TCL_OK;
#else
if (interp != NULL) {
diff --git a/tests/nre.test b/tests/nre.test
index e512eac..9df5eb1 100644
--- a/tests/nre.test
+++ b/tests/nre.test
@@ -64,6 +64,10 @@ if {[testConstraint testnrelevels]} {
namespace import testnre::*
}
+test nre-0.1 {levels while unwinding} {
+ testnreunwind
+} {0 0 0}
+
test nre-1.1 {self-recursive procs} -setup {
proc a i [makebody {a $i}]
} -body {