From dc2397f7548632910267f31bc1c97d45602453c0 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 7 Mar 2016 09:44:54 +0000 Subject: users/21352: ensure $'' doesn't get elided. Assign nulstring to it if empty. Test for all forms of quotation marks. --- Src/subst.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'Src/subst.c') diff --git a/Src/subst.c b/Src/subst.c index bb1dd8939..f2d0f6553 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -145,8 +145,12 @@ stringsubstquote(char *strstart, char **pstrdpos) strret = dyncat(strstart, strsub); } else if (strdpos[len]) strret = dyncat(strsub, strdpos + len); - else + else if (*strsub) strret = strsub; + else { + /* This ensures a $'' doesn't get elided. */ + strret = dupstring(nulstring); + } *pstrdpos = strret + (strdpos - strstart) + strlen(strsub); -- cgit v1.2.3 From 9e7cefcc957e1f1201cf90bdef3e8a9fd2bb492b Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Fri, 3 Jun 2016 09:59:11 +0000 Subject: unposted: internal: Document modify(). --- ChangeLog | 4 ++++ Src/subst.c | 13 +++++++++++++ 2 files changed, 17 insertions(+) (limited to 'Src/subst.c') diff --git a/ChangeLog b/ChangeLog index 385ea2d86..f629609cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-06-03 Daniel Shahaf + + * unposted: Src/subst.c: internal: Document modify(). + 2016-06-03 Peter Stephenson * 38586: Src/Modules/parameter.c, Test/D07multibyte.ztst: diff --git a/Src/subst.c b/Src/subst.c index f2d0f6553..4e13ce11d 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -4015,6 +4015,19 @@ arithsubst(char *a, char **bptr, char *rest) return t; } +/* This function implements colon modifiers. + * + * STR is an in/out parameter. On entry it is the string (e.g., path) + * to modified. On return it is the modified path. + * + * PTR is an in/out parameter. On entry it contains the string of colon + * modifiers. On return it points past the last recognised modifier. + * + * Example: + * ENTRY: *str is "." *ptr is ":AN" + * RETURN: *str is "/home/foobar" (equal to $PWD) *ptr points to the "N" + */ + /**/ void modify(char **str, char **ptr) -- cgit v1.2.3 From 984c18048b81c39bc06b73b484ee6e0d40340e19 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sat, 4 Jun 2016 09:51:23 -0700 Subject: 38599: skip the "no such named directory" warning when NO_EXEC is in effect --- ChangeLog | 5 +++++ Src/subst.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'Src/subst.c') diff --git a/ChangeLog b/ChangeLog index 37a6fd9dc..767af7991 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-06-04 Barton E. Schaefer + + * 38599: Src/subst.c: skip the "no such named directory" warning + when NO_EXEC is in effect + 2016-06-03 Barton E. Schaefer * users/21609: Completion/Unix/Type/_path_files: do not treat diff --git a/Src/subst.c b/Src/subst.c index 4e13ce11d..8e704b1c1 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -691,7 +691,7 @@ filesubstr(char **namptr, int assign) return 0; *ptr = 0; if (!(hom = getnameddir(++str))) { - if (isset(NOMATCH)) + if (isset(NOMATCH) && isset(EXECOPT)) zerr("no such user or named directory: %s", str); *ptr = save; return 0; -- 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/subst.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 f7c3aa170b8c36b146ba7644cf3912cb1329a5d2 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Wed, 10 Aug 2016 18:33:04 -0700 Subject: 39019 (cf. PWS 39013): fix SHWORDSPLIT regression introduced by workers/29313 Also add test cases for more join/split combinations --- ChangeLog | 6 ++++++ Src/subst.c | 21 +++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) (limited to 'Src/subst.c') diff --git a/ChangeLog b/ChangeLog index 7290210b1..c3953ec7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-08-10 Barton E. Schaefer + + * 39019 (cf. PWS 39013): Src/subst.c, Test/D04parameter.ztst: + fix SHWORDSPLIT regression introduced by workers/29313; add + test cases for more join/split combinations. + 2016-08-10 Mikael Magnusson * 39014: Src/zsh_system.h, configure.ac: Use special OpenBSD diff --git a/Src/subst.c b/Src/subst.c index e3af15694..ae3e4c40c 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3454,13 +3454,22 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * exception is that ${name:-word} and ${name:+word} will have already * done any requested splitting of the word value with quoting preserved. */ - if (ssub || (spbreak && isarr >= 0) || spsep || sep) { + if (ssub || spbreak || spsep || sep) { + int force_split = !ssub && (spbreak || spsep); if (isarr) { - val = sepjoin(aval, sep, 1); - isarr = 0; - ms_flags = 0; + if (nojoin == 0) { + val = sepjoin(aval, sep, 1); + isarr = 0; + ms_flags = 0; + } else if (force_split && nojoin == 2) { + /* Hack to simulate splitting individual elements: + * first join on what we later use to split + */ + val = sepjoin(aval, spsep, 1); + isarr = 0; + } } - if (!ssub && (spbreak || spsep)) { + if (force_split && !isarr) { aval = sepsplit(val, spsep, 0, 1); if (!aval || !aval[0]) val = dupstring(""); @@ -3527,7 +3536,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, } /* * TODO: It would be really quite nice to abstract the - * isarr and !issarr code into a function which gets + * isarr and !isarr code into a function which gets * passed a pointer to a function with the effect of * the promptexpand bit. Then we could use this for * a lot of stuff and bury val/aval/isarr inside a structure -- cgit v1.2.3 From 68e14c41f28e54aef90e580411dda2385a69f43f Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Fri, 12 Aug 2016 00:55:32 -0700 Subject: 39028: more join/split cases fixed and tested. --- ChangeLog | 5 +++++ Src/subst.c | 7 ++++--- Test/D04parameter.ztst | 10 ++++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) (limited to 'Src/subst.c') diff --git a/ChangeLog b/ChangeLog index c3953ec7d..a4a141eb1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-08-12 Barton E. Schaefer + + * 39028: Src/subst.c, Test/D04parameter.ztst: more join/split + cases fixed and tested. + 2016-08-10 Barton E. Schaefer * 39019 (cf. PWS 39013): Src/subst.c, Test/D04parameter.ztst: diff --git a/Src/subst.c b/Src/subst.c index ae3e4c40c..99e1650d0 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3461,11 +3461,12 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, val = sepjoin(aval, sep, 1); isarr = 0; ms_flags = 0; - } else if (force_split && nojoin == 2) { + } else if (force_split && (spsep || nojoin == 2)) { /* Hack to simulate splitting individual elements: - * first join on what we later use to split + * forced joining as previously determined, or + * join on what we later use to forcibly split */ - val = sepjoin(aval, spsep, 1); + val = sepjoin(aval, (nojoin == 1 ? sep : spsep), 1); isarr = 0; } } diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 35630c5ca..460a841c3 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -1970,8 +1970,14 @@ set -- one:two bucklemy:shoe IFS= setopt shwordsplit - print -l ${@} + print -l ${@} ${(s.:.)*} ${(s.:.j.-.)*} ) -0:Joining of $@ does not happen when IFS is empty +0:Joining of $@ does not happen when IFS is empty, but splitting $* does >one:two >bucklemy:shoe +>one +>twobucklemy +>shoe +>one +>two-bucklemy +>shoe -- cgit v1.2.3 From a1a58dde6adaa50625016f4c7048b456b2b99a1c Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Fri, 12 Aug 2016 16:10:26 -0700 Subject: 39035: ${(A)name=word} should expand as an array even when there is only one element. --- ChangeLog | 5 +++++ Src/subst.c | 1 + Test/D04parameter.ztst | 5 +++++ 3 files changed, 11 insertions(+) (limited to 'Src/subst.c') diff --git a/ChangeLog b/ChangeLog index b1dea8da3..ffe21020b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-08-12 Barton E. Schaefer + + * 39035: Src/subst.c, Test/D04parameter.ztst: ${(A)name=word} + should expand as an array even when there is only one element. + 2016-08-12 Peter Stephenson * 39031: Src/Zle/zle_word.c: Ensure variables are initialised in diff --git a/Src/subst.c b/Src/subst.c index 99e1650d0..c61551bf6 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2897,6 +2897,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, aval = paramvalarr(pm->gsu.h->getfn(pm), hkeys|hvals); } else setaparam(idbeg, a); + isarr = 1; } else { untokenize(val); setsparam(idbeg, ztrdup(val)); diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 460a841c3..37166fa21 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -82,6 +82,11 @@ >wasnull2d >wasnull2d + unset array + print ${#${(A)=array=word}} +0:${#${(A)=array=word}} counts array elements +>1 + (print ${set1:?okhere}; print ${unset1:?exiting1}; print not reached;) (print ${null1?okhere}; print ${null1:?exiting2}; print not reached;) 1:${...:?...}, ${...?...} -- 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/subst.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 fa48711e31c4d45819455e767ad106c41f9a92fe Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sun, 28 Aug 2016 19:12:17 -0700 Subject: 39115: repair forced joining when (@) and (j) are used together --- ChangeLog | 5 +++++ Src/subst.c | 5 +++-- Test/D04parameter.ztst | 9 +++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) (limited to 'Src/subst.c') diff --git a/ChangeLog b/ChangeLog index 2d9ac8133..8bc9372d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,11 @@ * 39112: Completion/X/Command/_x_utils: Use state_descr +2016-08-28 Barton E. Schaefer + + * 39115: Src/subst.c, Test/D04parameter.ztst: repair forced + joining when (@) and (j) are used together (broken by 39019) + 2016-08-27 Daniel Shahaf * 39105: Completion/Unix/Type/_absolute_command_paths: diff --git a/Src/subst.c b/Src/subst.c index 15eb59b64..4641b4ba5 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3458,7 +3458,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, if (ssub || spbreak || spsep || sep) { int force_split = !ssub && (spbreak || spsep); if (isarr) { - if (nojoin == 0) { + /* sep non-null here means F or j flag, force join */ + if (nojoin == 0 || sep) { val = sepjoin(aval, sep, 1); isarr = 0; ms_flags = 0; @@ -3467,7 +3468,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * forced joining as previously determined, or * join on what we later use to forcibly split */ - val = sepjoin(aval, (nojoin == 1 ? sep : spsep), 1); + val = sepjoin(aval, (nojoin == 1 ? NULL : spsep), 1); isarr = 0; } } diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 37166fa21..063007956 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -1986,3 +1986,12 @@ >one >two-bucklemy >shoe + + ( + set -- "one two" "bucklemy shoe" + IFS= + setopt shwordsplit rcexpandparam + print -l "X${(@j.-.)*}" + ) +0:Use of @ does not prevent forced join with j +>Xone two-bucklemy shoe -- 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/subst.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 a4b8ee13be494c8732c0348857befe87951a058b Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 14 Sep 2016 10:32:29 +0100 Subject: zsh-users/21903: Fix ${...?...} in interactive shell. On failure should abort back to top level, but we reset the error flag around commands. Add a hard error flag that's only reset at top level. --- ChangeLog | 6 ++++++ Src/subst.c | 7 +++++++ Src/zsh.h | 9 ++++++++- Test/D04parameter.ztst | 14 ++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) (limited to 'Src/subst.c') diff --git a/ChangeLog b/ChangeLog index 0c0b72272..357782c2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-09-14 Peter Stephenson + + * zsh-users/21903: Src/subst.c, Src/zsh.h, + Test/D04parameter.ztst: ${...?...} in interactive shell should + abort to top level, not just current command. + 2016-09-14 Marko Myllynen * unposted: Completion/Unix/Command/_libvirt: Add another diff --git a/Src/subst.c b/Src/subst.c index 1c2027f32..92fde4598 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2922,6 +2922,13 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, if (isset(EXECOPT)) { *idend = '\0'; zerr("%s: %s", idbeg, *s ? s : "parameter not set"); + /* + * In interactive shell we need to return to + * top-level prompt --- don't clear this error + * after handling a command as we do with + * most errors. + */ + errflag |= ERRFLAG_HARD; if (!interact) { if (mypid == getpid()) { /* diff --git a/Src/zsh.h b/Src/zsh.h index 996bc3369..2dc5e7e2a 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2807,7 +2807,14 @@ enum errflag_bits { /* * User interrupt. */ - ERRFLAG_INT = 2 + ERRFLAG_INT = 2, + /* + * Hard error --- return to top-level prompt in interactive + * shell. In non-interactive shell we'll typically already + * have exited. This is reset by "errflag = 0" in + * loop(toplevel = 1, ...). + */ + ERRFLAG_HARD = 4 }; /***********/ diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index be6e10461..762305197 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -95,6 +95,20 @@ ?(eval):1: unset1: exiting1 ?(eval):2: null1: exiting2 + PROMPT="" $ZTST_testdir/../Src/zsh -fis <<<' + unsetopt PROMPT_SP + PS2="" PS3="" PS4="" RPS1="" RPS2="" + foo() { + print ${1:?no arguments given} + print not reached + } + foo + print reached + ' +0:interactive shell returns to top level on ${...?...} error +?foo:1: 1: no arguments given +>reached + print ${set1:+word1} ${set1+word2} ${null1:+word3} ${null1+word4} print ${unset1:+word5} ${unset1+word6} 0:${...:+...}, ${...+...} -- cgit v1.2.3 From 07c8fbe59632be71e4ad5bfafbf6aa4884cd04c4 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 29 Sep 2016 11:00:44 +0100 Subject: 34943: Fixes for "command" with multiple options. These need to combine properly, and alos "command -p" with either -v or -V needs to search for builtins and then using the default system path. --- ChangeLog | 7 +++ Src/builtin.c | 10 +++- Src/exec.c | 153 ++++++++++++++++++++++++++++++++++++++------------- Src/subst.c | 2 +- Test/A01grammar.ztst | 10 ++++ 5 files changed, 143 insertions(+), 39 deletions(-) (limited to 'Src/subst.c') diff --git a/ChangeLog b/ChangeLog index 5dc281a6f..35dfae0d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2016-09-29 Peter Stephenson + + * 39493: Src/builtin.c, Src/exec.c, Src/subst.c, + Test/A01grammar.ztst: make "command" with multiple options work + better and ensure "command -p" with "-v" or "-V" checks for a + builtin and then using the system default command path. + 2016-09-28 Peter Stephenson * Martijn Dekker: 39463: configure.ac: another way of getting diff --git a/Src/builtin.c b/Src/builtin.c index 248f929d7..c78fd9b3a 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3643,7 +3643,15 @@ bin_whence(char *nam, char **argv, Options ops, int func) returnval = 1; } popheap(); - } else if ((cnam = findcmd(*argv, 1))) { + } else if (func == BIN_COMMAND && + (hn = builtintab->getnode(builtintab, *argv))) { + /* + * Special case for "command -p[vV]" which needs to + * show a builtin in preference to an external command. + */ + builtintab->printnode(hn, printflags); + informed = 1; + } else if ((cnam = findcmd(*argv, 1, func == BIN_COMMAND))) { /* Found external command. */ if (wd) { printf("%s: command\n", *argv); diff --git a/Src/exec.c b/Src/exec.c index c27c41c1b..c79a27895 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -207,7 +207,7 @@ static int (*execfuncs[WC_COUNT-WC_CURSH]) _((Estate, int)) = { /* structure for command builtin for when it is used with -v or -V */ static struct builtin commandbn = - BUILTIN(0, 0, bin_whence, 0, -1, BIN_COMMAND, "vV", NULL); + BUILTIN("command", 0, bin_whence, 0, -1, BIN_COMMAND, "pvV", NULL); /* parse string into a list */ @@ -575,6 +575,41 @@ commandnotfound(char *arg0, LinkList args) return doshfunc(shf, args, 1); } +/* + * Search the default path for cmd. + * pbuf of length plen is the buffer to use. + * Return NULL if not found. + */ + +static char * +search_defpath(char *cmd, char *pbuf, int plen) +{ + char *ps = DEFAULT_PATH, *pe = NULL, *s; + + for (ps = DEFAULT_PATH; ps; ps = pe ? pe+1 : NULL) { + pe = strchr(ps, ':'); + if (*ps == '/') { + s = pbuf; + if (pe) { + if (pe - ps >= plen) + continue; + struncpy(&s, ps, pe-ps); + } else { + if (strlen(ps) >= plen) + continue; + strucpy(&s, ps); + } + *s++ = '/'; + if ((s - pbuf) + strlen(cmd) >= plen) + continue; + strucpy(&s, cmd); + if (iscom(pbuf)) + return pbuf; + } + } + return NULL; +} + /* execute an external command */ /**/ @@ -663,27 +698,10 @@ execute(LinkList args, int flags, int defpath) /* for command -p, search the default path */ if (defpath) { - char *s, pbuf[PATH_MAX]; - char *dptr, *pe, *ps = DEFAULT_PATH; - - for(;ps;ps = pe ? pe+1 : NULL) { - pe = strchr(ps, ':'); - if (*ps == '/') { - s = pbuf; - if (pe) - struncpy(&s, ps, pe-ps); - else - strucpy(&s, ps); - *s++ = '/'; - if ((s - pbuf) + strlen(arg0) >= PATH_MAX) - continue; - strucpy(&s, arg0); - if (iscom(pbuf)) - break; - } - } + char pbuf[PATH_MAX]; + char *dptr; - if (!ps) { + if (!search_defpath(arg0, pbuf, PATH_MAX)) { if (commandnotfound(arg0, args) == 0) _exit(0); zerr("command not found: %s", arg0); @@ -760,17 +778,26 @@ execute(LinkList args, int flags, int defpath) /* * Get the full pathname of an external command. * If the second argument is zero, return the first argument if found; - * if non-zero, return the path using heap memory. (RET_IF_COM(X), above). + * if non-zero, return the path using heap memory. (RET_IF_COM(X), + * above). + * If the third argument is non-zero, use the system default path + * instead of the current path. */ /**/ mod_export char * -findcmd(char *arg0, int docopy) +findcmd(char *arg0, int docopy, int default_path) { char **pp; char *z, *s, buf[MAXCMDLEN]; Cmdnam cn; + if (default_path) + { + if (search_defpath(arg0, buf, MAXCMDLEN)) + return docopy ? dupstring(buf) : arg0; + return NULL; + } cn = (Cmdnam) cmdnamtab->getnode(cmdnamtab, arg0); if (!cn && isset(HASHCMDS) && !isrelative(arg0)) cn = hashcmd(arg0, path); @@ -2662,24 +2689,76 @@ execcmd(Estate state, int input, int output, int how, int last1) } checked = 0; if ((cflags & BINF_COMMAND) && nextnode(firstnode(args))) { - /* check for options to command builtin */ - char *next = (char *) getdata(nextnode(firstnode(args))); + /* + * Check for options to "command". + * If just -p, this is handled here: use the default + * path to execute. + * If -v or -V, possibly with -p, dispatch to bin_whence + * but with flag to indicate special handling of -p. + * Otherwise, just leave marked as BINF_COMMAND + * modifier with no additional action. + */ + LinkNode argnode = nextnode(firstnode(args)); + char *argdata = (char *) getdata(argnode); char *cmdopt; - if (next && *next == '-' && strlen(next) == 2 && - (cmdopt = strchr("pvV", next[1]))) - { - if (*cmdopt == 'p') { - uremnode(args, firstnode(args)); - use_defpath = 1; - if (nextnode(firstnode(args))) - next = (char *) getdata(nextnode(firstnode(args))); - } else { - hn = &commandbn.node; - is_builtin = 1; + int has_p = 0, has_vV = 0, has_other = 0; + while (*argdata == '-') { + /* Just to be definite, stop on single "-", too, */ + if (!argdata[1] || (argdata[1] == '-' && !argdata[2])) + break; + for (cmdopt = argdata+1; *cmdopt; cmdopt++) { + switch (*cmdopt) { + case 'p': + /* + * If we've got this multiple times (command + * -p -p) we'll treat the second -p as a + * command because we only remove one below. + * Don't think that's a big issue, and it's + * also traditional behaviour. + */ + has_p = 1; + break; + case 'v': + case 'V': + has_vV = 1; + break; + default: + has_other = 1; + break; + } + } + if (has_other) { + /* Don't know how to handle this, so don't */ + has_p = has_vV = 0; break; } + + argnode = nextnode(argnode); + if (!argnode) + break; + argdata = (char *) getdata(argnode); } - if (!strcmp(next, "--")) + if (has_vV) { + /* Leave everything alone, dispatch to whence */ + hn = &commandbn.node; + is_builtin = 1; + break; + } else if (has_p) { + /* Use default path; absorb command and option. */ + uremnode(args, firstnode(args)); + use_defpath = 1; + if ((argnode = nextnode(firstnode(args)))) + argdata = (char *) getdata(argnode); + } + /* + * Else just absorb command and any trailing + * end-of-options marker. This can only occur + * if we just had -p or something including more + * than just -p, -v and -V, in which case we behave + * as if this is command [non-option-stuff]. This + * isn't a good place for standard option handling. + */ + if (!strcmp(argdata, "--")) uremnode(args, firstnode(args)); } if ((cflags & BINF_EXEC) && nextnode(firstnode(args))) { diff --git a/Src/subst.c b/Src/subst.c index 92fde4598..ecd74879f 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -627,7 +627,7 @@ equalsubstr(char *str, int assign, int nomatch) cmdstr = dupstrpfx(str, pp-str); untokenize(cmdstr); remnulargs(cmdstr); - if (!(cnam = findcmd(cmdstr, 1))) { + if (!(cnam = findcmd(cmdstr, 1, 0))) { if (nomatch) zerr("%s not found", cmdstr); return NULL; diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst index 394480c19..921ff99a4 100644 --- a/Test/A01grammar.ztst +++ b/Test/A01grammar.ztst @@ -113,6 +113,16 @@ External command cat executed + command -pv cat + command -pv echo + command -p -V cat + command -p -V -- echo +0:command -p in combination +*>*/cat +>echo +>cat is /*/cat +>echo is a shell builtin + cd() { echo Not cd at all; } builtin cd . && unfunction cd 0:`builtin' precommand modifier -- cgit v1.2.3 From a96e34b459d55240b0f4af37ac73aca916720883 Mon Sep 17 00:00:00 2001 From: Julien Cretin Date: Thu, 6 Oct 2016 11:36:32 +0200 Subject: 39579: Fix string calculation for parameter quoting. Where there was no closing quote the size or position of the null could be wrongly calculated. --- ChangeLog | 4 ++++ Src/subst.c | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'Src/subst.c') diff --git a/ChangeLog b/ChangeLog index e3e276e00..aec3a20aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2016-10-06 Peter Stephenson + * Julien Cretin: 39579: Src/subst.c: position of \0 + with optional quoting in parameter substitution was wrongly + calculated. + * 39578: Test/C03traps.ztst: Test some more ERR_RETURN cases involving "&&" and functions. diff --git a/Src/subst.c b/Src/subst.c index ecd74879f..447177409 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3629,7 +3629,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, if (pre) ap[0][pre - 1] = ap[0][pre + sl] = (quotetype != QT_DOUBLE ? '\'' : '"'); - ap[0][pre + sl + 1] = '\0'; + ap[0][pre + sl + post] = '\0'; if (quotetype == QT_DOLLARS) ap[0][0] = '$'; } @@ -3667,12 +3667,12 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, char *tmp; tmp = quotestring(val, quotetype); sl = strlen(tmp); - val = (char *) zhalloc(pre + sl + 2); + val = (char *) zhalloc(pre + sl + post + 1); strcpy(val + pre, tmp); if (pre) val[pre - 1] = val[pre + sl] = (quotetype != QT_DOUBLE ? '\'' : '"'); - val[pre + sl + 1] = '\0'; + val[pre + sl + post] = '\0'; if (quotetype == QT_DOLLARS) val[0] = '$'; } else -- 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/subst.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 110ffae9fefa1367af4fdcc90a456de23b92436c Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Mon, 28 Nov 2016 22:53:24 -0800 Subject: 40035: Cosmetic fixes for comments and documentation. Mostly fixes to doubled words. --- ChangeLog | 7 +++++-- Completion/Base/Utility/_arguments | 2 +- Completion/Unix/Command/_git | 2 +- Completion/Unix/Type/_zfs_dataset | 2 +- Completion/Zsh/Command/_zstyle | 2 +- Completion/Zsh/Function/_zargs | 2 +- Doc/Zsh/builtins.yo | 2 +- Doc/Zsh/compsys.yo | 4 ++-- Doc/Zsh/contrib.yo | 2 +- Etc/ChangeLog-4.3 | 2 +- Src/Zle/zle_refresh.c | 2 +- Src/glob.c | 2 +- Src/hist.c | 2 +- Src/input.c | 2 +- Src/subst.c | 2 +- Src/zsh.h | 2 +- Util/helpfiles | 2 +- 17 files changed, 22 insertions(+), 19 deletions(-) (limited to 'Src/subst.c') diff --git a/ChangeLog b/ChangeLog index a016ce0e6..0d5f61198 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-11-29 Peter Stephenson + * 40035: Eitan Adler: Cosmetic fixes mostly for duplication in + comments and documentation. + * 40026: Src/Zle/zle_tricky.c: More care with redirection completion. Fixes for completion after > in "!> ." that should add to sanity. @@ -3523,7 +3526,7 @@ 2015-09-28 Barton E. Schaefer - * 36669: Src/lex.c: fix ${(z)...} of an an incomplete math + * 36669: Src/lex.c: fix ${(z)...} of an incomplete math expression by restoring "((" at the front of the token 2015-09-28 Daniel Shahaf @@ -9517,7 +9520,7 @@ 2013-07-20 Peter Stephenson * 31545: Src/exec.c, Src/parse.c: if FD_CLOEXEC is available, - so mark dump file file descriptors, avoiding possible + so mark dump file descriptors, avoiding possible multiple use of file descriptors. 2013-07-19 Peter Stephenson diff --git a/Completion/Base/Utility/_arguments b/Completion/Base/Utility/_arguments index 82c969629..d2c0d33de 100644 --- a/Completion/Base/Utility/_arguments +++ b/Completion/Base/Utility/_arguments @@ -105,7 +105,7 @@ if (( long )); then continue else # Still no comment, add the previous options anyway. - # Add a ':' after the option anyways, to make the the matching of + # Add a ':' after the option anyways, to make the matching of # the options lateron work as intended. # It will be removed again later. lopts+=("${^tmp[@]}":) diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 283c50cc0..da049bd23 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -6114,7 +6114,7 @@ __git_recent_branches() { local -aU valid_ref_names_munged=( ${"${(f)"$(_call_program valid-ref-names 'git for-each-ref --format="%(refname)" refs/heads/')"}"#refs/heads/} ) # 1. Obtain names of recently-checked-out branches from the reflog. - # 2. Remove ref names that that no longer exist from the list. + # 2. Remove ref names that no longer exist from the list. # (We must do this because #3 would otherwise croak on them.) __git_recent_branches__names; branches=( ${(@)reply:*valid_ref_names_munged} ) diff --git a/Completion/Unix/Type/_zfs_dataset b/Completion/Unix/Type/_zfs_dataset index 6c625e9ec..6bef04e45 100644 --- a/Completion/Unix/Type/_zfs_dataset +++ b/Completion/Unix/Type/_zfs_dataset @@ -4,7 +4,7 @@ local -a type expl_type_arr rsrc rdst paths_allowed local -a typearg datasetlist expl mlist local expl_type -# -e takes an argument which is passed as as the "descr" argument to _wanted +# -e takes an argument which is passed as the "descr" argument to _wanted # -p indicates that filesystem paths, not just dataset names, are allowed # -r1 indicates that we're completing the source of a rename # -r2 indicates that we're completing the destination of a rename diff --git a/Completion/Zsh/Command/_zstyle b/Completion/Zsh/Command/_zstyle index d6f285271..0e828225e 100644 --- a/Completion/Zsh/Command/_zstyle +++ b/Completion/Zsh/Command/_zstyle @@ -266,7 +266,7 @@ while (( $#state )); do _wanted contexts expl "$state_descr" compadd -a patterns ;; - # 'metapatterns': patterns that are are matched not against contexts, but + # 'metapatterns': patterns that are matched not against contexts, but # against patterns. (metapatterns) zstyle -g patterns diff --git a/Completion/Zsh/Function/_zargs b/Completion/Zsh/Function/_zargs index c24b276f2..f974ab646 100644 --- a/Completion/Zsh/Function/_zargs +++ b/Completion/Zsh/Function/_zargs @@ -4,7 +4,7 @@ local arguments eofstr pos=$((CURRENT)) numeofs=0 ret=1 cmdpos=1 #this doesn't handle '--' on the command line, only -- #it also by extension doesn't handle eofstr being the empty string -#it also also doesn't handle eofstr being -e or --eof, and everything will +#it also doesn't handle eofstr being -e or --eof, and everything will # probably also be confused if the command at the end takes a -e, --eof= or -- eofstr=${${${${words[(r)(--eof=*|-e*)]}#--eof=}#-e}:---} while { diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 169a31ea3..7b04d0648 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -570,7 +570,7 @@ with emulations to be set to their values in tt(sh). tt(fno) then calls tt(fni); because tt(fni) is also marked for sticky tt(sh) emulation, no option changes take place on entry to or exit from it. Hence the option tt(cshnullglob), turned off by tt(sh) emulation, will -be turned on within tt(fni) and remain on on return to tt(fno). On exit +be turned on within tt(fni) and remain on return to tt(fno). On exit from tt(fno), the emulation mode and all options will be restored to the state they were in before entry to the temporary emulation. diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index ceb98c7bc..60ef9ee2c 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -144,8 +144,8 @@ directory mentioned in the tt(fpath) parameter, and should be autoloaded few utility functions, arrange for all the necessary shell functions to be autoloaded, and will then re-define all widgets that do completion to use the new system. If you use the tt(menu-select) widget, which is part of the -tt(zsh/complist) module, you should make sure that that module is loaded -before the call to tt(compinit) so that that widget is also +tt(zsh/complist) module, you should make sure that the module is loaded +before the call to tt(compinit) so that the widget is also re-defined. If completion styles (see below) are set up to perform expansion as well as completion by default, and the TAB key is bound to tt(expand-or-complete), tt(compinit) will rebind it to tt(complete-word); diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 623507283..f764eb7c6 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -3854,7 +3854,7 @@ The expression tt(<) followed (with no space) by a shell identifier causes the value of the variable with that name to be pushed onto the stack. var(ident) may be an integer, in which case the previous result with that number (as shown before -the tt(>) in th standard standard tt(zcalc) prompt) is put on the stack. +the tt(>) in the standard tt(zcalc) prompt) is put on the stack. ) item(Exchange: tt(xy))( The pseudo-function tt(xy) causes the most recent two elements of diff --git a/Etc/ChangeLog-4.3 b/Etc/ChangeLog-4.3 index 1be618b48..6d85e40af 100644 --- a/Etc/ChangeLog-4.3 +++ b/Etc/ChangeLog-4.3 @@ -1182,7 +1182,7 @@ 2011-08-16 Wayne Davison - * 29650: Src/jobs.c: don't lose the the time info after a + * 29650: Src/jobs.c: don't lose the time info after a suspend+restore. 2011-08-15 Peter Stephenson diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index e78f1e562..8d173cda1 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -946,7 +946,7 @@ addmultiword(REFRESH_ELEMENT *base, ZLE_STRING_T tptr, int ichars) /* * Swap the old and new video buffers, plus any associated multiword - * buffers. The new buffer becomes the old one; the new new buffer + * buffers. The new buffer becomes the old one; the new buffer * will be filled with the command line next time. */ static void diff --git a/Src/glob.c b/Src/glob.c index 33bf2ae18..623e6f1d6 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -1174,7 +1174,7 @@ checkglobqual(char *str, int sl, int nobareglob, char **sp) } /* Main entry point to the globbing code for filename globbing. * - * np points to a node in the list list which will be expanded * + * np points to a node in the list which will be expanded * * into a series of nodes. */ /**/ diff --git a/Src/hist.c b/Src/hist.c index 5be7d2524..97fd34039 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -1038,7 +1038,7 @@ hbegin(int dohist) /* * pws: We used to test for "|| (inbufflags & INP_ALIAS)" * in this test, but at this point we don't have input - * set up up so this can trigger unnecessarily. + * set up so this can trigger unnecessarily. * I don't see how the test at this point could ever be * useful, since we only get here when we're initialising * the history mechanism, before we've done any input. diff --git a/Src/input.c b/Src/input.c index eb968ea72..fe94b8ef7 100644 --- a/Src/input.c +++ b/Src/input.c @@ -51,7 +51,7 @@ * Note that the input string is itself used as the input buffer: it is not * copied, nor is it every written back to, so using a constant string * should work. Consequently, when passing areas of memory from the heap - * it is necessary that that heap last as long as the operation of reading + * it is necessary that the heap last as long as the operation of reading * the string. After the string is read, the stack should be popped with * inpop(), which effectively flushes any unread input as well as restoring * the previous input state. diff --git a/Src/subst.c b/Src/subst.c index c7c552257..a26ebb1d6 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2368,7 +2368,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * This is the inner handling for the case referred to above * where we have something like ${${(P)name}...}. * - * Treat this as as a normal value here; all transformations on + * Treat this as a normal value here; all transformations on * result are in outer instance. */ aspar = 0; diff --git a/Src/zsh.h b/Src/zsh.h index a5d4455e3..63cada827 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1589,7 +1589,7 @@ struct zpc_disables_save { /* * Bit vector of ZPC_COUNT disabled characters. * We'll live dangerously and assumed ZPC_COUNT is no greater - * than the number of bits an an unsigned int. + * than the number of bits an unsigned int. */ unsigned int disables; }; diff --git a/Util/helpfiles b/Util/helpfiles index 699ca8321..9e837fe2d 100755 --- a/Util/helpfiles +++ b/Util/helpfiles @@ -19,7 +19,7 @@ # This script is called automatically during `make install' # unless specified otherwise. -# For usage and and more information see zshcontrib(1). +# For usage and more information see zshcontrib(1). sub Usage { print(STDERR "Usage: helpfiles zshbuiltins.1 dest-dir [link-file]\n"); -- cgit v1.2.3 From 3ba86f4db44e6b5f854909fbc639ef3111ec176b Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Tue, 29 Nov 2016 12:35:57 -0800 Subject: 40034: clear badcshglob when ignoring errors --- ChangeLog | 2 ++ Src/subst.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'Src/subst.c') diff --git a/ChangeLog b/ChangeLog index 6ed44eb4c..3255bf6b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2016-11-29 Barton E. Schaefer + * 40034: Src/subst.c: clear badcshglob when ignoring errors + * unposted: README: example describing 40032 * 40032: Src/params.c: consistency in handling of subscript diff --git a/Src/subst.c b/Src/subst.c index a26ebb1d6..06d2c9ea9 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -411,7 +411,9 @@ globlist(LinkList list, int nountok) next = nextnode(node); zglob(list, node, nountok); } - if (badcshglob == 1) + if (noerrs) + badcshglob = 0; + else if (badcshglob == 1) zerr("no match"); } -- cgit v1.2.3