about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>2000-03-16 00:39:55 +0000
committerTanaka Akira <akr@users.sourceforge.net>2000-03-16 00:39:55 +0000
commit2d44a00df196bcd2dc36a60f775b09af0a7d0bb9 (patch)
tree0bb9b2ecf54865f12d07450af2ce92ddda2dc32f
parente0e7f200809abacdab96ecbf73eea29efbcd06ba (diff)
downloadzsh-2d44a00df196bcd2dc36a60f775b09af0a7d0bb9.tar.gz
zsh-2d44a00df196bcd2dc36a60f775b09af0a7d0bb9.tar.xz
zsh-2d44a00df196bcd2dc36a60f775b09af0a7d0bb9.zip
zsh-workers/10149
-rw-r--r--Doc/Zsh/builtins.yo14
-rw-r--r--Src/builtin.c2
-rw-r--r--Src/exec.c12
-rw-r--r--Src/parse.c144
4 files changed, 123 insertions, 49 deletions
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 848f930f6..f185d865d 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -1295,8 +1295,8 @@ Equivalent to tt(whence -c).
 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
@@ -1332,6 +1332,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
 file will remain mapped if the script defined one or more functions
diff --git a/Src/builtin.c b/Src/builtin.c
index bbb8f1457..a4bc94005 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -124,7 +124,7 @@ static struct builtin builtins[] =
     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 --git a/Src/exec.c b/Src/exec.c
index 120b55eb5..9a8e7cd5d 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -3153,13 +3153,13 @@ static int
 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 @@ execautofn(Estate state, int do_exec)
     }
     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 @@ loadautofn(Shfunc shf)
     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 @@ runshfunc(Eprog prog, FuncWrap wrap, char *name)
 
 /**/
 Eprog
-getfpfunc(char *s)
+getfpfunc(char *s, int *ksh)
 {
     char **pp, buf[PATH_MAX];
     off_t len;
@@ -3376,7 +3376,7 @@ getfpfunc(char *s)
 	    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 --git a/Src/parse.c b/Src/parse.c
index 82404fcad..4390a0270 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -2206,8 +2206,8 @@ init_eprog(void)
 #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 @@ struct fdhead {
     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 @@ struct fdhead {
 #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 @@ dump_find_func(Wordcode h, char *name)
     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 @@ dump_find_func(Wordcode h, char *name)
 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 @@ bin_zcompile(char *nam, char **args, char *ops, int func)
     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 @@ load_dump_header(char *name)
 
     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 @@ fdswap(Wordcode p, int n)
 /* 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 @@ write_dump(int dfd, LinkList names, LinkList progs, int map,
 	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 @@ write_dump(int dfd, LinkList names, LinkList progs, int map,
 	    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_dump(int dfd, LinkList names, LinkList progs, int map,
 		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 @@ write_dump(int dfd, LinkList names, LinkList progs, int map,
 
 /**/
 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 @@ build_dump(char *nam, char *dump, char **files, int ali, int map)
 	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 @@ build_dump(char *nam, char *dump, char **files, int ali, int map)
 	}
 	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 @@ build_dump(char *nam, char *dump, char **files, int ali, int map)
 
     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 @@ build_dump(char *nam, char *dump, char **files, int ali, int map)
 }
 
 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 @@ cur_add_func(Shfunc shf, LinkList names, LinkList progs, int *hlen, int *tlen)
     } 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 @@ cur_add_func(Shfunc shf, LinkList names, LinkList progs, int *hlen, int *tlen)
 
 /**/
 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 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map)
 
 	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 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map)
 	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 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map)
 		    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 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map)
 	}
     } 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 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map)
 		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 @@ build_cur_dump(char *nam, char *dump, char **names, int match, int map)
     }
     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 @@ load_dump_file(char *dump, int other, int len)
 
 /**/
 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 @@ try_dump_file(char *path, char *name, char *file)
     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 @@ try_dump_file(char *path, char *name, char *file)
     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 @@ try_source_file(char *file)
 	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 @@ try_source_file(char *file)
     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 @@ try_source_file(char *file)
 
 /**/
 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 @@ check_dump_file(char *file, char *name)
 	    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 @@ check_dump_file(char *file, char *name)
 	    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 @@ dump_autoload(char *file, int on, char *ops, int func)
 	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;
     }