1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-01 09:41:44 +02:00

zsh-workers/10149

This commit is contained in:
Tanaka Akira 2000-03-16 00:39:55 +00:00
parent e0e7f20080
commit 2d44a00df1
4 changed files with 123 additions and 49 deletions

View file

@ -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

View file

@ -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),
};
/****************************************/

View file

@ -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) {

View file

@ -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;
}