mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-11-28 03:10:56 +01:00
zsh-workers/9332
This commit is contained in:
parent
cf10e60524
commit
63acd10601
21 changed files with 2472 additions and 1356 deletions
|
|
@ -143,7 +143,7 @@ math_length(char *name, char *arg, int id)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
ex_wrapper(List list, FuncWrap w, char *name)
|
ex_wrapper(Eprog prog, FuncWrap w, char *name)
|
||||||
{
|
{
|
||||||
if (strncmp(name, "example", 7))
|
if (strncmp(name, "example", 7))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -151,7 +151,7 @@ ex_wrapper(List list, FuncWrap w, char *name)
|
||||||
int ogd = opts[GLOBDOTS];
|
int ogd = opts[GLOBDOTS];
|
||||||
|
|
||||||
opts[GLOBDOTS] = 1;
|
opts[GLOBDOTS] = 1;
|
||||||
runshfunc(list, w, name);
|
runshfunc(prog, w, name);
|
||||||
opts[GLOBDOTS] = ogd;
|
opts[GLOBDOTS] = ogd;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -339,23 +339,23 @@ setfunction(char *name, char *val, int dis)
|
||||||
{
|
{
|
||||||
char *value = dupstring(val);
|
char *value = dupstring(val);
|
||||||
Shfunc shf;
|
Shfunc shf;
|
||||||
List list;
|
Eprog prog;
|
||||||
int sn;
|
int sn;
|
||||||
|
|
||||||
val = metafy(val, strlen(val), META_REALLOC);
|
val = metafy(val, strlen(val), META_REALLOC);
|
||||||
|
|
||||||
HEAPALLOC {
|
HEAPALLOC {
|
||||||
list = parse_string(val, 1);
|
prog = parse_string(val, 1);
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
|
|
||||||
if (!list || list == &dummy_list) {
|
if (!prog || prog == &dummy_eprog) {
|
||||||
zwarn("invalid function definition", value, 0);
|
zwarn("invalid function definition", value, 0);
|
||||||
zsfree(val);
|
zsfree(val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PERMALLOC {
|
PERMALLOC {
|
||||||
shf = (Shfunc) zalloc(sizeof(*shf));
|
shf = (Shfunc) zalloc(sizeof(*shf));
|
||||||
shf->funcdef = (List) dupstruct(list);
|
shf->funcdef = dupeprog(prog);
|
||||||
shf->flags = dis;
|
shf->flags = dis;
|
||||||
|
|
||||||
if (!strncmp(name, "TRAP", 4) &&
|
if (!strncmp(name, "TRAP", 4) &&
|
||||||
|
|
@ -463,8 +463,7 @@ getfunction(HashTable ht, char *name, int dis)
|
||||||
((shf->flags & PM_TAGGED) ? "Ut" : "U") :
|
((shf->flags & PM_TAGGED) ? "Ut" : "U") :
|
||||||
((shf->flags & PM_TAGGED) ? "t" : "")));
|
((shf->flags & PM_TAGGED) ? "t" : "")));
|
||||||
} else {
|
} else {
|
||||||
char *t = getpermtext((void *) dupstruct((void *)
|
char *t = getpermtext(shf->funcdef, NULL), *h;
|
||||||
shf->funcdef)), *h;
|
|
||||||
|
|
||||||
h = dupstring(t);
|
h = dupstring(t);
|
||||||
zsfree(t);
|
zsfree(t);
|
||||||
|
|
@ -528,8 +527,7 @@ scanfunctions(HashTable ht, ScanFunc func, int flags, int dis)
|
||||||
((shf->flags & PM_TAGGED) ? "Ut" : "U") :
|
((shf->flags & PM_TAGGED) ? "Ut" : "U") :
|
||||||
((shf->flags & PM_TAGGED) ? "t" : "")));
|
((shf->flags & PM_TAGGED) ? "t" : "")));
|
||||||
} else {
|
} else {
|
||||||
char *t = getpermtext((void *)
|
char *t = getpermtext(((Shfunc) hn)->funcdef, NULL);
|
||||||
dupstruct((void *) ((Shfunc) hn)->funcdef));
|
|
||||||
|
|
||||||
pm.u.str = dupstring(t);
|
pm.u.str = dupstring(t);
|
||||||
unmetafy(pm.u.str, NULL);
|
unmetafy(pm.u.str, NULL);
|
||||||
|
|
@ -577,13 +575,13 @@ funcstackgetfn(Param pm)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
func_wrapper(List list, FuncWrap w, char *name)
|
func_wrapper(Eprog prog, FuncWrap w, char *name)
|
||||||
{
|
{
|
||||||
PERMALLOC {
|
PERMALLOC {
|
||||||
pushnode(funcstack, ztrdup(name));
|
pushnode(funcstack, ztrdup(name));
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
|
|
||||||
runshfunc(list, w, name);
|
runshfunc(prog, w, name);
|
||||||
|
|
||||||
DPUTS(strcmp(name, (char *) getdata(firstnode(funcstack))),
|
DPUTS(strcmp(name, (char *) getdata(firstnode(funcstack))),
|
||||||
"funcstack wrapper with wrong function");
|
"funcstack wrapper with wrong function");
|
||||||
|
|
|
||||||
|
|
@ -1600,9 +1600,9 @@ zfsenddata(char *name, int recv, int progress, off_t startat)
|
||||||
char lsbuf[ZF_BUFSIZE], *ascbuf = NULL, *optr;
|
char lsbuf[ZF_BUFSIZE], *ascbuf = NULL, *optr;
|
||||||
off_t sofar = 0, last_sofar = 0;
|
off_t sofar = 0, last_sofar = 0;
|
||||||
readwrite_t read_ptr = zfread, write_ptr = zfwrite;
|
readwrite_t read_ptr = zfread, write_ptr = zfwrite;
|
||||||
List l;
|
Eprog prog;
|
||||||
|
|
||||||
if (progress && (l = getshfunc("zftp_progress")) != &dummy_list) {
|
if (progress && (prog = getshfunc("zftp_progress")) != &dummy_eprog) {
|
||||||
/*
|
/*
|
||||||
* progress to set up: ZFTP_COUNT is zero.
|
* progress to set up: ZFTP_COUNT is zero.
|
||||||
* We do this here in case we needed to wait for a RETR
|
* We do this here in case we needed to wait for a RETR
|
||||||
|
|
@ -1611,7 +1611,7 @@ zfsenddata(char *name, int recv, int progress, off_t startat)
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc("zftp_progress", l, NULL, 0, 1);
|
doshfunc("zftp_progress", prog, NULL, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
/* Now add in the bit of the file we've got/sent already */
|
/* Now add in the bit of the file we've got/sent already */
|
||||||
sofar = last_sofar = startat;
|
sofar = last_sofar = startat;
|
||||||
|
|
@ -1739,12 +1739,12 @@ zfsenddata(char *name, int recv, int progress, off_t startat)
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
if (!ret && sofar != last_sofar && progress &&
|
if (!ret && sofar != last_sofar && progress &&
|
||||||
(l = getshfunc("zftp_progress")) != &dummy_list) {
|
(prog = getshfunc("zftp_progress")) != &dummy_eprog) {
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
zfsetparam("ZFTP_COUNT", &sofar, ZFPM_READONLY|ZFPM_INTEGER);
|
zfsetparam("ZFTP_COUNT", &sofar, ZFPM_READONLY|ZFPM_INTEGER);
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc("zftp_progress", l, NULL, 0, 1);
|
doshfunc("zftp_progress", prog, NULL, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
last_sofar = sofar;
|
last_sofar = sofar;
|
||||||
}
|
}
|
||||||
|
|
@ -2444,7 +2444,7 @@ zfgetcwd(void)
|
||||||
{
|
{
|
||||||
char *ptr, *eptr;
|
char *ptr, *eptr;
|
||||||
int endc;
|
int endc;
|
||||||
List l;
|
Eprog prog;
|
||||||
|
|
||||||
if (zfprefs & ZFPF_DUMB)
|
if (zfprefs & ZFPF_DUMB)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -2471,11 +2471,11 @@ zfgetcwd(void)
|
||||||
* front end. By putting it here, and in close when ZFTP_PWD is unset,
|
* front end. By putting it here, and in close when ZFTP_PWD is unset,
|
||||||
* we at least cover the bases.
|
* we at least cover the bases.
|
||||||
*/
|
*/
|
||||||
if ((l = getshfunc("zftp_chpwd")) != &dummy_list) {
|
if ((prog = getshfunc("zftp_chpwd")) != &dummy_eprog) {
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc("zftp_chpwd", l, NULL, 0, 1);
|
doshfunc("zftp_chpwd", prog, NULL, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -2629,7 +2629,7 @@ zftp_getput(char *name, char **args, int flags)
|
||||||
{
|
{
|
||||||
int ret = 0, recv = (flags & ZFTP_RECV), getsize = 0, progress = 1;
|
int ret = 0, recv = (flags & ZFTP_RECV), getsize = 0, progress = 1;
|
||||||
char *cmd = recv ? "RETR " : (flags & ZFTP_APPE) ? "APPE " : "STOR ";
|
char *cmd = recv ? "RETR " : (flags & ZFTP_APPE) ? "APPE " : "STOR ";
|
||||||
List l;
|
Eprog prog;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point I'd like to set progress to 0 if we're
|
* At this point I'd like to set progress to 0 if we're
|
||||||
|
|
@ -2647,7 +2647,7 @@ zftp_getput(char *name, char **args, int flags)
|
||||||
for (; *args; args++) {
|
for (; *args; args++) {
|
||||||
char *ln, *rest = NULL;
|
char *ln, *rest = NULL;
|
||||||
off_t startat = 0;
|
off_t startat = 0;
|
||||||
if (progress && (l = getshfunc("zftp_progress")) != &dummy_list) {
|
if (progress && (prog = getshfunc("zftp_progress")) != &dummy_eprog) {
|
||||||
off_t sz;
|
off_t sz;
|
||||||
/*
|
/*
|
||||||
* This calls the SIZE command to get the size for remote
|
* This calls the SIZE command to get the size for remote
|
||||||
|
|
@ -2688,14 +2688,14 @@ zftp_getput(char *name, char **args, int flags)
|
||||||
* if and only if we called zfsenddata();
|
* if and only if we called zfsenddata();
|
||||||
*/
|
*/
|
||||||
if (progress && ret != 2 &&
|
if (progress && ret != 2 &&
|
||||||
(l = getshfunc("zftp_progress")) != &dummy_list) {
|
(prog = getshfunc("zftp_progress")) != &dummy_eprog) {
|
||||||
/* progress to finish: ZFTP_TRANSFER set to GF or PF */
|
/* progress to finish: ZFTP_TRANSFER set to GF or PF */
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
zfsetparam("ZFTP_TRANSFER", ztrdup(recv ? "GF" : "PF"),
|
zfsetparam("ZFTP_TRANSFER", ztrdup(recv ? "GF" : "PF"),
|
||||||
ZFPM_READONLY);
|
ZFPM_READONLY);
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc("zftp_progress", l, NULL, 0, 1);
|
doshfunc("zftp_progress", prog, NULL, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
}
|
}
|
||||||
if (rest) {
|
if (rest) {
|
||||||
|
|
@ -2795,7 +2795,7 @@ static void
|
||||||
zfclose(int leaveparams)
|
zfclose(int leaveparams)
|
||||||
{
|
{
|
||||||
char **aptr;
|
char **aptr;
|
||||||
List l;
|
Eprog prog;
|
||||||
|
|
||||||
if (zfsess->cfd == -1)
|
if (zfsess->cfd == -1)
|
||||||
return;
|
return;
|
||||||
|
|
@ -2837,11 +2837,11 @@ zfclose(int leaveparams)
|
||||||
zfunsetparam(*aptr);
|
zfunsetparam(*aptr);
|
||||||
|
|
||||||
/* Now ZFTP_PWD is unset. It's up to zftp_chpwd to notice. */
|
/* Now ZFTP_PWD is unset. It's up to zftp_chpwd to notice. */
|
||||||
if ((l = getshfunc("zftp_chpwd")) != &dummy_list) {
|
if ((prog = getshfunc("zftp_chpwd")) != &dummy_eprog) {
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc("zftp_chpwd", l, NULL, 0, 1);
|
doshfunc("zftp_chpwd", prog, NULL, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ bin_zprof(char *nam, char **args, char *ops, int func)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
zprof_wrapper(List list, FuncWrap w, char *name)
|
zprof_wrapper(Eprog prog, FuncWrap w, char *name)
|
||||||
{
|
{
|
||||||
struct sfunc sf, *sp;
|
struct sfunc sf, *sp;
|
||||||
Pfunc f;
|
Pfunc f;
|
||||||
|
|
@ -257,7 +257,7 @@ zprof_wrapper(List list, FuncWrap w, char *name)
|
||||||
gettimeofday(&tv, &dummy);
|
gettimeofday(&tv, &dummy);
|
||||||
sf.beg = prev = ((((double) tv.tv_sec) * 1000.0) +
|
sf.beg = prev = ((((double) tv.tv_sec) * 1000.0) +
|
||||||
(((double) tv.tv_usec) / 1000.0));
|
(((double) tv.tv_usec) / 1000.0));
|
||||||
runshfunc(list, w, name);
|
runshfunc(prog, w, name);
|
||||||
tv.tv_sec = tv.tv_usec = 0;
|
tv.tv_sec = tv.tv_usec = 0;
|
||||||
gettimeofday(&tv, &dummy);
|
gettimeofday(&tv, &dummy);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -491,11 +491,11 @@ after_complete(Hookdef dummy, Compldat dat)
|
||||||
static void
|
static void
|
||||||
callcompfunc(char *s, char *fn)
|
callcompfunc(char *s, char *fn)
|
||||||
{
|
{
|
||||||
List list;
|
Eprog prog;
|
||||||
int lv = lastval;
|
int lv = lastval;
|
||||||
char buf[20];
|
char buf[20];
|
||||||
|
|
||||||
if ((list = getshfunc(fn)) != &dummy_list) {
|
if ((prog = getshfunc(fn)) != &dummy_eprog) {
|
||||||
char **p, *tmp;
|
char **p, *tmp;
|
||||||
int aadd = 0, usea = 1, icf = incompfunc, osc = sfcontext;
|
int aadd = 0, usea = 1, icf = incompfunc, osc = sfcontext;
|
||||||
unsigned int rset, kset;
|
unsigned int rset, kset;
|
||||||
|
|
@ -724,7 +724,7 @@ callcompfunc(char *s, char *fn)
|
||||||
while (*p)
|
while (*p)
|
||||||
addlinknode(largs, dupstring(*p++));
|
addlinknode(largs, dupstring(*p++));
|
||||||
}
|
}
|
||||||
doshfunc(fn, list, largs, 0, 0);
|
doshfunc(fn, prog, largs, 0, 0);
|
||||||
cfret = lastval;
|
cfret = lastval;
|
||||||
lastval = olv;
|
lastval = olv;
|
||||||
} OLDHEAPS;
|
} OLDHEAPS;
|
||||||
|
|
|
||||||
|
|
@ -3431,12 +3431,12 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
}
|
}
|
||||||
if (cc->func) {
|
if (cc->func) {
|
||||||
/* This handles the compctl -K flag. */
|
/* This handles the compctl -K flag. */
|
||||||
List list;
|
Eprog prog;
|
||||||
char **r;
|
char **r;
|
||||||
int lv = lastval;
|
int lv = lastval;
|
||||||
|
|
||||||
/* Get the function. */
|
/* Get the function. */
|
||||||
if ((list = getshfunc(cc->func)) != &dummy_list) {
|
if ((prog = getshfunc(cc->func)) != &dummy_eprog) {
|
||||||
/* We have it, so build a argument list. */
|
/* We have it, so build a argument list. */
|
||||||
LinkList args = newlinklist();
|
LinkList args = newlinklist();
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
@ -3460,7 +3460,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
incompctlfunc = 1;
|
incompctlfunc = 1;
|
||||||
sfcontext = SFC_COMPLETE;
|
sfcontext = SFC_COMPLETE;
|
||||||
/* Call the function. */
|
/* Call the function. */
|
||||||
doshfunc(cc->func, list, args, 0, 1);
|
doshfunc(cc->func, prog, args, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
incompctlfunc = 0;
|
incompctlfunc = 0;
|
||||||
/* And get the result from the reply parameter. */
|
/* And get the result from the reply parameter. */
|
||||||
|
|
@ -3601,12 +3601,12 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
/* generate the user-defined display list: if anything fails, *
|
/* generate the user-defined display list: if anything fails, *
|
||||||
* we silently allow the normal completion list to be used. */
|
* we silently allow the normal completion list to be used. */
|
||||||
char **yaptr = NULL, *uv = NULL;
|
char **yaptr = NULL, *uv = NULL;
|
||||||
List list;
|
Eprog prog;
|
||||||
|
|
||||||
if (cc->ylist[0] == '$' || cc->ylist[0] == '(') {
|
if (cc->ylist[0] == '$' || cc->ylist[0] == '(') {
|
||||||
/* from variable */
|
/* from variable */
|
||||||
uv = cc->ylist + (cc->ylist[0] == '$');
|
uv = cc->ylist + (cc->ylist[0] == '$');
|
||||||
} else if ((list = getshfunc(cc->ylist)) != &dummy_list) {
|
} else if ((prog = getshfunc(cc->ylist)) != &dummy_eprog) {
|
||||||
/* from function: pass completions as arg list */
|
/* from function: pass completions as arg list */
|
||||||
LinkList args = newlinklist();
|
LinkList args = newlinklist();
|
||||||
LinkNode ln;
|
LinkNode ln;
|
||||||
|
|
@ -3630,7 +3630,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
if (incompfunc != 1)
|
if (incompfunc != 1)
|
||||||
incompctlfunc = 1;
|
incompctlfunc = 1;
|
||||||
sfcontext = SFC_COMPLETE;
|
sfcontext = SFC_COMPLETE;
|
||||||
doshfunc(cc->ylist, list, args, 0, 1);
|
doshfunc(cc->ylist, prog, args, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
incompctlfunc = 0;
|
incompctlfunc = 0;
|
||||||
uv = "reply";
|
uv = "reply";
|
||||||
|
|
|
||||||
|
|
@ -1177,7 +1177,7 @@ comp_setunset(int rset, int runset, int kset, int kunset)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
comp_wrapper(List list, FuncWrap w, char *name)
|
comp_wrapper(Eprog prog, FuncWrap w, char *name)
|
||||||
{
|
{
|
||||||
if (incompfunc != 1)
|
if (incompfunc != 1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -1214,7 +1214,7 @@ comp_wrapper(List list, FuncWrap w, char *name)
|
||||||
owords = arrdup(compwords);
|
owords = arrdup(compwords);
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
|
|
||||||
runshfunc(list, w, name);
|
runshfunc(prog, w, name);
|
||||||
|
|
||||||
if (comprestore && !strcmp(comprestore, "auto")) {
|
if (comprestore && !strcmp(comprestore, "auto")) {
|
||||||
compcurrent = ocur;
|
compcurrent = ocur;
|
||||||
|
|
|
||||||
|
|
@ -649,9 +649,9 @@ execzlefunc(Thingy func, char **args)
|
||||||
lastcmd = wflags;
|
lastcmd = wflags;
|
||||||
r = 1;
|
r = 1;
|
||||||
} else {
|
} else {
|
||||||
List l = getshfunc(w->u.fnnam);
|
Eprog prog = getshfunc(w->u.fnnam);
|
||||||
|
|
||||||
if(l == &dummy_list) {
|
if(prog == &dummy_eprog) {
|
||||||
/* the shell function doesn't exist */
|
/* the shell function doesn't exist */
|
||||||
char *nm = niceztrdup(w->u.fnnam);
|
char *nm = niceztrdup(w->u.fnnam);
|
||||||
char *msg = tricat("No such shell function `", nm, "'");
|
char *msg = tricat("No such shell function `", nm, "'");
|
||||||
|
|
@ -673,7 +673,7 @@ execzlefunc(Thingy func, char **args)
|
||||||
startparamscope();
|
startparamscope();
|
||||||
makezleparams(0);
|
makezleparams(0);
|
||||||
sfcontext = SFC_WIDGET;
|
sfcontext = SFC_WIDGET;
|
||||||
doshfunc(w->u.fnnam, l, largs, 0, 0);
|
doshfunc(w->u.fnnam, prog, largs, 0, 0);
|
||||||
ret = lastval;
|
ret = lastval;
|
||||||
lastval = olv;
|
lastval = olv;
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
|
|
|
||||||
|
|
@ -925,9 +925,9 @@ mod_export void
|
||||||
iremovesuffix(int c, int keep)
|
iremovesuffix(int c, int keep)
|
||||||
{
|
{
|
||||||
if (suffixfunc) {
|
if (suffixfunc) {
|
||||||
List l = getshfunc(suffixfunc);
|
Eprog prog = getshfunc(suffixfunc);
|
||||||
|
|
||||||
if (l != &dummy_list) {
|
if (prog != &dummy_eprog) {
|
||||||
LinkList args = newlinklist();
|
LinkList args = newlinklist();
|
||||||
char buf[20];
|
char buf[20];
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
@ -939,7 +939,7 @@ iremovesuffix(int c, int keep)
|
||||||
startparamscope();
|
startparamscope();
|
||||||
makezleparams(0);
|
makezleparams(0);
|
||||||
sfcontext = SFC_COMPLETE;
|
sfcontext = SFC_COMPLETE;
|
||||||
doshfunc(suffixfunc, l, args, 0, 1);
|
doshfunc(suffixfunc, prog, args, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
endparamscope();
|
endparamscope();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -971,7 +971,7 @@ cd_try_chdir(char *pfix, char *dest, int hard)
|
||||||
static void
|
static void
|
||||||
cd_new_pwd(int func, LinkNode dir)
|
cd_new_pwd(int func, LinkNode dir)
|
||||||
{
|
{
|
||||||
List l;
|
Eprog prog;
|
||||||
char *new_pwd, *s;
|
char *new_pwd, *s;
|
||||||
int dirstacksize;
|
int dirstacksize;
|
||||||
|
|
||||||
|
|
@ -1015,13 +1015,13 @@ cd_new_pwd(int func, LinkNode dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* execute the chpwd function */
|
/* execute the chpwd function */
|
||||||
if ((l = getshfunc("chpwd")) != &dummy_list) {
|
if ((prog = getshfunc("chpwd")) != &dummy_eprog) {
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc("chpwd", l, NULL, 0, 1);
|
doshfunc("chpwd", prog, NULL, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2003,7 +2003,7 @@ eval_autoload(Shfunc shf, char *name, char *ops, int func)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (shf->funcdef)
|
if (shf->funcdef)
|
||||||
freestruct(shf->funcdef);
|
freeeprog(shf->funcdef);
|
||||||
|
|
||||||
if (ops['X'] == 1) {
|
if (ops['X'] == 1) {
|
||||||
char *fargv[3];
|
char *fargv[3];
|
||||||
|
|
@ -2140,30 +2140,27 @@ bin_functions(char *name, char **argv, char *ops, int func)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static List
|
static Eprog
|
||||||
mkautofn(Shfunc shf)
|
mkautofn(Shfunc shf)
|
||||||
{
|
{
|
||||||
List l;
|
Eprog p;
|
||||||
Sublist s;
|
|
||||||
Pline p;
|
p = (Eprog) zalloc(sizeof(*p));
|
||||||
Cmd c;
|
p->len = 5 * sizeof(wordcode);
|
||||||
AutoFn a;
|
p->prog = (Wordcode) zalloc(p->len);
|
||||||
PERMALLOC {
|
p->strs = NULL;
|
||||||
a = (AutoFn)allocnode(N_AUTOFN);
|
p->shf = shf;
|
||||||
a->shf = shf;
|
p->npats = 0;
|
||||||
c = (Cmd)allocnode(N_CMD);
|
p->pats = NULL;
|
||||||
c->type = AUTOFN;
|
p->heap = 0;
|
||||||
c->u.autofn = a;
|
|
||||||
p = (Pline)allocnode(N_PLINE);
|
p->prog[0] = WCB_LIST(Z_SYNC | Z_END);
|
||||||
p->left = c;
|
p->prog[1] = WCB_SUBLIST(WC_SUBLIST_END, 0, 3);
|
||||||
p->type = END;
|
p->prog[2] = WCB_PIPE(WC_PIPE_END, 0);
|
||||||
s = (Sublist)allocnode(N_SUBLIST);
|
p->prog[3] = WCB_AUTOFN();
|
||||||
s->left = p;
|
p->prog[4] = WCB_END();
|
||||||
l = (List)allocnode(N_LIST);
|
|
||||||
l->left = s;
|
return p;
|
||||||
l->type = Z_SYNC;
|
|
||||||
} LASTALLOC;
|
|
||||||
return l;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unset: unset parameters */
|
/* unset: unset parameters */
|
||||||
|
|
@ -3328,14 +3325,14 @@ bin_emulate(char *nam, char **argv, char *ops, int func)
|
||||||
int
|
int
|
||||||
bin_eval(char *nam, char **argv, char *ops, int func)
|
bin_eval(char *nam, char **argv, char *ops, int func)
|
||||||
{
|
{
|
||||||
List list;
|
Eprog prog;
|
||||||
|
|
||||||
list = parse_string(zjoin(argv, ' '), 0);
|
prog = parse_string(zjoin(argv, ' '), 0);
|
||||||
if (!list) {
|
if (!prog) {
|
||||||
errflag = 0;
|
errflag = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
execlist(list, 1, 0);
|
execode(prog, 1, 0);
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
lastval = errflag;
|
lastval = errflag;
|
||||||
errflag = 0;
|
errflag = 0;
|
||||||
|
|
@ -3761,7 +3758,8 @@ int
|
||||||
bin_test(char *name, char **argv, char *ops, int func)
|
bin_test(char *name, char **argv, char *ops, int func)
|
||||||
{
|
{
|
||||||
char **s;
|
char **s;
|
||||||
Cond c;
|
Eprog prog;
|
||||||
|
struct estate state;
|
||||||
|
|
||||||
/* if "test" was invoked as "[", it needs a matching "]" *
|
/* if "test" was invoked as "[", it needs a matching "]" *
|
||||||
* which is subsequently ignored */
|
* which is subsequently ignored */
|
||||||
|
|
@ -3781,7 +3779,7 @@ bin_test(char *name, char **argv, char *ops, int func)
|
||||||
tok = NULLTOK;
|
tok = NULLTOK;
|
||||||
condlex = testlex;
|
condlex = testlex;
|
||||||
testlex();
|
testlex();
|
||||||
c = par_cond();
|
prog = parse_cond();
|
||||||
condlex = yylex;
|
condlex = yylex;
|
||||||
|
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
|
|
@ -3789,13 +3787,19 @@ bin_test(char *name, char **argv, char *ops, int func)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!c || tok == LEXERR) {
|
if (!prog || tok == LEXERR) {
|
||||||
zwarnnam(name, tokstr ? "parse error" : "argument expected", NULL, 0);
|
zwarnnam(name, tokstr ? "parse error" : "argument expected", NULL, 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* syntax is OK, so evaluate */
|
/* syntax is OK, so evaluate */
|
||||||
return !evalcond(c);
|
|
||||||
|
state.prog = prog;
|
||||||
|
state.pc = prog->prog;
|
||||||
|
state.strs = prog->strs;
|
||||||
|
|
||||||
|
|
||||||
|
return !evalcond(&state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* display a time, provided in units of 1/60s, as minutes and seconds */
|
/* display a time, provided in units of 1/60s, as minutes and seconds */
|
||||||
|
|
@ -3830,7 +3834,7 @@ bin_times(char *name, char **argv, char *ops, int func)
|
||||||
int
|
int
|
||||||
bin_trap(char *name, char **argv, char *ops, int func)
|
bin_trap(char *name, char **argv, char *ops, int func)
|
||||||
{
|
{
|
||||||
List l;
|
Eprog prog;
|
||||||
char *arg, *s;
|
char *arg, *s;
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
|
|
@ -3852,7 +3856,7 @@ bin_trap(char *name, char **argv, char *ops, int func)
|
||||||
if (!sigfuncs[sig])
|
if (!sigfuncs[sig])
|
||||||
printf("trap -- '' %s\n", sigs[sig]);
|
printf("trap -- '' %s\n", sigs[sig]);
|
||||||
else {
|
else {
|
||||||
s = getpermtext((void *) sigfuncs[sig]);
|
s = getpermtext(sigfuncs[sig], NULL);
|
||||||
printf("trap -- ");
|
printf("trap -- ");
|
||||||
quotedzputs(s, stdout);
|
quotedzputs(s, stdout);
|
||||||
printf(" %s\n", sigs[sig]);
|
printf(" %s\n", sigs[sig]);
|
||||||
|
|
@ -3878,15 +3882,15 @@ bin_trap(char *name, char **argv, char *ops, int func)
|
||||||
/* Sort out the command to execute on trap */
|
/* Sort out the command to execute on trap */
|
||||||
arg = *argv++;
|
arg = *argv++;
|
||||||
if (!*arg)
|
if (!*arg)
|
||||||
l = NULL;
|
prog = NULL;
|
||||||
else if (!(l = parse_string(arg, 0))) {
|
else if (!(prog = parse_string(arg, 0))) {
|
||||||
zwarnnam(name, "couldn't parse trap command", NULL, 0);
|
zwarnnam(name, "couldn't parse trap command", NULL, 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set traps */
|
/* set traps */
|
||||||
for (; *argv; argv++) {
|
for (; *argv; argv++) {
|
||||||
List t;
|
Eprog t;
|
||||||
|
|
||||||
sig = getsignum(*argv);
|
sig = getsignum(*argv);
|
||||||
if (sig == -1) {
|
if (sig == -1) {
|
||||||
|
|
@ -3894,10 +3898,10 @@ bin_trap(char *name, char **argv, char *ops, int func)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PERMALLOC {
|
PERMALLOC {
|
||||||
t = (List) dupstruct(l);
|
t = dupeprog(prog);
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
if (settrap(sig, t))
|
if (settrap(sig, t))
|
||||||
freestruct(t);
|
freeeprog(t);
|
||||||
}
|
}
|
||||||
return *argv != NULL;
|
return *argv != NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
121
Src/cond.c
121
Src/cond.c
|
|
@ -39,95 +39,108 @@ static char *condstr[COND_MOD] = {
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
evalcond(Cond c)
|
evalcond(Estate state)
|
||||||
{
|
{
|
||||||
struct stat *st;
|
struct stat *st;
|
||||||
char *left, *right = NULL;
|
char *left, *right = NULL;
|
||||||
|
wordcode code = *state->pc++;
|
||||||
|
int ctype = WC_COND_TYPE(code);
|
||||||
|
|
||||||
switch (c->type) {
|
switch (ctype) {
|
||||||
case COND_NOT:
|
case COND_NOT:
|
||||||
if (tracingcond)
|
if (tracingcond)
|
||||||
fprintf(stderr, " %s", condstr[c->type]);
|
fprintf(stderr, " %s", condstr[ctype]);
|
||||||
return !evalcond(c->left);
|
return !evalcond(state);
|
||||||
case COND_AND:
|
case COND_AND:
|
||||||
if (evalcond(c->left)) {
|
if (evalcond(state)) {
|
||||||
if (tracingcond)
|
if (tracingcond)
|
||||||
fprintf(stderr, " %s", condstr[c->type]);
|
fprintf(stderr, " %s", condstr[ctype]);
|
||||||
return evalcond(c->right);
|
return evalcond(state);
|
||||||
} else
|
} else {
|
||||||
|
state->pc += WC_COND_SKIP(code) - 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
case COND_OR:
|
case COND_OR:
|
||||||
if (!evalcond(c->left)) {
|
if (!evalcond(state)) {
|
||||||
if (tracingcond)
|
if (tracingcond)
|
||||||
fprintf(stderr, " %s", condstr[c->type]);
|
fprintf(stderr, " %s", condstr[ctype]);
|
||||||
return evalcond(c->right);
|
return evalcond(state);
|
||||||
} else
|
} else {
|
||||||
|
state->pc += WC_COND_SKIP(code) - 1;
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
case COND_MOD:
|
case COND_MOD:
|
||||||
case COND_MODI:
|
case COND_MODI:
|
||||||
{
|
{
|
||||||
Conddef cd;
|
Conddef cd;
|
||||||
|
char *name = ecgetstr(state, 0), **strs;
|
||||||
|
int l = WC_COND_SKIP(code);
|
||||||
|
|
||||||
if ((cd = getconddef((c->type == COND_MODI),
|
if (ctype == COND_MOD)
|
||||||
((char *) c->left) + 1, 1))) {
|
strs = ecgetarr(state, l, 1);
|
||||||
if (c->type == COND_MOD) {
|
else {
|
||||||
int l = arrlen((char **) c->right);
|
char *sbuf[3];
|
||||||
|
|
||||||
if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
|
sbuf[0] = ecgetstr(state, 0);
|
||||||
zerr("unrecognized condition: `%s'", (char *) c->left, 0);
|
sbuf[1] = ecgetstr(state, 0);
|
||||||
|
sbuf[2] = NULL;
|
||||||
|
|
||||||
|
strs = arrdup(sbuf);
|
||||||
|
l = 2;
|
||||||
|
}
|
||||||
|
if ((cd = getconddef((ctype == COND_MODI), name + 1, 1))) {
|
||||||
|
if (ctype == COND_MOD &&
|
||||||
|
(l < cd->min || (cd->max >= 0 && l > cd->max))) {
|
||||||
|
zerr("unrecognized condition: `%s'", name, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (tracingcond)
|
if (tracingcond)
|
||||||
tracemodcond((char *)c->left, (char **)c->right,
|
tracemodcond(name, strs, ctype == COND_MODI);
|
||||||
c->type == COND_MODI);
|
return cd->handler(strs, cd->condid);
|
||||||
return cd->handler((char **) c->right, cd->condid);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char **a = (char **) c->right, *s = a[0];
|
char *s = strs[0];
|
||||||
|
|
||||||
if (s && s[0] == '-' &&
|
strs[0] = dupstring(name);
|
||||||
(cd = getconddef(0, s + 1, 1))) {
|
name = s;
|
||||||
int l = arrlen(a);
|
|
||||||
|
|
||||||
|
if (name && name[0] == '-' &&
|
||||||
|
(cd = getconddef(0, name + 1, 1))) {
|
||||||
if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
|
if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
|
||||||
zerr("unrecognized condition: `%s'", (char *) c->left, 0);
|
zerr("unrecognized condition: `%s'", name, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (tracingcond)
|
if (tracingcond)
|
||||||
tracemodcond((char *)c->left, a, c->type == COND_MODI);
|
tracemodcond(name, strs, ctype == COND_MODI);
|
||||||
a[0] = (char *) c->left;
|
return cd->handler(strs, cd->condid);
|
||||||
return cd->handler(a, cd->condid);
|
|
||||||
} else
|
} else
|
||||||
zerr("unrecognized condition: `%s'", (char *) c->left, 0);
|
zerr("unrecognized condition: `%s'", name, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
left = dupstring((char *) c->left);
|
left = ecgetstr(state, 1);
|
||||||
singsub(&left);
|
singsub(&left);
|
||||||
untokenize(left);
|
untokenize(left);
|
||||||
if (c->right && c->type != COND_STREQ && c->type != COND_STRNEQ) {
|
if (ctype <= COND_GE && ctype != COND_STREQ && ctype != COND_STRNEQ) {
|
||||||
right = dupstring((char *) c->right);
|
right = ecgetstr(state, 1);
|
||||||
singsub(&right);
|
singsub(&right);
|
||||||
untokenize(right);
|
untokenize(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tracingcond) {
|
if (tracingcond) {
|
||||||
if (c->type < COND_MOD) {
|
if (ctype < COND_MOD) {
|
||||||
char *rt = (char *) right;
|
char *rt = (char *) right;
|
||||||
if (c->type == COND_STREQ || c->type == COND_STRNEQ) {
|
if (ctype == COND_STREQ || ctype == COND_STRNEQ) {
|
||||||
rt = dupstring(c->right);
|
rt = dupstring(ecrawstr(state->prog, state->pc));
|
||||||
singsub(&rt);
|
singsub(&rt);
|
||||||
untokenize(rt);
|
untokenize(rt);
|
||||||
}
|
}
|
||||||
fprintf(stderr, " %s %s %s", (char *)left, condstr[c->type],
|
fprintf(stderr, " %s %s %s", left, condstr[ctype], rt);
|
||||||
rt);
|
|
||||||
} else
|
} else
|
||||||
fprintf(stderr, " -%c %s", c->type, (char *)left);
|
fprintf(stderr, " -%c %s", ctype, left);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->type >= COND_EQ && c->type <= COND_GE) {
|
if (ctype >= COND_EQ && ctype <= COND_GE) {
|
||||||
mnumber mn1, mn2;
|
mnumber mn1, mn2;
|
||||||
mn1 = matheval(left);
|
mn1 = matheval(left);
|
||||||
mn2 = matheval(right);
|
mn2 = matheval(right);
|
||||||
|
|
@ -144,7 +157,7 @@ evalcond(Cond c)
|
||||||
mn2.u.d = (double)mn2.u.l;
|
mn2.u.d = (double)mn2.u.l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch(c->type) {
|
switch(ctype) {
|
||||||
case COND_EQ:
|
case COND_EQ:
|
||||||
return (mn1.type & MN_FLOAT) ? (mn1.u.d == mn2.u.d) :
|
return (mn1.type & MN_FLOAT) ? (mn1.u.d == mn2.u.d) :
|
||||||
(mn1.u.l == mn2.u.l);
|
(mn1.u.l == mn2.u.l);
|
||||||
|
|
@ -166,30 +179,32 @@ evalcond(Cond c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (c->type) {
|
switch (ctype) {
|
||||||
case COND_STREQ:
|
case COND_STREQ:
|
||||||
case COND_STRNEQ:
|
case COND_STRNEQ:
|
||||||
{
|
{
|
||||||
Patprog pprog = c->prog;
|
int test, npat = state->pc[1];
|
||||||
int test;
|
Patprog pprog = state->prog->pats[npat];
|
||||||
|
|
||||||
if (pprog == dummy_patprog1 || pprog == dummy_patprog2) {
|
if (pprog == dummy_patprog1 || pprog == dummy_patprog2) {
|
||||||
char *opat;
|
char *opat;
|
||||||
int save;
|
int save;
|
||||||
|
|
||||||
right = opat = dupstring((char *) c->right);
|
right = opat = dupstring(ecrawstr(state->prog, state->pc));
|
||||||
singsub(&right);
|
singsub(&right);
|
||||||
save = (!strcmp(opat, right) && pprog != dummy_patprog2);
|
save = (!state->prog->heap &&
|
||||||
|
!strcmp(opat, right) && pprog != dummy_patprog2);
|
||||||
|
|
||||||
if (!(pprog = patcompile(right, (save ? PAT_ZDUP : PAT_STATIC),
|
if (!(pprog = patcompile(right, (save ? PAT_ZDUP : PAT_STATIC),
|
||||||
NULL)))
|
NULL)))
|
||||||
zerr("bad pattern: %s", right, 0);
|
zerr("bad pattern: %s", right, 0);
|
||||||
else if (save)
|
else if (save)
|
||||||
c->prog = pprog;
|
state->prog->pats[npat] = pprog;
|
||||||
}
|
}
|
||||||
|
state->pc += 2;
|
||||||
test = (pprog && pattry(pprog, left));
|
test = (pprog && pattry(pprog, left));
|
||||||
|
|
||||||
return (c->type == COND_STREQ ? test : !test);
|
return (ctype == COND_STREQ ? test : !test);
|
||||||
}
|
}
|
||||||
case COND_STRLT:
|
case COND_STRLT:
|
||||||
return strcmp(left, right) < 0;
|
return strcmp(left, right) < 0;
|
||||||
|
|
@ -255,7 +270,7 @@ evalcond(Cond c)
|
||||||
a = st->st_mtime;
|
a = st->st_mtime;
|
||||||
if (!(st = getstat(right)))
|
if (!(st = getstat(right)))
|
||||||
return 0;
|
return 0;
|
||||||
return (c->type == COND_NT) ? a > st->st_mtime : a < st->st_mtime;
|
return (ctype == COND_NT) ? a > st->st_mtime : a < st->st_mtime;
|
||||||
}
|
}
|
||||||
case COND_EF:
|
case COND_EF:
|
||||||
{
|
{
|
||||||
|
|
@ -271,7 +286,7 @@ evalcond(Cond c)
|
||||||
return d == st->st_dev && i == st->st_ino;
|
return d == st->st_dev && i == st->st_ino;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
zerr("bad cond structure", NULL, 0);
|
zerr("bad cond code", NULL, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -390,7 +405,7 @@ tracemodcond(char *name, char **args, int inf)
|
||||||
{
|
{
|
||||||
char **aptr;
|
char **aptr;
|
||||||
MUSTUSEHEAP("tracemodcond");
|
MUSTUSEHEAP("tracemodcond");
|
||||||
args = duparray(args, (VFunc) dupstring);
|
args = arrdup(args);
|
||||||
for (aptr = args; *aptr; aptr++)
|
for (aptr = args; *aptr; aptr++)
|
||||||
untokenize(*aptr);
|
untokenize(*aptr);
|
||||||
if (inf) {
|
if (inf) {
|
||||||
|
|
|
||||||
612
Src/exec.c
612
Src/exec.c
File diff suppressed because it is too large
Load diff
|
|
@ -2551,15 +2551,15 @@ qualtime(char *name, struct stat *buf, off_t days, char *dummy)
|
||||||
static int
|
static int
|
||||||
qualsheval(char *name, struct stat *buf, off_t days, char *str)
|
qualsheval(char *name, struct stat *buf, off_t days, char *str)
|
||||||
{
|
{
|
||||||
List list;
|
Eprog prog;
|
||||||
|
|
||||||
if ((list = parse_string(str, 0))) {
|
if ((prog = parse_string(str, 0))) {
|
||||||
int ef = errflag, lv = lastval, ret;
|
int ef = errflag, lv = lastval, ret;
|
||||||
|
|
||||||
unsetparam("reply");
|
unsetparam("reply");
|
||||||
setsparam("REPLY", ztrdup(name));
|
setsparam("REPLY", ztrdup(name));
|
||||||
|
|
||||||
execlist(list, 1, 0);
|
execode(prog, 1, 0);
|
||||||
|
|
||||||
ret = lastval;
|
ret = lastval;
|
||||||
errflag = ef;
|
errflag = ef;
|
||||||
|
|
|
||||||
|
|
@ -842,7 +842,7 @@ freeshfuncnode(HashNode hn)
|
||||||
|
|
||||||
zsfree(shf->nam);
|
zsfree(shf->nam);
|
||||||
if (shf->funcdef)
|
if (shf->funcdef)
|
||||||
freestruct(shf->funcdef);
|
freeeprog(shf->funcdef);
|
||||||
zfree(shf, sizeof(struct shfunc));
|
zfree(shf, sizeof(struct shfunc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -879,7 +879,7 @@ printshfuncnode(HashNode hn, int printflags)
|
||||||
if (!f->funcdef)
|
if (!f->funcdef)
|
||||||
t = 0;
|
t = 0;
|
||||||
else
|
else
|
||||||
t = getpermtext((void *) f->funcdef);
|
t = getpermtext(f->funcdef, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
quotedzputs(f->nam, stdout);
|
quotedzputs(f->nam, stdout);
|
||||||
|
|
|
||||||
16
Src/init.c
16
Src/init.c
|
|
@ -95,7 +95,7 @@ mod_export int alloc_stackp;
|
||||||
void
|
void
|
||||||
loop(int toplevel, int justonce)
|
loop(int toplevel, int justonce)
|
||||||
{
|
{
|
||||||
List list;
|
Eprog prog;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
int oasp = toplevel ? 0 : alloc_stackp;
|
int oasp = toplevel ? 0 : alloc_stackp;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -112,7 +112,7 @@ loop(int toplevel, int justonce)
|
||||||
hbegin(1); /* init history mech */
|
hbegin(1); /* init history mech */
|
||||||
intr(); /* interrupts on */
|
intr(); /* interrupts on */
|
||||||
lexinit(); /* initialize lexical state */
|
lexinit(); /* initialize lexical state */
|
||||||
if (!(list = parse_event())) { /* if we couldn't parse a list */
|
if (!(prog = parse_event())) { /* if we couldn't parse a list */
|
||||||
hend();
|
hend();
|
||||||
if ((tok == ENDINPUT && !errflag) ||
|
if ((tok == ENDINPUT && !errflag) ||
|
||||||
(tok == LEXERR && (!isset(SHINSTDIN) || !toplevel)) ||
|
(tok == LEXERR && (!isset(SHINSTDIN) || !toplevel)) ||
|
||||||
|
|
@ -122,9 +122,9 @@ loop(int toplevel, int justonce)
|
||||||
}
|
}
|
||||||
if (hend()) {
|
if (hend()) {
|
||||||
int toksav = tok;
|
int toksav = tok;
|
||||||
List prelist;
|
Eprog preprog;
|
||||||
|
|
||||||
if (toplevel && (prelist = getshfunc("preexec")) != &dummy_list) {
|
if (toplevel && (preprog = getshfunc("preexec")) != &dummy_eprog) {
|
||||||
LinkList args;
|
LinkList args;
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
|
|
@ -135,16 +135,16 @@ loop(int toplevel, int justonce)
|
||||||
addlinknode(args, hist_ring->text);
|
addlinknode(args, hist_ring->text);
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc("preexec", prelist, args, 0, 1);
|
doshfunc("preexec", preprog, args, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
freelinklist(args, (FreeFunc) NULL);
|
freelinklist(args, (FreeFunc) NULL);
|
||||||
errflag = 0;
|
errflag = 0;
|
||||||
}
|
}
|
||||||
if (stopmsg) /* unset 'you have stopped jobs' flag */
|
if (stopmsg) /* unset 'you have stopped jobs' flag */
|
||||||
stopmsg--;
|
stopmsg--;
|
||||||
execlist(list, 0, 0);
|
execode(prog, 0, 0);
|
||||||
if (toplevel)
|
if (toplevel)
|
||||||
freestructs();
|
freeeprogs();
|
||||||
tok = toksav;
|
tok = toksav;
|
||||||
if (toplevel)
|
if (toplevel)
|
||||||
noexitct = 0;
|
noexitct = 0;
|
||||||
|
|
@ -560,6 +560,8 @@ setupvals(void)
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
init_eprog();
|
||||||
|
|
||||||
getkeyptr = NULL;
|
getkeyptr = NULL;
|
||||||
|
|
||||||
lineno = 1;
|
lineno = 1;
|
||||||
|
|
|
||||||
241
Src/loop.c
241
Src/loop.c
|
|
@ -47,15 +47,20 @@ mod_export int breaks;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execfor(Cmd cmd, LinkList args, int flags)
|
execfor(Estate state, int do_exec)
|
||||||
{
|
{
|
||||||
Forcmd node;
|
Wordcode end, loop;
|
||||||
char *str;
|
wordcode code = state->pc[-1];
|
||||||
|
int iscond = (WC_FOR_TYPE(code) == WC_FOR_COND);
|
||||||
|
char *name, *str, *cond, *advance;
|
||||||
zlong val = 0;
|
zlong val = 0;
|
||||||
|
LinkList args;
|
||||||
|
|
||||||
node = cmd->u.forcmd;
|
name = ecgetstr(state, 0);
|
||||||
if (node->condition) {
|
end = state->pc + WC_FOR_SKIP(code);
|
||||||
str = dupstring(node->name);
|
|
||||||
|
if (iscond) {
|
||||||
|
str = dupstring(name);
|
||||||
singsub(&str);
|
singsub(&str);
|
||||||
if (isset(XTRACE)) {
|
if (isset(XTRACE)) {
|
||||||
char *str2 = dupstring(str);
|
char *str2 = dupstring(str);
|
||||||
|
|
@ -66,9 +71,19 @@ execfor(Cmd cmd, LinkList args, int flags)
|
||||||
}
|
}
|
||||||
if (!errflag)
|
if (!errflag)
|
||||||
matheval(str);
|
matheval(str);
|
||||||
if (errflag)
|
if (errflag) {
|
||||||
|
state->pc = end;
|
||||||
return lastval = errflag;
|
return lastval = errflag;
|
||||||
} else if (!node->inflag) {
|
}
|
||||||
|
cond = ecgetstr(state, 0);
|
||||||
|
advance = ecgetstr(state, 0);
|
||||||
|
} else if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
|
||||||
|
if (!(args = ecgetlist(state, *state->pc++, 1))) {
|
||||||
|
state->pc = end;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
execsubst(args);
|
||||||
|
} else {
|
||||||
char **x;
|
char **x;
|
||||||
|
|
||||||
args = newlinklist();
|
args = newlinklist();
|
||||||
|
|
@ -79,9 +94,10 @@ execfor(Cmd cmd, LinkList args, int flags)
|
||||||
loops++;
|
loops++;
|
||||||
pushheap();
|
pushheap();
|
||||||
cmdpush(CS_FOR);
|
cmdpush(CS_FOR);
|
||||||
|
loop = state->pc;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (node->condition) {
|
if (iscond) {
|
||||||
str = dupstring(node->condition);
|
str = dupstring(cond);
|
||||||
singsub(&str);
|
singsub(&str);
|
||||||
if (!errflag) {
|
if (!errflag) {
|
||||||
while (iblank(*str))
|
while (iblank(*str))
|
||||||
|
|
@ -109,21 +125,21 @@ execfor(Cmd cmd, LinkList args, int flags)
|
||||||
break;
|
break;
|
||||||
if (isset(XTRACE)) {
|
if (isset(XTRACE)) {
|
||||||
printprompt4();
|
printprompt4();
|
||||||
fprintf(stderr, "%s=%s\n", node->name, str);
|
fprintf(stderr, "%s=%s\n", name, str);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
setsparam(node->name, ztrdup(str));
|
setsparam(name, ztrdup(str));
|
||||||
}
|
}
|
||||||
execlist(node->list, 1,
|
state->pc = loop;
|
||||||
(flags & CFLAG_EXEC) && args && empty(args));
|
execlist(state, 1, do_exec && args && empty(args));
|
||||||
if (breaks) {
|
if (breaks) {
|
||||||
breaks--;
|
breaks--;
|
||||||
if (breaks || !contflag)
|
if (breaks || !contflag)
|
||||||
break;
|
break;
|
||||||
contflag = 0;
|
contflag = 0;
|
||||||
}
|
}
|
||||||
if (node->condition && !errflag) {
|
if (iscond && !errflag) {
|
||||||
str = dupstring(node->advance);
|
str = dupstring(advance);
|
||||||
if (isset(XTRACE)) {
|
if (isset(XTRACE)) {
|
||||||
printprompt4();
|
printprompt4();
|
||||||
fprintf(stderr, "%s\n", str);
|
fprintf(stderr, "%s\n", str);
|
||||||
|
|
@ -149,25 +165,37 @@ execfor(Cmd cmd, LinkList args, int flags)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execselect(Cmd cmd, LinkList args, int flags)
|
execselect(Estate state, int do_exec)
|
||||||
{
|
{
|
||||||
Forcmd node;
|
Wordcode end, loop;
|
||||||
char *str, *s;
|
wordcode code = state->pc[-1];
|
||||||
|
char *str, *s, *name;
|
||||||
LinkNode n;
|
LinkNode n;
|
||||||
int i, usezle;
|
int i, usezle;
|
||||||
FILE *inp;
|
FILE *inp;
|
||||||
size_t more;
|
size_t more;
|
||||||
|
LinkList args;
|
||||||
|
|
||||||
node = cmd->u.forcmd;
|
end = state->pc + WC_FOR_SKIP(code);
|
||||||
if (!node->inflag) {
|
name = ecgetstr(state, 0);
|
||||||
|
|
||||||
|
if (WC_SELECT_TYPE(code) == WC_SELECT_PPARAM) {
|
||||||
char **x;
|
char **x;
|
||||||
|
|
||||||
args = newlinklist();
|
args = newlinklist();
|
||||||
for (x = pparams; *x; x++)
|
for (x = pparams; *x; x++)
|
||||||
addlinknode(args, dupstring(*x));
|
addlinknode(args, dupstring(*x));
|
||||||
|
} else {
|
||||||
|
if (!(args = ecgetlist(state, *state->pc++, 1))) {
|
||||||
|
state->pc = end;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
if (!args || empty(args))
|
execsubst(args);
|
||||||
|
}
|
||||||
|
if (!args || empty(args)) {
|
||||||
|
state->pc = end;
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
loops++;
|
loops++;
|
||||||
lastval = 0;
|
lastval = 0;
|
||||||
pushheap();
|
pushheap();
|
||||||
|
|
@ -175,6 +203,7 @@ execselect(Cmd cmd, LinkList args, int flags)
|
||||||
usezle = interact && SHTTY != -1 && isset(USEZLE);
|
usezle = interact && SHTTY != -1 && isset(USEZLE);
|
||||||
inp = fdopen(dup(usezle ? SHTTY : 0), "r");
|
inp = fdopen(dup(usezle ? SHTTY : 0), "r");
|
||||||
more = selectlist(args, 0);
|
more = selectlist(args, 0);
|
||||||
|
loop = state->pc;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (empty(bufstack)) {
|
if (empty(bufstack)) {
|
||||||
|
|
@ -219,8 +248,9 @@ execselect(Cmd cmd, LinkList args, int flags)
|
||||||
else
|
else
|
||||||
str = "";
|
str = "";
|
||||||
}
|
}
|
||||||
setsparam(node->name, ztrdup(str));
|
setsparam(name, ztrdup(str));
|
||||||
execlist(node->list, 1, 0);
|
state->pc = loop;
|
||||||
|
execlist(state, 1, 0);
|
||||||
freeheap();
|
freeheap();
|
||||||
if (breaks) {
|
if (breaks) {
|
||||||
breaks--;
|
breaks--;
|
||||||
|
|
@ -236,6 +266,7 @@ execselect(Cmd cmd, LinkList args, int flags)
|
||||||
popheap();
|
popheap();
|
||||||
fclose(inp);
|
fclose(inp);
|
||||||
loops--;
|
loops--;
|
||||||
|
state->pc = end;
|
||||||
return lastval;
|
return lastval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -302,28 +333,31 @@ selectlist(LinkList l, size_t start)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execwhile(Cmd cmd, LinkList args, int flags)
|
execwhile(Estate state, int do_exec)
|
||||||
{
|
{
|
||||||
struct whilecmd *node;
|
Wordcode end, loop;
|
||||||
int olderrexit, oldval;
|
wordcode code = state->pc[-1];
|
||||||
|
int olderrexit, oldval, isuntil = (WC_WHILE_TYPE(code) == WC_WHILE_UNTIL);
|
||||||
|
|
||||||
|
end = state->pc + WC_WHILE_SKIP(code);
|
||||||
olderrexit = noerrexit;
|
olderrexit = noerrexit;
|
||||||
node = cmd->u.whilecmd;
|
|
||||||
oldval = 0;
|
oldval = 0;
|
||||||
pushheap();
|
pushheap();
|
||||||
cmdpush(node->cond ? CS_UNTIL : CS_WHILE);
|
cmdpush(isuntil ? CS_UNTIL : CS_WHILE);
|
||||||
loops++;
|
loops++;
|
||||||
|
loop = state->pc;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
state->pc = loop;
|
||||||
noerrexit = 1;
|
noerrexit = 1;
|
||||||
execlist(node->cont, 1, 0);
|
execlist(state, 1, 0);
|
||||||
noerrexit = olderrexit;
|
noerrexit = olderrexit;
|
||||||
if (!((lastval == 0) ^ node->cond)) {
|
if (!((lastval == 0) ^ isuntil)) {
|
||||||
if (breaks)
|
if (breaks)
|
||||||
breaks--;
|
breaks--;
|
||||||
lastval = oldval;
|
lastval = oldval;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
execlist(node->loop, 1, 0);
|
execlist(state, 1, 0);
|
||||||
if (breaks) {
|
if (breaks) {
|
||||||
breaks--;
|
breaks--;
|
||||||
if (breaks || !contflag)
|
if (breaks || !contflag)
|
||||||
|
|
@ -345,21 +379,26 @@ execwhile(Cmd cmd, LinkList args, int flags)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execrepeat(Cmd cmd, LinkList args, int flags)
|
execrepeat(Estate state, int do_exec)
|
||||||
{
|
{
|
||||||
|
Wordcode end, loop;
|
||||||
|
wordcode code = state->pc[-1];
|
||||||
int count;
|
int count;
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
end = state->pc + WC_REPEAT_SKIP(code);
|
||||||
|
|
||||||
lastval = 0;
|
lastval = 0;
|
||||||
if (!args || empty(args) || nextnode(firstnode(args))) {
|
tmp = ecgetstr(state, 1);
|
||||||
zerr("bad argument for repeat", NULL, 0);
|
singsub(&tmp);
|
||||||
return 1;
|
count = atoi(tmp);
|
||||||
}
|
|
||||||
count = atoi(peekfirst(args));
|
|
||||||
pushheap();
|
pushheap();
|
||||||
cmdpush(CS_REPEAT);
|
cmdpush(CS_REPEAT);
|
||||||
loops++;
|
loops++;
|
||||||
|
loop = state->pc;
|
||||||
while (count-- > 0) {
|
while (count-- > 0) {
|
||||||
execlist(cmd->u.list, 1, 0);
|
state->pc = loop;
|
||||||
|
execlist(state, 1, 0);
|
||||||
freeheap();
|
freeheap();
|
||||||
if (breaks) {
|
if (breaks) {
|
||||||
breaks--;
|
breaks--;
|
||||||
|
|
@ -375,114 +414,140 @@ execrepeat(Cmd cmd, LinkList args, int flags)
|
||||||
cmdpop();
|
cmdpop();
|
||||||
popheap();
|
popheap();
|
||||||
loops--;
|
loops--;
|
||||||
|
state->pc = end;
|
||||||
return lastval;
|
return lastval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execif(Cmd cmd, LinkList args, int flags)
|
execif(Estate state, int do_exec)
|
||||||
{
|
{
|
||||||
struct ifcmd *node;
|
Wordcode end, next;
|
||||||
int olderrexit, s = 0;
|
wordcode code = state->pc[-1];
|
||||||
List *i, *t;
|
int olderrexit, s = 0, run = 0;
|
||||||
|
|
||||||
olderrexit = noerrexit;
|
olderrexit = noerrexit;
|
||||||
node = cmd->u.ifcmd;
|
end = state->pc + WC_IF_SKIP(code);
|
||||||
i = node->ifls;
|
|
||||||
t = node->thenls;
|
|
||||||
|
|
||||||
if (!noerrexit)
|
if (!noerrexit)
|
||||||
noerrexit = 1;
|
noerrexit = 1;
|
||||||
while (*i) {
|
while (state->pc < end) {
|
||||||
cmdpush(s ? CS_ELIF : CS_IF);
|
code = *state->pc++;
|
||||||
execlist(*i, 1, 0);
|
if (wc_code(code) != WC_IF ||
|
||||||
cmdpop();
|
(run = (WC_IF_TYPE(code) == WC_IF_ELSE))) {
|
||||||
if (!lastval)
|
if (run)
|
||||||
|
run = 2;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
next = state->pc + WC_IF_SKIP(code);
|
||||||
|
cmdpush(s ? CS_ELIF : CS_IF);
|
||||||
|
execlist(state, 1, 0);
|
||||||
|
cmdpop();
|
||||||
|
if (!lastval) {
|
||||||
|
run = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
s = 1;
|
s = 1;
|
||||||
i++;
|
state->pc = next;
|
||||||
t++;
|
|
||||||
}
|
}
|
||||||
noerrexit = olderrexit;
|
noerrexit = olderrexit;
|
||||||
|
|
||||||
if (*t) {
|
if (run) {
|
||||||
cmdpush(*i ? (s ? CS_ELIFTHEN : CS_IFTHEN) : CS_ELSE);
|
cmdpush(run == 2 ? CS_ELSE : (s ? CS_ELIFTHEN : CS_IFTHEN));
|
||||||
execlist(*t, 1, flags & CFLAG_EXEC);
|
execlist(state, 1, do_exec);
|
||||||
cmdpop();
|
cmdpop();
|
||||||
} else
|
} else
|
||||||
lastval = 0;
|
lastval = 0;
|
||||||
|
state->pc = end;
|
||||||
|
|
||||||
return lastval;
|
return lastval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
execcase(Cmd cmd, LinkList args, int flags)
|
execcase(Estate state, int do_exec)
|
||||||
{
|
{
|
||||||
struct casecmd *node;
|
Wordcode end, next;
|
||||||
char *word;
|
wordcode code = state->pc[-1];
|
||||||
List *l;
|
char *word, *pat;
|
||||||
char **p;
|
int npat, save;
|
||||||
Patprog *pp, pprog;
|
Patprog *spprog, pprog;
|
||||||
int save;
|
|
||||||
|
|
||||||
node = cmd->u.casecmd;
|
end = state->pc + WC_CASE_SKIP(code);
|
||||||
l = node->lists;
|
|
||||||
p = node->pats;
|
|
||||||
pp = node->progs;
|
|
||||||
|
|
||||||
word = dupstring(*p++);
|
word = ecgetstr(state, 1);
|
||||||
singsub(&word);
|
singsub(&word);
|
||||||
untokenize(word);
|
untokenize(word);
|
||||||
lastval = 0;
|
lastval = 0;
|
||||||
|
|
||||||
if (node) {
|
|
||||||
cmdpush(CS_CASE);
|
cmdpush(CS_CASE);
|
||||||
while (*p) {
|
while (state->pc < end) {
|
||||||
char *pat = NULL, *opat;
|
code = *state->pc++;
|
||||||
|
if (wc_code(code) != WC_CASE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pat = NULL;
|
||||||
pprog = NULL;
|
pprog = NULL;
|
||||||
save = 0;
|
save = 0;
|
||||||
|
npat = state->pc[1];
|
||||||
|
spprog = state->prog->pats + npat;
|
||||||
|
|
||||||
|
next = state->pc + WC_CASE_SKIP(code);
|
||||||
|
|
||||||
if (isset(XTRACE)) {
|
if (isset(XTRACE)) {
|
||||||
char *pat2;
|
char *pat2, *opat;
|
||||||
|
|
||||||
opat = pat = dupstring(*p + 1);
|
opat = pat = ecgetstr(state, 1);
|
||||||
singsub(&pat);
|
singsub(&pat);
|
||||||
save = (!strcmp(pat, opat) && *pp != dummy_patprog2);
|
save = (!state->prog->heap &&
|
||||||
|
!strcmp(pat, opat) && *spprog != dummy_patprog2);
|
||||||
|
|
||||||
pat2 = dupstring(pat);
|
pat2 = dupstring(pat);
|
||||||
untokenize(pat2);
|
untokenize(pat2);
|
||||||
printprompt4();
|
printprompt4();
|
||||||
fprintf(stderr, "case %s (%s)\n", word, pat2);
|
fprintf(stderr, "case %s (%s)\n", word, pat2);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
state->pc++;
|
||||||
if (*pp != dummy_patprog1 && *pp != dummy_patprog2)
|
} else
|
||||||
pprog = *pp;
|
state->pc += 2;
|
||||||
|
|
||||||
|
if (*spprog != dummy_patprog1 && *spprog != dummy_patprog2)
|
||||||
|
pprog = *spprog;
|
||||||
|
|
||||||
if (!pprog) {
|
if (!pprog) {
|
||||||
if (!pat) {
|
if (!pat) {
|
||||||
opat = pat = dupstring(*p + 1);
|
char *opat;
|
||||||
|
|
||||||
|
opat = pat = dupstring(ecrawstr(state->prog, state->pc - 2));
|
||||||
singsub(&pat);
|
singsub(&pat);
|
||||||
save = (!strcmp(pat, opat) && *pp != dummy_patprog2);
|
save = (!state->prog->heap &&
|
||||||
|
!strcmp(pat, opat) && *spprog != dummy_patprog2);
|
||||||
}
|
}
|
||||||
if (!(pprog = patcompile(pat, (save ? PAT_ZDUP : PAT_STATIC),
|
if (!(pprog = patcompile(pat, (save ? PAT_ZDUP : PAT_STATIC),
|
||||||
NULL)))
|
NULL)))
|
||||||
zerr("bad pattern: %s", pat, 0);
|
zerr("bad pattern: %s", pat, 0);
|
||||||
else if (save)
|
else if (save)
|
||||||
*pp = pprog;
|
*spprog = pprog;
|
||||||
}
|
}
|
||||||
if (pprog && pattry(pprog, word)) {
|
if (pprog && pattry(pprog, word)) {
|
||||||
do {
|
execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) &&
|
||||||
execlist(*l++, 1, **p == ';' && (flags & CFLAG_EXEC));
|
do_exec));
|
||||||
} while(**p++ == '&' && *p);
|
while (wc_code(code) == WC_CASE &&
|
||||||
break;
|
WC_CASE_TYPE(code) == WC_CASE_AND) {
|
||||||
|
state->pc = next;
|
||||||
|
code = *state->pc;
|
||||||
|
state->pc += 3;
|
||||||
|
next = state->pc + WC_CASE_SKIP(code) - 1;
|
||||||
|
execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) &&
|
||||||
|
do_exec));
|
||||||
}
|
}
|
||||||
p++;
|
break;
|
||||||
pp++;
|
} else
|
||||||
l++;
|
state->pc = next;
|
||||||
}
|
}
|
||||||
cmdpop();
|
cmdpop();
|
||||||
}
|
|
||||||
|
state->pc = end;
|
||||||
|
|
||||||
return lastval;
|
return lastval;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1064
Src/parse.c
1064
Src/parse.c
File diff suppressed because it is too large
Load diff
|
|
@ -39,7 +39,7 @@ mod_export int sigtrapped[VSIGCOUNT];
|
||||||
/* trap functions for each signal */
|
/* trap functions for each signal */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
mod_export List sigfuncs[VSIGCOUNT];
|
mod_export Eprog sigfuncs[VSIGCOUNT];
|
||||||
|
|
||||||
/* Variables used by signal queueing */
|
/* Variables used by signal queueing */
|
||||||
|
|
||||||
|
|
@ -674,7 +674,7 @@ dosavetrap(int sig, int level)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
mod_export int
|
mod_export int
|
||||||
settrap(int sig, List l)
|
settrap(int sig, Eprog l)
|
||||||
{
|
{
|
||||||
if (sig == -1)
|
if (sig == -1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -773,7 +773,7 @@ unsettrap(int sig)
|
||||||
if ((hn = removehashnode(shfunctab, func)))
|
if ((hn = removehashnode(shfunctab, func)))
|
||||||
shfunctab->freenode(hn);
|
shfunctab->freenode(hn);
|
||||||
} else if (sigfuncs[sig]) {
|
} else if (sigfuncs[sig]) {
|
||||||
freestruct(sigfuncs[sig]);
|
freeeprog(sigfuncs[sig]);
|
||||||
sigfuncs[sig] = NULL;
|
sigfuncs[sig] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -834,12 +834,12 @@ endtrapscope(void)
|
||||||
unsettrap(sig);
|
unsettrap(sig);
|
||||||
sigtrapped[sig] = st->flags;
|
sigtrapped[sig] = st->flags;
|
||||||
if (st->flags) {
|
if (st->flags) {
|
||||||
List list = (st->flags & ZSIG_FUNC) ?
|
Eprog prog = (st->flags & ZSIG_FUNC) ?
|
||||||
((Shfunc) st->list)->funcdef : (List) st->list;
|
((Shfunc) st->list)->funcdef : (Eprog) st->list;
|
||||||
/* prevent settrap from saving this */
|
/* prevent settrap from saving this */
|
||||||
int oldlt = opts[LOCALTRAPS];
|
int oldlt = opts[LOCALTRAPS];
|
||||||
opts[LOCALTRAPS] = 0;
|
opts[LOCALTRAPS] = 0;
|
||||||
settrap(sig, list);
|
settrap(sig, prog);
|
||||||
opts[LOCALTRAPS] = oldlt;
|
opts[LOCALTRAPS] = oldlt;
|
||||||
if ((sigtrapped[sig] = st->flags) & ZSIG_FUNC)
|
if ((sigtrapped[sig] = st->flags) & ZSIG_FUNC)
|
||||||
shfunctab->addnode(shfunctab, ((Shfunc)st->list)->nam,
|
shfunctab->addnode(shfunctab, ((Shfunc)st->list)->nam,
|
||||||
|
|
@ -851,11 +851,11 @@ endtrapscope(void)
|
||||||
|
|
||||||
if (exittr) {
|
if (exittr) {
|
||||||
dotrapargs(SIGEXIT, &exittr, (exittr & ZSIG_FUNC) ?
|
dotrapargs(SIGEXIT, &exittr, (exittr & ZSIG_FUNC) ?
|
||||||
((Shfunc)exitfn)->funcdef : (List) exitfn);
|
((Shfunc)exitfn)->funcdef : (Eprog) exitfn);
|
||||||
if (exittr & ZSIG_FUNC)
|
if (exittr & ZSIG_FUNC)
|
||||||
shfunctab->freenode((HashNode)exitfn);
|
shfunctab->freenode((HashNode)exitfn);
|
||||||
else
|
else
|
||||||
freestruct(exitfn);
|
freeeprog(exitfn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
670
Src/text.c
670
Src/text.c
|
|
@ -31,7 +31,7 @@
|
||||||
#include "text.pro"
|
#include "text.pro"
|
||||||
|
|
||||||
static char *tptr, *tbuf, *tlim;
|
static char *tptr, *tbuf, *tlim;
|
||||||
static int tsiz, tindent, tnewlins;
|
static int tsiz, tindent, tnewlins, tjob;
|
||||||
|
|
||||||
/* add a character to the text buffer */
|
/* add a character to the text buffer */
|
||||||
|
|
||||||
|
|
@ -72,18 +72,18 @@ taddstr(char *s)
|
||||||
tptr += sl;
|
tptr += sl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add an integer to the text buffer */
|
/**/
|
||||||
|
static void
|
||||||
#if 0 /**/
|
taddlist(Estate state, int num)
|
||||||
void
|
|
||||||
taddint(int x)
|
|
||||||
{
|
{
|
||||||
char buf[DIGBUFSIZE];
|
if (num) {
|
||||||
|
while (num--) {
|
||||||
sprintf(buf, "%d", x);
|
taddstr(ecgetstr(state, 0));
|
||||||
taddstr(buf);
|
taddchr(' ');
|
||||||
|
}
|
||||||
|
tptr--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* add a newline, or something equivalent, to the text buffer */
|
/* add a newline, or something equivalent, to the text buffer */
|
||||||
|
|
||||||
|
|
@ -105,14 +105,24 @@ taddnl(void)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
mod_export char *
|
mod_export char *
|
||||||
getpermtext(struct node *n)
|
getpermtext(Eprog prog, Wordcode c)
|
||||||
{
|
{
|
||||||
|
struct estate s;
|
||||||
|
|
||||||
|
if (!c)
|
||||||
|
c = prog->prog;
|
||||||
|
|
||||||
|
s.prog = prog;
|
||||||
|
s.pc = c;
|
||||||
|
s.strs = prog->strs;
|
||||||
|
|
||||||
tnewlins = 1;
|
tnewlins = 1;
|
||||||
tbuf = (char *)zalloc(tsiz = 32);
|
tbuf = (char *)zalloc(tsiz = 32);
|
||||||
tptr = tbuf;
|
tptr = tbuf;
|
||||||
tlim = tbuf + tsiz;
|
tlim = tbuf + tsiz;
|
||||||
tindent = 1;
|
tindent = 1;
|
||||||
gettext2(n);
|
tjob = 0;
|
||||||
|
gettext2(&s);
|
||||||
*tptr = '\0';
|
*tptr = '\0';
|
||||||
untokenize(tbuf);
|
untokenize(tbuf);
|
||||||
return tbuf;
|
return tbuf;
|
||||||
|
|
@ -122,366 +132,566 @@ getpermtext(struct node *n)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
char *
|
char *
|
||||||
getjobtext(struct node *n)
|
getjobtext(Eprog prog, Wordcode c)
|
||||||
{
|
{
|
||||||
static char jbuf[JOBTEXTSIZE];
|
static char jbuf[JOBTEXTSIZE];
|
||||||
|
|
||||||
|
struct estate s;
|
||||||
|
|
||||||
|
if (!c)
|
||||||
|
c = prog->prog;
|
||||||
|
|
||||||
|
s.prog = prog;
|
||||||
|
s.pc = c;
|
||||||
|
s.strs = prog->strs;
|
||||||
|
|
||||||
tnewlins = 0;
|
tnewlins = 0;
|
||||||
tbuf = NULL;
|
tbuf = NULL;
|
||||||
tptr = jbuf;
|
tptr = jbuf;
|
||||||
tlim = tptr + JOBTEXTSIZE - 1;
|
tlim = tptr + JOBTEXTSIZE - 1;
|
||||||
tindent = 1;
|
tindent = 1;
|
||||||
gettext2(n);
|
tjob = 1;
|
||||||
|
gettext2(&s);
|
||||||
*tptr = '\0';
|
*tptr = '\0';
|
||||||
untokenize(jbuf);
|
untokenize(jbuf);
|
||||||
return jbuf;
|
return jbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define gt2(X) gettext2((struct node *) (X))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
"gettext2" or "type checking and how to avoid it"
|
* gettext2() shows one way to walk through the word code without
|
||||||
an epic function by Paul Falstad
|
* recursion. We start by reading a word code and executing the
|
||||||
|
* action for it. Some codes have sub-structures (like, e.g. WC_FOR)
|
||||||
|
* and require something to be done after the sub-structure has been
|
||||||
|
* handled. For these codes a tstack structure which describes what
|
||||||
|
* has to be done is pushed onto a stack. Codes without sub-structures
|
||||||
|
* arrange for the next structure being taken from the stack so that
|
||||||
|
* the action for it is executed instead of the one for the next
|
||||||
|
* word code. If the stack is empty at this point, we have handled
|
||||||
|
* the whole structure we were called for.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _Cond(X) ((Cond) (X))
|
typedef struct tstack *Tstack;
|
||||||
#define _Cmd(X) ((Cmd) (X))
|
|
||||||
#define _Pline(X) ((Pline) (X))
|
struct tstack {
|
||||||
#define _Sublist(X) ((Sublist) (X))
|
Tstack prev;
|
||||||
#define _List(X) ((List) (X))
|
wordcode code;
|
||||||
#define _casecmd(X) ((struct casecmd *) (X))
|
int pop;
|
||||||
#define _ifcmd(X) ((struct ifcmd *) (X))
|
union {
|
||||||
#define _whilecmd(X) ((struct whilecmd *) (X))
|
struct {
|
||||||
|
LinkList list;
|
||||||
|
} _redir;
|
||||||
|
struct {
|
||||||
|
char *strs;
|
||||||
|
} _funcdef;
|
||||||
|
struct {
|
||||||
|
Wordcode end;
|
||||||
|
} _case;
|
||||||
|
struct {
|
||||||
|
int cond;
|
||||||
|
Wordcode end;
|
||||||
|
} _if;
|
||||||
|
struct {
|
||||||
|
int par;
|
||||||
|
} _cond;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Tstack tstack, tfree;
|
||||||
|
|
||||||
|
static Tstack
|
||||||
|
tpush(wordcode code, int pop)
|
||||||
|
{
|
||||||
|
Tstack s;
|
||||||
|
|
||||||
|
if ((s = tfree))
|
||||||
|
tfree = s->prev;
|
||||||
|
else
|
||||||
|
s = (Tstack) zalloc(sizeof(*s));
|
||||||
|
|
||||||
|
s->prev = tstack;
|
||||||
|
tstack = s;
|
||||||
|
s->code = code;
|
||||||
|
s->pop = pop;
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static void
|
static void
|
||||||
gettext2(struct node *n)
|
gettext2(Estate state)
|
||||||
{
|
{
|
||||||
Cmd nn;
|
Tstack s, n;
|
||||||
|
int stack = 0;
|
||||||
|
wordcode code;
|
||||||
|
|
||||||
if (!n || ((List) n) == &dummy_list)
|
while (1) {
|
||||||
|
if (stack) {
|
||||||
|
if (!(s = tstack))
|
||||||
return;
|
return;
|
||||||
switch (NT_TYPE(n->ntype)) {
|
if (s->pop) {
|
||||||
case N_LIST:
|
tstack = s->prev;
|
||||||
gt2(_List(n)->left);
|
s->prev = tfree;
|
||||||
if (_List(n)->type & Z_ASYNC) {
|
tfree = s;
|
||||||
|
}
|
||||||
|
code = s->code;
|
||||||
|
stack = 0;
|
||||||
|
} else {
|
||||||
|
s = NULL;
|
||||||
|
code = *state->pc++;
|
||||||
|
}
|
||||||
|
switch (wc_code(code)) {
|
||||||
|
case WC_LIST:
|
||||||
|
if (!s) {
|
||||||
|
tpush(code, (WC_LIST_TYPE(code) & Z_END));
|
||||||
|
stack = 0;
|
||||||
|
} else {
|
||||||
|
if (WC_LIST_TYPE(code) & Z_ASYNC) {
|
||||||
taddstr(" &");
|
taddstr(" &");
|
||||||
if (_List(n)->type & Z_DISOWN)
|
if (WC_LIST_TYPE(code) & Z_DISOWN)
|
||||||
taddstr("|");
|
taddstr("|");
|
||||||
}
|
}
|
||||||
if (_List(n)->right) {
|
if (!(stack = (WC_LIST_TYPE(code) & Z_END))) {
|
||||||
if (tnewlins)
|
if (tnewlins)
|
||||||
taddnl();
|
taddnl();
|
||||||
else
|
else
|
||||||
taddstr((_List(n)->type & Z_ASYNC) ? " " : "; ");
|
taddstr((WC_LIST_TYPE(code) & Z_ASYNC) ? " " : "; ");
|
||||||
gt2(_List(n)->right);
|
s->code = *state->pc++;
|
||||||
|
s->pop = (WC_LIST_TYPE(s->code) & Z_END);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case N_SUBLIST:
|
case WC_SUBLIST:
|
||||||
if (_Sublist(n)->flags & PFLAG_NOT)
|
if (!s) {
|
||||||
|
if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT)
|
||||||
taddstr("! ");
|
taddstr("! ");
|
||||||
if (_Sublist(n)->flags & PFLAG_COPROC)
|
if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_COPROC)
|
||||||
taddstr("coproc ");
|
taddstr("coproc ");
|
||||||
gt2(_Sublist(n)->left);
|
tpush(code, (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END));
|
||||||
if (_Sublist(n)->right) {
|
} else {
|
||||||
taddstr((_Sublist(n)->type == ORNEXT) ? " || " : " && ");
|
if (!(stack = (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END))) {
|
||||||
gt2(_Sublist(n)->right);
|
taddstr((WC_SUBLIST_TYPE(code) == WC_SUBLIST_OR) ?
|
||||||
|
" || " : " && ");
|
||||||
|
s->code = *state->pc++;
|
||||||
|
s->pop = (WC_SUBLIST_TYPE(s->code) == WC_SUBLIST_END);
|
||||||
|
if (WC_SUBLIST_FLAGS(s->code) & WC_SUBLIST_NOT)
|
||||||
|
taddstr("! ");
|
||||||
|
if (WC_SUBLIST_FLAGS(s->code) & WC_SUBLIST_COPROC)
|
||||||
|
taddstr("coproc ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case N_PLINE:
|
case WC_PIPE:
|
||||||
gt2(_Pline(n)->left);
|
if (!s) {
|
||||||
if (_Pline(n)->type == PIPE) {
|
tpush(code, (WC_PIPE_TYPE(code) == WC_PIPE_END));
|
||||||
|
if (WC_PIPE_TYPE(code) == WC_PIPE_MID)
|
||||||
|
state->pc++;
|
||||||
|
} else {
|
||||||
|
if (!(stack = (WC_PIPE_TYPE(code) == WC_PIPE_END))) {
|
||||||
taddstr(" | ");
|
taddstr(" | ");
|
||||||
gt2(_Pline(n)->right);
|
s->code = *state->pc++;
|
||||||
|
if (!(s->pop = (WC_PIPE_TYPE(s->code) == WC_PIPE_END)))
|
||||||
|
state->pc++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case N_CMD:
|
case WC_REDIR:
|
||||||
nn = _Cmd(n);
|
if (!s) {
|
||||||
switch (nn->type) {
|
state->pc--;
|
||||||
case SIMPLE:
|
n = tpush(code, 1);
|
||||||
getsimptext(nn);
|
n->u._redir.list = ecgetredirs(state);
|
||||||
|
} else {
|
||||||
|
getredirs(s->u._redir.list);
|
||||||
|
stack = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SUBSH:
|
case WC_ASSIGN:
|
||||||
|
taddstr(ecgetstr(state, 0));
|
||||||
|
taddchr('=');
|
||||||
|
if (WC_ASSIGN_TYPE(code) == WC_ASSIGN_ARRAY) {
|
||||||
|
taddchr('(');
|
||||||
|
taddlist(state, WC_ASSIGN_NUM(code));
|
||||||
|
taddstr(") ");
|
||||||
|
} else {
|
||||||
|
taddstr(ecgetstr(state, 0));
|
||||||
|
taddchr(' ');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WC_SIMPLE:
|
||||||
|
taddlist(state, WC_SIMPLE_ARGC(code));
|
||||||
|
stack = 1;
|
||||||
|
break;
|
||||||
|
case WC_SUBSH:
|
||||||
|
if (!s) {
|
||||||
taddstr("( ");
|
taddstr("( ");
|
||||||
tindent++;
|
tindent++;
|
||||||
gt2(nn->u.list);
|
tpush(code, 1);
|
||||||
|
} else {
|
||||||
tindent--;
|
tindent--;
|
||||||
taddstr(" )");
|
taddstr(" )");
|
||||||
|
stack = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ZCTIME:
|
case WC_CURSH:
|
||||||
taddstr("time ");
|
if (!s) {
|
||||||
|
taddstr("{ ");
|
||||||
tindent++;
|
tindent++;
|
||||||
gt2(nn->u.pline);
|
tpush(code, 1);
|
||||||
|
} else {
|
||||||
tindent--;
|
tindent--;
|
||||||
|
taddstr(" }");
|
||||||
|
stack = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FUNCDEF:
|
case WC_TIMED:
|
||||||
taddlist(nn->args);
|
if (!s) {
|
||||||
|
taddstr("time");
|
||||||
|
if (WC_TIMED_TYPE(code) == WC_TIMED_PIPE) {
|
||||||
|
taddchr(' ');
|
||||||
|
tindent++;
|
||||||
|
tpush(code, 1);
|
||||||
|
} else
|
||||||
|
stack = 1;
|
||||||
|
} else {
|
||||||
|
tindent--;
|
||||||
|
stack = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WC_FUNCDEF:
|
||||||
|
if (!s) {
|
||||||
|
Wordcode p = state->pc;
|
||||||
|
Wordcode end = p + WC_FUNCDEF_SKIP(code);
|
||||||
|
|
||||||
|
taddlist(state, *state->pc++);
|
||||||
|
if (tjob) {
|
||||||
|
taddstr(" () { ... }");
|
||||||
|
state->pc = end;
|
||||||
|
stack = 1;
|
||||||
|
} else {
|
||||||
taddstr(" () {");
|
taddstr(" () {");
|
||||||
tindent++;
|
tindent++;
|
||||||
taddnl();
|
taddnl();
|
||||||
gt2(nn->u.list);
|
n = tpush(code, 1);
|
||||||
|
n->u._funcdef.strs = state->strs;
|
||||||
|
state->strs = (char *) (p + (*state->pc));
|
||||||
|
state->pc += 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state->strs = s->u._funcdef.strs;
|
||||||
tindent--;
|
tindent--;
|
||||||
taddnl();
|
taddnl();
|
||||||
taddstr("}");
|
taddstr("}");
|
||||||
|
stack = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CURSH:
|
case WC_FOR:
|
||||||
taddstr("{ ");
|
if (!s) {
|
||||||
tindent++;
|
taddstr("for ");
|
||||||
gt2(nn->u.list);
|
if (WC_FOR_TYPE(code) == WC_FOR_COND) {
|
||||||
tindent--;
|
|
||||||
taddstr(" }");
|
|
||||||
break;
|
|
||||||
case CFOR:
|
|
||||||
case CSELECT:
|
|
||||||
taddstr((nn->type == CFOR) ? "for " : "select ");
|
|
||||||
if (nn->u.forcmd->condition) {
|
|
||||||
taddstr("((");
|
taddstr("((");
|
||||||
taddstr(nn->u.forcmd->name);
|
taddstr(ecgetstr(state, 0));
|
||||||
taddstr("; ");
|
taddstr("; ");
|
||||||
taddstr(nn->u.forcmd->condition);
|
taddstr(ecgetstr(state, 0));
|
||||||
taddstr("; ");
|
taddstr("; ");
|
||||||
taddstr(nn->u.forcmd->advance);
|
taddstr(ecgetstr(state, 0));
|
||||||
taddstr(")) do");
|
taddstr(")) do");
|
||||||
} else {
|
} else {
|
||||||
taddstr(nn->u.forcmd->name);
|
taddstr(ecgetstr(state, 0));
|
||||||
if (nn->u.forcmd->inflag) {
|
if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
|
||||||
taddstr(" in ");
|
taddstr(" in ");
|
||||||
taddlist(nn->args);
|
taddlist(state, *state->pc++);
|
||||||
}
|
}
|
||||||
taddnl();
|
taddnl();
|
||||||
taddstr("do");
|
taddstr("do");
|
||||||
}
|
}
|
||||||
tindent++;
|
tindent++;
|
||||||
taddnl();
|
taddnl();
|
||||||
gt2(nn->u.forcmd->list);
|
tpush(code, 1);
|
||||||
|
} else {
|
||||||
tindent--;
|
tindent--;
|
||||||
taddnl();
|
taddnl();
|
||||||
taddstr("done");
|
taddstr("done");
|
||||||
|
stack = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CIF:
|
case WC_SELECT:
|
||||||
gt2(nn->u.ifcmd);
|
if (!s) {
|
||||||
taddstr("fi");
|
taddstr("select ");
|
||||||
|
taddstr(ecgetstr(state, 0));
|
||||||
|
if (WC_SELECT_TYPE(code) == WC_SELECT_LIST) {
|
||||||
|
taddstr(" in ");
|
||||||
|
taddlist(state, *state->pc++);
|
||||||
|
}
|
||||||
|
tindent++;
|
||||||
|
taddnl();
|
||||||
|
tpush(code, 1);
|
||||||
|
} else {
|
||||||
|
tindent--;
|
||||||
|
taddnl();
|
||||||
|
taddstr("done");
|
||||||
|
stack = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CCASE:
|
case WC_WHILE:
|
||||||
gt2(nn->u.casecmd);
|
if (!s) {
|
||||||
|
taddstr(WC_WHILE_TYPE(code) == WC_WHILE_UNTIL ?
|
||||||
|
"until " : "while ");
|
||||||
|
tindent++;
|
||||||
|
tpush(code, 0);
|
||||||
|
} else if (!s->pop) {
|
||||||
|
tindent--;
|
||||||
|
taddnl();
|
||||||
|
taddstr("do");
|
||||||
|
tindent++;
|
||||||
|
taddnl();
|
||||||
|
s->pop = 1;
|
||||||
|
} else {
|
||||||
|
tindent--;
|
||||||
|
taddnl();
|
||||||
|
taddstr("done");
|
||||||
|
stack = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case COND:
|
case WC_REPEAT:
|
||||||
taddstr("[[ ");
|
if (!s) {
|
||||||
gt2(nn->u.cond);
|
|
||||||
taddstr(" ]]");
|
|
||||||
break;
|
|
||||||
case CARITH:
|
|
||||||
taddstr("((");
|
|
||||||
taddlist(nn->args);
|
|
||||||
taddstr("))");
|
|
||||||
break;
|
|
||||||
case CREPEAT:
|
|
||||||
taddstr("repeat ");
|
taddstr("repeat ");
|
||||||
taddlist(nn->args);
|
taddstr(ecgetstr(state, 0));
|
||||||
taddnl();
|
taddnl();
|
||||||
taddstr("do");
|
taddstr("do");
|
||||||
tindent++;
|
tindent++;
|
||||||
taddnl();
|
taddnl();
|
||||||
gt2(nn->u.list);
|
tpush(code, 1);
|
||||||
|
} else {
|
||||||
tindent--;
|
tindent--;
|
||||||
taddnl();
|
taddnl();
|
||||||
taddstr("done");
|
taddstr("done");
|
||||||
break;
|
stack = 1;
|
||||||
case CWHILE:
|
|
||||||
gt2(nn->u.whilecmd);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
getredirs(nn);
|
|
||||||
break;
|
break;
|
||||||
case N_COND:
|
case WC_CASE:
|
||||||
getcond(_Cond(n), 0);
|
if (!s) {
|
||||||
break;
|
Wordcode end = state->pc + WC_CASE_SKIP(code);
|
||||||
case N_CASE:
|
|
||||||
{
|
|
||||||
List *l;
|
|
||||||
char **p;
|
|
||||||
|
|
||||||
l = _casecmd(n)->lists;
|
|
||||||
p = _casecmd(n)->pats;
|
|
||||||
|
|
||||||
taddstr("case ");
|
taddstr("case ");
|
||||||
taddstr(*p++);
|
taddstr(ecgetstr(state, 0));
|
||||||
taddstr(" in");
|
taddstr(" in");
|
||||||
tindent++;
|
|
||||||
for (; l && *l; p++, l++) {
|
if (state->pc >= end) {
|
||||||
if (tnewlins)
|
if (tnewlins)
|
||||||
taddnl();
|
taddnl();
|
||||||
else
|
else
|
||||||
taddchr(' ');
|
taddchr(' ');
|
||||||
taddstr(*p + 1);
|
taddstr("esac");
|
||||||
|
stack = 1;
|
||||||
|
} else {
|
||||||
|
tindent++;
|
||||||
|
if (tnewlins)
|
||||||
|
taddnl();
|
||||||
|
else
|
||||||
|
taddchr(' ');
|
||||||
|
code = *state->pc++;
|
||||||
|
taddstr(ecgetstr(state, 0));
|
||||||
|
state->pc++;
|
||||||
taddstr(") ");
|
taddstr(") ");
|
||||||
tindent++;
|
tindent++;
|
||||||
gt2(*l);
|
n = tpush(code, 0);
|
||||||
tindent--;
|
n->u._case.end = end;
|
||||||
taddstr(" ;");
|
n->pop = (state->pc - 2 + WC_CASE_SKIP(code) >= end);
|
||||||
taddchr(**p);
|
|
||||||
}
|
}
|
||||||
|
} else if (state->pc < s->u._case.end) {
|
||||||
|
tindent--;
|
||||||
|
taddstr(WC_CASE_TYPE(code) == WC_CASE_OR ? " ;;" : ";&");
|
||||||
|
if (tnewlins)
|
||||||
|
taddnl();
|
||||||
|
else
|
||||||
|
taddchr(' ');
|
||||||
|
code = *state->pc++;
|
||||||
|
taddstr(ecgetstr(state, 0));
|
||||||
|
state->pc++;
|
||||||
|
taddstr(") ");
|
||||||
|
tindent++;
|
||||||
|
s->code = code;
|
||||||
|
s->pop = ((state->pc - 2 + WC_CASE_SKIP(code)) >=
|
||||||
|
s->u._case.end);
|
||||||
|
} else {
|
||||||
|
tindent--;
|
||||||
|
taddstr(WC_CASE_TYPE(code) == WC_CASE_OR ? " ;;" : ";&");
|
||||||
tindent--;
|
tindent--;
|
||||||
if (tnewlins)
|
if (tnewlins)
|
||||||
taddnl();
|
taddnl();
|
||||||
else
|
else
|
||||||
taddchr(' ');
|
taddchr(' ');
|
||||||
taddstr("esac");
|
taddstr("esac");
|
||||||
break;
|
stack = 1;
|
||||||
}
|
}
|
||||||
case N_IF:
|
break;
|
||||||
{
|
case WC_IF:
|
||||||
List *i, *t;
|
if (!s) {
|
||||||
|
Wordcode end = state->pc + WC_IF_SKIP(code);
|
||||||
|
|
||||||
taddstr("if ");
|
taddstr("if ");
|
||||||
for (i = _ifcmd(n)->ifls, t = _ifcmd(n)->thenls; *i; i++, t++) {
|
|
||||||
tindent++;
|
tindent++;
|
||||||
gt2(*i);
|
state->pc++;
|
||||||
|
|
||||||
|
n = tpush(code, 0);
|
||||||
|
n->u._if.end = end;
|
||||||
|
n->u._if.cond = 1;
|
||||||
|
} else if (s->pop) {
|
||||||
|
stack = 1;
|
||||||
|
} else if (s->u._if.cond) {
|
||||||
tindent--;
|
tindent--;
|
||||||
taddnl();
|
taddnl();
|
||||||
taddstr("then");
|
taddstr("then");
|
||||||
tindent++;
|
tindent++;
|
||||||
taddnl();
|
taddnl();
|
||||||
gt2(*t);
|
s->u._if.cond = 0;
|
||||||
|
} else if (state->pc < s->u._if.end) {
|
||||||
tindent--;
|
tindent--;
|
||||||
taddnl();
|
taddnl();
|
||||||
if (i[1]) {
|
code = *state->pc++;
|
||||||
|
if (WC_IF_TYPE(code) == WC_IF_ELIF) {
|
||||||
taddstr("elif ");
|
taddstr("elif ");
|
||||||
}
|
tindent++;
|
||||||
}
|
s->u._if.cond = 1;
|
||||||
if (*t) {
|
} else {
|
||||||
taddstr("else");
|
taddstr("else");
|
||||||
tindent++;
|
tindent++;
|
||||||
taddnl();
|
taddnl();
|
||||||
gt2(*t);
|
}
|
||||||
|
} else {
|
||||||
|
s->pop = 1;
|
||||||
tindent--;
|
tindent--;
|
||||||
taddnl();
|
taddnl();
|
||||||
|
taddstr("fi");
|
||||||
|
stack = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case WC_COND:
|
||||||
case N_WHILE:
|
|
||||||
taddstr((_whilecmd(n)->cond) ? "until " : "while ");
|
|
||||||
tindent++;
|
|
||||||
gt2(_whilecmd(n)->cont);
|
|
||||||
tindent--;
|
|
||||||
taddnl();
|
|
||||||
taddstr("do");
|
|
||||||
tindent++;
|
|
||||||
taddnl();
|
|
||||||
gt2(_whilecmd(n)->loop);
|
|
||||||
tindent--;
|
|
||||||
taddnl();
|
|
||||||
taddstr("done");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print a condition bracketed by [[ ... ]]. *
|
|
||||||
* With addpar non-zero, parenthesise the subexpression. */
|
|
||||||
|
|
||||||
/**/
|
|
||||||
static void
|
|
||||||
getcond(Cond nm, int addpar)
|
|
||||||
{
|
|
||||||
static char *c1[] =
|
|
||||||
{
|
{
|
||||||
|
static char *c1[] = {
|
||||||
"=", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
|
"=", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
|
||||||
"-ne", "-lt", "-gt", "-le", "-ge"
|
"-ne", "-lt", "-gt", "-le", "-ge"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (addpar)
|
int ctype;
|
||||||
|
|
||||||
|
if (!s) {
|
||||||
|
taddstr("[[ ");
|
||||||
|
n = tpush(code, 1);
|
||||||
|
n->u._cond.par = 2;
|
||||||
|
} else if (s->u._cond.par == 2) {
|
||||||
|
taddstr(" ]]");
|
||||||
|
stack = 1;
|
||||||
|
break;
|
||||||
|
} else if (s->u._cond.par == 1) {
|
||||||
|
taddstr(" )");
|
||||||
|
stack = 1;
|
||||||
|
break;
|
||||||
|
} else if (WC_COND_TYPE(s->code) == COND_AND) {
|
||||||
|
taddstr(" && ");
|
||||||
|
code = *state->pc++;
|
||||||
|
if (WC_COND_TYPE(code) == COND_OR) {
|
||||||
taddstr("( ");
|
taddstr("( ");
|
||||||
switch (nm->type) {
|
n = tpush(code, 1);
|
||||||
|
n->u._cond.par = 1;
|
||||||
|
}
|
||||||
|
} else if (WC_COND_TYPE(s->code) == COND_OR) {
|
||||||
|
taddstr(" || ");
|
||||||
|
code = *state->pc++;
|
||||||
|
if (WC_COND_TYPE(code) == COND_AND) {
|
||||||
|
taddstr("( ");
|
||||||
|
n = tpush(code, 1);
|
||||||
|
n->u._cond.par = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!stack) {
|
||||||
|
switch ((ctype = WC_COND_TYPE(code))) {
|
||||||
case COND_NOT:
|
case COND_NOT:
|
||||||
taddstr("! ");
|
taddstr("! ");
|
||||||
getcond(nm->left, _Cond(nm->left)->type <= COND_OR);
|
code = *state->pc++;
|
||||||
|
if (WC_COND_TYPE(code) <= COND_OR) {
|
||||||
|
taddstr("( ");
|
||||||
|
n = tpush(code, 1);
|
||||||
|
n->u._cond.par = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case COND_AND:
|
case COND_AND:
|
||||||
getcond(nm->left, _Cond(nm->left)->type == COND_OR);
|
tpush(code, 1);
|
||||||
taddstr(" && ");
|
code = *state->pc++;
|
||||||
getcond(nm->right, _Cond(nm->right)->type == COND_OR);
|
if (WC_COND_TYPE(code) == COND_OR) {
|
||||||
|
taddstr("( ");
|
||||||
|
n = tpush(code, 1);
|
||||||
|
n->u._cond.par = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case COND_OR:
|
case COND_OR:
|
||||||
/* This is deliberately over-generous with parentheses: *
|
tpush(code, 1);
|
||||||
* in fact omitting them gives correct precedence. */
|
code = *state->pc++;
|
||||||
getcond(nm->left, _Cond(nm->left)->type == COND_AND);
|
if (WC_COND_TYPE(code) == COND_AND) {
|
||||||
taddstr(" || ");
|
taddstr("( ");
|
||||||
getcond(nm->right, _Cond(nm->right)->type == COND_AND);
|
n = tpush(code, 1);
|
||||||
|
n->u._cond.par = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case COND_MOD:
|
case COND_MOD:
|
||||||
{
|
taddstr(ecgetstr(state, 0));
|
||||||
/* Module defined prefix condition. */
|
taddlist(state, WC_COND_SKIP(code));
|
||||||
char **p = (char **) nm->right;
|
stack = 1;
|
||||||
|
|
||||||
taddstr(nm->left);
|
|
||||||
for (; *p; p++) {
|
|
||||||
taddstr(" ");
|
|
||||||
taddstr(*p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case COND_MODI:
|
case COND_MODI:
|
||||||
/* Module defined infix condition. */
|
{
|
||||||
taddstr(((char **) nm->right)[0]);
|
char *name = ecgetstr(state, 0);
|
||||||
taddstr(" ");
|
|
||||||
taddstr(nm->left);
|
taddstr(ecgetstr(state, 0));
|
||||||
taddstr(" ");
|
taddchr(' ');
|
||||||
taddstr(((char **) nm->right)[1]);
|
taddstr(name);
|
||||||
|
taddchr(' ');
|
||||||
|
taddstr(ecgetstr(state, 0));
|
||||||
|
stack = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (nm->type <= COND_GE) {
|
if (ctype <= COND_GE) {
|
||||||
/* Binary test: `a = b' etc. */
|
/* Binary test: `a = b' etc. */
|
||||||
taddstr(nm->left);
|
taddstr(ecgetstr(state, 0));
|
||||||
taddstr(" ");
|
taddstr(" ");
|
||||||
taddstr(c1[nm->type - COND_STREQ]);
|
taddstr(c1[ctype - COND_STREQ]);
|
||||||
taddstr(" ");
|
taddstr(" ");
|
||||||
taddstr(nm->right);
|
taddstr(ecgetstr(state, 0));
|
||||||
|
if (ctype == COND_STREQ ||
|
||||||
|
ctype == COND_STRNEQ)
|
||||||
|
state->pc++;
|
||||||
} else {
|
} else {
|
||||||
/* Unary test: `-f foo' etc. */
|
/* Unary test: `-f foo' etc. */
|
||||||
char c2[4];
|
char c2[4];
|
||||||
|
|
||||||
c2[0] = '-';
|
c2[0] = '-';
|
||||||
c2[1] = nm->type;
|
c2[1] = ctype;
|
||||||
c2[2] = ' ';
|
c2[2] = ' ';
|
||||||
c2[3] = '\0';
|
c2[3] = '\0';
|
||||||
taddstr(c2);
|
taddstr(c2);
|
||||||
taddstr(nm->left);
|
taddstr(ecgetstr(state, 0));
|
||||||
}
|
}
|
||||||
|
stack = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (addpar)
|
|
||||||
taddstr(" )");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**/
|
|
||||||
static void
|
|
||||||
getsimptext(Cmd cmd)
|
|
||||||
{
|
|
||||||
LinkNode n;
|
|
||||||
|
|
||||||
if (cmd->vars)
|
|
||||||
for (n = firstnode(cmd->vars); n; incnode(n)) {
|
|
||||||
struct varasg *v = (struct varasg *)getdata(n);
|
|
||||||
|
|
||||||
taddstr(v->name);
|
|
||||||
taddchr('=');
|
|
||||||
if (PM_TYPE(v->type) == PM_ARRAY) {
|
|
||||||
taddchr('(');
|
|
||||||
taddlist(v->arr);
|
|
||||||
taddstr(") ");
|
|
||||||
} else if (PM_TYPE(v->type) == PM_HASHED) {
|
|
||||||
/* XXX */
|
|
||||||
} else {
|
|
||||||
taddstr(v->str);
|
|
||||||
taddchr(' ');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taddlist(cmd->args);
|
break;
|
||||||
|
case WC_ARITH:
|
||||||
|
taddstr("((");
|
||||||
|
taddstr(ecgetstr(state, 0));
|
||||||
|
taddstr("))");
|
||||||
|
stack = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
getredirs(Cmd cmd)
|
getredirs(LinkList redirs)
|
||||||
{
|
{
|
||||||
LinkNode n;
|
LinkNode n;
|
||||||
static char *fstr[] =
|
static char *fstr[] =
|
||||||
|
|
@ -489,12 +699,9 @@ getredirs(Cmd cmd)
|
||||||
">", ">|", ">>", ">>|", "&>", "&>|", "&>>", "&>>|", "<>", "<",
|
">", ">|", ">>", ">>|", "&>", "&>|", "&>>", "&>>|", "<>", "<",
|
||||||
"<<", "<<-", "<<<", "<&", ">&", NULL /* >&- */, "<", ">"
|
"<<", "<<-", "<<<", "<&", ">&", NULL /* >&- */, "<", ">"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!cmd->redir)
|
|
||||||
return;
|
|
||||||
taddchr(' ');
|
taddchr(' ');
|
||||||
for (n = firstnode(cmd->redir); n; incnode(n)) {
|
for (n = firstnode(redirs); n; incnode(n)) {
|
||||||
struct redir *f = (struct redir *)getdata(n);
|
Redir f = (Redir) getdata(n);
|
||||||
|
|
||||||
switch (f->type) {
|
switch (f->type) {
|
||||||
case WRITE:
|
case WRITE:
|
||||||
|
|
@ -532,18 +739,3 @@ getredirs(Cmd cmd)
|
||||||
}
|
}
|
||||||
tptr--;
|
tptr--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
|
||||||
static void
|
|
||||||
taddlist(LinkList l)
|
|
||||||
{
|
|
||||||
LinkNode n;
|
|
||||||
|
|
||||||
if (!l || !(n = firstnode(l)))
|
|
||||||
return;
|
|
||||||
for (; n; incnode(n)) {
|
|
||||||
taddstr(getdata(n));
|
|
||||||
taddchr(' ');
|
|
||||||
}
|
|
||||||
tptr--;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
272
Src/utils.c
272
Src/utils.c
|
|
@ -630,7 +630,7 @@ preprompt(void)
|
||||||
{
|
{
|
||||||
static time_t lastperiodic;
|
static time_t lastperiodic;
|
||||||
LinkNode ln;
|
LinkNode ln;
|
||||||
List list;
|
Eprog prog;
|
||||||
int period = getiparam("PERIOD");
|
int period = getiparam("PERIOD");
|
||||||
int mailcheck = getiparam("MAILCHECK");
|
int mailcheck = getiparam("MAILCHECK");
|
||||||
|
|
||||||
|
|
@ -643,11 +643,11 @@ preprompt(void)
|
||||||
|
|
||||||
/* If a shell function named "precmd" exists, *
|
/* If a shell function named "precmd" exists, *
|
||||||
* then execute it. */
|
* then execute it. */
|
||||||
if ((list = getshfunc("precmd")) != &dummy_list) {
|
if ((prog = getshfunc("precmd")) != &dummy_eprog) {
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc("precmd", list, NULL, 0, 1);
|
doshfunc("precmd", prog, NULL, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
}
|
}
|
||||||
if (errflag)
|
if (errflag)
|
||||||
|
|
@ -657,11 +657,11 @@ preprompt(void)
|
||||||
* "periodic" exists, 3) it's been greater than PERIOD since we *
|
* "periodic" exists, 3) it's been greater than PERIOD since we *
|
||||||
* executed "periodic", then execute it now. */
|
* executed "periodic", then execute it now. */
|
||||||
if (period && (time(NULL) > lastperiodic + period) &&
|
if (period && (time(NULL) > lastperiodic + period) &&
|
||||||
(list = getshfunc("periodic")) != &dummy_list) {
|
(prog = getshfunc("periodic")) != &dummy_eprog) {
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc("periodic", list, NULL, 0, 1);
|
doshfunc("periodic", prog, NULL, 0, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
lastperiodic = time(NULL);
|
lastperiodic = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -1890,275 +1890,17 @@ sepsplit(char *s, char *sep, int allownull)
|
||||||
/* Get the definition of a shell function */
|
/* Get the definition of a shell function */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
mod_export List
|
mod_export Eprog
|
||||||
getshfunc(char *nam)
|
getshfunc(char *nam)
|
||||||
{
|
{
|
||||||
Shfunc shf;
|
Shfunc shf;
|
||||||
|
|
||||||
if (!(shf = (Shfunc) shfunctab->getnode(shfunctab, nam)))
|
if (!(shf = (Shfunc) shfunctab->getnode(shfunctab, nam)))
|
||||||
return &dummy_list;
|
return &dummy_eprog;
|
||||||
|
|
||||||
return shf->funcdef;
|
return shf->funcdef;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate a tree element */
|
|
||||||
|
|
||||||
static int sizetab[N_COUNT] = {
|
|
||||||
sizeof(struct list),
|
|
||||||
sizeof(struct sublist),
|
|
||||||
sizeof(struct pline),
|
|
||||||
sizeof(struct cmd),
|
|
||||||
sizeof(struct redir),
|
|
||||||
sizeof(struct cond),
|
|
||||||
sizeof(struct forcmd),
|
|
||||||
sizeof(struct casecmd),
|
|
||||||
sizeof(struct ifcmd),
|
|
||||||
sizeof(struct whilecmd),
|
|
||||||
sizeof(struct varasg),
|
|
||||||
sizeof(struct autofn),
|
|
||||||
};
|
|
||||||
|
|
||||||
static int offstab[N_COUNT] = {
|
|
||||||
offsetof(struct list, left),
|
|
||||||
offsetof(struct sublist, left),
|
|
||||||
offsetof(struct pline, left),
|
|
||||||
offsetof(struct cmd, u),
|
|
||||||
offsetof(struct redir, name),
|
|
||||||
offsetof(struct cond, left),
|
|
||||||
offsetof(struct forcmd, name),
|
|
||||||
offsetof(struct casecmd, pats),
|
|
||||||
offsetof(struct ifcmd, ifls),
|
|
||||||
offsetof(struct whilecmd, cont),
|
|
||||||
offsetof(struct varasg, name),
|
|
||||||
sizeof(struct autofn),
|
|
||||||
};
|
|
||||||
|
|
||||||
static int flagtab[N_COUNT] = {
|
|
||||||
NT_SET(N_LIST, NT_NODE, NT_NODE, 0, 0),
|
|
||||||
NT_SET(N_SUBLIST, NT_NODE, NT_NODE, 0, 0),
|
|
||||||
NT_SET(N_PLINE, NT_NODE, NT_NODE, 0, 0),
|
|
||||||
NT_SET(N_CMD, NT_NODE, NT_STR | NT_LIST, NT_NODE | NT_LIST, NT_NODE | NT_LIST),
|
|
||||||
NT_SET(N_REDIR, NT_STR, 0, 0, 0),
|
|
||||||
NT_SET(N_COND, NT_NODE, NT_NODE, NT_PAT, 0),
|
|
||||||
NT_SET(N_FOR, NT_STR, NT_STR, NT_STR, NT_NODE),
|
|
||||||
NT_SET(N_CASE, NT_STR | NT_ARR, NT_PAT | NT_ARR, NT_NODE | NT_ARR, 0),
|
|
||||||
NT_SET(N_IF, NT_NODE | NT_ARR, NT_NODE | NT_ARR, 0, 0),
|
|
||||||
NT_SET(N_WHILE, NT_NODE, NT_NODE, 0, 0),
|
|
||||||
NT_SET(N_VARASG, NT_STR, NT_STR, NT_STR | NT_LIST, 0),
|
|
||||||
NT_SET(N_AUTOFN, 0, 0, 0, 0),
|
|
||||||
};
|
|
||||||
|
|
||||||
/**/
|
|
||||||
void *
|
|
||||||
allocnode(int type)
|
|
||||||
{
|
|
||||||
struct node *n;
|
|
||||||
|
|
||||||
n = (struct node *) ncalloc(sizetab[type]);
|
|
||||||
memset((void *) n, 0, sizetab[type]);
|
|
||||||
n->ntype = flagtab[type];
|
|
||||||
|
|
||||||
return (void *) n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* duplicate a syntax tree */
|
|
||||||
|
|
||||||
/**/
|
|
||||||
mod_export void *
|
|
||||||
dupstruct(void *a)
|
|
||||||
{
|
|
||||||
void **onodes, **nnodes, *ret, *n, *on;
|
|
||||||
int type;
|
|
||||||
size_t nodeoffs;
|
|
||||||
|
|
||||||
if (!a || ((List) a) == &dummy_list)
|
|
||||||
return a;
|
|
||||||
type = *(int *)a;
|
|
||||||
ret = alloc(sizetab[NT_TYPE(type)]);
|
|
||||||
memcpy(ret, a, nodeoffs = offstab[NT_TYPE(type)]);
|
|
||||||
onodes = (void **) ((char *)a + nodeoffs);
|
|
||||||
nnodes = (void **) ((char *)ret + nodeoffs);
|
|
||||||
for (type = (type & 0xffff00) >> 4; (type >>= 4); *nnodes++ = n) {
|
|
||||||
if (!(on = *onodes++))
|
|
||||||
n = NULL;
|
|
||||||
else {
|
|
||||||
switch (type & 0xf) {
|
|
||||||
case NT_NODE:
|
|
||||||
n = dupstruct(on);
|
|
||||||
break;
|
|
||||||
case NT_STR:
|
|
||||||
n = dupstring(on);
|
|
||||||
break;
|
|
||||||
case NT_PAT:
|
|
||||||
n = duppatprog(on);
|
|
||||||
break;
|
|
||||||
case NT_LIST | NT_NODE:
|
|
||||||
n = duplist(on, (VFunc) dupstruct);
|
|
||||||
break;
|
|
||||||
case NT_LIST | NT_STR:
|
|
||||||
n = duplist(on, (VFunc) (useheap ? dupstring : ztrdup));
|
|
||||||
break;
|
|
||||||
case NT_LIST | NT_PAT:
|
|
||||||
n = duplist(on, (VFunc) duppatprog);
|
|
||||||
break;
|
|
||||||
case NT_NODE | NT_ARR:
|
|
||||||
n = duparray(on, (VFunc) dupstruct);
|
|
||||||
break;
|
|
||||||
case NT_STR | NT_ARR:
|
|
||||||
n = duparray(on, (VFunc) (useheap ? dupstring : ztrdup));
|
|
||||||
break;
|
|
||||||
case NT_PAT | NT_ARR:
|
|
||||||
n = duparray(on, (VFunc) duppatprog);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DPUTS(1, "BUG: bad node type in dupstruct()");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free a syntax tree. Now, freestruct() only registers everything that
|
|
||||||
* has to be freed. Later, freestructs() will be called to do the real
|
|
||||||
* work. This is to avoid having functions that are currently executed
|
|
||||||
* free themselves by re-defining themselves. */
|
|
||||||
|
|
||||||
static LinkList freeslist = NULL;
|
|
||||||
|
|
||||||
/**/
|
|
||||||
mod_export void
|
|
||||||
freestruct(void *a)
|
|
||||||
{
|
|
||||||
if (!a || ((List) a) == &dummy_list)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PERMALLOC {
|
|
||||||
if (!freeslist)
|
|
||||||
freeslist = newlinklist();
|
|
||||||
addlinknode(freeslist, a);
|
|
||||||
} LASTALLOC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**/
|
|
||||||
void
|
|
||||||
freestructs(void)
|
|
||||||
{
|
|
||||||
void *a;
|
|
||||||
|
|
||||||
if (freeslist)
|
|
||||||
while ((a = getlinknode(freeslist)))
|
|
||||||
ifreestruct(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**/
|
|
||||||
static void
|
|
||||||
ifreestruct(void *a)
|
|
||||||
{
|
|
||||||
void **nodes, *n;
|
|
||||||
int type, size;
|
|
||||||
|
|
||||||
type = *(int *) a;
|
|
||||||
nodes = (void **) ((char *)a + offstab[NT_TYPE(type)]);
|
|
||||||
size = sizetab[NT_TYPE(type)];
|
|
||||||
for (type = (type & 0xffff00) >> 4; (type >>= 4);) {
|
|
||||||
if ((n = *nodes++)) {
|
|
||||||
switch (type & 0xf) {
|
|
||||||
case NT_NODE:
|
|
||||||
freestruct(n);
|
|
||||||
break;
|
|
||||||
case NT_STR:
|
|
||||||
zsfree((char *) n);
|
|
||||||
break;
|
|
||||||
case NT_PAT:
|
|
||||||
freepatprog((Patprog) n);
|
|
||||||
break;
|
|
||||||
case NT_LIST | NT_NODE:
|
|
||||||
freelinklist((LinkList) n, (FreeFunc) freestruct);
|
|
||||||
break;
|
|
||||||
case NT_LIST | NT_STR:
|
|
||||||
freelinklist((LinkList) n, (FreeFunc) zsfree);
|
|
||||||
break;
|
|
||||||
case NT_LIST | NT_PAT:
|
|
||||||
freelinklist((LinkList) n, (FreeFunc) freepatprog);
|
|
||||||
break;
|
|
||||||
case NT_NODE | NT_ARR:
|
|
||||||
{
|
|
||||||
void **p = (void **) n;
|
|
||||||
|
|
||||||
while (*p)
|
|
||||||
freestruct(*p++);
|
|
||||||
zfree(n, sizeof(void *) * (p + 1 - (void **) n));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NT_STR | NT_ARR:
|
|
||||||
freearray((char **) n);
|
|
||||||
break;
|
|
||||||
case NT_PAT | NT_ARR:
|
|
||||||
{
|
|
||||||
Patprog *p = (Patprog *) n;
|
|
||||||
|
|
||||||
while (*p)
|
|
||||||
freepatprog(*p++);
|
|
||||||
zfree(n, sizeof(void *) * ((void **) p + 1 - (void **) n));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
DPUTS(1, "BUG: bad node type in freenode()");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
DPUTS(size != ((char *) nodes) - ((char *) a),
|
|
||||||
"BUG: size wrong in freenode()");
|
|
||||||
#endif
|
|
||||||
zfree(a, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**/
|
|
||||||
LinkList
|
|
||||||
dupheaplist(LinkList l)
|
|
||||||
{
|
|
||||||
if (!l)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return duplist(l, (VFunc) dupstruct);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**/
|
|
||||||
static LinkList
|
|
||||||
duplist(LinkList l, VFunc func)
|
|
||||||
{
|
|
||||||
if (l && nonempty(l)) {
|
|
||||||
LinkList ret;
|
|
||||||
LinkNode node;
|
|
||||||
|
|
||||||
ret = newlinklist();
|
|
||||||
for (node = firstnode(l); node; incnode(node))
|
|
||||||
addlinknode(ret, func(getdata(node)));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**/
|
|
||||||
mod_export char **
|
|
||||||
duparray(char **arr, VFunc func)
|
|
||||||
{
|
|
||||||
if (arr && *arr) {
|
|
||||||
char **ret, **rr, *p;
|
|
||||||
|
|
||||||
ret = (char **) alloc((arrlen(arr) + 1) * sizeof(char *));
|
|
||||||
for (rr = ret; (p = *arr++);)
|
|
||||||
*rr++ = (char *)func(p);
|
|
||||||
*rr = NULL;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
char **
|
char **
|
||||||
mkarray(char *s)
|
mkarray(char *s)
|
||||||
|
|
|
||||||
348
Src/zsh.h
348
Src/zsh.h
|
|
@ -306,20 +306,12 @@ typedef struct patprog *Patprog;
|
||||||
typedef struct process *Process;
|
typedef struct process *Process;
|
||||||
typedef struct job *Job;
|
typedef struct job *Job;
|
||||||
typedef struct value *Value;
|
typedef struct value *Value;
|
||||||
typedef struct varasg *Varasg;
|
|
||||||
typedef struct cond *Cond;
|
|
||||||
typedef struct conddef *Conddef;
|
typedef struct conddef *Conddef;
|
||||||
typedef struct cmd *Cmd;
|
|
||||||
typedef struct pline *Pline;
|
|
||||||
typedef struct sublist *Sublist;
|
|
||||||
typedef struct list *List;
|
|
||||||
typedef struct redir *Redir;
|
typedef struct redir *Redir;
|
||||||
typedef struct complist *Complist;
|
typedef struct complist *Complist;
|
||||||
typedef struct heap *Heap;
|
typedef struct heap *Heap;
|
||||||
typedef struct heapstack *Heapstack;
|
typedef struct heapstack *Heapstack;
|
||||||
typedef struct histent *Histent;
|
typedef struct histent *Histent;
|
||||||
typedef struct forcmd *Forcmd;
|
|
||||||
typedef struct autofn *AutoFn;
|
|
||||||
typedef struct hookdef *Hookdef;
|
typedef struct hookdef *Hookdef;
|
||||||
|
|
||||||
typedef struct asgment *Asgment;
|
typedef struct asgment *Asgment;
|
||||||
|
|
@ -365,52 +357,6 @@ struct linklist {
|
||||||
/* Definitions for syntax trees */
|
/* Definitions for syntax trees */
|
||||||
/********************************/
|
/********************************/
|
||||||
|
|
||||||
/* struct list, struct sublist, struct pline, etc. all fit the form *
|
|
||||||
* of this structure and are used interchangably. The ptrs may hold *
|
|
||||||
* integers or pointers, depending on the type of the node. */
|
|
||||||
|
|
||||||
/* Generic node structure for syntax trees */
|
|
||||||
struct node {
|
|
||||||
int ntype; /* node type */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define N_LIST 0
|
|
||||||
#define N_SUBLIST 1
|
|
||||||
#define N_PLINE 2
|
|
||||||
#define N_CMD 3
|
|
||||||
#define N_REDIR 4
|
|
||||||
#define N_COND 5
|
|
||||||
#define N_FOR 6
|
|
||||||
#define N_CASE 7
|
|
||||||
#define N_IF 8
|
|
||||||
#define N_WHILE 9
|
|
||||||
#define N_VARASG 10
|
|
||||||
#define N_AUTOFN 11
|
|
||||||
#define N_COUNT 12
|
|
||||||
|
|
||||||
/* values for types[4] */
|
|
||||||
|
|
||||||
#define NT_EMPTY 0
|
|
||||||
#define NT_NODE 1
|
|
||||||
#define NT_STR 2
|
|
||||||
#define NT_PAT 3
|
|
||||||
#define NT_LIST 4
|
|
||||||
#define NT_ARR 8
|
|
||||||
|
|
||||||
#define NT_TYPE(T) ((T) & 0xff)
|
|
||||||
#define NT_N(T, N) (((T) >> (8 + (N) * 4)) & 0xf)
|
|
||||||
#define NT_SET(T0, T1, T2, T3, T4) \
|
|
||||||
((T0) | ((T1) << 8) | ((T2) << 12) | ((T3) << 16) | ((T4) << 20))
|
|
||||||
|
|
||||||
/* tree element for lists */
|
|
||||||
|
|
||||||
struct list {
|
|
||||||
int ntype; /* node type */
|
|
||||||
int type;
|
|
||||||
Sublist left;
|
|
||||||
List right;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* These are control flags that are passed *
|
/* These are control flags that are passed *
|
||||||
* down the execution pipeline. */
|
* down the execution pipeline. */
|
||||||
#define Z_TIMED (1<<0) /* pipeline is being timed */
|
#define Z_TIMED (1<<0) /* pipeline is being timed */
|
||||||
|
|
@ -418,95 +364,9 @@ struct list {
|
||||||
#define Z_ASYNC (1<<2) /* run this sublist asynchronously (&) */
|
#define Z_ASYNC (1<<2) /* run this sublist asynchronously (&) */
|
||||||
#define Z_DISOWN (1<<3) /* run this sublist without job control (&|) */
|
#define Z_DISOWN (1<<3) /* run this sublist without job control (&|) */
|
||||||
|
|
||||||
/* tree element for sublists */
|
|
||||||
|
|
||||||
struct sublist {
|
|
||||||
int ntype; /* node type */
|
|
||||||
int type;
|
|
||||||
int flags; /* see PFLAGs below */
|
|
||||||
Pline left;
|
|
||||||
Sublist right;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ORNEXT 10 /* || */
|
|
||||||
#define ANDNEXT 11 /* && */
|
|
||||||
|
|
||||||
#define PFLAG_NOT 1 /* ! ... */
|
|
||||||
#define PFLAG_COPROC 32 /* coproc ... */
|
|
||||||
|
|
||||||
/* tree element for pipes */
|
|
||||||
|
|
||||||
struct pline {
|
|
||||||
int ntype; /* node type */
|
|
||||||
int type;
|
|
||||||
Cmd left;
|
|
||||||
Pline right;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define END 0 /* pnode *right is null */
|
|
||||||
#define PIPE 1 /* pnode *right is the rest of the pipeline */
|
|
||||||
|
|
||||||
/* tree element for commands */
|
|
||||||
|
|
||||||
struct cmd {
|
|
||||||
int ntype; /* node type */
|
|
||||||
int type;
|
|
||||||
int flags; /* see CFLAGs below */
|
|
||||||
int lineno; /* lineno of script for command */
|
|
||||||
union {
|
|
||||||
List list; /* for SUBSH/CURSH/SHFUNC */
|
|
||||||
Forcmd forcmd;
|
|
||||||
struct casecmd *casecmd;
|
|
||||||
struct ifcmd *ifcmd;
|
|
||||||
struct whilecmd *whilecmd;
|
|
||||||
Sublist pline;
|
|
||||||
Cond cond;
|
|
||||||
AutoFn autofn;
|
|
||||||
void *generic;
|
|
||||||
} u;
|
|
||||||
LinkList args; /* command & argmument List (char *'s) */
|
|
||||||
LinkList redir; /* i/o redirections (struct redir *'s) */
|
|
||||||
LinkList vars; /* param assignments (struct varasg *'s) */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* cmd types */
|
|
||||||
#define SIMPLE 0
|
|
||||||
#define SUBSH 1
|
|
||||||
#define CURSH 2
|
|
||||||
#define ZCTIME 3
|
|
||||||
#define FUNCDEF 4
|
|
||||||
#define CFOR 5
|
|
||||||
#define CWHILE 6
|
|
||||||
#define CREPEAT 7
|
|
||||||
#define CIF 8
|
|
||||||
#define CCASE 9
|
|
||||||
#define CSELECT 10
|
|
||||||
#define COND 11
|
|
||||||
#define CARITH 12
|
|
||||||
#define AUTOFN 13
|
|
||||||
|
|
||||||
/* flags for command modifiers */
|
/* flags for command modifiers */
|
||||||
#define CFLAG_EXEC (1<<0) /* exec ... */
|
#define CFLAG_EXEC (1<<0) /* exec ... */
|
||||||
|
|
||||||
/* tree element for redirection lists */
|
|
||||||
|
|
||||||
struct redir {
|
|
||||||
int ntype; /* node type */
|
|
||||||
int type;
|
|
||||||
int fd1, fd2;
|
|
||||||
char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* tree element for conditionals */
|
|
||||||
|
|
||||||
struct cond {
|
|
||||||
int ntype; /* node type */
|
|
||||||
int type; /* can be cond_type, or a single */
|
|
||||||
/* letter (-a, -b, ...) */
|
|
||||||
void *left, *right;
|
|
||||||
Patprog prog; /* compiled pattern for `==' and `!=' */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define COND_NOT 0
|
#define COND_NOT 0
|
||||||
#define COND_AND 1
|
#define COND_AND 1
|
||||||
#define COND_OR 2
|
#define COND_OR 2
|
||||||
|
|
@ -545,42 +405,12 @@ struct conddef {
|
||||||
#define CONDDEF(name, flags, handler, min, max, condid) \
|
#define CONDDEF(name, flags, handler, min, max, condid) \
|
||||||
{ NULL, name, flags, handler, min, max, condid, NULL }
|
{ NULL, name, flags, handler, min, max, condid, NULL }
|
||||||
|
|
||||||
struct forcmd { /* for/select */
|
/* tree element for redirection lists */
|
||||||
/* Cmd->args contains list of words to loop thru */
|
|
||||||
int ntype; /* node type */
|
|
||||||
int inflag; /* if there is an in ... clause */
|
|
||||||
char *name; /* initializer or parameter name */
|
|
||||||
char *condition; /* arithmetic terminating condition */
|
|
||||||
char *advance; /* evaluated after each loop */
|
|
||||||
List list; /* list to look through for each name */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct casecmd {
|
struct redir {
|
||||||
/* Cmd->args contains word to test */
|
int type;
|
||||||
int ntype; /* node type */
|
int fd1, fd2;
|
||||||
char **pats; /* pattern strings */
|
char *name;
|
||||||
Patprog *progs; /* compiled patterns (on demand) */
|
|
||||||
List *lists; /* list to execute */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ifcmd {
|
|
||||||
int ntype; /* node type */
|
|
||||||
List *ifls;
|
|
||||||
List *thenls;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct whilecmd {
|
|
||||||
int ntype; /* node type */
|
|
||||||
int cond; /* 0 for while, 1 for until */
|
|
||||||
List cont; /* condition */
|
|
||||||
List loop; /* list to execute until condition met */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* node for autoloading functions */
|
|
||||||
|
|
||||||
struct autofn {
|
|
||||||
int ntype; /* node type */
|
|
||||||
Shfunc shf; /* the shell function to define */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The number of fds space is allocated for *
|
/* The number of fds space is allocated for *
|
||||||
|
|
@ -602,14 +432,12 @@ struct multio {
|
||||||
int fds[MULTIOUNIT]; /* list of src/dests redirected to/from this fd */
|
int fds[MULTIOUNIT]; /* list of src/dests redirected to/from this fd */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* variable assignment tree element */
|
/* structure for foo=bar assignments */
|
||||||
|
|
||||||
struct varasg {
|
struct asgment {
|
||||||
int ntype; /* node type */
|
struct asgment *next;
|
||||||
int type; /* nonzero means array */
|
|
||||||
char *name;
|
char *name;
|
||||||
char *str; /* should've been a union here. oh well */
|
char *value;
|
||||||
LinkList arr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* lvalue for variable assignment/expansion */
|
/* lvalue for variable assignment/expansion */
|
||||||
|
|
@ -623,16 +451,152 @@ struct value {
|
||||||
char **arr; /* cache for hash turned into array */
|
char **arr; /* cache for hash turned into array */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* structure for foo=bar assignments */
|
|
||||||
|
|
||||||
struct asgment {
|
|
||||||
struct asgment *next;
|
|
||||||
char *name;
|
|
||||||
char *value;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_ARRLEN 262144
|
#define MAX_ARRLEN 262144
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Defintions for byte code */
|
||||||
|
/********************************************/
|
||||||
|
|
||||||
|
typedef unsigned int wordcode;
|
||||||
|
typedef wordcode *Wordcode;
|
||||||
|
|
||||||
|
typedef struct eprog *Eprog;
|
||||||
|
|
||||||
|
struct eprog {
|
||||||
|
int heap; /* != 0 if this is in heap memory */
|
||||||
|
int len; /* total block length */
|
||||||
|
int npats; /* Patprog cache size */
|
||||||
|
Patprog *pats; /* the memory block, the patterns */
|
||||||
|
Wordcode prog; /* memory block ctd, the code */
|
||||||
|
char *strs; /* memory block ctd, the strings */
|
||||||
|
Shfunc shf; /* shell function for autoload */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct estate *Estate;
|
||||||
|
|
||||||
|
struct estate {
|
||||||
|
Eprog prog; /* the eprog executed */
|
||||||
|
Wordcode pc; /* program counter, current pos */
|
||||||
|
char *strs; /* strings from prog */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define WC_CODEBITS 5
|
||||||
|
|
||||||
|
#define wc_code(C) ((C) & ((wordcode) ((1 << WC_CODEBITS) - 1)))
|
||||||
|
#define wc_data(C) ((C) >> WC_CODEBITS)
|
||||||
|
#define wc_bld(C, D) (((wordcode) (C)) | (((wordcode) (D)) << WC_CODEBITS))
|
||||||
|
|
||||||
|
#define WC_END 0
|
||||||
|
#define WC_LIST 1
|
||||||
|
#define WC_SUBLIST 2
|
||||||
|
#define WC_PIPE 3
|
||||||
|
#define WC_REDIR 4
|
||||||
|
#define WC_ASSIGN 5
|
||||||
|
#define WC_SIMPLE 6
|
||||||
|
#define WC_SUBSH 7
|
||||||
|
#define WC_CURSH 8
|
||||||
|
#define WC_TIMED 9
|
||||||
|
#define WC_FUNCDEF 10
|
||||||
|
#define WC_FOR 11
|
||||||
|
#define WC_SELECT 12
|
||||||
|
#define WC_WHILE 13
|
||||||
|
#define WC_REPEAT 14
|
||||||
|
#define WC_CASE 15
|
||||||
|
#define WC_IF 16
|
||||||
|
#define WC_COND 17
|
||||||
|
#define WC_ARITH 18
|
||||||
|
#define WC_AUTOFN 19
|
||||||
|
|
||||||
|
#define WCB_END() wc_bld(WC_END, 0)
|
||||||
|
|
||||||
|
#define WC_LIST_TYPE(C) wc_data(C)
|
||||||
|
#define Z_END (1<<4)
|
||||||
|
#define WCB_LIST(T) wc_bld(WC_LIST, (T))
|
||||||
|
|
||||||
|
#define WC_SUBLIST_TYPE(C) (wc_data(C) & ((wordcode) 3))
|
||||||
|
#define WC_SUBLIST_END 0
|
||||||
|
#define WC_SUBLIST_AND 1
|
||||||
|
#define WC_SUBLIST_OR 2
|
||||||
|
#define WC_SUBLIST_FLAGS(C) (wc_data(C) & ((wordcode) 12))
|
||||||
|
#define WC_SUBLIST_COPROC 4
|
||||||
|
#define WC_SUBLIST_NOT 8
|
||||||
|
#define WC_SUBLIST_SKIP(C) (wc_data(C) >> 4)
|
||||||
|
#define WCB_SUBLIST(T,F,O) wc_bld(WC_SUBLIST, ((T) | (F) | ((O) << 4)))
|
||||||
|
|
||||||
|
#define WC_PIPE_TYPE(C) (wc_data(C) & ((wordcode) 1))
|
||||||
|
#define WC_PIPE_END 0
|
||||||
|
#define WC_PIPE_MID 1
|
||||||
|
#define WC_PIPE_LINENO(C) (wc_data(C) >> 1)
|
||||||
|
#define WCB_PIPE(T,L) wc_bld(WC_PIPE, ((T) | ((L) << 1)))
|
||||||
|
|
||||||
|
#define WC_REDIR_TYPE(C) wc_data(C)
|
||||||
|
#define WCB_REDIR(T) wc_bld(WC_REDIR, (T))
|
||||||
|
|
||||||
|
#define WC_ASSIGN_TYPE(C) (wc_data(C) & ((wordcode) 1))
|
||||||
|
#define WC_ASSIGN_SCALAR 0
|
||||||
|
#define WC_ASSIGN_ARRAY 1
|
||||||
|
#define WC_ASSIGN_NUM(C) (wc_data(C) >> 1)
|
||||||
|
#define WCB_ASSIGN(T,N) wc_bld(WC_ASSIGN, ((T) | ((N) << 1)))
|
||||||
|
|
||||||
|
#define WC_SIMPLE_ARGC(C) wc_data(C)
|
||||||
|
#define WCB_SIMPLE(N) wc_bld(WC_SIMPLE, (N))
|
||||||
|
|
||||||
|
#define WCB_SUBSH() wc_bld(WC_SUBSH, 0)
|
||||||
|
|
||||||
|
#define WCB_CURSH() wc_bld(WC_CURSH, 0)
|
||||||
|
|
||||||
|
#define WC_TIMED_TYPE(C) wc_data(C)
|
||||||
|
#define WC_TIMED_EMPTY 0
|
||||||
|
#define WC_TIMED_PIPE 1
|
||||||
|
#define WCB_TIMED(T) wc_bld(WC_TIMED, (T))
|
||||||
|
|
||||||
|
#define WC_FUNCDEF_SKIP(C) wc_data(C)
|
||||||
|
#define WCB_FUNCDEF(O) wc_bld(WC_FUNCDEF, (O))
|
||||||
|
|
||||||
|
#define WC_FOR_TYPE(C) (wc_data(C) & 3)
|
||||||
|
#define WC_FOR_PPARAM 0
|
||||||
|
#define WC_FOR_LIST 1
|
||||||
|
#define WC_FOR_COND 2
|
||||||
|
#define WC_FOR_SKIP(C) (wc_data(C) >> 2)
|
||||||
|
#define WCB_FOR(T,O) wc_bld(WC_FOR, ((T) | ((O) << 2)))
|
||||||
|
|
||||||
|
#define WC_SELECT_TYPE(C) (wc_data(C) & 1)
|
||||||
|
#define WC_SELECT_PPARAM 0
|
||||||
|
#define WC_SELECT_LIST 1
|
||||||
|
#define WC_SELECT_SKIP(C) (wc_data(C) >> 1)
|
||||||
|
#define WCB_SELECT(T,O) wc_bld(WC_SELECT, ((T) | ((O) << 1)))
|
||||||
|
|
||||||
|
#define WC_WHILE_TYPE(C) (wc_data(C) & 1)
|
||||||
|
#define WC_WHILE_WHILE 0
|
||||||
|
#define WC_WHILE_UNTIL 1
|
||||||
|
#define WC_WHILE_SKIP(C) (wc_data(C) >> 1)
|
||||||
|
#define WCB_WHILE(T,O) wc_bld(WC_WHILE, ((T) | ((O) << 1)))
|
||||||
|
|
||||||
|
#define WC_REPEAT_SKIP(C) wc_data(C)
|
||||||
|
#define WCB_REPEAT(O) wc_bld(WC_REPEAT, (O))
|
||||||
|
|
||||||
|
#define WC_CASE_TYPE(C) (wc_data(C) & 3)
|
||||||
|
#define WC_CASE_HEAD 0
|
||||||
|
#define WC_CASE_OR 1
|
||||||
|
#define WC_CASE_AND 2
|
||||||
|
#define WC_CASE_SKIP(C) (wc_data(C) >> 2)
|
||||||
|
#define WCB_CASE(T,O) wc_bld(WC_CASE, ((T) | ((O) << 2)))
|
||||||
|
|
||||||
|
#define WC_IF_TYPE(C) (wc_data(C) & 3)
|
||||||
|
#define WC_IF_HEAD 0
|
||||||
|
#define WC_IF_IF 1
|
||||||
|
#define WC_IF_ELIF 2
|
||||||
|
#define WC_IF_ELSE 3
|
||||||
|
#define WC_IF_SKIP(C) (wc_data(C) >> 2)
|
||||||
|
#define WCB_IF(T,O) wc_bld(WC_IF, ((T) | ((O) << 2)))
|
||||||
|
|
||||||
|
#define WC_COND_TYPE(C) (wc_data(C) & 127)
|
||||||
|
#define WC_COND_SKIP(C) (wc_data(C) >> 7)
|
||||||
|
#define WCB_COND(T,O) wc_bld(WC_COND, ((T) | ((O) << 7)))
|
||||||
|
|
||||||
|
#define WCB_ARITH() wc_bld(WC_ARITH, 0)
|
||||||
|
|
||||||
|
#define WCB_AUTOFN() wc_bld(WC_AUTOFN, 0)
|
||||||
|
|
||||||
/********************************************/
|
/********************************************/
|
||||||
/* Defintions for job table and job control */
|
/* Defintions for job table and job control */
|
||||||
|
|
@ -845,7 +809,7 @@ struct shfunc {
|
||||||
HashNode next; /* next in hash chain */
|
HashNode next; /* next in hash chain */
|
||||||
char *nam; /* name of shell function */
|
char *nam; /* name of shell function */
|
||||||
int flags; /* various flags */
|
int flags; /* various flags */
|
||||||
List funcdef; /* function definition */
|
Eprog funcdef; /* function definition */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Shell function context types. */
|
/* Shell function context types. */
|
||||||
|
|
@ -860,7 +824,7 @@ struct shfunc {
|
||||||
|
|
||||||
/* node in list of function call wrappers */
|
/* node in list of function call wrappers */
|
||||||
|
|
||||||
typedef int (*WrapFunc) _((List, FuncWrap, char *));
|
typedef int (*WrapFunc) _((Eprog, FuncWrap, char *));
|
||||||
|
|
||||||
struct funcwrap {
|
struct funcwrap {
|
||||||
FuncWrap next;
|
FuncWrap next;
|
||||||
|
|
@ -996,7 +960,7 @@ struct patprog {
|
||||||
#define GF_MATCHREF 0x0800
|
#define GF_MATCHREF 0x0800
|
||||||
|
|
||||||
/* Dummy Patprog pointers. Used mainly in executions trees, but the
|
/* Dummy Patprog pointers. Used mainly in executions trees, but the
|
||||||
* pattern code needs to knwo about it, too. */
|
* pattern code needs to know about it, too. */
|
||||||
|
|
||||||
#define dummy_patprog1 ((Patprog) 1)
|
#define dummy_patprog1 ((Patprog) 1)
|
||||||
#define dummy_patprog2 ((Patprog) 2)
|
#define dummy_patprog2 ((Patprog) 2)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue