diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Zle/zle_main.c | 2 | ||||
-rw-r--r-- | Src/builtin.c | 4 | ||||
-rw-r--r-- | Src/exec.c | 11 | ||||
-rw-r--r-- | Src/hist.c | 68 | ||||
-rw-r--r-- | Src/init.c | 2 | ||||
-rw-r--r-- | Src/utils.c | 24 |
6 files changed, 71 insertions, 40 deletions
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 7fb6878da..f564b84ee 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -736,7 +736,7 @@ raw_getbyte(long do_keytmout, char *cptr) # endif - callhookfunc(lwatch_funcs[i], funcargs, 0); + callhookfunc(lwatch_funcs[i], funcargs, 0, NULL); if (errflag) { /* No sensible way of handling errors here */ errflag = 0; diff --git a/Src/builtin.c b/Src/builtin.c index af2c24fd6..c7ed283a9 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -1139,7 +1139,7 @@ cd_new_pwd(int func, LinkNode dir, int quiet) fflush(stdout); fflush(stderr); if (!quiet) - callhookfunc("chpwd", NULL, 1); + callhookfunc("chpwd", NULL, 1, NULL); dirstacksize = getiparam("DIRSTACKSIZE"); /* handle directory stack sizes out of range */ @@ -4578,7 +4578,7 @@ zexit(int val, int from_where) lastval = val; if (sigtrapped[SIGEXIT]) dotrap(SIGEXIT); - callhookfunc("zshexit", NULL, 1); + callhookfunc("zshexit", NULL, 1, NULL); runhookdef(EXITHOOK, NULL); if (opts[MONITOR] && interact && (SHTTY != -1)) { release_pgrp(); diff --git a/Src/exec.c b/Src/exec.c index 7ce657032..437a45c37 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4093,6 +4093,16 @@ loadautofn(Shfunc shf, int fksh, int autol) /* * execute a shell function * + * name is the name of the function + * + * prog is the code to execute + * + * doshargs, if set, are parameters to pass to the function, + * in which the first element is the function name (even if + * FUNCTIONARGZERO is set as this is handled inside this function). + * + * flags are a set of the PM_ flags associated with the function. + * * If noreturnval is nonzero, then reset the current return * value (lastval) to its value before the shell function * was executed. However, in any case return the status value @@ -4160,6 +4170,7 @@ doshfunc(char *name, Eprog prog, LinkList doshargs, int flags, int noreturnval) oargv0 = argzero; argzero = ztrdup(getdata(node)); } + /* first node contains name regardless of option */ node = node->next; for (; node; node = node->next, x++) *x = ztrdup(getdata(node)); diff --git a/Src/hist.c b/Src/hist.c index a1bc73636..f856eedff 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -130,8 +130,7 @@ mod_export int hist_skip_flags; /* Bits of histactive variable */ #define HA_ACTIVE (1<<0) /* History mechanism is active */ -#define HA_NOSTORE (1<<1) /* Don't store the line when finished */ -#define HA_NOINC (1<<2) /* Don't store, curhist not incremented */ +#define HA_NOINC (1<<1) /* Don't store, curhist not incremented */ /* Array of word beginnings and endings in current history line. */ @@ -180,6 +179,30 @@ int hlinesz; static zlong defev; +/* Remember the last line in the history file so we can find it again. */ +static struct histfile_stats { + char *text; + time_t stim, mtim; + off_t fpos, fsiz; + zlong next_write_ev; +} lasthist; + +static struct histsave { + struct histfile_stats lasthist; + char *histfile; + HashTable histtab; + Histent hist_ring; + zlong curhist; + zlong histlinect; + zlong histsiz; + zlong savehistsiz; + int locallevel; +} *histsave_stack; +static int histsave_stack_size = 0; +static int histsave_stack_pos = 0; + +static zlong histfile_linect; + /* add a character to the current history word */ static void @@ -1082,7 +1105,8 @@ should_ignore_line(Eprog prog) mod_export int hend(Eprog prog) { - int flag, save = 1; + LinkList hookargs = newlinklist(); + int flag, save = 1, hookret, stack_pos = histsave_stack_pos; char *hf; DPUTS(stophist != 2 && !(inbufflags & INP_ALIAS) && !chline, @@ -1092,7 +1116,7 @@ hend(Eprog prog) settyinfo(&shttyinfo); if (!(histactive & HA_NOINC)) unlinkcurline(); - if (histactive & (HA_NOSTORE|HA_NOINC)) { + if (histactive & HA_NOINC) { zfree(chline, hlinesz); zfree(chwords, chwordlen*sizeof(short)); chline = NULL; @@ -1103,6 +1127,10 @@ hend(Eprog prog) if (hist_ignore_all_dups != isset(HISTIGNOREALLDUPS) && (hist_ignore_all_dups = isset(HISTIGNOREALLDUPS)) != 0) histremovedups(); + + addlinknode(hookargs, "zshaddhistory"); + addlinknode(hookargs, chline); + callhookfunc("zshaddhistory", hookargs, 1, &hookret); /* For history sharing, lock history file once for both read and write */ hf = getsparam("HISTFILE"); if (isset(SHAREHISTORY) && lockhistfile(hf, 0)) { @@ -1123,7 +1151,7 @@ hend(Eprog prog) } if (chwordpos <= 2) save = 0; - else if (should_ignore_line(prog)) + else if (hookret || should_ignore_line(prog)) save = -1; } if (flag & (HISTFLAG_DONE | HISTFLAG_RECALL)) { @@ -1203,6 +1231,12 @@ hend(Eprog prog) if (isset(SHAREHISTORY)? histfileIsLocked() : isset(INCAPPENDHISTORY)) savehistfile(hf, 0, HFILE_USE_OPTIONS | HFILE_FAST); unlockhistfile(hf); /* It's OK to call this even if we aren't locked */ + /* + * No good reason for the user to push the history more than once, but + * it's easy to be tidy... + */ + while (histsave_stack_pos > stack_pos) + pophiststack(); unqueue_signals(); return !(flag & HISTFLAG_NOEXEC || errflag); } @@ -1942,30 +1976,6 @@ resizehistents(void) } } -/* Remember the last line in the history file so we can find it again. */ -static struct histfile_stats { - char *text; - time_t stim, mtim; - off_t fpos, fsiz; - zlong next_write_ev; -} lasthist; - -static struct histsave { - struct histfile_stats lasthist; - char *histfile; - HashTable histtab; - Histent hist_ring; - zlong curhist; - zlong histlinect; - zlong histsiz; - zlong savehistsiz; - int locallevel; -} *histsave_stack; -static int histsave_stack_size = 0; -static int histsave_stack_pos = 0; - -static zlong histfile_linect; - static int readhistline(int start, char **bufp, int *bufsiz, FILE *in) { diff --git a/Src/init.c b/Src/init.c index e3c89008a..7a64df17e 100644 --- a/Src/init.c +++ b/Src/init.c @@ -175,7 +175,7 @@ loop(int toplevel, int justonce) addlinknode(args, dupstring(getjobtext(prog, NULL))); addlinknode(args, cmdstr = getpermtext(prog, NULL)); - callhookfunc("preexec", args, 1); + callhookfunc("preexec", args, 1, NULL); /* The only permanent storage is from getpermtext() */ zsfree(cmdstr); diff --git a/Src/utils.c b/Src/utils.c index 154ca8627..ae0d43876 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1117,25 +1117,31 @@ time_t lastwatch; /* * Call a function given by "name" with optional arguments - * "lnklist". If "arrayp" is not zero, we also look through + * "lnklist". If these are present the first argument is the function name. + * + * If "arrayp" is not zero, we also look through * the array "name"_functions and execute functions found there. + * + * If "retval" is not NULL, the return value of the first hook function to + * return non-zero is stored in *"retval". The return value is not otherwise + * available as the calling context is restored. */ /**/ mod_export int -callhookfunc(char *name, LinkList lnklst, int arrayp) +callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval) { Eprog prog; /* * Save stopmsg, since user doesn't get a chance to respond * to a list of jobs generated in a hook. */ - int osc = sfcontext, osm = stopmsg, stat = 1; + int osc = sfcontext, osm = stopmsg, stat = 1, ret = 0; sfcontext = SFC_HOOK; if ((prog = getshfunc(name)) != &dummy_eprog) { - doshfunc(name, prog, lnklst, 0, 1); + ret = doshfunc(name, prog, lnklst, 0, 1); stat = 0; } @@ -1151,7 +1157,9 @@ callhookfunc(char *name, LinkList lnklst, int arrayp) if ((arrptr = getaparam(arrnam))) { for (; *arrptr; arrptr++) { if ((prog = getshfunc(*arrptr)) != &dummy_eprog) { - doshfunc(arrnam, prog, lnklst, 0, 1); + int newret = doshfunc(arrnam, prog, lnklst, 0, 1); + if (!ret) + ret = newret; stat = 0; } } @@ -1161,6 +1169,8 @@ callhookfunc(char *name, LinkList lnklst, int arrayp) sfcontext = osc; stopmsg = osm; + if (retval) + *retval = ret; return stat; } @@ -1200,7 +1210,7 @@ preprompt(void) /* If a shell function named "precmd" exists, * * then execute it. */ - callhookfunc("precmd", NULL, 1); + callhookfunc("precmd", NULL, 1, NULL); if (errflag) return; @@ -1208,7 +1218,7 @@ preprompt(void) * "periodic" exists, 3) it's been greater than PERIOD since we * * executed any such hook, then execute it now. */ if (period && (time(NULL) > lastperiodic + period) && - !callhookfunc("periodic", NULL, 1)) + !callhookfunc("periodic", NULL, 1, NULL)) lastperiodic = time(NULL); if (errflag) return; |