From 1aec003155e8ccd8e0e3b9a6bd8c9fdb141d5c81 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 21 Jan 2016 16:30:21 +0000 Subject: 37722: test builtin should return status 2 on syntax error --- Src/builtin.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Src/builtin.c') diff --git a/Src/builtin.c b/Src/builtin.c index dd20f9eab..98ecb09e8 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -6531,7 +6531,7 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func) for (s = argv; *s; s++); if (s == argv || strcmp(s[-1], "]")) { zwarnnam(name, "']' expected"); - return 1; + return 2; } s[-1] = NULL; } @@ -6574,19 +6574,19 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func) if (errflag) { errflag &= ~ERRFLAG_ERROR; zcontext_restore(); - return 1; + return 2; } if (!prog || tok == LEXERR) { zwarnnam(name, tokstr ? "parse error" : "argument expected"); zcontext_restore(); - return 1; + return 2; } zcontext_restore(); if (*curtestarg) { zwarnnam(name, "too many arguments"); - return 1; + return 2; } /* syntax is OK, so evaluate */ -- cgit v1.2.3 From 7c59c953f28026559325473ba53be0dd3a661109 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 25 Jan 2016 16:23:16 +0000 Subject: 37765: Use FS_FUNC on fucstack to find autoload -X target. This is better than scriptname which can be updated due to e.g. intervening "eval". --- ChangeLog | 3 +++ Src/builtin.c | 32 +++++++++++++++++++++++++------- Test/C04funcdef.ztst | 13 +++++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 4a8077ab4..fb75a1e43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-01-25 Peter Stephenson + * 37765: Src/builtin.c, Test/C04funcdef.ztst: Use FS_FUNC on + funcstack to find autoload -X target rather than scriptname. + * 37776: Src/utils.c: set errflag before calling zwarning() to avoid recursive error messages. diff --git a/Src/builtin.c b/Src/builtin.c index 98ecb09e8..63f964d3d 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3142,15 +3142,33 @@ bin_functions(char *name, char **argv, Options ops, int func) queue_signals(); if (OPT_MINUS(ops,'X')) { - if ((shf = (Shfunc) shfunctab->getnode(shfunctab, scriptname))) { - DPUTS(!shf->funcdef, - "BUG: Calling autoload from empty function"); + Funcstack fs; + char *funcname = NULL; + for (fs = funcstack; fs; fs = fs->prev) { + if (fs->tp == FS_FUNC) { + /* + * dupstring here is paranoia but unlikely to be + * problematic + */ + funcname = dupstring(fs->name); + break; + } + } + if (!funcname) + { + zerrnam(name, "bad autoload"); + ret = 1; } else { - shf = (Shfunc) zshcalloc(sizeof *shf); - shfunctab->addnode(shfunctab, ztrdup(scriptname), shf); + if ((shf = (Shfunc) shfunctab->getnode(shfunctab, funcname))) { + DPUTS(!shf->funcdef, + "BUG: Calling autoload from empty function"); + } else { + shf = (Shfunc) zshcalloc(sizeof *shf); + shfunctab->addnode(shfunctab, ztrdup(funcname), shf); + } + shf->node.flags = on; + ret = eval_autoload(shf, funcname, ops, func); } - shf->node.flags = on; - ret = eval_autoload(shf, scriptname, ops, func); } else { if (OPT_ISSET(ops,'U') && !OPT_ISSET(ops,'u')) on &= ~PM_UNDEFINED; diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst index 0951e2cde..496577f6c 100644 --- a/Test/C04funcdef.ztst +++ b/Test/C04funcdef.ztst @@ -308,6 +308,19 @@ ?(eval):6: command not found: firstfn1 ?(eval):7: command not found: secondfn1 + ( + fpath=(.) + print "print oops was successfully autoloaded" >oops + oops() { eval autoload -X } + oops + which -x2 oops + ) +0:autoload containing eval +>oops was successfully autoloaded +>oops () { +> print oops was successfully autoloaded +>} + %clean rm -f file.in file.out -- cgit v1.2.3 From 95663e936596933d529a648ed3d6c707d1a1dffe Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Mon, 8 Feb 2016 20:50:07 -0800 Subject: 37914: reparse associative array subscripts in "unset" so keys with "[" or "]" may be backslash-escaped Also fix erroneous test case this revealed. --- ChangeLog | 6 ++++++ Src/builtin.c | 30 ++++++++++++++++++------------ Test/E01options.ztst | 2 +- 3 files changed, 25 insertions(+), 13 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 76add9f27..7faa5ecaf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,12 @@ * unposted: ChangeLog: Move the 37678 entry to the correct location (and author). +2016-02-08 Barton E. Schaefer + + * 37914: Src/builtin.c, Test/E01options.ztst: reparse associative + array subscripts in "unset" so keys with "[" or "]" may be + backslash-escaped. Fix erroneous test case this revealed. + 2016-02-07 Dominik Ritter * unposted: Doc/Zsh/mod_complist.yo: complist module docs: diff --git a/Src/builtin.c b/Src/builtin.c index 63f964d3d..4c8fbcdb1 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3350,15 +3350,24 @@ bin_unset(char *name, char **argv, Options ops, int func) /* do not glob -- unset the given parameter */ queue_signals(); while ((s = *argv++)) { - char *ss = strchr(s, '['); - char *sse = ss; + char *ss = strchr(s, '['), *subscript = 0; if (ss) { - if (skipparens('[', ']', &sse) || *sse) { - zerrnam(name, "%s: invalid parameter name", s); - returnval = 1; - continue; - } + char *sse; *ss = 0; + if ((sse = parse_subscript(ss+1, 1, ']'))) { + *sse = 0; + subscript = dupstring(ss+1); + *sse = ']'; + remnulargs(subscript); + untokenize(subscript); + } + } + if ((ss && !subscript) || !isident(s)) { + if (ss) + *ss = '['; + zerrnam(name, "%s: invalid parameter name", s); + returnval = 1; + continue; } pm = (Param) (paramtab == realparamtab ? /* getnode2() to avoid autoloading */ @@ -3376,11 +3385,8 @@ bin_unset(char *name, char **argv, Options ops, int func) } else if (ss) { if (PM_TYPE(pm->node.flags) == PM_HASHED) { HashTable tht = paramtab; - if ((paramtab = pm->gsu.h->getfn(pm))) { - *--sse = 0; - unsetparam(ss+1); - *sse = ']'; - } + if ((paramtab = pm->gsu.h->getfn(pm))) + unsetparam(subscript); paramtab = tht; } else if (PM_TYPE(pm->node.flags) == PM_SCALAR || PM_TYPE(pm->node.flags) == PM_ARRAY) { diff --git a/Test/E01options.ztst b/Test/E01options.ztst index f27076765..40e96afc9 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -776,7 +776,7 @@ unsetopt pathdirs pathtestdir/findme path=($oldpath) - unset $oldpath + unset oldpath rm -rf pdt_topdir pathtestdir 0:PATH_DIRS option >File in upper dir -- cgit v1.2.3 From e1c745a0dca56afb9cfcace1ef59449152290188 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Fri, 22 Apr 2016 10:12:17 -0700 Subject: 38306: in printf formats, treat a missing precision as zero rather than as unlimited --- ChangeLog | 5 +++++ Src/builtin.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 219d55608..4fa96e7fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-04-22 Barton E. Schaefer + + * 38306: Src/builtin.c: in printf formats, treat a missing + precision as zero rather than as unlimited + 2016-04-15 Barton E. Schaefer * 38289: Completion/compinit: "builtin enable" in $_comp_setup diff --git a/Src/builtin.c b/Src/builtin.c index 4c8fbcdb1..ad01ad4f1 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4736,7 +4736,8 @@ bin_print(char *name, char **args, Options ops, int func) } else if (idigit(*c)) { prec = strtoul(c, &endptr, 0); c = endptr; - } + } else + prec = 0; if (prec >= 0) *d++ = '.', *d++ = '*'; } -- cgit v1.2.3 From 9afb67eb6561e922fae29e7227a58517f73ad050 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Fri, 29 Apr 2016 13:15:33 -0700 Subject: unposted: silence spurious compiler warning --- ChangeLog | 2 ++ Src/builtin.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 8f98a7cd5..190646841 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2016-04-29 Barton E. Schaefer + * unposted: Src/builtin.c: silence spurious compiler warning + * 38358: Test/C02cond.ztst: "fgrep --" for noatime check in case a mount point is named "-" as in Fedora mock environment diff --git a/Src/builtin.c b/Src/builtin.c index ad01ad4f1..6f07fc678 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4048,7 +4048,7 @@ bin_print(char *name, char **args, Options ops, int func) int flags[6], *len; char *start, *endptr, *c, *d, *flag, *buf = NULL, spec[14], *fmt = NULL; char **first, **argp, *curarg, *flagch = "'0+- #", save = '\0', nullstr = '\0'; - size_t rcount, count = 0; + size_t rcount = 0, count = 0; FILE *fout = stdout; #ifdef HAVE_OPEN_MEMSTREAM size_t mcount; -- cgit v1.2.3 From 769bd4070a26ed356410187bfdd0e61939bf8481 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Tue, 7 Jun 2016 10:08:02 -0700 Subject: 38630: fix infinite loop of "hash =" --- ChangeLog | 4 ++++ Src/builtin.c | 1 + 2 files changed, 5 insertions(+) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 5ff60c6f2..b066f208e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-06-07 Barton E. Schaefer + + * 38630: Src/builtin.c: fix infinite loop of "hash =" + 2016-06-06 Daniel Shahaf * 38610: Functions/VCS_Info/VCS_INFO_quilt: vcs_info quilt: diff --git a/Src/builtin.c b/Src/builtin.c index 6f07fc678..c2fb81ed1 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3748,6 +3748,7 @@ bin_hash(char *name, char **argv, Options ops, UNUSED(int func)) if (!(asg = getasg(&argv, NULL))) { zwarnnam(name, "bad assignment"); returnval = 1; + break; } else if (ASG_VALUEP(asg)) { if(isset(RESTRICTED)) { zwarnnam(name, "restricted: %s", asg->value.scalar); -- cgit v1.2.3 From 5ea32ce2fcd527e9b6e6991c007d296afc5aa44d Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 29 Jun 2016 17:04:50 +0200 Subject: 38752: add comments to explain use of stdout instead of stderr for the which builtin --- ChangeLog | 5 +++++ Src/builtin.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 503b905f8..4f0a49397 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-06-29 Oliver Kiddle + + * 38752: Src/builtin.c: add comments to explain use of stdout + instead of stderr for the which builtin + 2016-06-27 Daniel Shahaf * 38760: Completion/Unix/Command/_git: _git-config: Stop trying diff --git a/Src/builtin.c b/Src/builtin.c index c2fb81ed1..bfb9e6929 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3633,6 +3633,7 @@ bin_whence(char *nam, char **argv, Options ops, int func) } } if (!informed && (wd || v || csh)) { + /* this is information and not an error so, as in csh, use stdout */ zputs(*argv, stdout); puts(wd ? ": none" : " not found"); returnval = 1; @@ -3652,7 +3653,7 @@ bin_whence(char *nam, char **argv, Options ops, int func) } informed = 1; } else { - /* Not found at all. */ + /* Not found at all. That's not an error as such so this goes to stdout */ if (v || csh || wd) zputs(*argv, stdout), puts(wd ? ": none" : " not found"); returnval = 1; -- 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/builtin.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 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/builtin.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 fe3a63fa6cdffa020e380d3e27cf0eb8f3b46b1f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 6 Sep 2016 09:42:33 +0100 Subject: 39181: Add PM_SINGLE and use for compstate. This flags that compstate (or any other special) can only have a single instance and an attempt to create a new one is an error. Given the very fiddly semantics of compstate any other usage seems pointless. No investigation yet of other variables that could use this. Note it's still possible to hide such variables; only instances that keep the special nature are affected. --- ChangeLog | 5 +++++ Src/Zle/complete.c | 5 +++-- Src/builtin.c | 4 ++++ Src/zsh.h | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 341555f9d..618a45e43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-09-06 Peter Stephenson + + * 39181: Src/builtin.c, Src/zsh.h, Src/Zle/complete.c: Add + PM_SINGLE for single instance and use for compstate. + 2016-09-06 Marko Myllynen * 39179 (plus tweak): Completion/Unix/Command/_libvirt: More diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c index b28b95ef9..4bf238fab 100644 --- a/Src/Zle/complete.c +++ b/Src/Zle/complete.c @@ -1238,8 +1238,9 @@ makecompparams(void) addcompparams(comprparams, comprpms); - if (!(cpm = createparam(COMPSTATENAME, - PM_SPECIAL|PM_REMOVABLE|PM_LOCAL|PM_HASHED))) + if (!(cpm = createparam( + COMPSTATENAME, + PM_SPECIAL|PM_REMOVABLE|PM_SINGLE|PM_LOCAL|PM_HASHED))) cpm = (Param) paramtab->getnode(paramtab, COMPSTATENAME); DPUTS(!cpm, "param not set in makecompparams"); diff --git a/Src/builtin.c b/Src/builtin.c index da453000c..3b82c9e7f 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2266,6 +2266,10 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), zerrnam(cname, "%s: restricted", pname); return pm; } + if (pm->node.flags & PM_SINGLE) { + zerrnam(cname, "%s: can only have a single instance", pname); + return pm; + } /* * For specials, we keep the same struct but zero everything. * Maybe it would be easier to create a new struct but copy diff --git a/Src/zsh.h b/Src/zsh.h index 36fddd000..87e6a9868 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1792,6 +1792,7 @@ struct tieddata { #define PM_ZSHSTORED (1<<18) /* function stored in zsh form */ /* Remaining flags do not correspond directly to command line arguments */ +#define PM_SINGLE (1<<20) /* special can only have a single instance */ #define PM_LOCAL (1<<21) /* this parameter will be made local */ #define PM_SPECIAL (1<<22) /* special builtin parameter */ #define PM_DONTIMPORT (1<<23) /* do not import this variable */ -- 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/builtin.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 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/builtin.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 3608fa79613783fbbc9e3a25e231c470fb81ed24 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Fri, 30 Sep 2016 15:52:08 -0700 Subject: 39509: in the event the current directory has been removed, use chasedots semantics for "cd ..". --- ChangeLog | 5 +++++ Src/builtin.c | 25 +++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 3b6b86fe2..2ed7dcc22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-09-30 Barton E. Schaefer + + * 39509: Src/builtins.c: in the event the current directory has + been removed, use chasedots semantics for "cd ..". + 2016-09-30 Peter Stephenson * 39519: Src/params.c: setting PM_EXPORT was missing in diff --git a/Src/builtin.c b/Src/builtin.c index c78fd9b3a..60dc07f25 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -1273,7 +1273,23 @@ fixdir(char *src) #ifdef __CYGWIN__ char *s0 = src; #endif - int ret = 0; + /* This function is always called with n path containing at + * least one slash, either because one was input by the user or + * because the caller has prepended either pwd or a cdpath dir. + * If asked to make a relative change and pwd is set to ".", + * the current directory has been removed out from under us, + * so force links to be chased. + * + * Ordinarily we can't get here with "../" as the first component + * but handle the silly special case of ".." in cdpath. + * + * Order of comparisons here looks funny, but it short-circuits + * most rapidly in the event of a false condition. Set to 2 + * here so we still obey the (lack of) CHASEDOTS option after + * the first "../" is preserved (test chasedots > 1 below). + */ + int chasedots = (src[0] == '.' && pwd[0] == '.' && pwd[1] == '\0' && + (src[1] == '/' || (src[1] == '.' && src[2] == '/'))) * 2; /*** if have RFS superroot directory ***/ #ifdef HAVE_SUPERROOT @@ -1305,12 +1321,12 @@ fixdir(char *src) while (dest > d0 + 1 && dest[-1] == '/') dest--; *dest = '\0'; - return ret; + return chasedots; } if (src[0] == '.' && src[1] == '.' && (src[2] == '\0' || src[2] == '/')) { - if (isset(CHASEDOTS)) { - ret = 1; + if (isset(CHASEDOTS) || chasedots > 1) { + chasedots = 1; /* and treat as normal path segment */ } else { if (dest > d0 + 1) { @@ -1348,6 +1364,7 @@ fixdir(char *src) dest[-1] = *src++ ^ 32; } } + /* unreached */ } /**/ -- cgit v1.2.3 From 4ab3fcc90d928d200f9e70c81189079c3316b42d Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 3 Oct 2016 13:43:20 +0100 Subject: 39545: Add some missing unqueue_signals(). All of these are added simply to fit existing logic in other branches. --- ChangeLog | 5 +++++ Src/Zle/computil.c | 1 + Src/Zle/zle_main.c | 1 + Src/builtin.c | 3 +++ Src/exec.c | 3 +++ Src/hist.c | 1 + Src/init.c | 4 +++- Src/mem.c | 8 ++++++-- Src/module.c | 1 + Src/params.c | 2 ++ Src/prompt.c | 4 +++- 11 files changed, 29 insertions(+), 4 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index a1c4e60e3..a68dfaf59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2016-10-03 Peter Stephenson + * 39545: Src/builtin.c, Src/exec.c, Src/hist.c, Src/init.c, + Src/mem.c, Src/module.c, Src/params.c, Src/prompt.c, + Src/Zle/computil.c, Src/Zle/zle_main.c: Add some missing + unqueue_signals(). + * 39521: Src/exec.c, Src/zsh.h, Test/A01grammar.ztst: Refactor start of execcmd(). This allows execpline2() easier access to the state at the start of execuation. diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index 27b78cd61..e9bad1cab 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -4865,6 +4865,7 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) } queue_signals(); if (!(tmp = getaparam(args[1]))) { + unqueue_signals(); zwarnnam(nam, "unknown parameter: %s", args[1]); return 0; } diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 0bdd82ba4..0b3b1fcf4 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1631,6 +1631,7 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func)) return 1; } else if (v) { if (*s) { + unqueue_signals(); zwarnnam(name, "not an identifier: `%s'", args[0]); return 1; } diff --git a/Src/builtin.c b/Src/builtin.c index 60dc07f25..a274ff791 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -1489,6 +1489,7 @@ bin_fc(char *nam, char **argv, Options ops, int func) } if (zleactive) { + unqueue_signals(); zwarnnam(nam, "no interactive history within ZLE"); return 1; } @@ -2808,6 +2809,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) return 0; } if (off & PM_TIED) { + unqueue_signals(); zerrnam(name, "use unset to remove tied variables"); return 1; } @@ -3138,6 +3140,7 @@ bin_functions(char *name, char **argv, Options ops, int func) queue_signals(); for (q = mathfuncs; q; q = q->next) { if (!strcmp(q->name, funcname)) { + unqueue_signals(); zwarnnam(name, "-M %s: function already exists", funcname); zsfree(p->name); diff --git a/Src/exec.c b/Src/exec.c index a4294288b..9890286b2 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1795,6 +1795,8 @@ execpline(Estate state, wordcode slcode, int how, int last1) deletejob(jn, 0); thisjob = pj; } + else + unqueue_signals(); if ((slflags & WC_SUBLIST_NOT) && !errflag) lastval = !lastval; } @@ -5556,6 +5558,7 @@ runshfunc(Eprog prog, FuncWrap wrap, char *name) if (!cont) { if (ou) zfree(ou, ouu); + unqueue_signals(); return; } wrap = wrap->next; diff --git a/Src/hist.c b/Src/hist.c index 5fc40bd67..eebd7dcde 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -653,6 +653,7 @@ histsubchar(int c) (c == '}' || c == ';' || c == '\'' || c == '"' || c == '`')) { /* Neither event nor word designator, no expansion */ safeinungetc(c); + unqueue_signals(); return bangchar; } *ptr = 0; diff --git a/Src/init.c b/Src/init.c index 3dea179b9..c12043b88 100644 --- a/Src/init.c +++ b/Src/init.c @@ -1442,8 +1442,10 @@ sourcehome(char *s) queue_signals(); if (EMULATION(EMULATE_SH|EMULATE_KSH) || !(h = getsparam_u("ZDOTDIR"))) { h = home; - if (!h) + if (!h) { + unqueue_signals(); return; + } } { diff --git a/Src/mem.c b/Src/mem.c index 021dad573..db311efbd 100644 --- a/Src/mem.c +++ b/Src/mem.c @@ -903,11 +903,15 @@ memory_validate(Heapid heap_id) queue_signals(); for (h = heaps; h; h = h->next) { - if (h->heap_id == heap_id) + if (h->heap_id == heap_id) { + unqueue_signals(); return 0; + } for (hs = heaps->sp; hs; hs = hs->next) { - if (hs->heap_id == heap_id) + if (hs->heap_id == heap_id) { + unqueue_signals(); return 0; + } } } diff --git a/Src/module.c b/Src/module.c index 46a7d7746..41f142adb 100644 --- a/Src/module.c +++ b/Src/module.c @@ -2242,6 +2242,7 @@ load_module(char const *name, Feature_enables enablesarr, int silent) return 0; } if (m->node.flags & MOD_BUSY) { + unqueue_signals(); zerr("circular dependencies for module ;%s", name); return 1; } diff --git a/Src/params.c b/Src/params.c index e11510246..1418021aa 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2803,6 +2803,7 @@ assignsparam(char *s, char *val, int flags) zerr("read-only variable: %s", v->pm->node.nam); *ss = '['; zsfree(val); + unqueue_signals(); return NULL; } flags &= ~ASSPM_WARN_CREATE; @@ -3117,6 +3118,7 @@ setnparam(char *s, mnumber val) if (!(v = getvalue(&vbuf, &t, 1))) { DPUTS(!v, "BUG: value not found for new parameter"); /* errflag |= ERRFLAG_ERROR; */ + unqueue_signals(); return NULL; } if (!was_unset && isset(WARNCREATEGLOBAL) && locallevel > forklevel) diff --git a/Src/prompt.c b/Src/prompt.c index d4f389809..ee77c8bc8 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -491,8 +491,10 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) if (!arg) arg++; queue_signals(); - if (!(hostnam = getsparam("HOST"))) + if (!(hostnam = getsparam("HOST"))) { + unqueue_signals(); break; + } if (arg < 0) { for (ss = hostnam + strlen(hostnam); ss > hostnam; ss--) if (ss[-1] == '.' && !++arg) -- cgit v1.2.3 From 276197d1d1998fb62a20b63099f770c2beee5749 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 11 Oct 2016 15:16:17 +0100 Subject: 36108: command -[vV] assumed -p --- ChangeLog | 4 ++++ Src/builtin.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 0f41c18fe..4ce4ec2e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-10-11 Peter Stephenson + + * 36108: Src/builtin.c: command -[vV] assumed -p. + 2016-10-10 Peter Stephenson * 39599: Src/loop.c, Test/A01grammar.ztst: Don't reset status diff --git a/Src/builtin.c b/Src/builtin.c index a274ff791..8b8b217d8 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3663,7 +3663,7 @@ bin_whence(char *nam, char **argv, Options ops, int func) returnval = 1; } popheap(); - } else if (func == BIN_COMMAND && + } else if (func == BIN_COMMAND && OPT_ISSET(ops,'p') && (hn = builtintab->getnode(builtintab, *argv))) { /* * Special case for "command -p[vV]" which needs to @@ -3671,7 +3671,9 @@ bin_whence(char *nam, char **argv, Options ops, int func) */ builtintab->printnode(hn, printflags); informed = 1; - } else if ((cnam = findcmd(*argv, 1, func == BIN_COMMAND))) { + } else if ((cnam = findcmd(*argv, 1, + func == BIN_COMMAND && + OPT_ISSET(ops,'p')))) { /* Found external command. */ if (wd) { printf("%s: command\n", *argv); -- cgit v1.2.3 From 7e7e2d7e63b52a6a2e990090954328bbf7fa5d80 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 19 Oct 2016 10:39:58 +0100 Subject: 39678: metafication of printf %q argument and result --- ChangeLog | 5 +++++ Src/builtin.c | 5 +++-- Test/D07multibyte.ztst | 4 ++++ 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 89366f7ec..d666a73bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-10-19 Peter Stephenson + + * 39678: Src/builtin.c, Test/D07multibyte.ztst: printf %q + argument needs metafying and result unmetafying. + 2016-10-18 m0viefreak * 39590: Src/Zle/compresult.c: zle: Call zle-line-pre-redraw diff --git a/Src/builtin.c b/Src/builtin.c index 8b8b217d8..2db739ffc 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4874,9 +4874,10 @@ bin_print(char *name, char **args, Options ops, int func) break; case 'q': stringval = curarg ? - quotestring(curarg, QT_BACKSLASH_SHOWNULL) : &nullstr; + quotestring(metafy(curarg, curlen, META_USEHEAP), + QT_BACKSLASH_SHOWNULL) : &nullstr; *d = 's'; - print_val(stringval); + print_val(unmetafy(stringval, &curlen)); break; case 'd': case 'i': diff --git a/Test/D07multibyte.ztst b/Test/D07multibyte.ztst index 1b1d042a8..3a6e95543 100644 --- a/Test/D07multibyte.ztst +++ b/Test/D07multibyte.ztst @@ -579,3 +579,7 @@ 0:Sorting of metafied Polish characters >a ą b c ć d e ę f >a ą b c ć d e ę f + + printf '%q%q\n' 你你 +0:printf %q and quotestring and general metafy / token madness +>你你 -- cgit v1.2.3 From ab81b98c49ace618f5a1607faf718e0b2e43948d Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sat, 29 Oct 2016 11:56:50 -0700 Subject: 39758: revise 39704 for array and hash parameters; more POSIXBUITINS tweaks for export 39704 was commit 0f5e670, forgot to reference article number in that log. "typeset -p" outputs "typeset" for array and hash parameters, even when exported, because those types can be marked export but are never pushed to the enviroment. For POSIXBUILTINS, "export var" does not implicitly set $var, and its export state is preserved when assigned (but not when explicitly unset). --- ChangeLog | 8 ++++++++ Src/builtin.c | 14 ++++++++++---- Src/params.c | 16 ++++++++-------- 3 files changed, 26 insertions(+), 12 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index f7487f01a..c453aee84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2016-10-29 Barton E. Schaefer + + * 39758: Src/builtin.c, Src/params.c: revise 39704 to output + "typeset" for array and hash parameters, even when exported; for + POSIXBUILTINS, "export var" does not implicitly set $var, and its + export state is preserved when assigned (but not when explicitly + unset). + 2016-10-28 Daniel Shahaf * users/22036: Doc/Zsh/zle.yo: bracketed-paste: Document diff --git a/Src/builtin.c b/Src/builtin.c index 2db739ffc..986ace238 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2008,11 +2008,12 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), * handled in createparam(). Here we just avoid using it for the * present tests if it's unset. * - * POSIXBUILTINS horror: we need to retain the 'readonly' flag - * of an unset parameter. + * POSIXBUILTINS horror: we need to retain the 'readonly' or 'export' + * flags of an unset parameter. */ usepm = pm && (!(pm->node.flags & PM_UNSET) || - (isset(POSIXBUILTINS) && (pm->node.flags & PM_READONLY))); + (isset(POSIXBUILTINS) && + (pm->node.flags & (PM_READONLY|PM_EXPORTED)))); /* * We need to compare types with an existing pm if special, @@ -2135,7 +2136,8 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), /* * Stricter rules about retaining readonly attribute in this case. */ - if ((on & PM_READONLY) && (!usepm || (pm->node.flags & PM_UNSET)) && + if ((on & (PM_READONLY|PM_EXPORTED)) && + (!usepm || (pm->node.flags & PM_UNSET)) && !ASG_VALUEP(asg)) on |= PM_UNSET; else if (usepm && (pm->node.flags & PM_READONLY) && @@ -2143,6 +2145,10 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), zerr("read-only variable: %s", pm->node.nam); return NULL; } + /* This is handled by createparam(): + if (usepm && (pm->node.flags & PM_EXPORTED) && !(off & PM_EXPORTED)) + on |= PM_EXPORTED; + */ } /* diff --git a/Src/params.c b/Src/params.c index 3084b1ffe..330f22bb2 100644 --- a/Src/params.c +++ b/Src/params.c @@ -940,7 +940,10 @@ createparam(char *name, int flags) zerr("%s: restricted", name); return NULL; } - if (!(oldpm->node.flags & PM_UNSET) || (oldpm->node.flags & PM_SPECIAL)) { + if (!(oldpm->node.flags & PM_UNSET) || + (oldpm->node.flags & PM_SPECIAL) || + /* POSIXBUILTINS horror: we need to retain 'export' flags */ + (isset(POSIXBUILTINS) && (oldpm->node.flags & PM_EXPORTED))) { oldpm->node.flags &= ~PM_UNSET; if ((oldpm->node.flags & PM_SPECIAL) && oldpm->ename) { Param altpm = @@ -5225,10 +5228,6 @@ printparamvalue(Param p, int printflags) { char *t, **u; - if ((p->node.flags & PM_EXPORTED) && !p->env) { - putchar('\n'); - return; - } if (printflags & PRINT_KV_PAIR) putchar(' '); else @@ -5332,7 +5331,8 @@ printparamnode(HashNode hn, int printflags) } if (locallevel && p->level >= locallevel) { printf("typeset "); /* printf("local "); */ - } else if (p->node.flags & PM_EXPORTED) { + } else if ((p->node.flags & PM_EXPORTED) && + !(p->node.flags & (PM_ARRAY|PM_HASHED))) { printf("export "); } else if (locallevel) { printf("typeset -g "); @@ -5350,8 +5350,8 @@ printparamnode(HashNode hn, int printflags) if (pmptr->flags & PMTF_TEST_LEVEL) { if (p->level) doprint = 1; - } else if ((pmptr->binflag != PM_EXPORTED || - ((p->node.flags & PM_LOCAL) || p->level)) && + } else if ((pmptr->binflag != PM_EXPORTED || p->level || + (p->node.flags & (PM_LOCAL|PM_ARRAY|PM_HASHED))) && (p->node.flags & pmptr->binflag)) doprint = 1; -- cgit v1.2.3 From 4b41e33cbcf8027b53ecae4467dc9232becb0420 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 5 Nov 2016 00:27:47 +0100 Subject: 39389: when printf -v is used with an array use separate elements each time the format is reused --- ChangeLog | 7 ++++++ Completion/Zsh/Command/_print | 17 +++++++++----- Completion/Zsh/Type/_globquals | 3 +-- Doc/Zsh/builtins.yo | 4 +++- Src/builtin.c | 51 +++++++++++++++++++++++++++++++----------- Test/B03print.ztst | 6 +++++ 6 files changed, 66 insertions(+), 22 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index d1ac1cd45..1ebcc3725 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2016-11-04 Oliver Kiddle + + * 39389: Src/builtin.c, Test/B03print.ztst, Doc/Zsh/builtins.yo, + Completion/Zsh/Type/_globquals, Completion/Zsh/Command/_print: + when printf -v is used with an array use separate elements each + time the format is reused + 2016-11-04 Daniel Shahaf * users/22080: Doc/Zsh/zle.yo: bracketed-paste: Third time's diff --git a/Completion/Zsh/Command/_print b/Completion/Zsh/Command/_print index 38f17ab8e..8df094107 100644 --- a/Completion/Zsh/Command/_print +++ b/Completion/Zsh/Command/_print @@ -1,15 +1,18 @@ #compdef print printf -local state expl line eflag pflag rest ret=1 +local state expl line eflag pflag rflag rest ret=1 if [[ $service = print ]]; then # -e flag available only after -R eflag="${words[1,CURRENT-1][(r)-*R*]:+-e[enable escapes]}" + rflag='-r[ignore escape conventions of echo]' # -p flag only relevant if we have a coprocess (:>&p) 2>/dev/null && pflag='(-s -u -z)-p[print arguments to input of coprocess]' + [[ -n ${words[(r)-*f]} ]] && rflag='-r[disable reuse of format string]' + if [[ -n ${words[1,CURRENT][(r)-*P*]} ]]; then rest='*: :->prompt' else @@ -17,11 +20,11 @@ if [[ $service = print ]]; then fi _arguments -C -s -A "-*" -S \ - '(-f)-r[ignore escape conventions of echo]' \ + '-r[ignore escape conventions of echo]' \ '(-r -b -f -m -s -l -N -o -O -i -c -u -p -z -D -P)-R[emulate BSD echo (no escapes, -n & -e flags only)]' \ '-b[recognise bindkey escape sequences]' \ - '-m[remove arguments matching specified pattern]' \ - '(-r -n -R -l -N -c)-f+[print arguments as for the printf builtin]:format:->printfformat' \ + '-m[remove arguments not matching specified pattern]:pattern' \ + '(-n -R -l -N -c)-f+[print arguments as for the printf builtin]:format:->printfformat' \ '(-u -p -z)-s[place results in the history list]' \ '(-c -f)-n[do not add a newline to the result]' \ '(-N -c -f)-l[print arguments separated by newlines]' \ @@ -33,11 +36,13 @@ if [[ $service = print ]]; then '(-n -l -N -f -C -s -z)-c[print arguments in columns]' \ '(-n -l -N -f -c -s -z)-C+[print arguments in specified number of columns]:columns' \ '(-s -p -z)-u+[specify file descriptor to print arguments to]:file descriptor:_file_descriptors' \ - '-v[store output in named parameter]:parameter:_parameters' \ + '(-s -z -p -u)-v[store output in named parameter]:parameter:_parameters' \ '(-s -p -u)-z[push arguments onto editing buffer stack]' \ '-D[substitute any arguments which are named directories using ~ notation]' \ '-P[perform prompt expansion]' \ - $pflag $eflag $rest && ret=0 + '(-X -f -a -C -c -z)-x+[expand leading tabs]:tab width' \ + '(-x -f -a -C -c -z)-X+[expand all tabs]:tab width' \ + $pflag $eflag $rflag $rest && ret=0 elif [[ $service = printf ]]; then state=printf fi diff --git a/Completion/Zsh/Type/_globquals b/Completion/Zsh/Type/_globquals index 6eef16877..a904bdf0d 100644 --- a/Completion/Zsh/Type/_globquals +++ b/Completion/Zsh/Type/_globquals @@ -121,8 +121,7 @@ while [[ -n $PREFIX ]]; do tmatch=( s m h d w M ) if zstyle -t ":completion:${curcontext}:time-specifiers" verbose; then zstyle -s ":completion:${curcontext}:time-specifiers" list-separator sep || sep=-- - print -v tdisp -f "%s ${sep//(#m)[%\\]/$MATCH$MATCH} %s\0" ${tmatch:^^tdisp} - tdisp=( ${(0)tdisp} ) + print -v tdisp -f "%s ${sep//(#m)[%\\]/$MATCH$MATCH} %s" ${tmatch:^^tdisp} fi alts+=( "time-specifiers:time specifier:compadd -E 0 -d tdisp -S '' -a tmatch" ) fi diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index dfbbaa034..169a31ea3 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1289,7 +1289,9 @@ required by the format than have been specified, the behaviour is as if zero or an empty string had been specified as the argument. The tt(-v) option causes the output to be stored as the value of the -parameter var(name), instead of printed. +parameter var(name), instead of printed. If var(name) is an array and +the format string is reused when consuming arguments then one +array element will be used for each use of the format string. ) findex(pushd) pindex(PUSHD_TO_HOME, use of) diff --git a/Src/builtin.c b/Src/builtin.c index 986ace238..083a3aeb3 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4087,10 +4087,11 @@ bin_print(char *name, char **args, Options ops, int func) { int flen, width, prec, type, argc, n, narg, curlen = 0; int nnl = 0, fmttrunc = 0, ret = 0, maxarg = 0, nc = 0; - int flags[6], *len; + int flags[6], *len, visarr = 0; char *start, *endptr, *c, *d, *flag, *buf = NULL, spec[14], *fmt = NULL; char **first, **argp, *curarg, *flagch = "'0+- #", save = '\0', nullstr = '\0'; size_t rcount = 0, count = 0; + size_t *cursplit, *splits = 0; FILE *fout = stdout; #ifdef HAVE_OPEN_MEMSTREAM size_t mcount; @@ -4122,7 +4123,7 @@ bin_print(char *name, char **args, Options ops, int func) return 1; \ } \ unlink(tmpf); \ - if ((fout = fdopen(tempfd, "w+")) == NULL) { \ + if ((FOUT = fdopen(tempfd, "w+")) == NULL) { \ close(tempfd); \ zwarnnam(name, "can't open temp file: %e", errno); \ return 1; \ @@ -4647,11 +4648,23 @@ bin_print(char *name, char **args, Options ops, int func) * special cases of printing to a ZLE buffer or the history, however. */ + if (OPT_ISSET(ops,'v')) { + struct value vbuf; + char* s = OPT_ARG(ops,'v'); + Value v = getvalue(&vbuf, &s, 0); + visarr = v && PM_TYPE(v->pm->node.flags) == PM_ARRAY; + } /* printf style output */ *spec = '%'; argp = args; do { rcount = count; + if (argp > args && visarr) { /* reusing format string */ + if (!splits) + cursplit = splits = (size_t *)zhalloc(sizeof(size_t) * + (arrlen(args) / (argp - args) + 1)); + *cursplit++ = count; + } if (maxarg) { first += maxarg; argc -= maxarg; @@ -5019,18 +5032,30 @@ bin_print(char *name, char **args, Options ops, int func) if (buf) free(buf); } else { - stringval = metafy(buf, rcount, META_REALLOC); - if (OPT_ISSET(ops,'z')) { - zpushnode(bufstack, stringval); - } else if (OPT_ISSET(ops,'v')) { - setsparam(OPT_ARG(ops, 'v'), stringval); + if (visarr) { + char **arrayval = zshcalloc((cursplit - splits + 2) * sizeof(char *)); + for (;cursplit >= splits; cursplit--) { + int start = cursplit == splits ? 0 : cursplit[-1]; + arrayval[cursplit - splits] = + metafy(buf + start, count - start, META_DUP); + count = start; + } + setaparam(OPT_ARG(ops, 'v'), arrayval); + free(buf); } else { - ent = prepnexthistent(); - ent->node.nam = stringval; - ent->stim = ent->ftim = time(NULL); - ent->node.flags = 0; - ent->words = (short *)NULL; - addhistnode(histtab, ent->node.nam, ent); + stringval = metafy(buf, rcount, META_REALLOC); + if (OPT_ISSET(ops,'z')) { + zpushnode(bufstack, stringval); + } else if (OPT_ISSET(ops,'v')) { + setsparam(OPT_ARG(ops, 'v'), stringval); + } else { + ent = prepnexthistent(); + ent->node.nam = stringval; + ent->stim = ent->ftim = time(NULL); + ent->node.flags = 0; + ent->words = (short *)NULL; + addhistnode(histtab, ent->node.nam, ent); + } } } unqueue_signals(); diff --git a/Test/B03print.ztst b/Test/B03print.ztst index a4431cbc8..6ee2a09c6 100644 --- a/Test/B03print.ztst +++ b/Test/B03print.ztst @@ -310,3 +310,9 @@ 0:print and printf into a variable >typeset -g foo='once more' >typeset -g foo=$'into\C-@the-breach\C-@-' + + typeset -a foo + print -f '%2$d %4s' -v foo one 1 two 2 three 3 + typeset -p foo +0:printf into an array variable +>typeset -a foo=( '1 one' '2 two' '3 three' ) -- cgit v1.2.3 From 5c28031ea6f0095aa80afa56c3264c6cc5f36fbb Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sat, 5 Nov 2016 00:30:42 +0100 Subject: 39834: when print used with -v and -l, include a final newline Also complete print -S option and make further use of the new printf to an array feature in other completion functions. --- ChangeLog | 6 ++++++ Completion/Zsh/Command/_fc | 5 +++-- Completion/Zsh/Command/_print | 33 +++++++++++++++++---------------- Completion/Zsh/Type/_ps1234 | 5 +++-- Src/builtin.c | 3 ++- 5 files changed, 31 insertions(+), 21 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 1ebcc3725..9f8e5a0c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2016-11-04 Oliver Kiddle + * 39834: Src/builtin.c, Completion/Zsh/Command/_print, + Completion/Zsh/Command/_fc, Completion/Zsh/Type/_ps1234: + when print used with -v and -l, include a final + newline; complete print -S option and make further use + of the new printf to an array feature + * 39389: Src/builtin.c, Test/B03print.ztst, Doc/Zsh/builtins.yo, Completion/Zsh/Type/_globquals, Completion/Zsh/Command/_print: when printf -v is used with an array use separate elements each diff --git a/Completion/Zsh/Command/_fc b/Completion/Zsh/Command/_fc index b90436a01..6cc01f32d 100644 --- a/Completion/Zsh/Command/_fc +++ b/Completion/Zsh/Command/_fc @@ -1,7 +1,8 @@ #compdef fc history r local curcontext="$curcontext" state state_descr line ret=1 -local events num cmd sep +local num cmd sep +local -a events typeset -A opt_args local fc_common fc_hist fc_r @@ -71,7 +72,7 @@ if [[ -n $state ]]; then if [[ -z ${line:#*=*} ]] && compset -P 1 '*='; then _message -e replacements 'replacement' elif [[ -prefix [0-9] ]]; then - events=( ${(0)"$(printf "%-${#HISTNO}.${#HISTNO}s $sep %s\0" "${(kv)history[@]}")"} ) + print -v events -f "%-${#HISTNO}.${#HISTNO}s $sep %s" "${(kv)history[@]}" _wanted -2V events expl "$state_descr" compadd -M "B:0=" -ld events - \ "${events[@]%% *}" elif [[ -prefix - ]]; then diff --git a/Completion/Zsh/Command/_print b/Completion/Zsh/Command/_print index 8df094107..0610cd4cf 100644 --- a/Completion/Zsh/Command/_print +++ b/Completion/Zsh/Command/_print @@ -21,27 +21,28 @@ if [[ $service = print ]]; then _arguments -C -s -A "-*" -S \ '-r[ignore escape conventions of echo]' \ - '(-r -b -f -m -s -l -N -o -O -i -c -u -p -z -D -P)-R[emulate BSD echo (no escapes, -n & -e flags only)]' \ + '(-r -b -f -m -s -S -l -N -o -O -i -c -u -p -z -D -P)-R[emulate BSD echo (no escapes, -n & -e flags only)]' \ '-b[recognise bindkey escape sequences]' \ '-m[remove arguments not matching specified pattern]:pattern' \ - '(-n -R -l -N -c)-f+[print arguments as for the printf builtin]:format:->printfformat' \ - '(-u -p -z)-s[place results in the history list]' \ + '(-n -R -l -N -c -S)-f+[print arguments as for the printf builtin]:format:->printfformat' \ + '(-u -p -z -S)-s[place results in the history list]' \ + '(-a -f -c -C -i -l -o -O -N -u -p -v -z -s -x -X)-S[place results in the history list, after splitting argument into words]' \ '(-c -f)-n[do not add a newline to the result]' \ - '(-N -c -f)-l[print arguments separated by newlines]' \ - '(-n -l -c -f)-N[print arguments separated and terminated by nulls]' \ - '(-O)-o[sort arguments in ascending order]' \ - '(-o)-O[sort arguments in descending order]' \ - '-i[case-insensitive sorting]' \ - '(-n -l -N -f -s -z)-a[with -c/-C, print arguments across before down]' \ - '(-n -l -N -f -C -s -z)-c[print arguments in columns]' \ - '(-n -l -N -f -c -s -z)-C+[print arguments in specified number of columns]:columns' \ - '(-s -p -z)-u+[specify file descriptor to print arguments to]:file descriptor:_file_descriptors' \ - '(-s -z -p -u)-v[store output in named parameter]:parameter:_parameters' \ - '(-s -p -u)-z[push arguments onto editing buffer stack]' \ + '(-N -c -f -S)-l[print arguments separated by newlines]' \ + '(-n -l -c -f -S)-N[print arguments separated and terminated by nulls]' \ + '(-O -S)-o[sort arguments in ascending order]' \ + '(-o -S)-O[sort arguments in descending order]' \ + '(-S)-i[case-insensitive sorting]' \ + '(-n -l -N -f -s -S -z)-a[with -c/-C, print arguments across before down]' \ + '(-n -l -N -f -C -s -S -z)-c[print arguments in columns]' \ + '(-n -l -N -f -c -s -S -z)-C+[print arguments in specified number of columns]:columns' \ + '(-s -S -p -z)-u+[specify file descriptor to print arguments to]:file descriptor:_file_descriptors' \ + '(-s -S -z -p -u)-v[store output in named parameter]:parameter:_parameters' \ + '(-s -S -p -u)-z[push arguments onto editing buffer stack]' \ '-D[substitute any arguments which are named directories using ~ notation]' \ '-P[perform prompt expansion]' \ - '(-X -f -a -C -c -z)-x+[expand leading tabs]:tab width' \ - '(-x -f -a -C -c -z)-X+[expand all tabs]:tab width' \ + '(-X -f -a -C -c -s -S -z)-x+[expand leading tabs]:tab width' \ + '(-x -f -a -C -c -s -S -z)-X+[expand all tabs]:tab width' \ $pflag $eflag $rflag $rest && ret=0 elif [[ $service = printf ]]; then state=printf diff --git a/Completion/Zsh/Type/_ps1234 b/Completion/Zsh/Type/_ps1234 index 0671cebb2..cf1982219 100644 --- a/Completion/Zsh/Type/_ps1234 +++ b/Completion/Zsh/Type/_ps1234 @@ -1,6 +1,6 @@ #compdef -value-,PROMPT,-default- -value-,PROMPT2,-default- -value-,PROMPT3,-default- -value-,PROMPT4,-default- -value-,RPROMPT,-default- -value-,RPROMPT2,-default- -value-,PS1,-default- -value-,PS2,-default- -value-,PS3,-default- -value-,PS4,-default- -value-,RPS1,-default- -value-,RPS2,-default- -value-,SPROMPT,-default- -local -a specs +local -a specs ccol local expl grp cols bs suf pre changed=1 ret=1 local -A ansi @@ -39,7 +39,8 @@ if compset -P '%[FK]'; then _description -V ansi-colors expl 'ansi color' grp="$expl[expl[(i)-V]+1]" - _comp_colors+=( ${(ps.\0.)"$(printf "($grp)=%s=%s\0" ${(kv)ansi})"} ) + print -v ccol -f "($grp)=%s=%s" ${(kv)ansi} + _comp_colors+=( $ccol ) compadd "$expl[@]" $suf $pre -k ansi && ret=0 if (( $#suf )) && compset -P "(<->|%v)"; then _wanted ansi-colors expl 'closing brace' compadd -S '' \} && ret=0 diff --git a/Src/builtin.c b/Src/builtin.c index 083a3aeb3..b7b7bdf18 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4621,7 +4621,8 @@ bin_print(char *name, char **args, Options ops, int func) OPT_ISSET(ops,'N') ? '\0' : ' ', fout); } } - if (!(OPT_ISSET(ops,'n') || OPT_ISSET(ops, 'v') || nnl)) + if (!(OPT_ISSET(ops,'n') || nnl || + (OPT_ISSET(ops, 'v') && !OPT_ISSET(ops, 'l')))) fputc(OPT_ISSET(ops,'N') ? '\0' : '\n', fout); if (IS_MSTREAM(fout) && (rcount = READ_MSTREAM(buf,fout)) == -1) ret = 1; -- cgit v1.2.3 From d91ffb1db2784c3ff17d93db8d1fe38816fc5129 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sat, 5 Nov 2016 13:49:07 -0700 Subject: 39838: another missing unqueue_signals() --- ChangeLog | 4 ++++ Src/builtin.c | 1 + 2 files changed, 5 insertions(+) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index a8f2c0b1d..bcea79190 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-11-05 Barton E. Schaefer + + * 39838: Src/builtin.c: another missing unqueue_signals() + 2016-11-04 Oliver Kiddle * 39829: Src/Zle/compcore.c: when compstate[insert] is emptied diff --git a/Src/builtin.c b/Src/builtin.c index b7b7bdf18..6c9d05872 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4552,6 +4552,7 @@ bin_print(char *name, char **args, Options ops, int func) short *words; if (nwords > 1) { zwarnnam(name, "option -S takes a single argument"); + unqueue_signals(); return 1; } words = NULL; -- cgit v1.2.3 From a57977d01acc3b1b63aec1b79394ef7ffd052912 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 8 Nov 2016 13:02:24 +0000 Subject: 39870: ensure exit trap can always run --- ChangeLog | 3 +++ Src/builtin.c | 5 +++++ Test/C03traps.ztst | 15 +++++++++++++++ 3 files changed, 23 insertions(+) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index edf3e78c9..e89b0c616 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ 2016-11-08 Peter Stephenson + * Src/builtin.c, Test/C03traps.ztst: ensure exit trap can always + run. + * unposted: Src/utils.c: follow up to 39867: don't need test against zero any more. diff --git a/Src/builtin.c b/Src/builtin.c index 6c9d05872..696971944 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5435,6 +5435,11 @@ zexit(int val, int from_where) } } lastval = val; + /* + * Now we are committed to exiting any previous state + * is irrelevant. Ensure trap can run. + */ + errflag = intrap = 0; if (sigtrapped[SIGEXIT]) dotrap(SIGEXIT); callhookfunc("zshexit", NULL, 1, NULL); diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index 74b83f33a..828a3d10f 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -626,6 +626,21 @@ F:Must be tested with a top-level script rather than source or function >before-out >before-in + if zmodload zsh/system 2>/dev/null; then + ( + trap 'echo TERM; exit 2' TERM + trap 'echo EXIT' EXIT + kill -s TERM "$sysparams[pid]" + echo 'FATAL: we should never get here!' 1>&2 + exit 1 + ) + else + ZTST_skip="zsh/system library not found." + fi +2:EXIT trap from TERM trap +>TERM +>EXIT + %clean rm -f TRAPEXIT -- 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/builtin.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 ee1222454e0fd58b70878ed6864146e00a835fd8 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 23 Nov 2016 11:52:12 +0100 Subject: unposted: fix printf -v to an array without format string reuse --- ChangeLog | 7 ++++++- Src/builtin.c | 2 +- Test/B03print.ztst | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index a70ead69f..641992bd1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -2016-11-21 Oliver Kiddle +2016-11-23 Oliver Kiddle + + * unposted: Src/builtin.c, Test/B03print.ztst: fix printf -v + to an array without format string reuse + +2016-11-21 Oliver Kiddle * 39993: Test/Y01completion.ztst: Tests for 39981. diff --git a/Src/builtin.c b/Src/builtin.c index d3c628592..ab159ad09 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5034,7 +5034,7 @@ bin_print(char *name, char **args, Options ops, int func) if (buf) free(buf); } else { - if (visarr) { + if (visarr && splits) { char **arrayval = zshcalloc((cursplit - splits + 2) * sizeof(char *)); for (;cursplit >= splits; cursplit--) { int start = cursplit == splits ? 0 : cursplit[-1]; diff --git a/Test/B03print.ztst b/Test/B03print.ztst index 6ee2a09c6..3f9a4046d 100644 --- a/Test/B03print.ztst +++ b/Test/B03print.ztst @@ -316,3 +316,9 @@ typeset -p foo 0:printf into an array variable >typeset -a foo=( '1 one' '2 two' '3 three' ) + + typeset -a foo + print -f '%s' -v foo string + typeset -p foo +0:printf to an array variable without format string reuse +>typeset foo=string -- cgit v1.2.3 From a81f280bfa185ba1df9c5ffee535631e4f1736f4 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Thu, 24 Nov 2016 06:57:52 +0000 Subject: 40010: builtins: Say 'bad option: +x', not 'bad option: -x', when +x was passed. --- ChangeLog | 3 +++ Src/builtin.c | 5 +++-- Test/A02alias.ztst | 5 +++++ 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'Src/builtin.c') diff --git a/ChangeLog b/ChangeLog index 88727c93b..53dcc07de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-11-28 Daniel Shahaf + * 40010: Src/builtin.c, Test/A02alias.ztst: builtins: Say + 'bad option: +x', not 'bad option: -x', when +x was passed. + * 40009: Src/hashtable.c: alias -L: Emit aliases that begin with a plus sign correctly. diff --git a/Src/builtin.c b/Src/builtin.c index ab159ad09..e641a97a1 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -249,7 +249,7 @@ int execbuiltin(LinkList args, LinkList assigns, Builtin bn) { char *pp, *name, *optstr; - int flags, sense, argc, execop, xtr = isset(XTRACE); + int flags, argc, execop, xtr = isset(XTRACE); struct options ops; /* initialise options structure */ @@ -294,6 +294,7 @@ execbuiltin(LinkList args, LinkList assigns, Builtin bn) /* Sort out the options. */ if (optstr) { char *arg = *argv; + int sense; /* 1 for -x, 0 for +x */ /* while arguments look like options ... */ while (arg && /* Must begin with - or maybe + */ @@ -387,7 +388,7 @@ execbuiltin(LinkList args, LinkList assigns, Builtin bn) if (*arg) { if(*arg == Meta) *++arg ^= 32; - zwarnnam(name, "bad option: -%c", *arg); + zwarnnam(name, "bad option: %c%c", "+-"[sense], *arg); return 1; } arg = *++argv; diff --git a/Test/A02alias.ztst b/Test/A02alias.ztst index 1e09cd3f1..e52578ec3 100644 --- a/Test/A02alias.ztst +++ b/Test/A02alias.ztst @@ -110,3 +110,8 @@ 127:No endless loop with suffix alias in command position >You said it. ?(eval):1: command not found: thingummy.mysuff + + alias +x; alias -z +1:error message has the correct sign +?(eval):alias:1: bad option: +x +?(eval):alias:1: bad option: -z -- cgit v1.2.3