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

zsh-workers/10144

This commit is contained in:
Tanaka Akira 2000-03-15 09:39:05 +00:00
parent 05eb5d93b1
commit 2bb32164c7
6 changed files with 240 additions and 67 deletions

View file

@ -1296,6 +1296,7 @@ findex(zcompile)
cindex(wordcode, creation) cindex(wordcode, creation)
cindex(compilation) cindex(compilation)
xitem(tt(zcompile) [ tt(-U) ] [ tt(-r) | tt(-m) ] var(file) [ var(name) ... ]) 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) ... ])
item(tt(zcompile -t) var(file) [ var(name) ... ])( item(tt(zcompile -t) var(file) [ var(name) ... ])(
This builtin command can be used to create and display files This builtin command can be used to create and display files
containing the wordcode for functions or scripts. In the first form, a wordcode containing the wordcode for functions or scripts. In the first form, a wordcode
@ -1342,7 +1343,15 @@ upshot of this is that the wordcode file is machine independent and if
it is read or mapped, only one half of the file will really be used it is read or mapped, only one half of the file will really be used
(and mapped). (and mapped).
In the second form, with the tt(-t) option, an existing wordcode file is If given the tt(-c) option, the names have to be names currently
defined in the shell or marked as autoloaded. The definitions for all
these functions will be written into the wordcode var(file). If the
tt(-M) option is given, too, the var(name)s are used as patterns and
all functions whose names match one of these patterns will be
written. If no var(name) is given, the definitions of all functions
currently defined or marked as autoloaded will be written.
In the third form, with the tt(-t) option, an existing wordcode file is
tested. Without further arguments, the names of the original files tested. Without further arguments, the names of the original files
used for it are listed. The first line tells the version of the shell used for it are listed. The first line tells the version of the shell
the file was created with and how the file will be used (mapping or the file was created with and how the file will be used (mapping or

View file

@ -345,7 +345,7 @@ setfunction(char *name, char *val, int dis)
return; return;
} }
shf = (Shfunc) zalloc(sizeof(*shf)); shf = (Shfunc) zalloc(sizeof(*shf));
shf->funcdef = zdupeprog(prog); shf->funcdef = dupeprog(prog, 0);
shf->flags = dis; shf->flags = dis;
if (!strncmp(name, "TRAP", 4) && if (!strncmp(name, "TRAP", 4) &&

View file

@ -124,7 +124,7 @@ static struct builtin builtins[] =
BUILTIN("where", 0, bin_whence, 0, -1, 0, "pmsw", "ca"), BUILTIN("where", 0, bin_whence, 0, -1, 0, "pmsw", "ca"),
BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsw", "c"), BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsw", "c"),
BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "ILabcfdipue", NULL), BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "ILabcfdipue", NULL),
BUILTIN("zcompile", 0, bin_zcompile, 0, -1, 0, "tUmr", NULL), BUILTIN("zcompile", 0, bin_zcompile, 0, -1, 0, "tUmrcM", NULL),
}; };
/****************************************/ /****************************************/
@ -3895,7 +3895,7 @@ bin_trap(char *name, char **argv, char *ops, int func)
zwarnnam(name, "undefined signal: %s", *argv, 0); zwarnnam(name, "undefined signal: %s", *argv, 0);
break; break;
} }
t = zdupeprog(prog); t = dupeprog(prog, 0);
if (settrap(sig, t)) if (settrap(sig, t))
freeeprog(t); freeeprog(t);
} }

View file

@ -3184,7 +3184,7 @@ execautofn(Estate state, int do_exec)
if (prog->alloc == EA_MAP) if (prog->alloc == EA_MAP)
shf->funcdef = stripkshdef(prog, shf->nam); shf->funcdef = stripkshdef(prog, shf->nam);
else else
shf->funcdef = zdupeprog(stripkshdef(prog, shf->nam)); shf->funcdef = dupeprog(stripkshdef(prog, shf->nam), 0);
shf->flags &= ~PM_UNDEFINED; shf->flags &= ~PM_UNDEFINED;
} }
popheap(); popheap();
@ -3217,7 +3217,7 @@ loadautofn(Shfunc shf)
if (prog->alloc == EA_MAP) if (prog->alloc == EA_MAP)
shf->funcdef = stripkshdef(prog, shf->nam); shf->funcdef = stripkshdef(prog, shf->nam);
else else
shf->funcdef = zdupeprog(stripkshdef(prog, shf->nam)); shf->funcdef = dupeprog(stripkshdef(prog, shf->nam), 0);
shf->flags &= ~PM_UNDEFINED; shf->flags &= ~PM_UNDEFINED;
popheap(); popheap();
@ -3359,7 +3359,7 @@ runshfunc(Eprog prog, FuncWrap wrap, char *name)
* list of its contents. */ * list of its contents. */
/**/ /**/
static Eprog Eprog
getfpfunc(char *s) getfpfunc(char *s)
{ {
char **pp, buf[PATH_MAX]; char **pp, buf[PATH_MAX];

View file

@ -239,7 +239,7 @@ countlinknodes(LinkList list)
} }
/**/ /**/
void mod_export void
rolllist(LinkList l, LinkNode nd) rolllist(LinkList l, LinkNode nd)
{ {
l->last->next = l->first; l->last->next = l->first;
@ -251,7 +251,7 @@ rolllist(LinkList l, LinkNode nd)
} }
/**/ /**/
LinkList mod_export LinkList
newsizedlist(int size) newsizedlist(int size)
{ {
LinkList list; LinkList list;
@ -271,3 +271,16 @@ newsizedlist(int size)
return list; return list;
} }
/**/
mod_export int
listcontains(LinkList list, void *dat)
{
LinkNode node;
for (node = firstnode(list); node; incnode(node))
if (getdata(node) == dat)
return 1;
return 0;
}

View file

@ -1980,7 +1980,7 @@ yyerror(int noerr)
/**/ /**/
mod_export Eprog mod_export Eprog
zdupeprog(Eprog p) dupeprog(Eprog p, int heap)
{ {
Eprog r; Eprog r;
int i; int i;
@ -1989,12 +1989,13 @@ zdupeprog(Eprog p)
if (p == &dummy_eprog) if (p == &dummy_eprog)
return p; return p;
r = (Eprog) zalloc(sizeof(*r)); r = (heap ? (Eprog) zhalloc(sizeof(*r)) : (Eprog) zalloc(sizeof(*r)));
r->alloc = EA_REAL; r->alloc = EA_REAL;
r->dump = NULL; r->dump = NULL;
r->len = p->len; r->len = p->len;
r->npats = p->npats; r->npats = p->npats;
pp = r->pats = (Patprog *) zcalloc(r->len); pp = r->pats = (heap ? (Patprog *) hcalloc(r->len) :
(Patprog *) zcalloc(r->len));
r->prog = (Wordcode) (r->pats + r->npats); r->prog = (Wordcode) (r->pats + r->npats);
r->strs = ((char *) r->prog) + (p->strs - ((char *) p->prog)); r->strs = ((char *) r->prog) + (p->strs - ((char *) p->prog));
memcpy(r->prog, p->prog, r->len - (p->npats * sizeof(Patprog))); memcpy(r->prog, p->prog, r->len - (p->npats * sizeof(Patprog)));
@ -2263,6 +2264,7 @@ int
bin_zcompile(char *nam, char **args, char *ops, int func) bin_zcompile(char *nam, char **args, char *ops, int func)
{ {
int map; int map;
char *dump;
if (ops['t']) { if (ops['t']) {
Wordcode f; Wordcode f;
@ -2295,14 +2297,19 @@ bin_zcompile(char *nam, char **args, char *ops, int func)
zwarnnam(nam, "too few arguments", NULL, 0); zwarnnam(nam, "too few arguments", NULL, 0);
return 1; return 1;
} }
if ((ops['c'] && ops['U']) || (!ops['c'] && ops['M'])) {
zwarnnam(nam, "illegal combination of options", NULL, 0);
return 1;
}
map = (ops['m'] ? 2 : (ops['r'] ? 0 : 1)); map = (ops['m'] ? 2 : (ops['r'] ? 0 : 1));
if (!args[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);
return build_dump(nam, dump = (strsfx(FD_EXT, *args) ? *args : dyncat(*args, FD_EXT));
(strsfx(FD_EXT, *args) ? *args : dyncat(*args, FD_EXT)),
args + 1, ops['U'], map); return (ops['c'] ? build_cur_dump(nam, dump, args + 1, ops['M'], map) :
build_dump(nam, dump, args + 1, ops['U'], map));
} }
/* Load the header of a dump file. Returns NULL if the file isn't a /* Load the header of a dump file. Returns NULL if the file isn't a
@ -2374,16 +2381,73 @@ fdswap(Wordcode p, int n)
/* Write a dump file. */ /* Write a dump file. */
static void
write_dump(int dfd, LinkList names, LinkList progs, int map,
int hlen, int tlen)
{
LinkNode name, node;
int other = 0, ohlen, tmp;
wordcode pre[FD_PRELEN];
char *tail, *n;
struct fdhead head;
Eprog prog;
if (map == 1)
map = (tlen >= FD_MINMAP);
for (ohlen = hlen; ; hlen = ohlen) {
fdmagic(pre) = (other ? FD_OMAGIC : FD_MAGIC);
fdsetflags(pre, ((map ? FDF_MAP : 0) | other));
fdsetother(pre, tlen);
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);
head.start = hlen;
hlen += (prog->len - (prog->npats * sizeof(Patprog)) +
sizeof(wordcode) - 1) / sizeof(wordcode);
head.len = prog->len - (prog->npats * sizeof(Patprog));
head.npats = prog->npats;
head.strs = prog->strs - ((char *) prog->prog);
head.hlen = (sizeof(struct fdhead) / sizeof(wordcode)) +
(strlen(n) + sizeof(wordcode)) / sizeof(wordcode);
if ((tail = strrchr(n, '/')))
tail++;
else
tail= n;
head.tail = tail - n;
if (other)
fdswap((Wordcode) &head, sizeof(head) / sizeof(wordcode));
write(dfd, &head, sizeof(head));
tmp = strlen(n) + 1;
write(dfd, n, tmp);
if ((tmp &= (sizeof(wordcode) - 1)))
write(dfd, &head, sizeof(wordcode) - tmp);
}
for (node = firstnode(progs); node; incnode(node)) {
prog = (Eprog) getdata(node);
tmp = (prog->len - (prog->npats * sizeof(Patprog)) +
sizeof(wordcode) - 1) / sizeof(wordcode);
if (other)
fdswap(prog->prog, (((Wordcode) prog->strs) - prog->prog));
write(dfd, prog->prog, tmp * sizeof(wordcode));
}
if (other)
break;
other = FDF_OTHER;
}
}
/**/ /**/
static int 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 dfd, fd, hlen, tlen, flen, tmp, ona = noaliases, other = 0, ohlen; int dfd, fd, hlen, tlen, flen, ona = noaliases;
LinkList progs; LinkList progs, names;
LinkNode node; char *file;
struct fdhead head;
wordcode pre[FD_PRELEN];
char *file, **ofiles = files, **oofiles = files, *tail;
Eprog prog; Eprog prog;
if (!strsfx(FD_EXT, dump)) if (!strsfx(FD_EXT, dump))
@ -2394,6 +2458,7 @@ build_dump(char *nam, char *dump, char **files, int ali, int map)
return 1; return 1;
} }
progs = newlinklist(); progs = newlinklist();
names = newlinklist();
noaliases = ali; noaliases = ali;
for (hlen = FD_PRELEN, tlen = 0; *files; files++) { for (hlen = FD_PRELEN, tlen = 0; *files; files++) {
@ -2434,9 +2499,10 @@ build_dump(char *nam, char *dump, char **files, int ali, int map)
zfree(file, flen); zfree(file, flen);
addlinknode(progs, prog); addlinknode(progs, prog);
addlinknode(names, *files);
flen = (strlen(*files) + sizeof(wordcode)) / sizeof(wordcode); flen = (strlen(*files) + sizeof(wordcode)) / sizeof(wordcode);
hlen += (sizeof(head) / sizeof(wordcode)) + flen; hlen += (sizeof(struct fdhead) / sizeof(wordcode)) + flen;
tlen += (prog->len - (prog->npats * sizeof(Patprog)) + tlen += (prog->len - (prog->npats * sizeof(Patprog)) +
sizeof(wordcode) - 1) / sizeof(wordcode); sizeof(wordcode) - 1) / sizeof(wordcode);
@ -2444,53 +2510,138 @@ build_dump(char *nam, char *dump, char **files, int ali, int map)
noaliases = ona; noaliases = ona;
tlen = (tlen + hlen) * sizeof(wordcode); tlen = (tlen + hlen) * sizeof(wordcode);
if (map == 1)
map = (tlen >= FD_MINMAP);
for (ohlen = hlen; ; hlen = ohlen) { write_dump(dfd, names, progs, map, hlen, tlen);
fdmagic(pre) = (other ? FD_OMAGIC : FD_MAGIC);
fdsetflags(pre, ((map ? FDF_MAP : 0) | other));
fdsetother(pre, tlen);
strcpy(fdversion(pre), ZSH_VERSION);
write(dfd, pre, FD_PRELEN * sizeof(wordcode));
for (node = firstnode(progs), ofiles = oofiles; node;
ofiles++, incnode(node)) {
prog = (Eprog) getdata(node);
head.start = hlen;
hlen += (prog->len - (prog->npats * sizeof(Patprog)) +
sizeof(wordcode) - 1) / sizeof(wordcode);
head.len = prog->len - (prog->npats * sizeof(Patprog));
head.npats = prog->npats;
head.strs = prog->strs - ((char *) prog->prog);
head.hlen = (sizeof(struct fdhead) / sizeof(wordcode)) +
(strlen(*ofiles) + sizeof(wordcode)) / sizeof(wordcode);
if ((tail = strrchr(*ofiles, '/')))
tail++;
else
tail= *ofiles;
head.tail = tail - *ofiles;
if (other)
fdswap((Wordcode) &head, sizeof(head) / sizeof(wordcode));
write(dfd, &head, sizeof(head));
tmp = strlen(*ofiles) + 1;
write(dfd, *ofiles, tmp);
if ((tmp &= (sizeof(wordcode) - 1)))
write(dfd, &head, sizeof(wordcode) - tmp);
}
for (node = firstnode(progs); node; incnode(node)) {
prog = (Eprog) getdata(node);
tmp = (prog->len - (prog->npats * sizeof(Patprog)) +
sizeof(wordcode) - 1) / sizeof(wordcode);
if (other)
fdswap(prog->prog, (((Wordcode) prog->strs) - prog->prog));
write(dfd, prog->prog, tmp * sizeof(wordcode));
}
if (other)
break;
other = FDF_OTHER;
}
close(dfd); close(dfd);
return 0;
}
static int
cur_add_func(Shfunc shf, LinkList names, LinkList progs, int *hlen, int *tlen)
{
Eprog prog;
if (shf->flags & PM_UNDEFINED) {
int ona = noaliases;
noaliases = (shf->flags & PM_UNALIASED);
if (!(prog = getfpfunc(shf->nam)) || prog == &dummy_eprog) {
noaliases = ona;
return 1;
}
if (prog->dump)
prog = dupeprog(prog, 1);
noaliases = ona;
} else
prog = dupeprog(shf->funcdef, 1);
addlinknode(progs, prog);
addlinknode(names, shf->nam);
*hlen += ((sizeof(struct fdhead) / sizeof(wordcode)) +
((strlen(shf->nam) + sizeof(wordcode)) / sizeof(wordcode)));
*tlen += (prog->len - (prog->npats * sizeof(Patprog)) +
sizeof(wordcode) - 1) / sizeof(wordcode);
return 0;
}
/**/
static int
build_cur_dump(char *nam, char *dump, char **names, int match, int map)
{
int dfd, hlen, tlen;
LinkList progs, lnames;
Shfunc shf;
if (!strsfx(FD_EXT, dump))
dump = dyncat(dump, FD_EXT);
if ((dfd = open(dump, O_WRONLY|O_CREAT, 0600)) < 0) {
zwarnnam(nam, "can't write dump file: %s", dump, 0);
return 1;
}
progs = newlinklist();
lnames = newlinklist();
hlen = FD_PRELEN;
tlen = 0;
if (!*names) {
int i;
HashNode hn;
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)) {
zwarnnam(nam, "can't load function: %s", shf->nam, 0);
errflag = 0;
close(dfd);
unlink(dump);
return 1;
}
} else if (match) {
char *pat;
Patprog pprog;
int i;
HashNode hn;
for (; *names; names++) {
tokenize(pat = dupstring(*names));
if (!(pprog = patcompile(pat, PAT_STATIC, NULL))) {
zwarnnam(nam, "bad pattern: %s", *names, 0);
close(dfd);
unlink(dump);
return 1;
}
for (i = 0; i < shfunctab->hsize; i++)
for (hn = shfunctab->nodes[i]; hn; hn = hn->next)
if (!listcontains(lnames, hn->nam) &&
pattry(pprog, hn->nam) &&
cur_add_func((Shfunc) hn, lnames, progs,
&hlen, &tlen)) {
zwarnnam(nam, "can't load function: %s", shf->nam, 0);
errflag = 0;
close(dfd);
unlink(dump);
return 1;
}
}
} else {
for (; *names; names++) {
if (errflag ||
!(shf = (Shfunc) shfunctab->getnode(shfunctab, *names))) {
zwarnnam(nam, "unknown function: %s", *names, 0);
errflag = 0;
close(dfd);
unlink(dump);
return 1;
}
if (cur_add_func(shf, lnames, progs, &hlen, &tlen)) {
zwarnnam(nam, "can't load function: %s", shf->nam, 0);
errflag = 0;
close(dfd);
unlink(dump);
return 1;
}
}
}
if (empty(progs)) {
zwarnnam(nam, "no functions", NULL, 0);
errflag = 0;
close(dfd);
unlink(dump);
return 1;
}
tlen = (tlen + hlen) * sizeof(wordcode);
write_dump(dfd, lnames, progs, map, hlen, tlen);
close(dfd);
return 0; return 0;
} }