summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Modules/parameter.c5
-rw-r--r--Src/builtin.c27
-rw-r--r--Src/exec.c12
-rw-r--r--Src/parse.c25
-rw-r--r--Src/subst.c1
5 files changed, 43 insertions, 27 deletions
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 55157a90c..04d448529 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -410,11 +410,6 @@ getfunction(UNUSED(HashTable ht), const char *name, int dis)
} else
h = dyncat(start, t);
zsfree(t);
- /*
- * TBD: Is this unmetafy correct? Surely as this
- * is a parameter value it stays metafied?
- */
- unmetafy(h, NULL);
if (shf->redir) {
t = getpermtext(shf->redir, NULL, 1);
diff --git a/Src/builtin.c b/Src/builtin.c
index a9afb4540..9358e8b1f 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -69,7 +69,7 @@ static struct builtin builtins[] =
* But that's actually not useful, so it's more consistent to
* cause an error.
*/
- BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "aAdDe:EfiIlmnpPrRt:W", NULL),
+ BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "aAdDe:EfiIlLmnpPrRt:W", NULL),
BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%Z:%ghlprtux", "E"),
BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmMtTuUz", NULL),
@@ -81,7 +81,7 @@ static struct builtin builtins[] =
BUILTIN("hashinfo", 0, bin_hashinfo, 0, 0, 0, NULL, NULL),
#endif
- BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "adDEfimnpPrt:", "l"),
+ BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "adDEfiLmnpPrt:", "l"),
BUILTIN("integer", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "HL:%R:%Z:%ghi:%lprtux", "i"),
BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL),
BUILTIN("kill", BINF_HANDLES_OPTS, bin_kill, 0, -1, 0, NULL, NULL),
@@ -104,7 +104,7 @@ static struct builtin builtins[] =
BUILTIN("pushd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_PUSHD, "qsPL", NULL),
BUILTIN("pushln", 0, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"),
BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
- BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "nrl", NULL),
+ BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "nrlL", NULL),
BUILTIN("read", 0, bin_read, 0, -1, 0, "cd:ek:%lnpqrst:%zu:AE", NULL),
BUILTIN("readonly", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%lptux", "r"),
BUILTIN("rehash", 0, bin_hash, 0, 0, 0, "df", "r"),
@@ -1689,9 +1689,6 @@ fclist(FILE *f, Options ops, zlong first, zlong last,
fclose(f);
return 1;
}
- /* suppress "no substitution" warning if no substitution is requested */
- if (!subs)
- fclistdone = 1;
ent = gethistent(first, first < last? GETHIST_DOWNWARD : GETHIST_UPWARD);
if (!ent || (first < last? ent->histnum > last : ent->histnum < last)) {
@@ -1726,11 +1723,14 @@ fclist(FILE *f, Options ops, zlong first, zlong last,
}
for (;;) {
- s = dupstring(ent->node.nam);
+ if (!OPT_ISSET(ops,'L') || !(ent->node.flags & HIST_FOREIGN))
+ s = dupstring(ent->node.nam);
+ else
+ s = NULL;
/* this if does the pattern matching, if required */
- if (!pprog || pattry(pprog, s)) {
+ if (s && (!pprog || pattry(pprog, s))) {
/* perform substitution */
- fclistdone |= fcsubs(&s, subs);
+ fclistdone |= (subs ? fcsubs(&s, subs) : 1);
/* do numbering */
if (!OPT_ISSET(ops,'n')) {
@@ -1780,7 +1780,10 @@ fclist(FILE *f, Options ops, zlong first, zlong last,
if (f != stdout)
fclose(f);
if (!fclistdone) {
- zwarnnam("fc", "no substitutions performed");
+ if (subs)
+ zwarnnam("fc", "no substitutions performed");
+ else if (OPT_ISSET(ops,'L') || pprog)
+ zwarnnam("fc", "no matching events found");
return 1;
}
return 0;
@@ -4713,6 +4716,10 @@ bin_shift(char *name, char **argv, Options ops, UNUSED(int func))
return ret;
}
+/*
+ * Position of getopts option within OPTIND argument with multiple options.
+ */
+
/**/
int optcind;
diff --git a/Src/exec.c b/Src/exec.c
index 527d61197..9f163a627 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -4910,9 +4910,11 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
if (!(flags & PM_UNDEFINED))
scriptname = dupstring(name);
oldzoptind = zoptind;
- zoptind = 1;
oldoptcind = optcind;
- optcind = 0;
+ if (!isset(POSIXBUILTINS)) {
+ zoptind = 1;
+ optcind = 0;
+ }
/* We need to save the current options even if LOCALOPTIONS is *
* not currently set. That's because if it gets set in the *
@@ -5049,8 +5051,10 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
argzero = oargv0;
}
pparams = pptab;
- optcind = oldoptcind;
- zoptind = oldzoptind;
+ if (!isset(POSIXBUILTINS)) {
+ zoptind = oldzoptind;
+ optcind = oldoptcind;
+ }
scriptname = oldscriptname;
oflags = ooflags;
diff --git a/Src/parse.c b/Src/parse.c
index 06cea744e..c932851d9 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -2212,13 +2212,14 @@ par_cond_2(void)
{
char *s1, *s2, *s3;
int dble = 0;
+ int n_testargs = (condlex == testlex) ? arrlen(testargs) + 1 : 0;
- if (condlex == testlex) {
+ if (n_testargs) {
/* See the description of test in POSIX 1003.2 */
if (tok == NULLTOK)
/* no arguments: false */
return par_cond_double(dupstring("-n"), dupstring(""));
- if (!*testargs) {
+ if (n_testargs == 1) {
/* one argument: [ foo ] is equivalent to [ -n foo ] */
s1 = tokstr;
condlex();
@@ -2227,7 +2228,7 @@ par_cond_2(void)
return par_cond_double(s1, dupstring("1"));
return par_cond_double(dupstring("-n"), s1);
}
- if (testargs[1]) {
+ if (n_testargs > 2) {
/* three arguments: if the second argument is a binary operator, *
* perform that binary test on the first and the third argument */
if (!strcmp(*testargs, "=") ||
@@ -2253,7 +2254,7 @@ par_cond_2(void)
* In "test" compatibility mode, "! -a ..." and "! -o ..."
* are treated as "[string] [and] ..." and "[string] [or] ...".
*/
- if (!(condlex == testlex && *testargs &&
+ if (!(n_testargs > 1 &&
(!strcmp(*testargs, "-a") || !strcmp(*testargs, "-o"))))
{
condlex();
@@ -2277,19 +2278,27 @@ par_cond_2(void)
}
s1 = tokstr;
dble = (s1 && *s1 == '-'
- && (condlex != testlex
+ && (!n_testargs
|| strspn(s1+1, "abcdefghknoprstuwxzLONGS") == 1)
&& !s1[2]);
if (tok != STRING) {
/* Check first argument for [[ STRING ]] re-interpretation */
if (s1 /* tok != DOUTBRACK && tok != DAMPER && tok != DBAR */
- && tok != LEXERR && (!dble || condlex == testlex)) {
+ && tok != LEXERR && (!dble || n_testargs)) {
condlex();
return par_cond_double(dupstring("-n"), s1);
} else
YYERROR(ecused);
}
condlex();
+ if (n_testargs == 2 && tok != STRING && tokstr && s1[0] == '-') {
+ /*
+ * Something like "test -z" followed by a token.
+ * We'll turn the token into a string (we've also
+ * checked it does have a string representation).
+ */
+ tok = STRING;
+ }
if (tok == INANG || tok == OUTANG) {
enum lextok xtok = tok;
condlex();
@@ -2308,7 +2317,7 @@ par_cond_2(void)
* mean we have to go back and fix up the first one
*/
if (tok != LEXERR) {
- if (!dble || condlex == testlex)
+ if (!dble || n_testargs)
return par_cond_double(dupstring("-n"), s1);
else
return par_cond_multi(s1, newlinklist());
@@ -2316,7 +2325,7 @@ par_cond_2(void)
YYERROR(ecused);
}
s2 = tokstr;
- if (condlex != testlex)
+ if (!n_testargs)
dble = (s2 && *s2 == '-' && !s2[2]);
incond++; /* parentheses do globbing */
condlex();
diff --git a/Src/subst.c b/Src/subst.c
index d4a04b8e5..81d34d28a 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -2156,6 +2156,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags)
nojoin = !(ifs && *ifs);
}
} else if ((c == '#' || c == Pound) &&
+ (inbrace || !isset(POSIXIDENTIFIERS)) &&
(itype_end(s+1, IIDENT, 0) != s + 1
|| (cc = s[1]) == '*' || cc == Star || cc == '@'
|| cc == '?' || cc == Quest