summaryrefslogtreecommitdiffstats
path: root/Src
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>2000-03-15 09:39:05 +0000
committerTanaka Akira <akr@users.sourceforge.net>2000-03-15 09:39:05 +0000
commit2bb32164c71a0cb61e48d818b1209b952435a63f (patch)
tree681b988d22970d49e7203027359caf4812e07d5d /Src
parentzsh-workers/10143 (diff)
downloadzsh-2bb32164c71a0cb61e48d818b1209b952435a63f.tar
zsh-2bb32164c71a0cb61e48d818b1209b952435a63f.tar.gz
zsh-2bb32164c71a0cb61e48d818b1209b952435a63f.tar.bz2
zsh-2bb32164c71a0cb61e48d818b1209b952435a63f.tar.lz
zsh-2bb32164c71a0cb61e48d818b1209b952435a63f.tar.xz
zsh-2bb32164c71a0cb61e48d818b1209b952435a63f.tar.zst
zsh-2bb32164c71a0cb61e48d818b1209b952435a63f.zip
zsh-workers/10144
Diffstat (limited to 'Src')
-rw-r--r--Src/Modules/parameter.c2
-rw-r--r--Src/builtin.c4
-rw-r--r--Src/exec.c6
-rw-r--r--Src/linklist.c17
-rw-r--r--Src/parse.c261
5 files changed, 227 insertions, 63 deletions
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 606ce4583..5dce2f958 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -345,7 +345,7 @@ setfunction(char *name, char *val, int dis)
return;
}
shf = (Shfunc) zalloc(sizeof(*shf));
- shf->funcdef = zdupeprog(prog);
+ shf->funcdef = dupeprog(prog, 0);
shf->flags = dis;
if (!strncmp(name, "TRAP", 4) &&
diff --git a/Src/builtin.c b/Src/builtin.c
index 73876b1fa..bbb8f1457 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, "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);
break;
}
- t = zdupeprog(prog);
+ t = dupeprog(prog, 0);
if (settrap(sig, t))
freeeprog(t);
}
diff --git a/Src/exec.c b/Src/exec.c
index 336983e46..120b55eb5 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -3184,7 +3184,7 @@ execautofn(Estate state, int do_exec)
if (prog->alloc == EA_MAP)
shf->funcdef = stripkshdef(prog, shf->nam);
else
- shf->funcdef = zdupeprog(stripkshdef(prog, shf->nam));
+ shf->funcdef = dupeprog(stripkshdef(prog, shf->nam), 0);
shf->flags &= ~PM_UNDEFINED;
}
popheap();
@@ -3217,7 +3217,7 @@ loadautofn(Shfunc shf)
if (prog->alloc == EA_MAP)
shf->funcdef = stripkshdef(prog, shf->nam);
else
- shf->funcdef = zdupeprog(stripkshdef(prog, shf->nam));
+ shf->funcdef = dupeprog(stripkshdef(prog, shf->nam), 0);
shf->flags &= ~PM_UNDEFINED;
popheap();
@@ -3359,7 +3359,7 @@ runshfunc(Eprog prog, FuncWrap wrap, char *name)
* list of its contents. */
/**/
-static Eprog
+Eprog
getfpfunc(char *s)
{
char **pp, buf[PATH_MAX];
diff --git a/Src/linklist.c b/Src/linklist.c
index e449957da..ff1c84317 100644
--- a/Src/linklist.c
+++ b/Src/linklist.c
@@ -239,7 +239,7 @@ countlinknodes(LinkList list)
}
/**/
-void
+mod_export void
rolllist(LinkList l, LinkNode nd)
{
l->last->next = l->first;
@@ -251,7 +251,7 @@ rolllist(LinkList l, LinkNode nd)
}
/**/
-LinkList
+mod_export LinkList
newsizedlist(int size)
{
LinkList list;
@@ -271,3 +271,16 @@ newsizedlist(int size)
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;
+}
diff --git a/Src/parse.c b/Src/parse.c
index 1d6b18cf3..82404fcad 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -1980,7 +1980,7 @@ yyerror(int noerr)
/**/
mod_export Eprog
-zdupeprog(Eprog p)
+dupeprog(Eprog p, int heap)
{
Eprog r;
int i;
@@ -1989,12 +1989,13 @@ zdupeprog(Eprog p)
if (p == &dummy_eprog)
return p;
- r = (Eprog) zalloc(sizeof(*r));
+ r = (heap ? (Eprog) zhalloc(sizeof(*r)) : (Eprog) zalloc(sizeof(*r)));
r->alloc = EA_REAL;
r->dump = NULL;
r->len = p->len;
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->strs = ((char *) r->prog) + (p->strs - ((char *) p->prog));
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)
{
int map;
+ char *dump;
if (ops['t']) {
Wordcode f;
@@ -2295,14 +2297,19 @@ bin_zcompile(char *nam, char **args, char *ops, int func)
zwarnnam(nam, "too few arguments", NULL, 0);
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));
- if (!args[1])
+ if (!args[1] && !ops['c'])
return build_dump(nam, dyncat(*args, FD_EXT), args, ops['U'], map);
- return build_dump(nam,
- (strsfx(FD_EXT, *args) ? *args : dyncat(*args, FD_EXT)),
- args + 1, ops['U'], map);
+ 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));
}
/* 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. */
+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
build_dump(char *nam, char *dump, char **files, int ali, int map)
{
- int dfd, fd, hlen, tlen, flen, tmp, ona = noaliases, other = 0, ohlen;
- LinkList progs;
- LinkNode node;
- struct fdhead head;
- wordcode pre[FD_PRELEN];
- char *file, **ofiles = files, **oofiles = files, *tail;
+ int dfd, fd, hlen, tlen, flen, ona = noaliases;
+ LinkList progs, names;
+ char *file;
Eprog prog;
if (!strsfx(FD_EXT, dump))
@@ -2394,6 +2458,7 @@ 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++) {
@@ -2434,9 +2499,10 @@ build_dump(char *nam, char *dump, char **files, int ali, int map)
zfree(file, flen);
addlinknode(progs, prog);
+ addlinknode(names, *files);
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)) +
sizeof(wordcode) - 1) / sizeof(wordcode);
@@ -2444,53 +2510,138 @@ build_dump(char *nam, char *dump, char **files, int ali, int map)
noaliases = ona;
tlen = (tlen + hlen) * sizeof(wordcode);
- 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));
+ write_dump(dfd, names, progs, map, hlen, tlen);
- 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);
+ 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;
}
- 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 (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;
+ }
}
- if (other)
- break;
- other = FDF_OTHER;
+ } 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;
}