summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2016-01-01 16:50:52 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2016-01-01 16:50:52 (GMT)
commita1740d976679e2a4928898a1eddd1dad22f4fd16 (patch)
treec76b6d4f48f632f6175737e6e4f389b7c2763d56
parente9795fb40711ccc9e08e1a60232a31797bf8356a (diff)
downloadtcl-a1740d976679e2a4928898a1eddd1dad22f4fd16.zip
tcl-a1740d976679e2a4928898a1eddd1dad22f4fd16.tar.gz
tcl-a1740d976679e2a4928898a1eddd1dad22f4fd16.tar.bz2
Make al zipfs command Tcl_Obj-based
-rw-r--r--generic/tclZipfs.h2
-rw-r--r--generic/zipfs.c284
2 files changed, 176 insertions, 110 deletions
diff --git a/generic/tclZipfs.h b/generic/tclZipfs.h
index bcf6cef..01c9e96 100644
--- a/generic/tclZipfs.h
+++ b/generic/tclZipfs.h
@@ -28,7 +28,7 @@ extern "C" {
#endif
ZIPFSAPI int Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname,
- const char *mntpt, const char *passwd);
+ const char *mntpt, const char *passwd);
ZIPFSAPI int Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname);
ZIPFSAPI int Tclzipfs_Init(Tcl_Interp *interp);
ZIPFSAPI int Tclzipfs_SafeInit(Tcl_Interp *interp);
diff --git a/generic/zipfs.c b/generic/zipfs.c
index 1f126ce..55c6d2c 100644
--- a/generic/zipfs.c
+++ b/generic/zipfs.c
@@ -91,15 +91,15 @@
* Macros to read and write 16 and 32 bit integers from/to ZIP archives.
*/
-#define zip_read_int(p) \
+#define zip_read_int(p) \
((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24))
-#define zip_read_short(p) \
+#define zip_read_short(p) \
((p)[0] | ((p)[1] << 8))
-#define zip_write_int(p, v) \
- (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \
+#define zip_write_int(p, v) \
+ (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \
(p)[2] = ((v) >> 16) & 0xff; (p)[3] = ((v) >> 24) & 0xff;
-#define zip_write_short(p, v) \
+#define zip_write_short(p, v) \
(p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff;
/*
@@ -1488,7 +1488,7 @@ done:
/*
*-------------------------------------------------------------------------
*
- * ZipFSMountCmd --
+ * ZipFSMountObjCmd --
*
* This procedure is invoked to process the "zipfs::mount" command.
*
@@ -1502,23 +1502,23 @@ done:
*/
static int
-ZipFSMountCmd(ClientData clientData, Tcl_Interp *interp,
- int argc, const char **argv)
+ZipFSMountObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[])
{
- if (argc > 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " ?zipfile ?mountpoint? ?password???\"", 0);
+ if (objc > 4) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "?zipfile mountpoint password?");
return TCL_ERROR;
}
- return Tclzipfs_Mount(interp, (argc > 1) ? argv[1] : NULL,
- (argc > 2) ? argv[2] : NULL,
- (argc > 3) ? argv[3] : NULL);
+ return Tclzipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL,
+ (objc > 2) ? Tcl_GetString(objv[2]) : NULL,
+ (objc > 3) ? Tcl_GetString(objv[3]) : NULL);
}
/*
*-------------------------------------------------------------------------
*
- * ZipFSUnmountCmd --
+ * ZipFSUnmountObjCmd --
*
* This procedure is invoked to process the "zipfs::unmount" command.
*
@@ -1532,21 +1532,20 @@ ZipFSMountCmd(ClientData clientData, Tcl_Interp *interp,
*/
static int
-ZipFSUnmountCmd(ClientData clientData, Tcl_Interp *interp,
- int argc, const char **argv)
+ZipFSUnmountObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[])
{
- if (argc != 2) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " zipfile\"", (char *) NULL);
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "zipfile");
return TCL_ERROR;
}
- return Tclzipfs_Unmount(interp, argv[1]);
+ return Tclzipfs_Unmount(interp, Tcl_GetString(objv[1]));
}
/*
*-------------------------------------------------------------------------
*
- * ZipFSMountCmd --
+ * ZipFSMkKeyObjCmd --
*
* This procedure is invoked to process the "zipfs::mkkey" command.
* It produces a rotated password to be embedded into an image file.
@@ -1561,28 +1560,28 @@ ZipFSUnmountCmd(ClientData clientData, Tcl_Interp *interp,
*/
static int
-ZipFSMkKeyCmd(ClientData clientData, Tcl_Interp *interp,
- int argc, const char **argv)
+ZipFSMkKeyObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[])
{
int len, i = 0;
- char pwbuf[264];
+ char *pw, pwbuf[264];
- if (argc != 2) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " password\"", (char *) NULL);
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "password");
return TCL_ERROR;
}
- len = strlen(argv[1]);
+ pw = Tcl_GetString(objv[1]);
+ len = strlen(pw);
if (len == 0) {
return TCL_OK;
}
- if ((len > 255) || (strchr(argv[1], 0xff) != NULL)) {
+ if ((len > 255) || (strchr(pw, 0xff) != NULL)) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("illegal password", -1));
return TCL_ERROR;
}
while (len > 0) {
- int ch = argv[1][len - 1];
+ int ch = pw[len - 1];
pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f];
i++;
@@ -1928,7 +1927,7 @@ seekErr:
/*
*-------------------------------------------------------------------------
*
- * ZipFSMkZipOrImgCmd --
+ * ZipFSMkZipOrImgObjCmd --
*
* This procedure is creates a new ZIP archive file or image file
* given output filename, input directory of files to be archived,
@@ -1945,75 +1944,107 @@ seekErr:
*/
static int
-ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp,
- int isImg, int argc, const char **argv)
+ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int isImg, int isList, int objc, Tcl_Obj *const objv[])
{
Tcl_Channel out;
- int len = 0, pwlen = 0, slen = 0, i, count, ret = TCL_ERROR, largc, pos[3];
- const char **largv;
- Tcl_DString ds;
+ int len = 0, pwlen = 0, slen = 0, i, count, ret = TCL_ERROR, lobjc, pos[3];
+ Tcl_Obj **lobjv, *list = NULL;
ZipEntry *z;
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
Tcl_HashTable fileHash;
- char pwbuf[264], buf[4096];
+ char *strip = NULL, *pw = NULL, pwbuf[264], buf[4096];
- if ((argc < 3) || (argc > (isImg ? 6 : 5))) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " outfile indir ?strip? ?password?",
- isImg ? " ?infile?\"" : "\"", (char *) NULL);
- return TCL_ERROR;
+ if (isList) {
+ if ((objc < 3) || (objc > (isImg ? 5 : 4))) {
+ Tcl_WrongNumArgs(interp, 1, objv, isImg ?
+ "outfile inlist ?password infile?" :
+ "outfile inlist ?password?");
+ return TCL_ERROR;
+ }
+ } else {
+ if ((objc < 3) || (objc > (isImg ? 6 : 5))) {
+ Tcl_WrongNumArgs(interp, 1, objv, isImg ?
+ "outfile indir ?strip password infile?" :
+ "outfile indir ?strip password?");
+ return TCL_ERROR;
+ }
}
pwbuf[0] = 0;
- if (argc > 4) {
- pwlen = strlen(argv[4]);
- if ((pwlen > 255) || (strchr(argv[4], 0xff) != NULL)) {
- Tcl_AppendResult(interp, "illegal password", (char *) NULL);
+ if (objc > (isList ? 3 : 4)) {
+ pw = Tcl_GetString(objv[isList ? 3 : 4]);
+ pwlen = strlen(pw);
+ if ((pwlen > 255) || (strchr(pw, 0xff) != NULL)) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("illegal password", -1));
return TCL_ERROR;
}
}
- Tcl_DStringInit(&ds);
- Tcl_DStringAppendElement(&ds, "::zipfs::find");
- Tcl_DStringAppendElement(&ds, argv[2]);
- if (Tcl_Eval(interp, Tcl_DStringValue(&ds)) != TCL_OK) {
- Tcl_DStringFree(&ds);
+ if (isList) {
+ list = objv[2];
+ Tcl_IncrRefCount(list);
+ } else {
+ Tcl_Obj *cmd[3];
+
+ cmd[1] = Tcl_NewStringObj("::zipfs::find", -1);
+ cmd[2] = objv[2];
+ cmd[0] = Tcl_NewListObj(2, cmd + 1);
+ Tcl_IncrRefCount(cmd[0]);
+ if (Tcl_EvalObjEx(interp, cmd[0], TCL_EVAL_DIRECT) != TCL_OK) {
+ Tcl_DecrRefCount(cmd[0]);
+ return TCL_ERROR;
+ }
+ Tcl_DecrRefCount(cmd[0]);
+ list = Tcl_GetObjResult(interp);
+ Tcl_IncrRefCount(list);
+ }
+ if (Tcl_ListObjGetElements(interp, list, &lobjc, &lobjv) != TCL_OK) {
+ Tcl_DecrRefCount(list);
return TCL_ERROR;
}
- Tcl_DStringFree(&ds);
- if (Tcl_SplitList(interp, Tcl_GetStringResult(interp), &largc, &largv)
- != TCL_OK) {
+ if (isList && (lobjc % 2)) {
+ Tcl_DecrRefCount(list);
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("need even number of elements", -1));
return TCL_ERROR;
}
- Tcl_ResetResult(interp);
- if (largc == 0) {
- Tcl_Free((char *) largv);
- Tcl_AppendResult(interp, "empty archive", (char *) NULL);
+ if (lobjc == 0) {
+ Tcl_DecrRefCount(list);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1));
return TCL_ERROR;
}
- out = Tcl_OpenFileChannel(interp, argv[1], "w", 0755);
+ out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "w", 0755);
if ((out == NULL) ||
(Tcl_SetChannelOption(interp, out, "-translation", "binary")
!= TCL_OK) ||
(Tcl_SetChannelOption(interp, out, "-encoding", "binary")
!= TCL_OK)) {
+ Tcl_DecrRefCount(list);
Tcl_Close(interp, out);
- Tcl_Free((char *) largv);
return TCL_ERROR;
}
if (isImg) {
ZipFile zf0;
+ const char *imgName;
- if (ZipFSOpenArchive(interp, (argc > 5) ? argv[5] :
- Tcl_GetNameOfExecutable(), 0, &zf0) != TCL_OK) {
+ if (isList) {
+ imgName = (objc > 4) ? Tcl_GetString(objv[4]) :
+ Tcl_GetNameOfExecutable();
+ } else {
+ imgName = (objc > 5) ? Tcl_GetString(objv[5]) :
+ Tcl_GetNameOfExecutable();
+ }
+ if (ZipFSOpenArchive(interp, imgName, 0, &zf0) != TCL_OK) {
+ Tcl_DecrRefCount(list);
Tcl_Close(interp, out);
- Tcl_Free((char *) largv);
return TCL_ERROR;
}
- if (pwlen && (argc > 4)) {
+ if ((pw != NULL) && pwlen) {
i = 0;
len = pwlen;
while (len > 0) {
- int ch = argv[4][len - 1];
+ int ch = pw[len - 1];
pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f];
i++;
@@ -2029,9 +2060,9 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp,
}
i = Tcl_Write(out, (char *) zf0.data, zf0.baseoffsp);
if (i != zf0.baseoffsp) {
- Tcl_AppendResult(interp, "write error", (char *) NULL);
+ Tcl_DecrRefCount(list);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1));
Tcl_Close(interp, out);
- Tcl_Free((char *) largv);
ZipFSCloseArchive(interp, &zf0);
return TCL_ERROR;
}
@@ -2040,9 +2071,9 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp,
if (len > 0) {
i = Tcl_Write(out, pwbuf, len);
if (i != len) {
- Tcl_AppendResult(interp, "write error", (char *) NULL);
+ Tcl_DecrRefCount(list);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1));
Tcl_Close(interp, out);
- Tcl_Free((char *) largv);
return TCL_ERROR;
}
}
@@ -2051,18 +2082,25 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp,
}
Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS);
pos[0] = Tcl_Tell(out);
- if (argc > 3) {
- slen = strlen(argv[3]);
+ if (!isList && (objc > 3)) {
+ strip = Tcl_GetString(objv[3]);
+ slen = strlen(strip);
}
- for (i = 0; i < largc; i++) {
- const char *name = largv[i];
+ for (i = 0; i < lobjc; i += (isList ? 2 : 1)) {
+ const char *path, *name;
- if (slen > 0) {
- len = strlen(name);
- if ((len <= slen) || (strncmp(argv[3], name, slen) != 0)) {
- continue;
+ path = Tcl_GetString(lobjv[i]);
+ if (isList) {
+ name = Tcl_GetString(lobjv[i + 1]);
+ } else {
+ name = path;
+ if (slen > 0) {
+ len = strlen(name);
+ if ((len <= slen) || (strncmp(strip, name, slen) != 0)) {
+ continue;
+ }
+ name += slen;
}
- name += slen;
}
while (name[0] == '/') {
++name;
@@ -2070,23 +2108,28 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp,
if (name[0] == '\0') {
continue;
}
- if (ZipAddFile(interp, largv[i], name, out,
- (pwlen > 0) ? argv[4] : NULL, buf, sizeof (buf), &fileHash)
- != TCL_OK) {
+ if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf),
+ &fileHash) != TCL_OK) {
goto done;
}
}
pos[1] = Tcl_Tell(out);
count = 0;
- for (i = 0; i < largc; i++) {
- const char *name = largv[i];
+ for (i = 0; i < lobjc; i += (isList ? 2 : 1)) {
+ const char *path, *name;
- if (slen > 0) {
- len = strlen(name);
- if ((len <= slen) || (strncmp(argv[3], name, slen) != 0)) {
- continue;
+ path = Tcl_GetString(lobjv[i]);
+ if (isList) {
+ name = Tcl_GetString(lobjv[i + 1]);
+ } else {
+ name = path;
+ if (slen > 0) {
+ len = strlen(name);
+ if ((len <= slen) || (strncmp(strip, name, slen) != 0)) {
+ continue;
+ }
+ name += slen;
}
- name += slen;
}
while (name[0] == '/') {
++name;
@@ -2117,10 +2160,10 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp,
zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0);
zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0);
zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]);
- memcpy(buf + ZIP_CENTRAL_HEADER_LEN, z->name, len);
- len += ZIP_CENTRAL_HEADER_LEN;
- if (Tcl_Write(out, buf, len) != len) {
- Tcl_AppendResult(interp, "write error", (char *) NULL);
+ if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) !=
+ ZIP_CENTRAL_HEADER_LEN) ||
+ (Tcl_Write(out, z->name, len) != len)) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1));
goto done;
}
count++;
@@ -2136,14 +2179,18 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp,
zip_write_int(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]);
zip_write_short(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0);
if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) {
- Tcl_AppendResult(interp, "write error", (char *) NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1));
goto done;
}
Tcl_Flush(out);
ret = TCL_OK;
done:
- Tcl_Free((char *) largv);
- Tcl_Close(interp, out);
+ if (ret == TCL_OK) {
+ ret = Tcl_Close(interp, out);
+ } else {
+ Tcl_Close(interp, out);
+ }
+ Tcl_DecrRefCount(list);
hPtr = Tcl_FirstHashEntry(&fileHash, &search);
while (hPtr != NULL) {
z = (ZipEntry *) Tcl_GetHashValue(hPtr);
@@ -2158,7 +2205,7 @@ done:
/*
*-------------------------------------------------------------------------
*
- * ZipFSMkZipCmd --
+ * ZipFSMkZipObjCmd --
*
* This procedure is invoked to process the "zipfs::mkzip" command.
* See description of ZipFSMkZipOrImgCmd().
@@ -2173,16 +2220,23 @@ done:
*/
static int
-ZipFSMkZipCmd(ClientData clientData, Tcl_Interp *interp,
- int argc, const char **argv)
+ZipFSMkZipObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[])
+{
+ return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 0, objc, objv);
+}
+
+static int
+ZipFSLMkZipObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[])
{
- return ZipFSMkZipOrImgCmd(clientData, interp, 0, argc, argv);
+ return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 1, objc, objv);
}
/*
*-------------------------------------------------------------------------
*
- * ZipFSMkImgCmd --
+ * ZipFSMkImgObjCmd --
*
* This procedure is invoked to process the "zipfs::mkimg" command.
* See description of ZipFSMkZipOrImgCmd().
@@ -2197,10 +2251,17 @@ ZipFSMkZipCmd(ClientData clientData, Tcl_Interp *interp,
*/
static int
-ZipFSMkImgCmd(ClientData clientData, Tcl_Interp *interp,
- int argc, const char **argv)
+ZipFSMkImgObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[])
+{
+ return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 0, objc, objv);
+}
+
+static int
+ZipFSLMkImgObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[])
{
- return ZipFSMkZipOrImgCmd(clientData, interp, 1, argc, argv);
+ return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 1, objc, objv);
}
/*
@@ -3938,11 +3999,16 @@ Zipfs_doInit(Tcl_Interp *interp, int safe)
Unlock();
Tcl_PkgProvide(interp, "zipfs", "1.0");
if (!safe) {
- Tcl_CreateCommand(interp, "::zipfs::mount", ZipFSMountCmd, 0, 0);
- Tcl_CreateCommand(interp, "::zipfs::unmount", ZipFSUnmountCmd, 0, 0);
- Tcl_CreateCommand(interp, "::zipfs::mkkey", ZipFSMkKeyCmd, 0, 0);
- Tcl_CreateCommand(interp, "::zipfs::mkimg", ZipFSMkImgCmd, 0, 0);
- Tcl_CreateCommand(interp, "::zipfs::mkzip", ZipFSMkZipCmd, 0, 0);
+ 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_GlobalEval(interp, findproc);
}
Tcl_CreateObjCommand(interp, "::zipfs::exists", ZipFSExistsObjCmd, 0, 0);