Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Default fpath




If you apply this patch and have wordcode files, you have to build
them anew, because the header format has changed slightly. zrecompile
will not be able to detect this.


Bart Schaefer wrote:

> ...
> 
> [Tagging .zwc for zsh/ksh loading:]
> } 
> }   zcompile -z comp.zwc .../Completion/*/_*
> } 
> } to have them all loaded zsh-like.
> } 
> }   zcompile foo.zwc -z bar -k baz
> } 
> } would load bar zsh-like and baz ksh-like.
> } 
> } Ok?
> 
> Seems fine to me.  Hmm, maybe autoload should have the `k' and `z' opts,
> too, but they only work with +X (the load-it now option).  That would
> fix something that's been bugging me for a while.

Here is the patch for zcompile. If neither is given, the setting of
KSHAUTOLOAD at the time of loading is used to determine how to load
the function.

I haven't added that for autoload yet and there is another thing:
loadautofn() should probably make use of this too, maybe execute the
Eprog it gets from getfpfunc() when it knows that the function should
be ksh-autoloaded (either because the dump file said so or because
`autoload +x' said so). But then, it doesn't do that if KSHAUTOLOAD is 
set. I guess that's some security issue?

Bye
 Sven

diff -ru ../z.old/Doc/Zsh/builtins.yo Doc/Zsh/builtins.yo
--- ../z.old/Doc/Zsh/builtins.yo	Wed Mar 15 14:28:37 2000
+++ Doc/Zsh/builtins.yo	Wed Mar 15 16:50:13 2000
@@ -1295,8 +1295,8 @@
 findex(zcompile)
 cindex(wordcode, creation)
 cindex(compilation)
-xitem(tt(zcompile) [ tt(-U) ] [ tt(-r) | tt(-m) ] var(file) [ var(name) ... ])
-xitem(tt(zcompile) tt(-c) [ tt(-M) ] [ tt(-r) | tt(-m) ] var(file) [ var(name) ... ])
+xitem(tt(zcompile) [ tt(-U) ] [ tt(-z) | tt(-k) ] [ tt(-r) | tt(-m) ] var(file) [ var(name) ... ])
+xitem(tt(zcompile) tt(-c) [ tt(-M) ] [ tt(-z) | tt(-k) ] [ tt(-r) | tt(-m) ] var(file) [ var(name) ... ])
 item(tt(zcompile -t) var(file) [ var(name) ... ])(
 This builtin command can be used to create and display files
 containing the wordcode for functions or scripts. In the first form, a wordcode
@@ -1331,6 +1331,16 @@
 map wordcode files into memory. On such systems, the wordcode will
 only be read from the file, independent on the mode selected when the 
 file was created.
+
+The tt(-z) and tt(-k) options are used when the wordcode file contains
+functions and these functions are autoloaded. If tt(-z) is given, the
+function will be autoloaded as if the tt(KSHAUTOLOAD) option weren't
+set, even if it is. The tt(-k) makes the function be loaded as if
+tt(KASHAUTOLOAD) were set and if neither of these options is given,
+the function will be loaded as determined by the setting of the
+tt(KSHAUTOLOAD) option at the time the function is loaded. These
+options may also be given in the lists of var(name)s and make all
+following functions be loaded as described.
 
 When creating wordcode files for scripts instead of functions, it is
 often better to use the tt(-r) option. Otherwise the whole wordcode
diff -ru ../z.old/Src/builtin.c Src/builtin.c
--- ../z.old/Src/builtin.c	Wed Mar 15 14:28:22 2000
+++ Src/builtin.c	Wed Mar 15 15:57:34 2000
@@ -124,7 +124,7 @@
     BUILTIN("where", 0, bin_whence, 0, -1, 0, "pmsw", "ca"),
     BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsw", "c"),
     BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "ILabcfdipue", NULL),
-    BUILTIN("zcompile", 0, bin_zcompile, 0, -1, 0, "tUmrcM", NULL),
+    BUILTIN("zcompile", 0, bin_zcompile, 0, -1, 0, "tUmrcMzk", NULL),
 };
 
 /****************************************/
diff -ru ../z.old/Src/exec.c Src/exec.c
--- ../z.old/Src/exec.c	Wed Mar 15 14:28:23 2000
+++ Src/exec.c	Wed Mar 15 16:16:05 2000
@@ -3153,13 +3153,13 @@
 execautofn(Estate state, int do_exec)
 {
     Shfunc shf = state->prog->shf;
-    int noalias = noaliases;
+    int noalias = noaliases, ksh = 1;
     Eprog prog;
 
     pushheap();
 
     noaliases = (shf->flags & PM_UNALIASED);
-    prog = getfpfunc(shf->nam);
+    prog = getfpfunc(shf->nam, &ksh);
     noaliases = noalias;
 
     if (prog == &dummy_eprog) {
@@ -3169,7 +3169,7 @@
     }
     if (!prog)
 	prog = &dummy_eprog;
-    if (isset(KSHAUTOLOAD)) {
+    if (ksh == 2 || (ksh == 1 && isset(KSHAUTOLOAD))) {
 	VARARR(char, n, strlen(shf->nam) + 1);
 	strcpy(n, shf->nam);
 	execode(prog, 1, 0);
@@ -3205,7 +3205,7 @@
     pushheap();
 
     noaliases = (shf->flags & PM_UNALIASED);
-    prog = getfpfunc(shf->nam);
+    prog = getfpfunc(shf->nam, NULL);
     noaliases = noalias;
 
     if (prog == &dummy_eprog) {
@@ -3360,7 +3360,7 @@
 
 /**/
 Eprog
-getfpfunc(char *s)
+getfpfunc(char *s, int *ksh)
 {
     char **pp, buf[PATH_MAX];
     off_t len;
@@ -3376,7 +3376,7 @@
 	    sprintf(buf, "%s/%s", *pp, s);
 	else
 	    strcpy(buf, s);
-	if ((r = try_dump_file(*pp, s, buf)))
+	if ((r = try_dump_file(*pp, s, buf, ksh)))
 	    return r;
 	unmetafy(buf, NULL);
 	if (!access(buf, R_OK) && (fd = open(buf, O_RDONLY | O_NOCTTY)) != -1) {
diff -ru ../z.old/Src/parse.c Src/parse.c
--- ../z.old/Src/parse.c	Wed Mar 15 14:28:25 2000
+++ Src/parse.c	Wed Mar 15 16:40:18 2000
@@ -2206,8 +2206,8 @@
 #define FD_MINMAP 4096
 
 #define FD_PRELEN 12
-#define FD_MAGIC  0x01020304
-#define FD_OMAGIC 0x04030201
+#define FD_MAGIC  0x02030405
+#define FD_OMAGIC 0x05040302
 
 #define FDF_MAP   1
 #define FDF_OTHER 2
@@ -2220,7 +2220,7 @@
     wordcode npats;		/* number of patterns needed */
     wordcode strs;		/* offset to strings */
     wordcode hlen;		/* header length (incl. name) */
-    wordcode tail;		/* offset to name tail */
+    wordcode flags;		/* flags and offset to name tail */
 };
 
 #define fdheaderlen(f) (((Wordcode) (f))[FD_PRELEN])
@@ -2243,8 +2243,25 @@
 #define firstfdhead(f) ((FDHead) (((Wordcode) (f)) + FD_PRELEN))
 #define nextfdhead(f)  ((FDHead) (((Wordcode) (f)) + (f)->hlen))
 
+#define fdhflags(f)      (((FDHead) (f))->flags)
+#define fdhtail(f)       (((FDHead) (f))->flags >> 2)
+#define fdhbldflags(f,t) ((f) | ((t) << 2))
+
+#define FDHF_KSHLOAD 1
+#define FDHF_ZSHLOAD 2
+
 #define fdname(f)      ((char *) (((FDHead) (f)) + 1))
 
+/* This is used when building wordcode files. */
+
+typedef struct wcfunc *WCFunc;
+
+struct wcfunc {
+    char *name;
+    Eprog prog;
+    int flags;
+};
+
 /* Try to find the description for the given function name. */
 
 static FDHead
@@ -2253,7 +2270,7 @@
     FDHead n, e = (FDHead) (h + fdheaderlen(h));
 
     for (n = firstfdhead(h); n < e; n = nextfdhead(n))
-	if (!strcmp(name, fdname(n) + n->tail))
+	if (!strcmp(name, fdname(n) + fdhtail(n)))
 	    return n;
 
     return NULL;
@@ -2263,9 +2280,16 @@
 int
 bin_zcompile(char *nam, char **args, char *ops, int func)
 {
-    int map;
+    int map, flags;
     char *dump;
 
+    if (ops['k'] && ops['z']) {
+	zwarnnam(nam, "illegal combination of options", NULL, 0);
+	return 1;
+    }
+    flags = (ops['k'] ? FDHF_KSHLOAD :
+	     (ops['z'] ? FDHF_ZSHLOAD : 0));
+
     if (ops['t']) {
 	Wordcode f;
 
@@ -2304,12 +2328,12 @@
     map = (ops['m'] ? 2 : (ops['r'] ? 0 : 1));
 
     if (!args[1] && !ops['c'])
-	return build_dump(nam, dyncat(*args, FD_EXT), args, ops['U'], map);
+	return build_dump(nam, dyncat(*args, FD_EXT), args, ops['U'], map, flags);
 
     dump = (strsfx(FD_EXT, *args) ? *args : dyncat(*args, FD_EXT));
 
-    return (ops['c'] ? build_cur_dump(nam, dump, args + 1, ops['M'], map) :
-	    build_dump(nam, dump, args + 1, ops['U'], map));
+    return (ops['c'] ? build_cur_dump(nam, dump, args + 1, ops['M'], map, flags) :
+	    build_dump(nam, dump, args + 1, ops['U'], map, flags));
 }
 
 /* Load the header of a dump file. Returns NULL if the file isn't a
@@ -2327,6 +2351,7 @@
 
     if (read(fd, buf, (FD_PRELEN + 1) * sizeof(wordcode)) !=
 	((FD_PRELEN + 1) * sizeof(wordcode)) ||
+	(fdmagic(buf) != FD_MAGIC && fdmagic(buf) != FD_OMAGIC) ||
 	strcmp(ZSH_VERSION, fdversion(buf))) {
 	close(fd);
 	return NULL;
@@ -2382,10 +2407,10 @@
 /* Write a dump file. */
 
 static void
-write_dump(int dfd, LinkList names, LinkList progs, int map,
-	   int hlen, int tlen)
+write_dump(int dfd, LinkList progs, int map, int hlen, int tlen)
 {
-    LinkNode name, node;
+    LinkNode node;
+    WCFunc wcf;
     int other = 0, ohlen, tmp;
     wordcode pre[FD_PRELEN];
     char *tail, *n;
@@ -2402,10 +2427,10 @@
 	strcpy(fdversion(pre), ZSH_VERSION);
 	write(dfd, pre, FD_PRELEN * sizeof(wordcode));
 
-	for (node = firstnode(progs), name = firstnode(names); node;
-	     incnode(node), incnode(name)) {
-	    n = (char *) getdata(name);
-	    prog = (Eprog) getdata(node);
+	for (node = firstnode(progs); node; incnode(node)) {
+	    wcf = (WCFunc) getdata(node);
+	    n = wcf->name;
+	    prog = wcf->prog;
 	    head.start = hlen;
 	    hlen += (prog->len - (prog->npats * sizeof(Patprog)) +
 		     sizeof(wordcode) - 1) / sizeof(wordcode);
@@ -2417,8 +2442,8 @@
 	    if ((tail = strrchr(n, '/')))
 		tail++;
 	    else
-		tail= n;
-	    head.tail = tail - n;
+		tail = n;
+	    head.flags = fdhbldflags(wcf->flags, (tail - n));
 	    if (other)
 		fdswap((Wordcode) &head, sizeof(head) / sizeof(wordcode));
 	    write(dfd, &head, sizeof(head));
@@ -2428,7 +2453,7 @@
 		write(dfd, &head, sizeof(wordcode) - tmp);
 	}
 	for (node = firstnode(progs); node; incnode(node)) {
-	    prog = (Eprog) getdata(node);
+	    prog = ((WCFunc) getdata(node))->prog;
 	    tmp = (prog->len - (prog->npats * sizeof(Patprog)) +
 		   sizeof(wordcode) - 1) / sizeof(wordcode);
 	    if (other)
@@ -2443,12 +2468,13 @@
 
 /**/
 static int
-build_dump(char *nam, char *dump, char **files, int ali, int map)
+build_dump(char *nam, char *dump, char **files, int ali, int map, int flags)
 {
     int dfd, fd, hlen, tlen, flen, ona = noaliases;
-    LinkList progs, names;
+    LinkList progs;
     char *file;
     Eprog prog;
+    WCFunc wcf;
 
     if (!strsfx(FD_EXT, dump))
 	dump = dyncat(dump, FD_EXT);
@@ -2458,10 +2484,16 @@
 	return 1;
     }
     progs = newlinklist();
-    names = newlinklist();
     noaliases = ali;
 
     for (hlen = FD_PRELEN, tlen = 0; *files; files++) {
+	if (!strcmp(*files, "-k")) {
+	    flags = (flags & ~(FDHF_KSHLOAD | FDHF_ZSHLOAD)) | FDHF_KSHLOAD;
+	    continue;
+	} else if (!strcmp(*files, "-z")) {
+	    flags = (flags & ~(FDHF_KSHLOAD | FDHF_ZSHLOAD)) | FDHF_ZSHLOAD;
+	    continue;
+	}
 	if ((fd = open(*files, O_RDONLY)) < 0 ||
 	    (flen = lseek(fd, 0, 2)) == -1) {
 	    if (fd >= 0)
@@ -2498,8 +2530,11 @@
 	}
 	zfree(file, flen);
 
-	addlinknode(progs, prog);
-	addlinknode(names, *files);
+	wcf = (WCFunc) zhalloc(sizeof(*wcf));
+	wcf->name = *files;
+	wcf->prog = prog;
+	wcf->flags = flags;
+	addlinknode(progs, wcf);
 
 	flen = (strlen(*files) + sizeof(wordcode)) / sizeof(wordcode);
 	hlen += (sizeof(struct fdhead) / sizeof(wordcode)) + flen;
@@ -2511,7 +2546,7 @@
 
     tlen = (tlen + hlen) * sizeof(wordcode);
 
-    write_dump(dfd, names, progs, map, hlen, tlen);
+    write_dump(dfd, progs, map, hlen, tlen);
 
     close(dfd);
 
@@ -2519,15 +2554,17 @@
 }
 
 static int
-cur_add_func(Shfunc shf, LinkList names, LinkList progs, int *hlen, int *tlen)
+cur_add_func(Shfunc shf, LinkList names, LinkList progs,
+	     int *hlen, int *tlen, int flags)
 {
     Eprog prog;
+    WCFunc wcf;
 
     if (shf->flags & PM_UNDEFINED) {
 	int ona = noaliases;
 
 	noaliases = (shf->flags & PM_UNALIASED);
-	if (!(prog = getfpfunc(shf->nam)) || prog == &dummy_eprog) {
+	if (!(prog = getfpfunc(shf->nam, NULL)) || prog == &dummy_eprog) {
 	    noaliases = ona;
 
 	    return 1;
@@ -2538,7 +2575,11 @@
     } else
 	prog = dupeprog(shf->funcdef, 1);
 
-    addlinknode(progs, prog);
+    wcf = (WCFunc) zhalloc(sizeof(*wcf));
+    wcf->name = shf->nam;
+    wcf->prog = prog;
+    wcf->flags = flags;
+    addlinknode(progs, wcf);
     addlinknode(names, shf->nam);
 
     *hlen += ((sizeof(struct fdhead) / sizeof(wordcode)) +
@@ -2551,7 +2592,7 @@
 
 /**/
 static int
-build_cur_dump(char *nam, char *dump, char **names, int match, int map)
+build_cur_dump(char *nam, char *dump, char **names, int match, int map, int flags)
 {
     int dfd, hlen, tlen;
     LinkList progs, lnames;
@@ -2576,7 +2617,8 @@
 
 	for (i = 0; i < shfunctab->hsize; i++)
 	    for (hn = shfunctab->nodes[i]; hn; hn = hn->next)
-		if (cur_add_func((Shfunc) hn, lnames, progs, &hlen, &tlen)) {
+		if (cur_add_func((Shfunc) hn, lnames, progs,
+				 &hlen, &tlen, flags)) {
 		    zwarnnam(nam, "can't load function: %s", shf->nam, 0);
 		    errflag = 0;
 		    close(dfd);
@@ -2590,6 +2632,13 @@
 	HashNode hn;
 
 	for (; *names; names++) {
+	    if (!strcmp(*names, "-k")) {
+		flags = (flags & ~(FDHF_KSHLOAD | FDHF_ZSHLOAD)) | FDHF_KSHLOAD;
+		continue;
+	    } else if (!strcmp(*names, "-z")) {
+		flags = (flags & ~(FDHF_KSHLOAD | FDHF_ZSHLOAD)) | FDHF_ZSHLOAD;
+		continue;
+	    }
 	    tokenize(pat = dupstring(*names));
 	    if (!(pprog = patcompile(pat, PAT_STATIC, NULL))) {
 		zwarnnam(nam, "bad pattern: %s", *names, 0);
@@ -2602,7 +2651,7 @@
 		    if (!listcontains(lnames, hn->nam) &&
 			pattry(pprog, hn->nam) &&
 			cur_add_func((Shfunc) hn, lnames, progs,
-				     &hlen, &tlen)) {
+				     &hlen, &tlen, flags)) {
 			zwarnnam(nam, "can't load function: %s", shf->nam, 0);
 			errflag = 0;
 			close(dfd);
@@ -2612,6 +2661,13 @@
 	}
     } else {
 	for (; *names; names++) {
+	    if (!strcmp(*names, "-k")) {
+		flags = (flags & ~(FDHF_KSHLOAD | FDHF_ZSHLOAD)) | FDHF_KSHLOAD;
+		continue;
+	    } else if (!strcmp(*names, "-z")) {
+		flags = (flags & ~(FDHF_KSHLOAD | FDHF_ZSHLOAD)) | FDHF_ZSHLOAD;
+		continue;
+	    }
 	    if (errflag ||
 		!(shf = (Shfunc) shfunctab->getnode(shfunctab, *names))) {
 		zwarnnam(nam, "unknown function: %s", *names, 0);
@@ -2620,7 +2676,7 @@
 		unlink(dump);
 		return 1;
 	    }
-	    if (cur_add_func(shf, lnames, progs, &hlen, &tlen)) {
+	    if (cur_add_func(shf, lnames, progs, &hlen, &tlen, flags)) {
 		zwarnnam(nam, "can't load function: %s", shf->nam, 0);
 		errflag = 0;
 		close(dfd);
@@ -2638,7 +2694,7 @@
     }
     tlen = (tlen + hlen) * sizeof(wordcode);
 
-    write_dump(dfd, lnames, progs, map, hlen, tlen);
+    write_dump(dfd, progs, map, hlen, tlen);
 
     close(dfd);
 
@@ -2722,7 +2778,7 @@
 
 /**/
 Eprog
-try_dump_file(char *path, char *name, char *file)
+try_dump_file(char *path, char *name, char *file, int *ksh)
 {
     Eprog prog;
     struct stat std, stc, stn;
@@ -2730,7 +2786,7 @@
     char *dig, *wc;
 
     if (strsfx(FD_EXT, path))
-	return check_dump_file(path, name);
+	return check_dump_file(path, name, ksh);
 
     dig = dyncat(path, FD_EXT);
     wc = dyncat(file, FD_EXT);
@@ -2746,13 +2802,13 @@
     if (!rd &&
 	(rc || std.st_mtime > stc.st_mtime) &&
 	(rn || std.st_mtime > stn.st_mtime) &&
-	(prog = check_dump_file(dig, name)))
+	(prog = check_dump_file(dig, name, ksh)))
 	return prog;
 
     /* No digest file. Now look for the per-function compiled file. */
     if (!rc &&
 	(rn || stc.st_mtime > stn.st_mtime) &&
-	(prog = check_dump_file(wc, name)))
+	(prog = check_dump_file(wc, name, ksh)))
 	return prog;
 
     /* No compiled file for the function. The caller (getfpfunc() will
@@ -2777,7 +2833,7 @@
 	tail = file;
 
     if (strsfx(FD_EXT, file))
-	return check_dump_file(file, tail);
+	return check_dump_file(file, tail, NULL);
 
     wc = dyncat(file, FD_EXT);
 
@@ -2785,7 +2841,7 @@
     rn = stat(file, &stn);
 
     if (!rc && (rn || stc.st_mtime > stn.st_mtime) &&
-	(prog = check_dump_file(wc, tail)))
+	(prog = check_dump_file(wc, tail, NULL)))
 	return prog;
 
     return NULL;
@@ -2796,7 +2852,7 @@
 
 /**/
 static Eprog
-check_dump_file(char *file, char *name)
+check_dump_file(char *file, char *name, int *ksh)
 {
     int isrec = 0;
     Wordcode d;
@@ -2853,6 +2909,10 @@
 	    while (np--)
 		*pp++ = dummy_patprog1;
 
+	    if (ksh)
+		*ksh = ((fdhflags(h) & FDHF_KSHLOAD) ? 2 :
+			((fdhflags(h) & FDHF_ZSHLOAD) ? 0 : 1));
+
 	    return prog;
 	} else if (fdflags(d) & FDF_MAP) {
 	    load_dump_file(file, (fdflags(d) & FDF_OTHER), fdother(d));
@@ -2898,6 +2958,10 @@
 	    while (np--)
 		*pp++ = dummy_patprog1;
 
+	    if (ksh)
+		*ksh = ((fdhflags(h) & FDHF_KSHLOAD) ? 2 :
+			((fdhflags(h) & FDHF_ZSHLOAD) ? 0 : 1));
+
 	    return prog;
 	}
     }
@@ -2973,7 +3037,7 @@
 	shf = (Shfunc) zcalloc(sizeof *shf);
 	shf->flags = on;
 	shf->funcdef = mkautofn(shf);
-	shfunctab->addnode(shfunctab, ztrdup(fdname(n) + n->tail), shf);
+	shfunctab->addnode(shfunctab, ztrdup(fdname(n) + fdhtail(n)), shf);
 	if (ops['X'] && eval_autoload(shf, shf->nam, ops, func))
 	    ret = 1;
     }

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author