From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25328 invoked by alias); 2 Mar 2017 12:03:25 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 40697 Received: (qmail 26178 invoked from network); 2 Mar 2017 12:03:25 -0000 X-Qmail-Scanner-Diagnostics: from mailout3.w1.samsung.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(210.118.77.13):SA:0(-5.0/5.0):. Processed in 1.912162 secs); 02 Mar 2017 12:03:25 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=RCVD_IN_DNSWL_HI, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=unavailable autolearn_force=no version=3.4.1 X-Envelope-From: p.stephenson@samsung.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: none (ns1.primenet.com.au: domain at samsung.com does not designate permitted sender hosts) X-AuditID: cbfec7f5-f79d06d000004445-f4-58b807a9bea9 Date: Thu, 02 Mar 2017 11:53:08 +0000 From: Peter Stephenson To: zsh-workers@zsh.org Subject: Re: [^ax-y] doesn't work but [^x-ya] does Message-id: <20170302115308.5a8fccfa@pwslap01u.europe.root.pri> In-reply-to: <1488453733.41855.897947392.73E9E4B0@webmail.messagingengine.com> Organization: Samsung Cambridge Solution Centre X-Mailer: Claws Mail 3.7.9 (GTK+ 2.22.0; i386-redhat-linux-gnu) MIME-version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrLIsWRmVeSWpSXmKPExsWy7djPc7or2XdEGBxfwGxxsPkhkwOjx6qD H5gCGKO4bFJSczLLUov07RK4Mo7OuMRc8KiDsWLGlYvsDYw3E7oYOTkkBEwkls+6xQhhi0lc uLeerYuRi0NIYCmjxIEt85hAEkICvUwS8zpDYRr6n7SzQ8SXMUp0deRBNExjknjTsJIdwjnN KPF97Vco5wyjxNFrU8FaWARUJfZ8/c8GYrMJGEpM3TQbbLeIgLjE2bXnWUBsYQEjiYPPJoLZ vAL2Eiv2LAU7g1PAT2LRy2tgNr+AvsTVv5+YIE6yl5h55QwjRL2gxI/J98B6mQV0JLZte8wO YctLbF7zlhnkIAmBZnaJGXf3ARVxADmyEpsOMEPMcZHovzAZGhbCEq+Ob2GHsGUkLk/uZoGw +xklnnT7QsyZwShx+swONoiEtUTf7YuMEMv4JCZtm84MMZ9XoqNNCKLEQ6J//V+o+Y4Syz9O Z53AqDgLydmzkJw9C8nZCxiZVzGKpJYW56anFpvqFSfmFpfmpesl5+duYgQmgtP/jn/dwbj0 mNUhRgEORiUe3gNM2yOEWBPLiitzDzFKcDArifAysu2IEOJNSaysSi3Kjy8qzUktPsQozcGi JM67Z8GVcCGB9MSS1OzU1ILUIpgsEwenVAOjdrbdvD0Kbq2/NgUdTLINWHTG+45NWozerLln WTfZLJmyZ7qD6k8mT5sLIls/bKyO+Xom6dX2y8d05B2uxReynss8fLn3WZNPZaoNu+gh5c/p u4uPB3A2cuw9/EDbyFjqhIh9LpNRdesh3ace4ikHOCM71zAfnlx5tujHiX36DLm24nr+77Yq sRRnJBpqMRcVJwIA43Q1UAADAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrBIsWRmVeSWpSXmKPExsVy+t/xK7ob2HdEGCz7amxxsPkhkwOjx6qD H5gCGKPcbDJSE1NSixRS85LzUzLz0m2VQkPcdC2UFPISc1NtlSJ0fUOClBTKEnNKgTwjAzTg 4BzgHqykb5fglnF0xiXmgkcdjBUzrlxkb2C8mdDFyMkhIWAi0f+knR3CFpO4cG89WxcjF4eQ wBJGiWWbJjJDODOYJOZ82gDlnGaUaJjzAMo5wyhxYG8LG0g/i4CqxJ6v/8FsNgFDiambZjOC 2CIC4hJn155nAbGFBYwkDj6bCGbzCthLrNizlAnE5hTwk1j08hoTxND5TBL/278wgyT4BfQl rv79xARxoL3EzCtnGCGaBSV+TL4HNohZQEti87YmVghbXmLzmrdgvUIC6hI37u5mn8AoPAtJ yywkLbOQtCxgZF7FKJJaWpybnltspFecmFtcmpeul5yfu4kRGEvbjv3csoOx613wIUYBDkYl Ht4DTNsjhFgTy4orcw8xSnAwK4nwMrLtiBDiTUmsrEotyo8vKs1JLT7EaAoMmYnMUqLJ+cA4 zyuJNzQxNLc0NDK2sDA3MlIS55364Uq4kEB6YklqdmpqQWoRTB8TB6dUA+MxJQHPLW/l/ske Dv64/EUj68fVaUuZEjoKBNI/5XwVvHFvA//He0VnE+72aP7amat0wUTE3Olrbrh/1fp/0zN8 rnzZ+SHwemLKg2LlH9LrK/3snNd3LVq96+7KmxMaX/4/1z5/D8PCxBnpCT1T4j4xr5Z8e/dR n/XD5ovLD7z8ce5eWvREj8x3SizFGYmGWsxFxYkABVkysLsCAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170302115312eucas1p2d0d4870f491e4dc4c0fef36f9e62bbff X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?UTF-8?B?UGV0ZXIgU3RlcGhlbnNvbhtTQ1NDLURhdGEgUGxhbmUb?= =?UTF-8?B?7IK87ISx7KCE7J6QG1ByaW5jaXBhbCBFbmdpbmVlciwgU29mdHdhcmU=?= X-Global-Sender: =?UTF-8?B?UGV0ZXIgU3RlcGhlbnNvbhtTQ1NDLURhdGEgUGxhbmUbU2Ft?= =?UTF-8?B?c3VuZyBFbGVjdHJvbmljcxtQcmluY2lwYWwgRW5naW5lZXIsIFNvZnR3YXJl?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDA1Q0QwNTAwNTg=?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20170302073436epcas2p1ee2d6d723bc7b0865e11243777a08417 X-RootMTR: 20170302073436epcas2p1ee2d6d723bc7b0865e11243777a08417 References: <1488440005.4187177.897775384.2538F781@webmail.messagingengine.com> <20170302104710.6eed8ece@pwslap01u.europe.root.pri> <1488453733.41855.897947392.73E9E4B0@webmail.messagingengine.com> On Thu, 02 Mar 2017 03:22:13 -0800 Sebastian Gniazdowski wrote: > Looked at code few times when debugging, had an unexamined impression > that sister variable of "seen_brct" is needed: > > - if (!in_brace_param) > - in_brace_param = bct; > + if (!in_brace_param) { > + if ((in_brace_param = bct)) > + seen_brct = 0; > + } We could certainly improve things along those lines, possibly using a count of braces which we use elsewhere, but I think we would then just find problems in expressions a stage more complicated. Here's the brute force approach --- it passes all tests, but I bet there's more fall out to come, and it's all over the place, so I'm not sure if there might be a better way. I won't commit it yet. pws diff --git a/Src/cond.c b/Src/cond.c index 8ab0193..0811c5c 100644 --- a/Src/cond.c +++ b/Src/cond.c @@ -138,13 +138,13 @@ evalcond(Estate state, char *fromtest) strs = arrdup(sbuf); l = 2; } - if (name && name[0] == '-') + if (name && (name[0] == '-' || name[0] == Dash)) errname = name; - else if (strs[0] && *strs[0] == '-') + else if (strs[0] && (*strs[0] == '-' || *strs[0] == Dash)) errname = strs[0]; else errname = ""; - if (name && name[0] == '-' && + if (name && (name[0] == '-' || name[0] == Dash) && (cd = getconddef((ctype == COND_MODI), name + 1, 1))) { if (ctype == COND_MOD && (l < cd->min || (cd->max >= 0 && l > cd->max))) { @@ -171,7 +171,7 @@ evalcond(Estate state, char *fromtest) strs[0] = dupstring(name); name = s; - if (name && name[0] == '-' && + if (name && (name[0] == '-' || name[0] == Dash) && (cd = getconddef(0, name + 1, 1))) { if (l < cd->min || (cd->max >= 0 && l > cd->max)) { zwarnnam(fromtest, "unknown condition: %s", diff --git a/Src/exec.c b/Src/exec.c index 83d1513..8e4d8a3 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2779,9 +2779,11 @@ execcmd_exec(Estate state, Execcmd_params eparams, char *argdata = (char *) getdata(argnode); char *cmdopt; int has_p = 0, has_vV = 0, has_other = 0; - while (*argdata == '-') { + while (*argdata == '-' || *argdata == Dash) { /* Just to be definite, stop on single "-", too, */ - if (!argdata[1] || (argdata[1] == '-' && !argdata[2])) + if (!argdata[1] || + ((argdata[1] == '-' || argdata[1] == Dash) + && !argdata[2])) break; for (cmdopt = argdata+1; *cmdopt; cmdopt++) { switch (*cmdopt) { @@ -2835,7 +2837,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, * as if this is command [non-option-stuff]. This * isn't a good place for standard option handling. */ - if (!strcmp(argdata, "--")) + if ((argdata[0] == '-' || argdata[0] == Dash) && + (argdata[1] == '-' || argdata[1] == Dash) && !argdata[2]) uremnode(args, firstnode(args)); } if ((cflags & BINF_EXEC) && nextnode(firstnode(args))) { @@ -2855,7 +2858,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, * people aren't likely to mix the option style * with the zsh style. */ - while (next && *next == '-' && strlen(next) >= 2) { + while (next && (*next == '-' || *next == Dash) && + strlen(next) >= 2) { if (!firstnode(args)) { zerr("exec requires a command to execute"); lastval = 1; @@ -2863,7 +2867,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, goto done; } uremnode(args, firstnode(args)); - if (!strcmp(next, "--")) + if ((next[0] == '-' || next[0] == Dash) && + (next[1] == '-' || next[1] == Dash) && !next[2]) break; for (cmdopt = &next[1]; *cmdopt; ++cmdopt) { switch (*cmdopt) { diff --git a/Src/glob.c b/Src/glob.c index ff6b258..2e4a3ba 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -1314,6 +1314,7 @@ zglob(LinkList list, LinkNode np, int nountok) sense ^= 1; break; case '-': + case Dash: /* Toggle matching of symbolic links */ sense ^= 2; break; @@ -1608,7 +1609,8 @@ zglob(LinkList list, LinkNode np, int nountok) ++s; } /* See if it's greater than, equal to, or less than */ - if ((g_range = *s == '+' ? 1 : *s == '-' ? -1 : 0)) + if ((g_range = *s == '+' ? 1 : + (*s == '-' || *s == Dash) ? -1 : 0)) ++s; data = qgetnum(&s); break; @@ -2025,13 +2027,13 @@ hasbraces(char *str) if (bracechardots(str-1, NULL, NULL)) return 1; lbr = str - 1; - if (*str == '-') + if (*str == '-' || *str == Dash) str++; while (idigit(*str)) str++; if (*str == '.' && str[1] == '.') { str++; str++; - if (*str == '-') + if (*str == '-' || *str == Dash) str++; while (idigit(*str)) str++; @@ -2040,7 +2042,7 @@ hasbraces(char *str) return 1; else if (*str == '.' && str[1] == '.') { str++; str++; - if (*str == '-') + if (*str == '-' || *str == Dash) str++; while (idigit(*str)) str++; @@ -2123,7 +2125,7 @@ xpandredir(struct redir *fn, LinkList redirtab) fn->name = s; untokenize(s); if (fn->type == REDIR_MERGEIN || fn->type == REDIR_MERGEOUT) { - if (s[0] == '-' && !s[1]) + if ((s[0] == '-' || s[0] == Dash) && !s[1]) fn->type = REDIR_CLOSE; else if (s[0] == 'p' && !s[1]) fn->fd2 = -2; @@ -2329,12 +2331,16 @@ xpandbraces(LinkList list, LinkNode *np) * str+1 is the first number in the range, dots+2 the last, * and dots2+2 is the increment if that's given. */ /* TODO: sorry about this */ - int minw = (str[1] == '0' || (str[1] == '-' && str[2] == '0')) + int minw = (str[1] == '0' || + ((str[1] == '-' || str[1] == Dash) && str[2] == '0')) ? wid1 - : (dots[2] == '0' || (dots[2] == '-' && dots[3] == '0')) + : (dots[2] == '0' || + ((dots[2] == '-' || dots[2] == Dash) && + dots[3] == '0')) ? wid2 : (dots2 && (dots2[2] == '0' || - (dots2[2] == '-' && dots2[3] == '0'))) + ((dots2[2] == '-' || dots2[2] == Dash) && + dots2[3] == '0'))) ? wid3 : 0; if (rincr < 0) { @@ -2392,7 +2398,8 @@ xpandbraces(LinkList list, LinkNode *np) c2 = ztokens[c2 - STOUC(Pound)]; if ((char) c2 == Meta) c2 = 32 ^ p[1]; - if (c1 == '-' && lastch >= 0 && p < str2 && lastch <= (int)c2) { + if ((c1 == '-' || c1 == Dash) && + lastch >= 0 && p < str2 && lastch <= (int)c2) { while (lastch < (int)c2) ccl[lastch++] = 1; lastch = -1; @@ -3528,7 +3535,7 @@ zshtokenize(char *s, int flags) } t = s; while (idigit(*++s)); - if (*s != '-') + if (*s != '-' && *s != Dash) goto cont; while (idigit(*++s)); if (*s != '>') diff --git a/Src/lex.c b/Src/lex.c index 8896128..59e9d14 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -1359,17 +1359,13 @@ gettokstr(int c, int sub) case LX2_DASH: /* * - shouldn't be treated as a special character unless - * we're in a pattern. Howeve,simply counting "[" doesn't - * work as []a-z] is a valid expression and we don't know - * down here what this "[" is for as $foo[stuff] is valid - * in zsh. So just detect an opening [, which is enough - * to turn this into a pattern; the Dash will be harmlessly - * untokenised if not wanted. + * we're in a pattern. Unfortunately, working out for + * sure in complicated expressions whether we're in a + * pattern is tricky. So we'll make it special and + * turn it back any time we don't need it special. + * This is not ideal as it's a lot of work. */ - if (seen_brct) - c = Dash; - else - c = '-'; + c = Dash; break; case LX2_BANG: /* diff --git a/Src/math.c b/Src/math.c index f19c0ed..1f6f4d4 100644 --- a/Src/math.c +++ b/Src/math.c @@ -463,7 +463,7 @@ lexconstant(void) char *nptr; nptr = ptr; - if (*nptr == '-') + if (*nptr == '-' || *nptr == Dash) nptr++; if (*nptr == '0') { @@ -527,7 +527,7 @@ lexconstant(void) } if (*nptr == 'e' || *nptr == 'E') { nptr++; - if (*nptr == '+' || *nptr == '-') + if (*nptr == '+' || *nptr == '-' || *nptr == Dash) nptr++; while (idigit(*nptr) || *nptr == '_') nptr++; @@ -599,7 +599,8 @@ zzlex(void) } return (unary) ? UPLUS : PLUS; case '-': - if (*ptr == '-') { + case Dash: + if (*ptr == '-' || *ptr == Dash) { ptr++; return (unary) ? PREMINUS : POSTMINUS; } diff --git a/Src/parse.c b/Src/parse.c index 699ea49..0443237 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -2317,6 +2317,19 @@ par_cond_1(void) } /* + * Return 1 if condition matches. This also works for non-elided options. + * + * input is test string, may begin - or Dash. + * cond is condition following the -. + */ +static int check_cond(const char *input, const char *cond) +{ + if (input[0] != '-' && input[0] != Dash) + return 0; + return !strcmp(input + 1, cond); +} + +/* * cond_2 : BANG cond_2 | INPAR { SEPER } cond_2 { SEPER } OUTPAR | STRING STRING STRING @@ -2342,7 +2355,7 @@ par_cond_2(void) s1 = tokstr; condlex(); /* ksh behavior: [ -t ] means [ -t 1 ]; bash disagrees */ - if (unset(POSIXBUILTINS) && !strcmp(s1, "-t")) + if (unset(POSIXBUILTINS) && check_cond(s1, "t")) return par_cond_double(s1, dupstring("1")); return par_cond_double(dupstring("-n"), s1); } @@ -2352,7 +2365,8 @@ par_cond_2(void) if (!strcmp(*testargs, "=") || !strcmp(*testargs, "==") || !strcmp(*testargs, "!=") || - (**testargs == '-' && get_cond_num(*testargs + 1) >= 0)) { + ((**testargs == '-' || **testargs == Dash) + && get_cond_num(*testargs + 1) >= 0)) { s1 = tokstr; condlex(); s2 = tokstr; @@ -2374,8 +2388,8 @@ par_cond_2(void) * In "test" compatibility mode, "! -a ..." and "! -o ..." * are treated as "[string] [and] ..." and "[string] [or] ...". */ - if (!(n_testargs > 1 && - (!strcmp(*testargs, "-a") || !strcmp(*testargs, "-o")))) + if (!(n_testargs > 1 && (check_cond(*testargs, "a") || + check_cond(*testargs, "o")))) { condlex(); ecadd(WCB_COND(COND_NOT, 0)); @@ -2397,7 +2411,7 @@ par_cond_2(void) return r; } s1 = tokstr; - dble = (s1 && *s1 == '-' + dble = (s1 && (*s1 == '-' || *s1 == Dash) && (!n_testargs || strspn(s1+1, "abcdefghknoprstuvwxzLONGS") == 1) && !s1[2]); @@ -2411,7 +2425,8 @@ par_cond_2(void) YYERROR(ecused); } condlex(); - if (n_testargs == 2 && tok != STRING && tokstr && s1[0] == '-') { + if (n_testargs == 2 && tok != STRING && tokstr && + (s1[0] == '-' || s1[0] == Dash)) { /* * Something like "test -z" followed by a token. * We'll turn the token into a string (we've also @@ -2448,7 +2463,7 @@ par_cond_2(void) } s2 = tokstr; if (!n_testargs) - dble = (s2 && *s2 == '-' && !s2[2]); + dble = (s2 && (*s2 == '-' || *s2 == Dash) && !s2[2]); incond++; /* parentheses do globbing */ do condlex(); while (COND_SEP()); incond--; /* parentheses do grouping */ @@ -2476,7 +2491,7 @@ par_cond_2(void) static int par_cond_double(char *a, char *b) { - if (a[0] != '-' || !a[1]) + if ((a[0] != '-' && a[0] != Dash) || !a[1]) COND_ERROR("parse error: condition expected: %s", a); else if (!a[2] && strspn(a+1, "abcdefgknoprstuvwxzhLONGS") == 1) { ecadd(WCB_COND(a[1], 0)); @@ -2534,7 +2549,7 @@ par_cond_triple(char *a, char *b, char *c) ecadd(WCB_COND(COND_REGEX, 0)); ecstr(a); ecstr(c); - } else if (b[0] == '-') { + } else if (b[0] == '-' || b[0] == Dash) { if ((t0 = get_cond_num(b + 1)) > -1) { ecadd(WCB_COND(t0 + COND_NT, 0)); ecstr(a); @@ -2545,7 +2560,7 @@ par_cond_triple(char *a, char *b, char *c) ecstr(a); ecstr(c); } - } else if (a[0] == '-' && a[1]) { + } else if ((a[0] == '-' || a[0] == Dash) && a[1]) { ecadd(WCB_COND(COND_MOD, 2)); ecstr(a); ecstr(b); @@ -2560,7 +2575,7 @@ par_cond_triple(char *a, char *b, char *c) static int par_cond_multi(char *a, LinkList l) { - if (a[0] != '-' || !a[1]) + if ((a[0] != '-' && a[0] != Dash) || !a[1]) COND_ERROR("condition expected: %s", a); else { LinkNode n; @@ -3256,10 +3271,10 @@ build_dump(char *nam, char *dump, char **files, int ali, int map, int flags) for (hlen = FD_PRELEN, tlen = 0; *files; files++) { struct stat st; - if (!strcmp(*files, "-k")) { + if (check_cond(*files, "k")) { flags = (flags & ~(FDHF_KSHLOAD | FDHF_ZSHLOAD)) | FDHF_KSHLOAD; continue; - } else if (!strcmp(*files, "-z")) { + } else if (check_cond(*files, "z")) { flags = (flags & ~(FDHF_KSHLOAD | FDHF_ZSHLOAD)) | FDHF_ZSHLOAD; continue; } diff --git a/Src/subst.c b/Src/subst.c index 02dbe28..12a5283 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -481,6 +481,8 @@ multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep, for ( ; *x; x += l) { int rawc = -1; convchar_t c; + if (*x == Dash) + *x = '-'; if (itok(STOUC(*x))) { /* token, can't be separator, must be single byte */ rawc = *x; @@ -1766,7 +1768,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, */ c = *s; if (itype_end(s, IIDENT, 1) == s && *s != '#' && c != Pound && - c != '-' && c != '!' && c != '$' && c != String && c != Qstring && + c != '-' && c != Dash && + c != '!' && c != '$' && c != String && c != Qstring && c != '?' && c != Quest && c != '*' && c != Star && c != '@' && c != '{' && c != Inbrace && c != '=' && c != Equals && c != Hat && @@ -1895,13 +1898,13 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, if (quotetype == QT_DOLLARS || quotetype == QT_BACKSLASH_PATTERN) goto flagerr; - if (s[1] == '-' || s[1] == '+') { + if (s[1] == '-' || s[1] == Dash || s[1] == '+') { if (quotemod) goto flagerr; s++; quotemod = 1; - quotetype = (*s == '-') ? QT_SINGLE_OPTIONAL : - QT_QUOTEDZPUTS; + quotetype = (*s == '+') ? QT_QUOTEDZPUTS : + QT_SINGLE_OPTIONAL; } else { if (quotetype == QT_SINGLE_OPTIONAL) { /* extra q's after '-' not allowed */ @@ -2210,7 +2213,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, */ || ((cc == '#' || cc == Pound) && s[2] == Outbrace) - || cc == '-' || (cc == ':' && s[2] == '-') + || cc == '-' || cc == Dash || + (cc == ':' && (s[2] == '-' || s[2] == Dash)) || (isstring(cc) && (s[2] == Inbrace || s[2] == Inpar)))) { getlen = 1 + whichlen, s++; /* @@ -2606,7 +2610,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * examine properly later on. */ if (inbrace && - (c = *s) != '-' && c != '+' && c != ':' && c != '%' && c != '/' && + (c = *s) != '-' && c != Dash && + c != '+' && c != ':' && c != '%' && c != '/' && c != '=' && c != Equals && c != '#' && c != Pound && c != '?' && c != Quest && @@ -2690,7 +2695,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, /* Check for ${..?..} or ${..=..} or one of those. * * Only works if the name is in braces. */ - if (inbrace && ((c = *s) == '-' || + if (inbrace && ((c = *s) == '-' || c == Dash || c == '+' || c == ':' || /* i.e. a doubled colon */ c == '=' || c == Equals || @@ -2802,6 +2807,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, vunset = 1; /* Fall Through! */ case '-': + case Dash: if (vunset) { int split_flags; val = dupstring(s); diff --git a/Src/utils.c b/Src/utils.c index 7f3ddad..c016680 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2376,7 +2376,7 @@ zstrtol_underscore(const char *s, char **t, int base, int underscore) while (inblank(*s)) s++; - if ((neg = (*s == '-'))) + if ((neg = (*s == '-' || *s == Dash))) s++; else if (*s == '+') s++; @@ -6118,7 +6118,9 @@ quotedzputs(char const *s, FILE *stream) } else *ptr++ = '\''; while(*s) { - if (*s == Meta) + if (*s == Dash) + c = '-'; + else if (*s == Meta) c = *++s ^ 32; else c = *s; @@ -6155,7 +6157,9 @@ quotedzputs(char const *s, FILE *stream) } else { /* use Bourne-style quoting, avoiding empty quoted strings */ while (*s) { - if (*s == Meta) + if (*s == Dash) + c = '-'; + else if (*s == Meta) c = *++s ^ 32; else c = *s; diff --git a/Test/D02glob.ztst b/Test/D02glob.ztst index 1385d57..413381f 100644 --- a/Test/D02glob.ztst +++ b/Test/D02glob.ztst @@ -686,3 +686,9 @@ rm glob.tmp/link 0:modifier ':P' resolves symlinks before '..' components *>*glob.tmp/hello/world + + foo=a + value="ac" + print ${value//[${foo}b-z]/x} +0:handling of - range in complicated pattern context +>xx