From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5203 invoked from network); 15 Mar 2000 15:58:00 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 15 Mar 2000 15:58:00 -0000 Received: (qmail 11813 invoked by alias); 15 Mar 2000 15:57:47 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 10149 Received: (qmail 11787 invoked from network); 15 Mar 2000 15:57:43 -0000 Date: Wed, 15 Mar 2000 16:57:41 +0100 (MET) Message-Id: <200003151557.QAA27085@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: "Bart Schaefer"'s message of Tue, 14 Mar 2000 17:55:41 +0000 Subject: 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@informatik.hu-berlin.de