summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2011-06-19 20:12:00 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2011-06-19 20:12:00 +0000
commit6062529d3fc7c7d29c63d0726d2449d4b56f33ac (patch)
tree8131c4e1678053413559fe71159201f891786a70 /Src
parent437d5d98f6d05588e23a6d9fda50184d0b6a80bb (diff)
downloadzsh-6062529d3fc7c7d29c63d0726d2449d4b56f33ac.tar.gz
zsh-6062529d3fc7c7d29c63d0726d2449d4b56f33ac.zip
29492: add argument handling to anonymous functions
Diffstat (limited to 'Src')
-rw-r--r--Src/exec.c65
-rw-r--r--Src/parse.c30
-rw-r--r--Src/text.c30
3 files changed, 92 insertions, 33 deletions
diff --git a/Src/exec.c b/Src/exec.c
index 2558185c8..87a167ba6 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -50,20 +50,20 @@ int noerrexit;
* noerrs = 1: suppress error messages
* noerrs = 2: don't set errflag on parse error, either
*/
-
+
/**/
mod_export int noerrs;
-
+
/* do not save history on exec and exit */
/**/
int nohistsave;
-
+
/* error/break flag */
-
+
/**/
mod_export int errflag;
-
+
/*
* State of trap return value. Value is from enum trap_state.
*/
@@ -88,23 +88,23 @@ int trap_state;
* - non-negative in a trap once it was triggered. It should remain
* non-negative until restored after execution of the trap.
*/
-
+
/**/
int trap_return;
-
+
/* != 0 if this is a subshell */
-
+
/**/
int subsh;
-
+
/* != 0 if we have a return pending */
-
+
/**/
mod_export int retflag;
/**/
long lastval2;
-
+
/* The table of file descriptors. A table element is zero if the *
* corresponding fd is not used by the shell. It is greater than *
* 1 if the fd is used by a <(...) or >(...) substitution and 1 if *
@@ -148,12 +148,12 @@ int fdtable_flocks;
mod_export int zleactive;
/* pid of process undergoing 'process substitution' */
-
+
/**/
pid_t cmdoutpid;
-
+
/* exit status of process undergoing 'process substitution' */
-
+
/**/
int cmdoutval;
@@ -166,7 +166,7 @@ int cmdoutval;
/**/
int use_cmdoutval;
-/* The context in which a shell function is called, see SFC_* in zsh.h. */
+/* The context in which a shell function is called, see SFC_* in zsh.h. */
/**/
mod_export int sfcontext;
@@ -239,7 +239,7 @@ parse_string(char *s, int reset_lineno)
/**/
mod_export struct rlimit current_limits[RLIM_NLIMITS], limits[RLIM_NLIMITS];
-
+
/**/
mod_export int
zsetlimit(int limnum, char *nam)
@@ -340,7 +340,7 @@ zfork(struct timeval *tv)
*
* (when waiting for the grep, ignoring execpline2 for now). At this time,
* zsh has built two job-table entries for it: one for the cat and one for
- * the grep. If the user hits ^Z at this point (and jobbing is used), the
+ * the grep. If the user hits ^Z at this point (and jobbing is used), the
* shell is notified that the grep was suspended. The list_pipe flag is
* used to tell the execpline where it was waiting that it was in a pipeline
* with a shell construct at the end (which may also be a shell function or
@@ -351,7 +351,7 @@ zfork(struct timeval *tv)
* shell (its pid and the text for it) in the job entry of the cat. The pid
* is passed down in the list_pipe_pid variable.
* But there is a problem: the suspended grep is a child of the parent shell
- * and can't be adopted by the sub-shell. So the parent shell also has to
+ * and can't be adopted by the sub-shell. So the parent shell also has to
* keep the information about this process (more precisely: this pipeline)
* by keeping the job table entry it created for it. The fact that there
* are two jobs which have to be treated together is remembered by setting
@@ -528,10 +528,10 @@ isgooderr(int e, char *dir)
{
/*
* Maybe the directory was unreadable, or maybe it wasn't
- * even a directory.
+ * even a directory.
*/
return ((e != EACCES || !access(dir, X_OK)) &&
- e != ENOENT && e != ENOTDIR);
+ e != ENOENT && e != ENOTDIR);
}
/*
@@ -639,7 +639,7 @@ execute(LinkList args, int flags, int defpath)
break;
}
- /* for command -p, search the default path */
+ /* for command -p, search the default path */
if (defpath) {
char *s, pbuf[PATH_MAX];
char *dptr, *pe, *ps = DEFAULT_PATH;
@@ -676,7 +676,7 @@ execute(LinkList args, int flags, int defpath)
eno = ee;
} else {
-
+
if ((cn = (Cmdnam) cmdnamtab->getnode(cmdnamtab, arg0))) {
char nn[PATH_MAX], *dptr;
@@ -1312,9 +1312,9 @@ sublist_done:
donetrap = 1;
}
if (lastval) {
- int errreturn = isset(ERRRETURN) &&
+ int errreturn = isset(ERRRETURN) &&
(isset(INTERACTIVE) || locallevel || sourcelevel);
- int errexit = isset(ERREXIT) ||
+ int errexit = isset(ERREXIT) ||
(isset(ERRRETURN) && !errreturn);
if (errexit) {
if (sigtrapped[SIGEXIT])
@@ -1536,7 +1536,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
else if (pid) {
char dummy;
- lpforked =
+ lpforked =
(killpg(jobtab[list_pipe_job].gleader, 0) == -1 ? 2 : 1);
list_pipe_pid = pid;
list_pipe_start = bgtime;
@@ -3112,7 +3112,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
ESUB_PGRP | ESUB_FAKE;
if (type != WC_SUBSH)
flags |= ESUB_KEEPTRAP;
- if ((do_exec || (type >= WC_CURSH && last1 == 1))
+ if ((do_exec || (type >= WC_CURSH && last1 == 1))
&& !forked)
flags |= ESUB_REVERTPGRP;
entersubsh(flags);
@@ -4184,10 +4184,19 @@ execfuncdef(Estate state, UNUSED(int do_exec))
* Anonymous function, execute immediately.
* Function name is "(anon)", parameter list is empty.
*/
- LinkList args = newlinklist();
+ LinkList args;
+
+ state->pc = end;
+ end += *state->pc++;
+ args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok);
+
+ if (htok && args)
+ execsubst(args);
+ if (!args)
+ args = newlinklist();
shf->node.nam = "(anon)";
- addlinknode(args, shf->node.nam);
+ pushnode(args, shf->node.nam);
execshfunc(shf, args);
ret = lastval;
diff --git a/Src/parse.c b/Src/parse.c
index 4720dc3cf..5b6f09949 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -1480,12 +1480,25 @@ par_funcdef(void)
ecbuf[p + num + 4] = ecnpats;
ecbuf[p + 1] = num;
- lineno += oldlineno;
ecnpats = onp;
ecssub = oecssub;
ecnfunc++;
ecbuf[p] = WCB_FUNCDEF(ecused - 1 - p);
+
+ if (num == 0) {
+ /* Unnamed function */
+ int parg = ecadd(0);
+ ecadd(0);
+ while (tok == STRING) {
+ ecstr(tokstr);
+ num++;
+ zshlex();
+ }
+ ecbuf[parg] = ecused - parg; /*?*/
+ ecbuf[parg+1] = num;
+ }
+ lineno += oldlineno;
}
/*
@@ -1730,13 +1743,26 @@ par_simple(int *complex, int nr)
ecbuf[p + argc + 3] = ecsoffs - so;
ecbuf[p + argc + 4] = ecnpats;
- lineno += oldlineno;
ecnpats = onp;
ecssub = oecssub;
ecnfunc++;
ecbuf[p] = WCB_FUNCDEF(ecused - 1 - p);
+ if (argc == 0) {
+ /* Unnamed function */
+ int parg = ecadd(0);
+ ecadd(0);
+ while (tok == STRING) {
+ ecstr(tokstr);
+ argc++;
+ zshlex();
+ }
+ ecbuf[parg] = ecused - parg; /*?*/
+ ecbuf[parg+1] = argc;
+ }
+ lineno += oldlineno;
+
isfunc = 1;
isnull = 0;
break;
diff --git a/Src/text.c b/Src/text.c
index 669037a2d..f55553ed0 100644
--- a/Src/text.c
+++ b/Src/text.c
@@ -253,6 +253,7 @@ struct tstack {
struct {
char *strs;
Wordcode end;
+ int nargs;
} _funcdef;
struct {
Wordcode end;
@@ -456,19 +457,31 @@ gettext2(Estate state)
if (!s) {
Wordcode p = state->pc;
Wordcode end = p + WC_FUNCDEF_SKIP(code);
+ int nargs = *state->pc++;
- taddlist(state, *state->pc++);
+ taddlist(state, nargs);
+ if (nargs)
+ taddstr(" ");
if (tjob) {
- taddstr(" () { ... }");
+ taddstr("() { ... }");
state->pc = end;
+ if (!nargs) {
+ /*
+ * Unnamed fucntion.
+ * We're not going to pull any arguments off
+ * later, so skip them now...
+ */
+ state->pc += *end;
+ }
stack = 1;
} else {
- taddstr(" () {");
+ taddstr("() {");
tindent++;
taddnl(1);
n = tpush(code, 1);
n->u._funcdef.strs = state->strs;
n->u._funcdef.end = end;
+ n->u._funcdef.nargs = nargs;
state->strs += *state->pc;
state->pc += 3;
}
@@ -478,6 +491,17 @@ gettext2(Estate state)
dec_tindent();
taddnl(0);
taddstr("}");
+ if (s->u._funcdef.nargs == 0) {
+ /* Unnamed function with post-arguments */
+ int nargs;
+ s->u._funcdef.end += *state->pc++;
+ nargs = *state->pc++;
+ if (nargs) {
+ taddstr(" ");
+ taddlist(state, nargs);
+ }
+ state->pc = s->u._funcdef.end;
+ }
stack = 1;
}
break;