From be32864e6ff6a872d63314b4baedbfbf2eed54bd Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 25 Jan 2016 15:43:06 +0000 Subject: 37776: Set errflag before calls to zwarning(). This avoids an attempt to call zerr() or zerrnam() recusrively. --- Src/utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Src/utils.c') diff --git a/Src/utils.c b/Src/utils.c index fd0bab320..17ebfebf9 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -169,12 +169,12 @@ VA_DCL errflag |= ERRFLAG_ERROR; return; } + errflag |= ERRFLAG_ERROR; VA_START(ap, fmt); VA_GET_ARG(ap, fmt, const char *); zwarning(NULL, fmt, ap); va_end(ap); - errflag |= ERRFLAG_ERROR; } /**/ @@ -188,13 +188,13 @@ VA_DCL if (errflag || noerrs) return; + errflag |= ERRFLAG_ERROR; VA_START(ap, fmt); VA_GET_ARG(ap, cmd, const char *); VA_GET_ARG(ap, fmt, const char *); zwarning(cmd, fmt, ap); va_end(ap); - errflag |= ERRFLAG_ERROR; } /**/ -- cgit v1.2.3 From 69c86cd2c3f1533d9b4b345f98d3922418bc6dac Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 25 Jan 2016 18:01:07 +0100 Subject: 37780: Care printing error if nothing to print. --- ChangeLog | 3 +++ Src/utils.c | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 4ab9b14ed..8c8791cf2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,9 @@ 2016-01-25 Peter Stephenson + * 37780: Kamil Dudka: Src/utils.c: Careful in case both argzero + and scriptname are null in zerr(). + * 37765: Src/builtin.c, Test/C04funcdef.ztst: Use FS_FUNC on funcstack to find autoload -X target rather than scriptname. diff --git a/Src/utils.c b/Src/utils.c index 17ebfebf9..053731cfa 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -133,9 +133,11 @@ zwarning(const char *cmd, const char *fmt, va_list ap) if (isatty(2)) zleentry(ZLE_CMD_TRASH); + char *prefix = scriptname ? scriptname : (argzero ? argzero : ""); + if (cmd) { if (unset(SHINSTDIN) || locallevel) { - nicezputs(scriptname ? scriptname : argzero, stderr); + nicezputs(prefix, stderr); fputc((unsigned char)':', stderr); } nicezputs(cmd, stderr); @@ -147,8 +149,7 @@ zwarning(const char *cmd, const char *fmt, va_list ap) * program/script is running. It's also set in shell functions, * so test locallevel, too. */ - nicezputs((isset(SHINSTDIN) && !locallevel) ? "zsh" : - scriptname ? scriptname : argzero, stderr); + nicezputs((isset(SHINSTDIN) && !locallevel) ? "zsh" : prefix, stderr); fputc((unsigned char)':', stderr); } -- cgit v1.2.3 From a4020e10a33f3f78681a2e18fb7add56338d4e81 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Wed, 3 Feb 2016 01:24:56 +0900 Subject: 37868: add 'static' to file local variables --- ChangeLog | 8 ++++++++ Src/Modules/curses.c | 2 +- Src/Modules/param_private.c | 10 +++++----- Src/Modules/tcp.c | 2 +- Src/Modules/termcap.c | 2 +- Src/Modules/zftp.c | 8 ++++---- Src/Zle/complist.c | 2 +- Src/Zle/zle_misc.c | 2 +- Src/Zle/zle_utils.c | 4 ++-- Src/cond.c | 3 ++- Src/exec.c | 2 -- Src/glob.c | 2 +- Src/jobs.c | 6 +++--- Src/params.c | 2 +- Src/prompt.c | 2 +- Src/utils.c | 4 ++-- 16 files changed, 34 insertions(+), 27 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index d4adbe886..a8e76e238 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2016-02-03 Jun-ichi Takimoto + + * 37868: Src/Modules/curses.c, Src/Modules/param_private.c, + Src/Modules/tcp.c, Src/Modules/termcap.c, Src/Modules/zftp.c, + Src/Zle/complist.c, Src/Zle/zle_misc.c, Src/Zle/zle_utils.c, + Src/cond.c, Src/exec.c, Src/glob.c, Src/jobs.c, Src/params.c, + Src/prompt.c, Src/utils.c: add 'static' to file local variables. + 2016-01-31 Barton E. Schaefer * 37859: Src/text.c: NULL-terminate cond_binary_ops static array. diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c index b8a79ed11..a04841a85 100644 --- a/Src/Modules/curses.c +++ b/Src/Modules/curses.c @@ -202,7 +202,7 @@ static const struct zcurses_mouse_event zcurses_mouse_map[] = { { 0, 0, 0 } }; -mmask_t zcurses_mouse_mask = ALL_MOUSE_EVENTS; +static mmask_t zcurses_mouse_mask = ALL_MOUSE_EVENTS; #endif diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c index 2f51cb099..86416c5c5 100644 --- a/Src/Modules/param_private.c +++ b/Src/Modules/param_private.c @@ -42,19 +42,19 @@ struct gsu_closure { void *g; }; -const struct gsu_scalar scalar_private_gsu = +static const struct gsu_scalar scalar_private_gsu = { pps_getfn, pps_setfn, pps_unsetfn }; -const struct gsu_integer integer_private_gsu = +static const struct gsu_integer integer_private_gsu = { ppi_getfn, ppi_setfn, ppi_unsetfn }; -const struct gsu_float float_private_gsu = +static const struct gsu_float float_private_gsu = { ppf_getfn, ppf_setfn, ppf_unsetfn }; -const struct gsu_array array_private_gsu = +static const struct gsu_array array_private_gsu = { ppa_getfn, ppa_setfn, ppa_unsetfn }; -const struct gsu_hash hash_private_gsu = +static const struct gsu_hash hash_private_gsu = { pph_getfn, pph_setfn, pph_unsetfn }; /* diff --git a/Src/Modules/tcp.c b/Src/Modules/tcp.c index 5af68834f..dec12142b 100644 --- a/Src/Modules/tcp.c +++ b/Src/Modules/tcp.c @@ -208,7 +208,7 @@ freehostent(UNUSED(struct hostent *ptr)) /**/ #endif /* !HAVE_GETIPNODEBYNAME */ -LinkList ztcp_sessions; +static LinkList ztcp_sessions; /* "allocate" a tcp_session */ static Tcp_session diff --git a/Src/Modules/termcap.c b/Src/Modules/termcap.c index 29c28360c..60a6e138a 100644 --- a/Src/Modules/termcap.c +++ b/Src/Modules/termcap.c @@ -295,7 +295,7 @@ scantermcap(UNUSED(HashTable ht), ScanFunc func, int flags) } } -struct paramdef partab[] = { +static struct paramdef partab[] = { SPECIALPMDEF("termcap", PM_READONLY, NULL, gettermcap, scantermcap) }; diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index b4081df5f..deed35e2f 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -344,10 +344,10 @@ static int zfsesscnt; */ /* flags for alarm set, alarm gone off */ -int zfalarmed, zfdrrrring; +static int zfalarmed, zfdrrrring; /* remember old alarm status */ -time_t oaltime; -unsigned int oalremain; +static time_t oaltime; +static unsigned int oalremain; /* * Where to jump to when the alarm goes off. This is much @@ -357,7 +357,7 @@ unsigned int oalremain; * * gcc -O gives apparently spurious `may be clobbered by longjmp' warnings. */ -jmp_buf zfalrmbuf; +static jmp_buf zfalrmbuf; /* The signal handler itself */ diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index 0ccb88505..06a07a4e8 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -113,7 +113,7 @@ static Cmgroup *mgtab, *mgtabp; * Allow us to keep track of pointer arithmetic for mgtab; could * just as well have been for mtab but wasn't. */ -int mgtabsize; +static int mgtabsize; #endif /* diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index 0483f758d..25f65b39c 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -1497,7 +1497,7 @@ struct suffixset { }; /* The list of suffix structures */ -struct suffixset *suffixlist; +static struct suffixset *suffixlist; /* Shell function to call to remove the suffix. */ diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index a2c88102a..68794c66a 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -587,7 +587,7 @@ struct zle_position { }; /* LIFO stack of positions */ -struct zle_position *zle_positions; +static struct zle_position *zle_positions; /* * Save positions including cursor, end-of-line and @@ -1412,7 +1412,7 @@ zlong undo_changeno; /* If positive, don't undo beyond this point */ -zlong undo_limitno; +static zlong undo_limitno; /**/ void diff --git a/Src/cond.c b/Src/cond.c index c5ab65eea..0381fe94b 100644 --- a/Src/cond.c +++ b/Src/cond.c @@ -30,7 +30,8 @@ #include "zsh.mdh" #include "cond.pro" -int tracingcond; +/**/ +int tracingcond; /* updated by execcond() in exec.c */ static char *condstr[COND_MOD] = { "!", "&&", "||", "==", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq", diff --git a/Src/exec.c b/Src/exec.c index 352615c83..b60fc90bd 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4518,8 +4518,6 @@ spawnpipes(LinkList l, int nullexec) } } -extern int tracingcond; - /* evaluate a [[ ... ]] */ /**/ diff --git a/Src/glob.c b/Src/glob.c index 69de15544..2051016ec 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -306,7 +306,7 @@ statfullpath(const char *s, struct stat *st, int l) /* This may be set by qualifier functions to an array of strings to insert * into the list instead of the original string. */ -char **inserts; +static char **inserts; /* add a match to the list */ diff --git a/Src/jobs.c b/Src/jobs.c index b47ba8c60..2a9dbe7d6 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1970,9 +1970,9 @@ struct bgstatus { }; typedef struct bgstatus *Bgstatus; /* The list of those entries */ -LinkList bgstatus_list; +static LinkList bgstatus_list; /* Count of entries. Reaches value of _SC_CHILD_MAX and stops. */ -long bgstatus_count; +static long bgstatus_count; /* * Remove and free a bgstatus entry. @@ -2372,7 +2372,7 @@ bin_fg(char *name, char **argv, Options ops, int func) return retval; } -const struct { +static const struct { const char *name; int num; } alt_sigs[] = { diff --git a/Src/params.c b/Src/params.c index a1f0292cc..76ed61c39 100644 --- a/Src/params.c +++ b/Src/params.c @@ -416,7 +416,7 @@ IPDEF10("pipestatus", pipestatus_gsu), * and $@, this is not readonly. This parameter is not directly * visible in user space. */ -initparam argvparam_pm = IPDEF9F("", &pparams, NULL, \ +static initparam argvparam_pm = IPDEF9F("", &pparams, NULL, \ PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT); #undef BR diff --git a/Src/prompt.c b/Src/prompt.c index be067ee7e..831c4f948 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -1831,7 +1831,7 @@ struct colour_sequences { char *end; /* Escape sequence terminator */ char *def; /* Code to reset default colour */ }; -struct colour_sequences fg_bg_sequences[2]; +static struct colour_sequences fg_bg_sequences[2]; /* * We need a buffer for colour sequence composition. It may diff --git a/Src/utils.c b/Src/utils.c index 053731cfa..de4af5a51 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -56,12 +56,12 @@ typedef struct widechar_array *Widechar_array; * The wordchars variable turned into a wide character array. * This is much more convenient for testing. */ -struct widechar_array wordchars_wide; +static struct widechar_array wordchars_wide; /* * The same for the separators (IFS) array. */ -struct widechar_array ifs_wide; +static struct widechar_array ifs_wide; /* Function to set one of the above from the multibyte array */ -- cgit v1.2.3 From 6d82ce161a760af4421c1153e78741bda95bf6b6 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 11 Feb 2016 15:23:57 +0000 Subject: 37946: make rm * warnings more informative. Now count files that would be deleted up to 100. --- ChangeLog | 5 +++++ Src/utils.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index a549e1112..a6e3514fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-02-11 Peter Stephenson + + * 37946: Src/utils.c: make rm * warnings more informative about + files being deleted. + 2016-02-09 Peter Stephenson * 37893: Doc/Zsh/builtins.yo: document behaviour of typeset -U diff --git a/Src/utils.c b/Src/utils.c index de4af5a51..12911d3f4 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2634,13 +2634,36 @@ zsleep_random(long max_us, time_t end_time) int checkrmall(char *s) { + DIR *rmd; + int count = 0; if (!shout) return 1; - fprintf(shout, "zsh: sure you want to delete all the files in "); if (*s != '/') { - nicezputs(pwd[1] ? pwd : "", shout); - fputc('/', shout); - } + if (pwd[1]) + s = zhtricat(pwd, "/", s); + else + s = dyncat("/", s); + } + const int max_count = 100; + if ((rmd = opendir(unmeta(s)))) { + int ignoredots = !isset(GLOBDOTS); + while (zreaddir(rmd, ignoredots)) { + count++; + if (count > max_count) + break; + } + closedir(rmd); + } + if (count > max_count) + fprintf(shout, "zsh: sure you want to delete more than %d files in ", + max_count); + else if (count == 1) + fprintf(shout, "zsh: sure you want to delete the only file in "); + else if (count > 0) + fprintf(shout, "zsh: sure you want to delete all %d files in ", + count); + else + fprintf(shout, "zsh: sure you want to delete all the files in "); nicezputs(s, shout); if(isset(RMSTARWAIT)) { fputs("? (waiting ten seconds)", shout); -- cgit v1.2.3 From 8cf68f05ab1b13f147521ad64df34dae256e09fb Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 2 Jun 2016 10:59:51 +0100 Subject: 21603: Make read_poll more interruptible. If we interrupted the first read we still did the fallback read. This is wrong. --- ChangeLog | 5 +++++ Src/utils.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 98dd0c617..9f1220d49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-06-02 Peter Stephenson + + * users/21603: Src/utils.c: Don't do second attempt at read/poll + from terminal if interrupted. + 2016-05-22 Peter Stephenson * 38515: Matthew Martin: Completion/Zsh/Context/_subscript: diff --git a/Src/utils.c b/Src/utils.c index 12911d3f4..95be1fb98 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2534,7 +2534,7 @@ read_poll(int fd, int *readchar, int polltty, zlong microseconds) #endif #endif - if (fd >= 0 && ret < 0) { + if (fd >= 0 && ret < 0 && !errflag) { /* * Final attempt: set non-blocking read and try to read a character. * Praise Bill, this works under Cygwin (nothing else seems to). -- cgit v1.2.3 From 1a368bf31f2b2e6e96290a4803bdcd81e9f17393 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sat, 30 Jul 2016 10:14:35 +0000 Subject: 38973: Optimize indexing array parameters. % () { for 1 in $prefix/zsh/bin/zsh Src/zsh; do $1 -f -c 'a=( {1..1000000} ); repeat 3 time ( repeat 300 : $a[1] )'; done } ( repeat 300; do; : $a[1]; done; ) 1.68s user 0.01s system 98% cpu 1.718 total ( repeat 300; do; : $a[1]; done; ) 1.69s user 0.01s system 99% cpu 1.710 total ( repeat 300; do; : $a[1]; done; ) 1.69s user 0.01s system 99% cpu 1.714 total ( repeat 300; do; : $a[1]; done; ) 0.00s user 0.01s system 72% cpu 0.022 total ( repeat 300; do; : $a[1]; done; ) 0.00s user 0.01s system 72% cpu 0.022 total ( repeat 300; do; : $a[1]; done; ) 0.01s user 0.01s system 69% cpu 0.023 total --- ChangeLog | 3 +++ Src/params.c | 2 +- Src/subst.c | 15 +++++++++++---- Src/utils.c | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 5 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 7752ce68b..bcc9d09bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-08-01 Daniel Shahaf + * 38973: Src/params.c, Src/subst.c, Src/utils.c: Optimize + indexing array parameters. + * 38964: Completion/Unix/Command/_git: _git-config: Complete option names present in the config file. diff --git a/Src/params.c b/Src/params.c index e7a73657b..33f177ecc 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2026,7 +2026,7 @@ getstrvalue(Value v) else { if (v->start < 0) v->start += arrlen(ss); - s = (v->start >= arrlen(ss) || v->start < 0) ? + s = (arrlen_le(ss, v->start) || v->start < 0) ? (char *) hcalloc(1) : ss[v->start]; } return s; diff --git a/Src/subst.c b/Src/subst.c index 8e704b1c1..e3af15694 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2548,12 +2548,19 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * necessary joining of arrays until this point * to avoid the multsub() horror. */ - int tmplen = arrlen(v->pm->gsu.a->getfn(v->pm)); - if (v->start < 0) + /* arrlen() is expensive, so only compute it if needed. */ + int tmplen = -1; + + if (v->start < 0) { + tmplen = arrlen(v->pm->gsu.a->getfn(v->pm)); v->start += tmplen + ((v->flags & VALFLAG_INV) ? 1 : 0); - if (!(v->flags & VALFLAG_INV) && - (v->start >= tmplen || v->start < 0)) + } + if (!(v->flags & VALFLAG_INV)) + if (v->start < 0 || + (tmplen != -1 + ? v->start >= tmplen + : arrlen_le(v->pm->gsu.a->getfn(v->pm), v->start))) vunset = 1; } if (!vunset) { diff --git a/Src/utils.c b/Src/utils.c index 95be1fb98..95da96058 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2280,6 +2280,46 @@ arrlen(char **s) return count; } +/* Return TRUE iff arrlen(s) >= lower_bound, but more efficiently. */ + +/**/ +mod_export char +arrlen_ge(char **s, unsigned lower_bound) +{ + while (lower_bound--) + if (!*s++) + return 0 /* FALSE */; + + return 1 /* TRUE */; +} + +/* Return TRUE iff arrlen(s) > lower_bound, but more efficiently. */ + +/**/ +mod_export char +arrlen_gt(char **s, unsigned lower_bound) +{ + return arrlen_ge(s, 1+lower_bound); +} + +/* Return TRUE iff arrlen(s) <= upper_bound, but more efficiently. */ + +/**/ +mod_export char +arrlen_le(char **s, unsigned upper_bound) +{ + return arrlen_lt(s, 1+upper_bound); +} + +/* Return TRUE iff arrlen(s) < upper_bound, but more efficiently. */ + +/**/ +mod_export char +arrlen_lt(char **s, unsigned upper_bound) +{ + return !arrlen_ge(s, upper_bound); +} + /* Skip over a balanced pair of parenthesis. */ /**/ -- cgit v1.2.3 From f9b170351136e7e2e04cecf4f1f6c686b0c1324d Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sat, 30 Jul 2016 10:50:48 +0000 Subject: 38971: Start using the new arrlen_ge() / arrlen_le() helpers. --- ChangeLog | 4 ++++ Src/Modules/terminfo.c | 2 +- Src/Modules/zutil.c | 4 ++-- Src/builtin.c | 6 +++--- Src/params.c | 4 ++-- Src/prompt.c | 6 +++--- Src/utils.c | 2 +- 7 files changed, 16 insertions(+), 12 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index bcc9d09bb..28ce9bb71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2016-08-01 Daniel Shahaf + * 38971: Src/Modules/terminfo.c, Src/Modules/zutil.c, + Src/builtin.c, Src/params.c, Src/prompt.c, Src/utils.c: Start + using the new arrlen_ge() / arrlen_le() helpers. + * 38973: Src/params.c, Src/subst.c, Src/utils.c: Optimize indexing array parameters. diff --git a/Src/Modules/terminfo.c b/Src/Modules/terminfo.c index e0439afca..bbd325899 100644 --- a/Src/Modules/terminfo.c +++ b/Src/Modules/terminfo.c @@ -99,7 +99,7 @@ bin_echoti(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) return 1; } /* check that the number of arguments provided is not too high */ - if (arrlen(argv) > 9) { + if (arrlen_gt(argv, 9)) { zwarnnam(name, "too many arguments"); return 1; } diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 477575ccd..d95c0c254 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -472,7 +472,7 @@ bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) Patprog prog; char *pat; - if (arrlen(args) < 2) { + if (arrlen_lt(args, 2)) { zwarnnam(nam, "not enough arguments"); return 1; } @@ -491,7 +491,7 @@ bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) Style s; char *context, *stylename; - switch (arrlen(args)) { + switch (arrlen_ge(args, 3) ? 3 : arrlen(args)) { case 2: context = args[0]; stylename = args[1]; diff --git a/Src/builtin.c b/Src/builtin.c index bfb9e6929..fb14b2e33 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3406,7 +3406,7 @@ bin_unset(char *name, char **argv, Options ops, int func) } else { /* start is after the element for reverse index */ int start = vbuf.start - !!(vbuf.flags & VALFLAG_INV); - if (start < arrlen(vbuf.pm->u.arr)) { + if (arrlen_gt(vbuf.pm->u.arr, start)) { char *arr[2]; arr[0] = ""; arr[1] = 0; @@ -5026,7 +5026,7 @@ bin_shift(char *name, char **argv, Options ops, UNUSED(int func)) if (*argv) { for (; *argv; argv++) if ((s = getaparam(*argv))) { - if (num > arrlen(s)) { + if (arrlen_lt(s, num)) { zwarnnam(name, "shift count must be <= $#"); ret++; continue; @@ -5095,7 +5095,7 @@ bin_getopts(UNUSED(char *name), char **argv, UNUSED(Options ops), UNUSED(int fun zoptind = 1; optcind = 0; } - if(zoptind > arrlen(args)) + if (arrlen_lt(args, zoptind)) /* no more options */ return 1; diff --git a/Src/params.c b/Src/params.c index 33f177ecc..0eda7848f 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2225,13 +2225,13 @@ getarrvalue(Value v) v->start += arrlen(s); if (v->end < 0) v->end += arrlen(s) + 1; - if (v->start > arrlen(s) || v->start < 0) + if (arrlen_lt(s, v->start) || v->start < 0) s = arrdup(nular); else s = arrdup(s + v->start); if (v->end <= v->start) s[0] = NULL; - else if (v->end - v->start <= arrlen(s)) + else if (arrlen_ge(s, v->end - v->start)) s[v->end - v->start] = NULL; return s; } diff --git a/Src/prompt.c b/Src/prompt.c index bb2745358..d4f389809 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -395,11 +395,11 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) test = 1; break; case 'v': - if (arrlen(psvar) >= arg) + if (arrlen_ge(psvar, arg)) test = 1; break; case 'V': - if (arrlen(psvar) >= arg) { + if (arrlen_ge(psvar, arg)) { if (*psvar[(arg ? arg : 1) - 1]) test = 1; } @@ -736,7 +736,7 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) arg = 1; else if (arg < 0) arg += arrlen(psvar) + 1; - if (arg > 0 && arrlen(psvar) >= arg) + if (arg > 0 && arrlen_ge(psvar, arg)) stradd(psvar[arg - 1]); break; case 'E': diff --git a/Src/utils.c b/Src/utils.c index 95da96058..0a5954f65 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1157,7 +1157,7 @@ finddir(char *s) scanhashtable(nameddirtab, 0, 0, 0, finddir_scan, 0); ares = subst_string_by_hook("zsh_directory_name", "d", finddir_full); - if (ares && arrlen(ares) >= 2 && + if (ares && arrlen_ge(ares, 2) && (len = (int)zstrtol(ares[1], NULL, 10)) > finddir_best) { /* better duplicate this string since it's come from REPLY */ finddir_last = (Nameddir)hcalloc(sizeof(struct nameddir)); -- cgit v1.2.3 From 7154052ebe3d810390164a05c39ff83f98a1d858 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sat, 30 Jul 2016 16:16:22 +0000 Subject: 39046 + 39061: New :P history modifier. --- ChangeLog | 10 ++++++++++ Completion/Base/Completer/_external_pwds | 2 +- Completion/Zsh/Type/_history_modifiers | 5 +++-- Doc/Zsh/contrib.yo | 2 +- Doc/Zsh/expn.yo | 9 +++++++++ Functions/MIME/zsh-mime-handler | 2 +- Functions/VCS_Info/VCS_INFO_quilt | 2 +- Functions/Zle/expand-absolute-path | 2 +- NEWS | 11 +++++++++++ Src/params.c | 2 +- Src/subst.c | 13 +++++++++++++ Src/utils.c | 14 ++++++++------ Test/D02glob.ztst | 8 ++++++++ 13 files changed, 68 insertions(+), 14 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 65263033a..d3a7d3356 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2016-08-22 Daniel Shahaf + + * 39046 + 39061: Completion/Base/Completer/_external_pwds, + Completion/Zsh/Type/_history_modifiers, Doc/Zsh/contrib.yo, + Doc/Zsh/expn.yo, Functions/MIME/zsh-mime-handler, + Functions/VCS_Info/VCS_INFO_quilt, + Functions/Zle/expand-absolute-path, NEWS, Src/params.c, + Src/subst.c, Src/utils.c, Test/D02glob.ztst: New :P history + modifier. + 2016-08-20 Jun-ichi Takimoto * 39064: configure.ac, Src/Modules/mathfuc.c: use scalbn() instead diff --git a/Completion/Base/Completer/_external_pwds b/Completion/Base/Completer/_external_pwds index 4ad50f02b..79e3ba0eb 100644 --- a/Completion/Base/Completer/_external_pwds +++ b/Completion/Base/Completer/_external_pwds @@ -22,7 +22,7 @@ case $OSTYPE in ) ;; linux*) - dirs=( /proc/${^$(pidof zsh):#$$}/cwd(N:A) ) + dirs=( /proc/${^$(pidof zsh):#$$}/cwd(N:P) ) dirs=( $^dirs(N^@) ) ;; *) diff --git a/Completion/Zsh/Type/_history_modifiers b/Completion/Zsh/Type/_history_modifiers index 658f9f346..1a049d6cb 100644 --- a/Completion/Zsh/Type/_history_modifiers +++ b/Completion/Zsh/Type/_history_modifiers @@ -64,8 +64,8 @@ while true; do ) if (( ! global )); then list+=( - "a:absolute path" - "A:absolute path resolving symbolic links" + "a:absolute path, resolve '..' lexically" + "A:as ':a', then resolve symlinks" "c:PATH search for command" "g:globally apply s or &" "h:head - strip trailing path element" @@ -73,6 +73,7 @@ while true; do "r:root - strip suffix" "e:leave only extension" "Q:strip quotes" + "P:realpath, resolve '..' physically" "l:lower case all words" "u:upper case all words" ) diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 00ed08029..63df292ac 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -3477,7 +3477,7 @@ will ensure that any files found in that area will be executed as MIME types even if they are executable. As this example shows, the complete file name is matched against the pattern, regardless of how the file was passed to the handler. The file is resolved to a full path using -the tt(:A) modifier described in +the tt(:P) modifier described in ifzman(the subsection Modifiers in zmanref(zshexpn))\ ifnzman(noderef(Modifiers)); this means that symbolic links are resolved where possible, so that diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index ca4b94f5e..ecb1877a2 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -240,6 +240,7 @@ function, symbolic links are not resolved, so on those systems `tt(a)' and `tt(A)' are equivalent. Note: tt(foo:A) and tt(realpath+LPAR()foo+RPAR()) are different on some inputs. +For tt(realpath+LPAR()foo+RPAR()) semantics, see the `tt(P)` modifier. ) item(tt(c))( Resolve a command name into an absolute path by searching the command @@ -265,6 +266,14 @@ item(tt(p))( Print the new command but do not execute it. Only works with history expansion. ) +item(tt(P))( +Turn a file name into an absolute path, like tt(realpath+LPAR()3+RPAR()). +The resulting path will be absolute, have neither `tt(.)' nor `tt(..)' components, +and refer to the same directory entry as the input filename. + +Unlike tt(realpath+LPAR()3+RPAR()), non-existent trailing components are +permitted and preserved. +) item(tt(q))( Quote the substituted words, escaping further substitutions. Works with history expansion and parameter expansion, though for parameters diff --git a/Functions/MIME/zsh-mime-handler b/Functions/MIME/zsh-mime-handler index 24e5184fc..288a0796d 100644 --- a/Functions/MIME/zsh-mime-handler +++ b/Functions/MIME/zsh-mime-handler @@ -127,7 +127,7 @@ for pattern in $exec_asis; do files=(${dirpref}${~pattern}) if [[ -n ${files[(r)$1]} ]]; then for pattern in $exec_never; do - [[ ${1:A} = ${~pattern} ]] && break 2 + [[ ${1:P} = ${~pattern} ]] && break 2 done if (( list )); then for (( i = 1; i <= $#; i++ )); do diff --git a/Functions/VCS_Info/VCS_INFO_quilt b/Functions/VCS_Info/VCS_INFO_quilt index e7cd89f78..6adf0a358 100644 --- a/Functions/VCS_Info/VCS_INFO_quilt +++ b/Functions/VCS_Info/VCS_INFO_quilt @@ -170,7 +170,7 @@ function VCS_INFO_quilt() { applied=() fi patches=$(<$pc/.quilt_patches) - patches=`builtin cd -q "${pc:h}" && print -r - ${patches:A}` + patches=`builtin cd -q "${pc:h}" && print -r - ${patches:P}` fi if zstyle -t "${context}" get-unapplied; then # This zstyle call needs to be moved further up if `quilt' needs diff --git a/Functions/Zle/expand-absolute-path b/Functions/Zle/expand-absolute-path index b85757600..4887f3c60 100644 --- a/Functions/Zle/expand-absolute-path +++ b/Functions/Zle/expand-absolute-path @@ -10,7 +10,7 @@ autoload -Uz modify-current-argument if (( ! ${+functions[glob-expand-absolute-path]} )); then glob-expand-absolute-path() { local -a files - files=(${~1}(N:A)) + files=(${~1}(N:P)) (( ${#files} )) || return REPLY=${(D)files[1]} } diff --git a/NEWS b/NEWS index 15822ad34..65b246d33 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,17 @@ CHANGES FROM PREVIOUS VERSIONS OF ZSH Note also the list of incompatibilities in the README file. +Changes from 5.2 to 5.3 +----------------------- + +The new word modifier ':P' computes the physical path of the argument. +It is different from the existing ':a' modifier which always resolves +'/before/here/../after' to '/before/after', and differs from the +existing ':A' modifier which resolves symlinks only after 'here/..' is +removed, even when /before/here is itself a symbolic link. It is +recommended to review uses of ':A' and, if appropriate, convert them +to ':P' as soon as compatibility with 5.2 is no longer a requirement. + Changes from 5.1.1 to 5.2 ------------------------- diff --git a/Src/params.c b/Src/params.c index 0eda7848f..842b2f0d1 100644 --- a/Src/params.c +++ b/Src/params.c @@ -4336,7 +4336,7 @@ void homesetfn(UNUSED(Param pm), char *x) { zsfree(home); - if (x && isset(CHASELINKS) && (home = xsymlink(x))) + if (x && isset(CHASELINKS) && (home = xsymlink(x, 0))) zsfree(x); else home = x ? x : ztrdup(""); diff --git a/Src/subst.c b/Src/subst.c index c61551bf6..15eb59b64 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -4081,6 +4081,7 @@ modify(char **str, char **ptr) case 'u': case 'q': case 'Q': + case 'P': c = **ptr; break; @@ -4287,6 +4288,12 @@ modify(char **str, char **ptr) untokenize(copy); } break; + case 'P': + if (*copy != '/') { + copy = zhtricat(metafy(zgetcwd(), -1, META_HEAPDUP), "/", copy); + } + copy = xsymlink(copy, 1); + break; } tc = *tt; *tt = '\0'; @@ -4363,6 +4370,12 @@ modify(char **str, char **ptr) untokenize(*str); } break; + case 'P': + if (**str != '/') { + *str = zhtricat(metafy(zgetcwd(), -1, META_HEAPDUP), "/", *str); + } + *str = xsymlink(*str, 1); + break; } } if (rec < 0) { diff --git a/Src/utils.c b/Src/utils.c index 0a5954f65..45fd19286 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -801,9 +801,9 @@ findpwd(char *s) char *t; if (*s == '/') - return xsymlink(s); + return xsymlink(s, 0); s = tricat((pwd[1]) ? pwd : "", "/", s); - t = xsymlink(s); + t = xsymlink(s, 0); zsfree(s); return t; } @@ -969,11 +969,13 @@ xsymlinks(char *s, int full) /* * expand symlinks in s, and remove other weird things: * note that this always expands symlinks. + * + * 'heap' indicates whether to malloc() or allocate on the heap. */ /**/ char * -xsymlink(char *s) +xsymlink(char *s, int heap) { if (*s != '/') return NULL; @@ -981,8 +983,8 @@ xsymlink(char *s) if (xsymlinks(s + 1, 1) < 0) zwarn("path expansion failed, using root directory"); if (!*xbuf) - return ztrdup("/"); - return ztrdup(xbuf); + return heap ? dupstring("/") : ztrdup("/"); + return heap ? dupstring(xbuf) : ztrdup(xbuf); } /**/ @@ -1260,7 +1262,7 @@ getnameddir(char *name) /* Retrieve an entry from the password table/database for this user. */ struct passwd *pw; if ((pw = getpwnam(name))) { - char *dir = isset(CHASELINKS) ? xsymlink(pw->pw_dir) + char *dir = isset(CHASELINKS) ? xsymlink(pw->pw_dir, 0) : ztrdup(pw->pw_dir); if (dir) { adduserdir(name, dir, ND_USERNAME, 1); diff --git a/Test/D02glob.ztst b/Test/D02glob.ztst index 7befbc21f..1385d57d9 100644 --- a/Test/D02glob.ztst +++ b/Test/D02glob.ztst @@ -678,3 +678,11 @@ rm glob.tmp/link 0:modifier ':A' resolves '..' components before symlinks # There should be no output + + ln -s dir3/subdir glob.tmp/link + () { + print ${1:P} + } glob.tmp/link/../../hello/world + rm glob.tmp/link +0:modifier ':P' resolves symlinks before '..' components +*>*glob.tmp/hello/world -- cgit v1.2.3 From acad0620ef85b725d40d85b181e1aac1de0794c4 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Tue, 23 Aug 2016 18:18:50 +0900 Subject: 39087: fix 'conditionally uninitialized' variables --- ChangeLog | 3 +++ Src/builtin.c | 2 +- Src/utils.c | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 38b790e59..bba59595a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-08-23 Jun-ichi Takimoto + * 39087: Src/builtin.c, Src/utils.c: fix 'conditionally + uninitialized' variables + * 39086: Src/mem.c: declare file local variables as 'static' 2016-08-22 Oliver Kiddle diff --git a/Src/builtin.c b/Src/builtin.c index fb14b2e33..da453000c 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -1610,7 +1610,7 @@ bin_fc(char *nam, char **argv, Options ops, int func) unqueue_signals(); if (fcedit(editor, fil)) { if (stuff(fil)) - zwarnnam("fc", "%e: %s", errno, s); + zwarnnam("fc", "%e: %s", errno, fil); else { loop(0,1); retval = lastval; diff --git a/Src/utils.c b/Src/utils.c index 45fd19286..d209078f4 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -5082,8 +5082,10 @@ mb_niceformat(const char *s, FILE *stream, char **outstrp, int flags) cnt = 1; /* FALL THROUGH */ default: - if (c == L'\'' && (flags & NICEFLAG_QUOTE)) + if (c == L'\'' && (flags & NICEFLAG_QUOTE)) { fmt = "\\'"; + newl = 2; + } else fmt = wcs_nicechar_sel(c, &newl, NULL, flags & NICEFLAG_QUOTE); break; -- cgit v1.2.3 From f368720b8b9b481f82cef2e84a7e035864dff5f1 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Fri, 9 Sep 2016 09:38:06 +0000 Subject: 39252: internal: quotestring: Drop the 'e' parameter, which no caller uses. --- ChangeLog | 7 +++++++ Src/Zle/compcore.c | 2 +- Src/Zle/compctl.c | 20 ++++++++++---------- Src/Zle/computil.c | 6 +++--- Src/Zle/zle_misc.c | 2 +- Src/Zle/zle_tricky.c | 24 ++++++++++++------------ Src/builtin.c | 2 +- Src/subst.c | 12 ++++++------ Src/text.c | 4 ++-- Src/utils.c | 27 ++++----------------------- 10 files changed, 47 insertions(+), 59 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index a0e643615..7fba3550c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2016-09-11 Daniel Shahaf + + * 39252: Src/Zle/compcore.c, Src/Zle/compctl.c, + Src/Zle/computil.c, Src/Zle/zle_misc.c, Src/Zle/zle_tricky.c, + Src/builtin.c, Src/subst.c, Src/text.c, Src/utils.c: internal: + quotestring: Drop the 'e' parameter, which no caller uses. + 2016-09-09 Daniel Shahaf * unposted: Test/D04parameter.ztst: Add tests for ${(q)} being diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index ae7068fc9..2f9fb3308 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -1055,7 +1055,7 @@ multiquote(char *s, int ign) p += ign; while (*p) { if (ign >= 0 || p[1]) - s = quotestring(s, NULL, *p); + s = quotestring(s, *p); p++; } } diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index ce4576297..c2da2977f 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -1400,7 +1400,7 @@ printcompctl(char *s, Compctl cc, int printflags, int ispat) untokenize(p); quotedzputs(p, stdout); } else - quotedzputs(quotestring(s, NULL, QT_BACKSLASH), stdout); + quotedzputs(quotestring(s, QT_BACKSLASH), stdout); } /* loop through flags w/o args that are set, printing them if so */ @@ -1536,7 +1536,7 @@ printcompctl(char *s, Compctl cc, int printflags, int ispat) char *p = dupstring(s); untokenize(p); - quotedzputs(quotestring(p, NULL, QT_BACKSLASH), stdout); + quotedzputs(quotestring(p, QT_BACKSLASH), stdout); } } putchar('\n'); @@ -1740,8 +1740,8 @@ static int addwhat; * This uses the instring variable exported from zle_tricky.c. */ -#define quotename(s, e) \ -quotestring(s, e, instring == QT_NONE ? QT_BACKSLASH : instring) +#define quotename(s) \ +quotestring(s, instring == QT_NONE ? QT_BACKSLASH : instring) /* Hook functions */ @@ -3153,10 +3153,10 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) lpre = zhalloc(lpl + 1); memcpy(lpre, s, lpl); lpre[lpl] = '\0'; - qlpre = quotename(lpre, NULL); + qlpre = quotename(lpre); lsuf = dupstring(s + offs); lsl = strlen(lsuf); - qlsuf = quotename(lsuf, NULL); + qlsuf = quotename(lsuf); /* First check for ~.../... */ if (ic == Tilde) { @@ -3175,11 +3175,11 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) rpre = (*p || *lpre == Tilde || *lpre == Equals) ? (noreal = 0, getreal(tt)) : dupstring(tt); - qrpre = quotename(rpre, NULL); + qrpre = quotename(rpre); for (p = lsuf; *p && *p != String && *p != Tick; p++); rsuf = *p ? (noreal = 0, getreal(lsuf)) : dupstring(lsuf); - qrsuf = quotename(rsuf, NULL); + qrsuf = quotename(rsuf); /* Check if word is a pattern. */ @@ -3315,10 +3315,10 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) /* And get the file prefix. */ fpre = dupstring(((s1 == s || s1 == rpre || ic) && (*s != '/' || zlemetacs == wb)) ? s1 : s1 + 1); - qfpre = quotename(fpre, NULL); + qfpre = quotename(fpre); /* And the suffix. */ fsuf = dupstrpfx(rsuf, s2 - rsuf); - qfsuf = quotename(fsuf, NULL); + qfsuf = quotename(fsuf); if (comppatmatch && *comppatmatch && (ispattern & 2)) { int t2; diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index 1c90a543a..16b681cda 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -3554,7 +3554,7 @@ comp_quote(char *str, int prefix) if ((x = (prefix && *str == '='))) *str = 'x'; - ret = quotestring(str, NULL, *compqstack); + ret = quotestring(str, *compqstack); if (x) *str = *ret = '='; @@ -4744,7 +4744,7 @@ cf_ignore(char **names, LinkList ign, char *style, char *path) for (; (n = *names); names++) { if (!ztat(n, &nst, 1) && S_ISDIR(nst.st_mode)) { if (tpwd && nst.st_dev == est.st_dev && nst.st_ino == est.st_ino) { - addlinknode(ign, quotestring(n, NULL, QT_BACKSLASH)); + addlinknode(ign, quotestring(n, QT_BACKSLASH)); continue; } if (tpar && !strncmp((c = dupstring(n)), path, pl)) { @@ -4760,7 +4760,7 @@ cf_ignore(char **names, LinkList ign, char *style, char *path) if (found || ((e = strrchr(c, '/')) && e > c + pl && !ztat(c, &st, 1) && st.st_dev == nst.st_dev && st.st_ino == nst.st_ino)) - addlinknode(ign, quotestring(n, NULL, QT_BACKSLASH)); + addlinknode(ign, quotestring(n, QT_BACKSLASH)); } } } diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index a040ca0df..fbd40cd03 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -780,7 +780,7 @@ bracketedpaste(char **args) int n; ZLE_STRING_T wpaste; wpaste = stringaszleline((zmult == 1) ? pbuf : - quotestring(pbuf, NULL, QT_SINGLE_OPTIONAL), 0, &n, NULL, NULL); + quotestring(pbuf, QT_SINGLE_OPTIONAL), 0, &n, NULL, NULL); cuttext(wpaste, n, CUT_REPLACE); if (!(zmod.flags & MOD_VIBUF)) { kct = -1; diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 1d4e1d284..958e79ffb 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -424,8 +424,8 @@ mod_export int instring, inbackt; * This uses the instring variable above. */ -#define quotename(s, e) \ -quotestring(s, e, instring == QT_NONE ? QT_BACKSLASH : instring) +#define quotename(s) \ +quotestring(s, instring == QT_NONE ? QT_BACKSLASH : instring) /* Check if the given string is the name of a parameter and if this * * parameter is one worth expanding. */ @@ -2004,11 +2004,11 @@ get_comp_string(void) new->next = NULL; new->str = dupstrpfx(bbeg, len); - new->str = ztrdup(quotename(new->str, NULL)); + new->str = ztrdup(quotename(new->str)); untokenize(new->str); new->pos = begi; *dbeg = '\0'; - new->qpos = strlen(quotename(predup, NULL)); + new->qpos = strlen(quotename(predup)); *dbeg = '{'; i -= len; boffs -= len; @@ -2067,11 +2067,11 @@ get_comp_string(void) lastbrbeg = new; new->str = dupstrpfx(bbeg, len); - new->str = ztrdup(quotename(new->str, NULL)); + new->str = ztrdup(quotename(new->str)); untokenize(new->str); new->pos = begi; *dbeg = '\0'; - new->qpos = strlen(quotename(predup, NULL)); + new->qpos = strlen(quotename(predup)); *dbeg = '{'; i -= len; boffs -= len; @@ -2117,7 +2117,7 @@ get_comp_string(void) brend = new; new->str = dupstrpfx(bbeg, len); - new->str = ztrdup(quotename(new->str, NULL)); + new->str = ztrdup(quotename(new->str)); untokenize(new->str); new->pos = dp - predup - len + 1; new->qpos = len; @@ -2146,11 +2146,11 @@ get_comp_string(void) lastbrbeg = new; new->str = dupstrpfx(bbeg, len); - new->str = ztrdup(quotename(new->str, NULL)); + new->str = ztrdup(quotename(new->str)); untokenize(new->str); new->pos = begi; *dbeg = '\0'; - new->qpos = strlen(quotename(predup, NULL)); + new->qpos = strlen(quotename(predup)); *dbeg = '{'; boffs -= len; memmove(dbeg, dbeg + len, 1+strlen(dbeg+len)); @@ -2165,7 +2165,7 @@ get_comp_string(void) p = bp->pos; l = bp->qpos; bp->pos = strlen(predup + p + l); - bp->qpos = strlen(quotename(predup + p + l, NULL)); + bp->qpos = strlen(quotename(predup + p + l)); memmove(predup + p, predup + p + l, 1+bp->pos); } } @@ -2288,7 +2288,7 @@ doexpansion(char *s, int lst, int olst, int explincmd) foredel(we - wb, CUT_RAW); while ((ss = (char *)ugetnode(vl))) { ret = 0; - ss = quotename(ss, NULL); + ss = quotename(ss); untokenize(ss); inststr(ss); if (nonempty(vl) || !first) { @@ -2997,7 +2997,7 @@ processcmd(UNUSED(char **args)) inststr(" "); untokenize(s); - inststr(quotename(s, NULL)); + inststr(quotename(s)); zsfree(s); done = 1; diff --git a/Src/builtin.c b/Src/builtin.c index 3b82c9e7f..248f929d7 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4844,7 +4844,7 @@ bin_print(char *name, char **args, Options ops, int func) break; case 'q': stringval = curarg ? - quotestring(curarg, NULL, QT_BACKSLASH_SHOWNULL) : &nullstr; + quotestring(curarg, QT_BACKSLASH_SHOWNULL) : &nullstr; *d = 's'; print_val(stringval); break; diff --git a/Src/subst.c b/Src/subst.c index 4641b4ba5..1c2027f32 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3615,7 +3615,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, char *tmp; for (; *ap; ap++) { - tmp = quotestring(*ap, NULL, quotetype); + tmp = quotestring(*ap, quotetype); sl = strlen(tmp); *ap = (char *) zhalloc(pre + sl + post + 1); strcpy((*ap) + pre, tmp); @@ -3628,7 +3628,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, } } else for (; *ap; ap++) - *ap = quotestring(*ap, NULL, QT_BACKSLASH_SHOWNULL); + *ap = quotestring(*ap, QT_BACKSLASH_SHOWNULL); } else { int one = noerrs, oef = errflag, haserr = 0; @@ -3658,7 +3658,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, } else if (quotetype > QT_BACKSLASH) { int sl; char *tmp; - tmp = quotestring(val, NULL, quotetype); + tmp = quotestring(val, quotetype); sl = strlen(tmp); val = (char *) zhalloc(pre + sl + 2); strcpy(val + pre, tmp); @@ -3669,7 +3669,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, if (quotetype == QT_DOLLARS) val[0] = '$'; } else - val = quotestring(val, NULL, QT_BACKSLASH_SHOWNULL); + val = quotestring(val, QT_BACKSLASH_SHOWNULL); } else { int one = noerrs, oef = errflag, haserr; @@ -4274,7 +4274,7 @@ modify(char **str, char **ptr) subst(©, hsubl, hsubr, gbal); break; case 'q': - copy = quotestring(copy, NULL, QT_BACKSLASH_SHOWNULL); + copy = quotestring(copy, QT_BACKSLASH_SHOWNULL); break; case 'Q': { @@ -4356,7 +4356,7 @@ modify(char **str, char **ptr) subst(str, hsubl, hsubr, gbal); break; case 'q': - *str = quotestring(*str, NULL, QT_BACKSLASH); + *str = quotestring(*str, QT_BACKSLASH); break; case 'Q': { diff --git a/Src/text.c b/Src/text.c index cf6d3eb42..d387d361a 100644 --- a/Src/text.c +++ b/Src/text.c @@ -1068,11 +1068,11 @@ getredirs(LinkList redirs) */ if (!has_token(f->name)) { taddchr('\''); - taddstr(quotestring(f->name, NULL, QT_SINGLE)); + taddstr(quotestring(f->name, QT_SINGLE)); taddchr('\''); } else { taddchr('"'); - taddstr(quotestring(f->name, NULL, QT_DOUBLE)); + taddstr(quotestring(f->name, QT_DOUBLE)); taddchr('"'); } if (sav) diff --git a/Src/utils.c b/Src/utils.c index d209078f4..b434821e5 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1047,9 +1047,9 @@ substnamedir(char *s) Nameddir d = finddir(s); if (!d) - return quotestring(s, NULL, QT_BACKSLASH); + return quotestring(s, QT_BACKSLASH); return zhtricat("~", d->node.nam, quotestring(s + strlen(d->dir), - NULL, QT_BACKSLASH)); + QT_BACKSLASH)); } @@ -5649,10 +5649,6 @@ addunprintable(char *v, const char *u, const char *uend) /* * Quote the string s and return the result as a string from the heap. * - * If e is non-zero, the - * pointer it points to may point to a position in s and in e the position - * of the corresponding character in the quoted string is returned. - * * The last argument is a QT_ value defined in zsh.h other than QT_NONE. * * Most quote styles other than backslash assume the quotes are to @@ -5665,13 +5661,13 @@ addunprintable(char *v, const char *u, const char *uend) /**/ mod_export char * -quotestring(const char *s, char **e, int instring) +quotestring(const char *s, int instring) { const char *u; char *v; int alloclen; char *buf; - int sf = 0, shownull = 0; + int shownull = 0; /* * quotesub is used with QT_SINGLE_OPTIONAL. * quotesub = 0: mechanism not active @@ -5742,10 +5738,6 @@ quotestring(const char *s, char **e, int instring) while (*u) { uend = u + MB_METACHARLENCONV(u, &cc); - if (e && !sf && *e <= u) { - *e = v; - sf = 1; - } if ( #ifdef MULTIBYTE_SUPPORT cc != WEOF && @@ -5772,11 +5764,6 @@ quotestring(const char *s, char **e, int instring) } } else if (instring == QT_BACKSLASH_PATTERN) { while (*u) { - if (e && !sf && *e == u) { - *e = v; - sf = 1; - } - if (ipattern(*u)) *v++ = '\\'; *v++ = *u++; @@ -5795,8 +5782,6 @@ quotestring(const char *s, char **e, int instring) */ while (*u) { int dobackslash = 0; - if (e && *e == u) - *e = v, sf = 1; if (*u == Tick || *u == Qtick) { char c = *u++; @@ -5984,10 +5969,6 @@ quotestring(const char *s, char **e, int instring) *v++ = '\''; *v = '\0'; - if (e && *e == u) - *e = v, sf = 1; - DPUTS(e && !sf, "BUG: Wild pointer *e in quotestring()"); - v = dupstring(buf); zfree(buf, alloclen); return v; -- cgit v1.2.3 From e61ed2b80d60ca095006d7512f90c07e6c572ee0 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Thu, 29 Sep 2016 11:16:24 -0700 Subject: 39470: failure to open a supposedly unique temp file name should result in an error Also band-aid for signal-related race conditions in temp file name generation --- ChangeLog | 6 ++++++ Src/exec.c | 16 +++++++++++----- Src/utils.c | 4 ++++ 3 files changed, 21 insertions(+), 5 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index ca9d23b57..f93bdb10a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-09-29 Barton E. Schaefer + + * 39470: Src/exec.c, Src/utils.c: failure to open a supposedly + unique temp file name should result in an error; band-aid for + signal-related race conditions in temp file name generation + 2016-09-29 Peter Stephenson * 39502: Src/exec.c, Test/A01grammar.ztst: need to fork for diff --git a/Src/exec.c b/Src/exec.c index e3915ddfe..04868bd37 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4412,11 +4412,17 @@ getoutputfile(char *cmd, char **eptr) untokenize(s); } - addfilelist(nam, 0); + if (!s) /* Unclear why we need to do this before open() */ + child_block(); /* but it has been so for a long time: leave it */ - if (!s) - child_block(); - fd = open(nam, O_WRONLY | O_CREAT | O_EXCL | O_NOCTTY, 0600); + if ((fd = open(nam, O_WRONLY | O_CREAT | O_EXCL | O_NOCTTY, 0600)) < 0) { + zerr("process substitution failed: %e", errno); + free(nam); + if (!s) + child_unblock(); + return NULL; + } + addfilelist(nam, 0); if (s) { /* optimised here-string */ @@ -4427,7 +4433,7 @@ getoutputfile(char *cmd, char **eptr) return nam; } - if (fd < 0 || (cmdoutpid = pid = zfork(NULL)) == -1) { + if ((cmdoutpid = pid = zfork(NULL)) == -1) { /* fork or open error */ child_unblock(); return nam; diff --git a/Src/utils.c b/Src/utils.c index b434821e5..db4352908 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2164,6 +2164,7 @@ gettempfile(const char *prefix, int use_heap, char **tempname) #if HAVE_MKSTEMP char *suffix = prefix ? ".XXXXXX" : "XXXXXX"; + queue_signals(); if (!prefix && !(prefix = getsparam("TMPPREFIX"))) prefix = DEFAULT_TMPPREFIX; if (use_heap) @@ -2180,6 +2181,7 @@ gettempfile(const char *prefix, int use_heap, char **tempname) #else int failures = 0; + queue_signals(); do { if (!(fn = gettempname(prefix, use_heap))) { fd = -1; @@ -2193,6 +2195,8 @@ gettempfile(const char *prefix, int use_heap, char **tempname) } while (errno == EEXIST && ++failures < 16); #endif *tempname = fn; + + unqueue_signals(); return fd; } -- cgit v1.2.3 From 9c68ef083b9ddd94c3ca7027214b2e8a31a1bc47 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 4 Nov 2016 09:56:03 +0000 Subject: 39825: optimise mb_metastrlenend() for 7-bit character. As the shell relies intimately on US-ASCII as a subset we can skip the multibyte functions if we are dealing with a complete 7-bit character. --- ChangeLog | 5 +++++ Src/utils.c | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index e83dccbe6..1b1ecd75d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-11-04 Peter Stephenson + + * Sebastian: 39825: Src/utils.c: Optimise mb_metastrlenend() for + the common case of 7-bit character. + 2016-11-04 Jun-ichi Takimoto * 39818 (Oliver Kiddle): Completion/Unix/Command/_awk: add nawk diff --git a/Src/utils.c b/Src/utils.c index db4352908..733f57088 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -5323,7 +5323,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr) char inchar, *laststart; size_t ret; wchar_t wc; - int num, num_in_char; + int num, num_in_char, complete; if (!isset(MULTIBYTE)) return ztrlen(ptr); @@ -5331,6 +5331,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr) laststart = ptr; ret = MB_INVALID; num = num_in_char = 0; + complete = 1; memset(&mb_shiftstate, 0, sizeof(mb_shiftstate)); while (*ptr && !(eptr && ptr >= eptr)) { @@ -5339,6 +5340,18 @@ mb_metastrlenend(char *ptr, int width, char *eptr) else inchar = *ptr; ptr++; + + if (complete && (inchar >= 0 && inchar <= 0x7f)) { + /* + * We rely on 7-bit US-ASCII as a subset, so skip + * multibyte handling if we have such a character. + */ + num++; + laststart = ptr; + num_in_char = 0; + continue; + } + ret = mbrtowc(&wc, &inchar, 1, &mb_shiftstate); if (ret == MB_INCOMPLETE) { @@ -5358,6 +5371,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr) * so we don't count characters twice. */ num_in_char++; + complete = 0; } else { if (ret == MB_INVALID) { /* Reset, treat as single character */ @@ -5380,6 +5394,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr) num++; laststart = ptr; num_in_char = 0; + complete = 1; } } -- cgit v1.2.3 From 39521515c3be054170eb9507c520f0e433cd304e Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 8 Nov 2016 10:09:26 +0000 Subject: 39867, tweaked: Use cast to unsigned char to test character. We want the unsigned variant to be <= 0x7f. Use the normal STOUC() macro and turn this into a single test. --- ChangeLog | 5 +++++ Src/utils.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 5d2e003f3..39ff8c7ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-11-08 Peter Stephenson + + * 39867: Src/utils.c: cast to unsigned char to compare against + 0x7f. + 2016-11-07 Peter Stephenson * Felix Neumärker: Completion/Unix/Command/_module: follow diff --git a/Src/utils.c b/Src/utils.c index 733f57088..d73110a3e 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -5341,7 +5341,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr) inchar = *ptr; ptr++; - if (complete && (inchar >= 0 && inchar <= 0x7f)) { + if (complete && (inchar >= 0 && STOUC(inchar) <= STOUC(0x7f))) { /* * We rely on 7-bit US-ASCII as a subset, so skip * multibyte handling if we have such a character. -- cgit v1.2.3 From 1683371fa5be3bd038ee5c73fe53dcab8809204e Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 8 Nov 2016 10:51:03 +0000 Subject: unposted: follow up to 39867: don't need test against zero --- ChangeLog | 3 +++ Src/utils.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 4409e6ea2..fc51df7d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-11-08 Peter Stephenson + * unposted: Src/utils.c: follow up to 39867: don't need test + against zero any more. + * Sebastian: 39869: can transfer ownership of core of array when assigning. diff --git a/Src/utils.c b/Src/utils.c index d73110a3e..93e757ce8 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -5341,7 +5341,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr) inchar = *ptr; ptr++; - if (complete && (inchar >= 0 && STOUC(inchar) <= STOUC(0x7f))) { + if (complete && STOUC(inchar) <= STOUC(0x7f)) { /* * We rely on 7-bit US-ASCII as a subset, so skip * multibyte handling if we have such a character. -- cgit v1.2.3 From a1633e09a761b9135a0a7084d2489d359a004e5a Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 9 Nov 2016 11:54:57 +0000 Subject: 39886 based on 39877: Optimise arrdup to arrdup_max. Only duplicate as much of the array as is needed. --- ChangeLog | 3 +++ Src/params.c | 24 +++++++++++++++++------- Src/utils.c | 25 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 7 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 416ecf114..8d2f472b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-11-09 Peter Stephenson + * 39886 based on 39877 (Sebastian): Src/params.c, Src/utils.c: + add arrdup_max() so as not to duplicate entire arrays unnecessarily. + * Sebastian: 39875: Src/params.c, Src/string.c: add dupstring_glen() to avoid redundant strlen() calls. diff --git a/Src/params.c b/Src/params.c index 3f0179267..772345bd1 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2294,14 +2294,24 @@ getarrvalue(Value v) v->start += arrlen(s); if (v->end < 0) v->end += arrlen(s) + 1; - if (arrlen_lt(s, v->start) || v->start < 0) + + /* Null if 1) array too short, 2) index still negative */ + if (arrlen_lt(s, v->start) || v->start < 0) { s = arrdup(nular); - else - s = arrdup(s + v->start); - if (v->end <= v->start) - s[0] = NULL; - else if (arrlen_ge(s, v->end - v->start)) - s[v->end - v->start] = NULL; + } else if (v->end <= v->start) { + s = arrdup_max(s, 1); + s[0] = NULL; + } else { + /* Copy to a point before the end of the source array: + * arrdup_max will copy at most v->end - v->start elements, + * starting from v->start element. Original code said: + * s[v->end - v->start] = NULL + * which means that there are exactly the same number of + * elements as the value of the above *0-based* index. + */ + s = arrdup_max(s + v->start, v->end - v->start); + } + return s; } diff --git a/Src/utils.c b/Src/utils.c index 93e757ce8..3d535b85c 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -4229,6 +4229,31 @@ arrdup(char **s) return y; } +/* Duplicate at most max elements of the array s with heap memory */ + +/**/ +mod_export char ** +arrdup_max(char **s, unsigned max) +{ + char **x, **y, **send; + int len; + + len = arrlen(s); + + /* Limit has sense only if not equal to len */ + if (max > len) + max = len; + + y = x = (char **) zhalloc(sizeof(char *) * (max + 1)); + + send = s + max; + while (s < send) + *x++ = dupstring(*s++); + *x = NULL; + + return y; +} + /**/ mod_export char ** zarrdup(char **s) -- cgit v1.2.3 From 99acd1e7f48414e34aa08ec8246caa09088861df Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 14 Nov 2016 10:12:04 +0000 Subject: 39906: More multibyte optimisations for US-ASCII. This treats characters 0 to 0x7f as single byte US-ASCII along the lines we already do in other places in the code. --- ChangeLog | 5 +++++ Src/utils.c | 26 +++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 3ca016ef4..27e01c232 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-11-14 Peter Stephenson + + * 39906: Src/utils.c: More optimisation of multibyte handling + for US-ASCII along existing lines. + 2016-11-13 Barton E. Schaefer * unposted: Src/Zle/zle_utils.c: comment in zlecallhook() points diff --git a/Src/utils.c b/Src/utils.c index 3d535b85c..cceaf4c57 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -84,7 +84,15 @@ set_widearray(char *mb_array, Widechar_array wca) mb_charinit(); while (*mb_array) { - int mblen = mb_metacharlenconv(mb_array, &wci); + int mblen; + + if (STOUC(*mb_array) <= 0x7f) { + mb_array++; + *wcptr++ = (wchar_t)*mb_array; + continue; + } + + mblen = mb_metacharlenconv(mb_array, &wci); if (!mblen) break; @@ -5249,6 +5257,12 @@ mb_metacharlenconv_r(const char *s, wint_t *wcp, mbstate_t *mbsp) const char *ptr; wchar_t wc; + if (STOUC(*s) <= 0x7f) { + if (wcp) + *wcp = (wint_t)*s; + return 1; + } + for (ptr = s; *ptr; ) { if (*ptr == Meta) { inchar = *++ptr ^ 32; @@ -5301,7 +5315,7 @@ mb_metacharlenconv_r(const char *s, wint_t *wcp, mbstate_t *mbsp) mod_export int mb_metacharlenconv(const char *s, wint_t *wcp) { - if (!isset(MULTIBYTE)) { + if (!isset(MULTIBYTE) || STOUC(*s) <= 0x7f) { /* treat as single byte, possibly metafied */ if (wcp) *wcp = (wint_t)(*s == Meta ? s[1] ^ 32 : *s); @@ -5442,6 +5456,12 @@ mb_charlenconv_r(const char *s, int slen, wint_t *wcp, mbstate_t *mbsp) const char *ptr; wchar_t wc; + if (slen && STOUC(*s) <= 0x7f) { + if (wcp) + *wcp = (wint_t)*s; + return 1; + } + for (ptr = s; slen; ) { inchar = *ptr; ptr++; @@ -5477,7 +5497,7 @@ mb_charlenconv_r(const char *s, int slen, wint_t *wcp, mbstate_t *mbsp) mod_export int mb_charlenconv(const char *s, int slen, wint_t *wcp) { - if (!isset(MULTIBYTE)) { + if (!isset(MULTIBYTE) || STOUC(*s) <= 0x7f) { if (wcp) *wcp = (wint_t)*s; return 1; -- cgit v1.2.3 From 921b39ac6b25dbfcc477fc7db4ed1c5c3ffb778c Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 15 Nov 2016 18:01:32 +0000 Subject: 39949: Special case for "-" in directory names. It can be sh-tokenized to Dash to allow for appearing in ranges after substitution, so needs to be turned back to "-" in that case. --- ChangeLog | 4 ++++ Src/subst.c | 16 ++++++------- Src/utils.c | 70 +++++++++++++++++++++++++++++++------------------------ Test/B09hash.ztst | 8 +++++++ 4 files changed, 59 insertions(+), 39 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 885777e37..0040c2367 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2016-11-15 Peter Stephenson + * 39949: Src/subst.c, Src/utils.c, Test/B09hash.ztst: "-" is + allowed in named directories, so needs a special case when + sh-tokenized for possible ranges. + * 39947: Test/D04parameter.ztst: Test out-of-rantge multiple array subscripts with and without (@). diff --git a/Src/subst.c b/Src/subst.c index 447177409..c7c552257 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -684,19 +684,19 @@ filesubstr(char **namptr, int assign) *namptr = dyncat(ds, ptr); return 1; } else if ((ptr = itype_end(str+1, IUSER, 0)) != str+1) { /* ~foo */ - char *hom, save; + char *untok, *hom; - save = *ptr; - if (!isend(save)) + if (!isend(*ptr)) return 0; - *ptr = 0; - if (!(hom = getnameddir(++str))) { + untok = dupstring(++str); + untok[ptr-str] = 0; + untokenize(untok); + + if (!(hom = getnameddir(untok))) { if (isset(NOMATCH) && isset(EXECOPT)) - zerr("no such user or named directory: %s", str); - *ptr = save; + zerr("no such user or named directory: %s", untok); return 0; } - *ptr = save; *namptr = dyncat(hom, ptr); return 1; } diff --git a/Src/utils.c b/Src/utils.c index cceaf4c57..92d831172 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -3959,7 +3959,7 @@ inittyptab(void) #endif /* typtab['.'] |= IIDENT; */ /* Allow '.' in variable names - broken */ typtab['_'] = IIDENT | IUSER; - typtab['-'] = typtab['.'] = IUSER; + typtab['-'] = typtab['.'] = typtab[STOUC(Dash)] = IUSER; typtab[' '] |= IBLANK | INBLANK; typtab['\t'] |= IBLANK | INBLANK; typtab['\n'] |= INBLANK; @@ -4157,42 +4157,50 @@ itype_end(const char *ptr, int itype, int once) (itype != IIDENT || !isset(POSIXIDENTIFIERS))) { mb_charinit(); while (*ptr) { - wint_t wc; - int len = mb_metacharlenconv(ptr, &wc); - - if (!len) - break; - - if (wc == WEOF) { - /* invalid, treat as single character */ - int chr = STOUC(*ptr == Meta ? ptr[1] ^ 32 : *ptr); - /* in this case non-ASCII characters can't match */ - if (chr > 127 || !zistype(chr,itype)) - break; - } else if (len == 1 && isascii(*ptr)) { - /* ASCII: can't be metafied, use standard test */ + int len; + if (itok(*ptr)) { + /* Not untokenised yet --- can happen in raw command line */ + len = 1; if (!zistype(*ptr,itype)) break; } else { - /* - * Valid non-ASCII character. - */ - switch (itype) { - case IWORD: - if (!iswalnum(wc) && - !wmemchr(wordchars_wide.chars, wc, - wordchars_wide.len)) - return (char *)ptr; - break; + wint_t wc; + len = mb_metacharlenconv(ptr, &wc); - case ISEP: - if (!wmemchr(ifs_wide.chars, wc, ifs_wide.len)) - return (char *)ptr; + if (!len) break; - default: - if (!iswalnum(wc)) - return (char *)ptr; + if (wc == WEOF) { + /* invalid, treat as single character */ + int chr = STOUC(*ptr == Meta ? ptr[1] ^ 32 : *ptr); + /* in this case non-ASCII characters can't match */ + if (chr > 127 || !zistype(chr,itype)) + break; + } else if (len == 1 && isascii(*ptr)) { + /* ASCII: can't be metafied, use standard test */ + if (!zistype(*ptr,itype)) + break; + } else { + /* + * Valid non-ASCII character. + */ + switch (itype) { + case IWORD: + if (!iswalnum(wc) && + !wmemchr(wordchars_wide.chars, wc, + wordchars_wide.len)) + return (char *)ptr; + break; + + case ISEP: + if (!wmemchr(ifs_wide.chars, wc, ifs_wide.len)) + return (char *)ptr; + break; + + default: + if (!iswalnum(wc)) + return (char *)ptr; + } } } ptr += len; diff --git a/Test/B09hash.ztst b/Test/B09hash.ztst index 49f304838..7b5dfb43e 100644 --- a/Test/B09hash.ztst +++ b/Test/B09hash.ztst @@ -69,3 +69,11 @@ >one=/first/directory >two=/directory/the/second >three=/noch/ein/verzeichnis + + hash -d t-t=/foo + i="~t-t" + print ~t-t/bar + print ${~i}/rab +0:Dashes are untokenized in directory hash names +>/foo/bar +>/foo/rab -- cgit v1.2.3 From 98b7960c78ef720c3d830bef2258f6aa86c055de Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Mon, 14 Nov 2016 14:44:57 -0800 Subject: 39943: no need to compute arrlen() in arrdup_max() when max == 0. --- ChangeLog | 5 +++++ Src/utils.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 0040c2367..488f1ed45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,11 @@ * 39947: Test/D04parameter.ztst: Test out-of-rantge multiple array subscripts with and without (@). +2016-11-14 Barton E. Schaefer + + * 39943: Src/utils.c: no need to compute arrlen() in arrdup_max() + when max == 0. + 2016-11-15 Jun-ichi Takimoto * 39937: Src/params.c: fix a problem introduced by 39886. diff --git a/Src/utils.c b/Src/utils.c index 92d831172..151e9e4eb 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -4252,9 +4252,10 @@ mod_export char ** arrdup_max(char **s, unsigned max) { char **x, **y, **send; - int len; + int len = 0; - len = arrlen(s); + if (max) + len = arrlen(s); /* Limit has sense only if not equal to len */ if (max > len) -- cgit v1.2.3 From a62e1640bcafbb82d86ea8d8ce057a83c4683d60 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 17 Nov 2016 19:49:17 +0000 Subject: 39958: Add extra byte to PATH_MAX allocations. This ensures we've got enough space for a null, although this isn't always needed. --- ChangeLog | 6 ++++++ Src/Zle/compctl.c | 2 +- Src/builtin.c | 2 +- Src/compat.c | 6 +++--- Src/exec.c | 16 ++++++++-------- Src/glob.c | 4 ++-- Src/hist.c | 2 +- Src/utils.c | 12 ++++++------ 8 files changed, 28 insertions(+), 22 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index aa3b57bf0..f3dbffcc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-11-17 Peter Stephenson + + * 39958: Src/Zle/compctl.c, Src/builtin.c, Src/compat.c, + Src/exec.c, Src/glob.c, Src/hist.c, Src/utils.c: Add spare byte + to PATH_MAX allocation to allow for possible null. + 2016-11-17 Daniel Shahaf * 39921: Completion/Unix/Command/_git: __git_recent_branches: diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index 09e590569..52c6f1233 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -2135,7 +2135,7 @@ gen_matches_files(int dirs, int execs, int all) { DIR *d; struct stat buf; - char *n, p[PATH_MAX], *q = NULL, *e, *pathpref; + char *n, p[PATH_MAX+1], *q = NULL, *e, *pathpref; LinkList l = NULL; int ns = 0, ng = opts[NULLGLOB], test, aw = addwhat, pathpreflen; diff --git a/Src/builtin.c b/Src/builtin.c index 696971944..d3c628592 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -973,7 +973,7 @@ cd_do_chdir(char *cnam, char *dest, int hard) * Normalize path under Cygwin to avoid messing with * DOS style names with drives in them */ - static char buf[PATH_MAX]; + static char buf[PATH_MAX+1]; #ifdef HAVE_CYGWIN_CONV_PATH cygwin_conv_path(CCP_WIN_A_TO_POSIX | CCP_RELATIVE, dest, buf, PATH_MAX); diff --git a/Src/compat.c b/Src/compat.c index 9041c0bed..81afd4dfd 100644 --- a/Src/compat.c +++ b/Src/compat.c @@ -270,7 +270,7 @@ zgetdir(struct dirsav *d) int len; #endif - buf = zhalloc(bufsiz = PATH_MAX); + buf = zhalloc(bufsiz = PATH_MAX+1); pos = bufsiz - 1; buf[pos] = '\0'; strcpy(nbuf, "../"); @@ -439,11 +439,11 @@ zgetcwd(void) free(cwd); } #else - char *cwdbuf = zalloc(PATH_MAX); + char *cwdbuf = zalloc(PATH_MAX+1); ret = getcwd(cwdbuf, PATH_MAX); if (ret) ret = dupstring(ret); - zfree(cwdbuf, PATH_MAX); + zfree(cwdbuf, PATH_MAX+1); #endif /* GETCWD_CALLS_MALLOC */ } #endif /* HAVE_GETCWD */ diff --git a/Src/exec.c b/Src/exec.c index ad80dd059..f544a33e7 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -437,7 +437,7 @@ static int zexecve(char *pth, char **argv, char **newenvp) { int eno; - static char buf[PATH_MAX * 2]; + static char buf[PATH_MAX * 2+1]; char **eep; unmetafy(pth, NULL); @@ -620,7 +620,7 @@ static void execute(LinkList args, int flags, int defpath) { Cmdnam cn; - char buf[MAXCMDLEN], buf2[MAXCMDLEN]; + char buf[MAXCMDLEN+1], buf2[MAXCMDLEN+1]; char *s, *z, *arg0; char **argv, **pp, **newenvp = NULL; int eno = 0, ee; @@ -701,7 +701,7 @@ execute(LinkList args, int flags, int defpath) /* for command -p, search the default path */ if (defpath) { - char pbuf[PATH_MAX]; + char pbuf[PATH_MAX+1]; char *dptr; if (!search_defpath(arg0, pbuf, PATH_MAX)) { @@ -721,7 +721,7 @@ execute(LinkList args, int flags, int defpath) } else { if ((cn = (Cmdnam) cmdnamtab->getnode(cmdnamtab, arg0))) { - char nn[PATH_MAX], *dptr; + char nn[PATH_MAX+1], *dptr; if (cn->node.flags & HASHED) strcpy(nn, cn->u.cmd); @@ -814,7 +814,7 @@ findcmd(char *arg0, int docopy, int default_path) } } if (cn) { - char nn[PATH_MAX]; + char nn[PATH_MAX+1]; if (cn->node.flags & HASHED) strcpy(nn, cn->u.cmd); @@ -905,7 +905,7 @@ mod_export Cmdnam hashcmd(char *arg0, char **pp) { Cmdnam cn; - char *s, buf[PATH_MAX]; + char *s, buf[PATH_MAX+1]; char **pq; for (; *pp; pp++) @@ -5602,7 +5602,7 @@ runshfunc(Eprog prog, FuncWrap wrap, char *name) Eprog getfpfunc(char *s, int *ksh, char **fname) { - char **pp, buf[PATH_MAX]; + char **pp, buf[PATH_MAX+1]; off_t len; off_t rlen; char *d; @@ -5732,7 +5732,7 @@ cancd(char *s) char *t; if (*s != '/') { - char sbuf[PATH_MAX], **cp; + char sbuf[PATH_MAX+1], **cp; if (cancd2(s)) return s; diff --git a/Src/glob.c b/Src/glob.c index 50f6dceb3..33bf2ae18 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -283,7 +283,7 @@ addpath(char *s, int l) static int statfullpath(const char *s, struct stat *st, int l) { - char buf[PATH_MAX]; + char buf[PATH_MAX+1]; DPUTS(strlen(s) + !*s + pathpos - pathbufcwd >= PATH_MAX, "BUG: statfullpath(): pathname too long"); @@ -779,7 +779,7 @@ parsepat(char *str) /* Now there is no (#X) in front, we can check the path. */ if (!pathbuf) - pathbuf = zalloc(pathbufsz = PATH_MAX); + pathbuf = zalloc(pathbufsz = PATH_MAX+1); DPUTS(pathbufcwd, "BUG: glob changed directory"); if (*str == '/') { /* pattern has absolute path */ str++; diff --git a/Src/hist.c b/Src/hist.c index eebd7dcde..5be7d2524 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -1843,7 +1843,7 @@ chrealpath(char **junkptr) # ifdef REALPATH_ACCEPTS_NULL char *lastpos, *nonreal, *real; # else - char *lastpos, *nonreal, pathbuf[PATH_MAX]; + char *lastpos, *nonreal, pathbuf[PATH_MAX+1]; char *real = pathbuf; # endif #endif diff --git a/Src/utils.c b/Src/utils.c index 151e9e4eb..7bbd5887f 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -845,7 +845,7 @@ ispwd(char *s) return 0; } -static char xbuf[PATH_MAX*2]; +static char xbuf[PATH_MAX*2+1]; /**/ static char ** @@ -884,7 +884,7 @@ static int xsymlinks(char *s, int full) { char **pp, **opp; - char xbuf2[PATH_MAX*3], xbuf3[PATH_MAX*2]; + char xbuf2[PATH_MAX*3+1], xbuf3[PATH_MAX*2+1]; int t0, ret = 0; zulong xbuflen = strlen(xbuf); @@ -1003,7 +1003,7 @@ print_if_link(char *s, int all) *xbuf = '\0'; if (all) { char *start = s + 1; - char xbuflink[PATH_MAX]; + char xbuflink[PATH_MAX+1]; for (;;) { if (xsymlinks(start, 0) > 0) { printf(" -> "); @@ -1140,7 +1140,7 @@ finddir(char *s) if(homenode.diff==1) homenode.diff = 0; if(!finddir_full) - finddir_full = zalloc(ffsz = PATH_MAX); + finddir_full = zalloc(ffsz = PATH_MAX+1); finddir_full[0] = 0; return finddir_last = NULL; } @@ -1644,7 +1644,7 @@ checkmailpath(char **s) } else if (S_ISDIR(st.st_mode)) { LinkList l; DIR *lock = opendir(unmeta(*s)); - char buf[PATH_MAX * 2], **arr, **ap; + char buf[PATH_MAX * 2 + 1], **arr, **ap; int ct = 1; if (lock) { @@ -6916,7 +6916,7 @@ strsfx(char *s, char *t) static int upchdir(int n) { - char buf[PATH_MAX]; + char buf[PATH_MAX+1]; char *s; int err = -1; -- cgit v1.2.3 From b3a88a53d379d6b59ccee468723a034f65fd757d Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sat, 19 Nov 2016 07:55:42 +0000 Subject: 39982: $SPROMPT: Don't accept a spelling correction at space/tab. The patch also downscopes a couple of local variables, with no functional change. --- ChangeLog | 5 +++++ README | 5 +++++ Src/utils.c | 8 ++++---- 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index 58ed68801..d6d241534 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-11-24 Daniel Shahaf + + * 39982: README, Src/utils.c: $SPROMPT: Don't accept a spelling + correction at space/tab. + 2016-11-23 Bart Schaefer * unposted: Src/Zle/zle_main.c: clear ERRFLAG_ERROR before diff --git a/README b/README index 855e76492..568f1ad6c 100644 --- a/README +++ b/README @@ -116,6 +116,11 @@ are output as "export" commands unless the parameter is also local, and other parameters not local to the scope are output with the "-g" option. Previously, only "typeset" commands were output, never using "-g". +8) At spelling-correction prompt ($SPROMPT), where the choices offered are +[nyae], previously would be accepted to mean [N] and and + would be accepted to mean [Y]. Now and are invalid +choices: typing either of them remains at the prompt. + Incompatibilities between 5.0.8 and 5.2 --------------------------------------- diff --git a/Src/utils.c b/Src/utils.c index 7bbd5887f..7f3ddad40 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2944,9 +2944,7 @@ mod_export void spckword(char **s, int hist, int cmd, int ask) { char *t, *correct_ignore; - int x; char ic = '\0'; - int ne; int preflen = 0; int autocd = cmd && isset(AUTOCD) && strcmp(*s, ".") && strcmp(*s, ".."); @@ -3015,6 +3013,7 @@ spckword(char **s, int hist, int cmd, int ask) } else { guess = *s; if (*guess == Tilde || *guess == String) { + int ne; ic = *guess; if (!*++t) return; @@ -3059,6 +3058,7 @@ spckword(char **s, int hist, int cmd, int ask) if (errflag) return; if (best && (int)strlen(best) > 1 && strcmp(best, guess)) { + int x; if (ic) { char *u; if (preflen) { @@ -3088,14 +3088,14 @@ spckword(char **s, int hist, int cmd, int ask) free(pptbuf); fflush(shout); zbeep(); - x = getquery("nyae \t", 0); + x = getquery("nyae", 0); if (cmd && x == 'n') pathchecked = path; } else x = 'n'; } else x = 'y'; - if (x == 'y' || x == ' ' || x == '\t') { + if (x == 'y') { *s = dupstring(best); if (hist) hwrep(best); -- cgit v1.2.3