From 9d47e8398d299e53ffe4e7ddf3731d2fedae9948 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Tue, 13 May 2014 08:16:50 -0700 Subject: 32609: [[ $var ]] behaves as [[ -n $var ]] for bash/ksh compatibility Also restore ksh [ -t ] compatibility when POSIX_BUILTINS is not set, and allow operators defined by modules to be called with no arguments, although this affects only runtime interpretation, not parsing. --- ChangeLog | 8 ++++++++ Src/parse.c | 41 ++++++++++++++++++++++++++++------------- Test/C02cond.ztst | 8 ++++++++ 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 58e1ffa2d..a50a756c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2014-05-13 Barton E. Schaefer + + * 32609: Src/parse.c, Test/CO2cond.ztst: [[ $var ]] behaves as + [[ -n $var ]] for bash/ksh compatibility; restore ksh [ -t ] + compatibility when POSIX_BUILTINS is not set; allow operators + defined by modules to be called with no arguments, although + this affects only runtime interpretation, not parsing. + 2014-05-09 Peter Stephenson * Eric Cook: 32602: Doc/Zsh/grammar.yo: status of try + always diff --git a/Src/parse.c b/Src/parse.c index 530a07033..5f1303f1c 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -2068,6 +2068,9 @@ par_cond_2(void) /* one argument: [ foo ] is equivalent to [ -n foo ] */ s1 = tokstr; condlex(); + /* ksh behavior: [ -t ] means [ -t 1 ]; bash disagrees */ + if (unset(POSIXBUILTINS) && !strcmp(s1, "-t")) + return par_cond_double(s1, dupstring("1")); return par_cond_double(dupstring("-n"), s1); } if (testargs[1]) { @@ -2086,6 +2089,10 @@ par_cond_2(void) return par_cond_triple(s1, s2, s3); } } + /* + * We fall through here on any non-numeric infix operator + * or any other time there are at least two arguments. + */ } if (tok == BANG) { /* @@ -2114,18 +2121,20 @@ par_cond_2(void) condlex(); return r; } + s1 = tokstr; + dble = (s1 && *s1 == '-' + && (condlex != testlex + || strspn(s1+1, "abcdefghknoprstuwxzLONGS") == 1) + && !s1[2]); if (tok != STRING) { - if (tok && tok != LEXERR && condlex == testlex) { - s1 = tokstr; + /* Check first argument for [[ STRING ]] re-interpretation */ + if (s1 /* tok != DOUTBRACK && tok != DAMPER && tok != DBAR */ + && tok != LEXERR && (!dble || condlex == testlex)) { condlex(); - return par_cond_double("-n", s1); + return par_cond_double(dupstring("-n"), s1); } else YYERROR(ecused); } - s1 = tokstr; - if (condlex == testlex) - dble = (*s1 == '-' && strspn(s1+1, "abcdefghknoprstuwxzLONGS") == 1 - && !s1[2]); condlex(); if (tok == INANG || tok == OUTANG) { enum lextok xtok = tok; @@ -2140,15 +2149,21 @@ par_cond_2(void) return 1; } if (tok != STRING) { - if (tok != LEXERR && condlex == testlex) { - if (!dble) - return par_cond_double("-n", s1); - else if (!strcmp(s1, "-t")) - return par_cond_double(s1, "1"); + /* + * Check second argument in case semantics e.g. [ = -a = ] + * mean we have to go back and fix up the first one + */ + if (tok != LEXERR) { + if (!dble || condlex == testlex) + return par_cond_double(dupstring("-n"), s1); + else + return par_cond_multi(s1, newlinklist()); } else YYERROR(ecused); } - s2 = tokstr; + s2 = tokstr; + if (condlex != testlex) + dble = (s2 && *s2 == '-' && !s2[2]); incond++; /* parentheses do globbing */ condlex(); incond--; /* parentheses do grouping */ diff --git a/Test/C02cond.ztst b/Test/C02cond.ztst index 94fca8b68..69001476c 100644 --- a/Test/C02cond.ztst +++ b/Test/C02cond.ztst @@ -349,6 +349,14 @@ F:Failures in these cases do not indicate a problem in the shell. >0 >1 + foo='' + [[ $foo ]] || print foo is empty + foo=full + [[ $foo ]] && print foo is full +0:bash compatibility with single [[ ... ]] argument +>foo is empty +>foo is full + %clean # This works around a bug in rm -f in some versions of Cygwin chmod 644 unmodish -- cgit 1.4.1