The check for empty patterns and patterns matching the empty string
in commitid 1004D8283F068C41C3C was bogus; it fixed Jb_boin’s issue but izabers’s 「var=foo; echo "${var/*/x}"」 was broken; in fact we only want to not do the looping for // if the pattern matches much. Also, fix a spelling mistake in the manpage and change some wording to also work with associative arrays (in the future; no change).
This commit is contained in:
parent
d3331c04d4
commit
babd9c4cf0
6
check.t
6
check.t
@ -1,4 +1,4 @@
|
|||||||
# $MirOS: src/bin/mksh/check.t,v 1.693 2015/04/29 20:44:32 tg Exp $
|
# $MirOS: src/bin/mksh/check.t,v 1.694 2015/05/23 17:43:18 tg Exp $
|
||||||
# -*- mode: sh -*-
|
# -*- mode: sh -*-
|
||||||
#-
|
#-
|
||||||
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
@ -30,7 +30,7 @@
|
|||||||
# (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
|
# (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
|
||||||
|
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
@(#)MIRBSD KSH R51 2015/04/29
|
@(#)MIRBSD KSH R51 2015/05/23
|
||||||
description:
|
description:
|
||||||
Check version of shell.
|
Check version of shell.
|
||||||
stdin:
|
stdin:
|
||||||
@ -39,7 +39,7 @@ name: KSH_VERSION
|
|||||||
category: shell:legacy-no
|
category: shell:legacy-no
|
||||||
---
|
---
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
@(#)LEGACY KSH R51 2015/04/29
|
@(#)LEGACY KSH R51 2015/05/23
|
||||||
description:
|
description:
|
||||||
Check version of legacy shell.
|
Check version of legacy shell.
|
||||||
stdin:
|
stdin:
|
||||||
|
29
eval.c
29
eval.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.168 2015/04/29 18:32:42 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.169 2015/05/23 17:43:19 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* string expansion
|
* string expansion
|
||||||
@ -528,43 +528,27 @@ expand(
|
|||||||
afree(tpat0, ATEMP);
|
afree(tpat0, ATEMP);
|
||||||
|
|
||||||
/* check for special cases */
|
/* check for special cases */
|
||||||
d = str_val(st->var);
|
|
||||||
switch (*pat) {
|
switch (*pat) {
|
||||||
case '#':
|
case '#':
|
||||||
/* anchor at begin */
|
|
||||||
tpat0 = pat + 1;
|
|
||||||
tpat1 = rrep;
|
|
||||||
tpat2 = d;
|
|
||||||
break;
|
|
||||||
case '%':
|
case '%':
|
||||||
/* anchor at end */
|
|
||||||
tpat0 = pat + 1;
|
tpat0 = pat + 1;
|
||||||
tpat1 = d;
|
|
||||||
tpat2 = rrep;
|
|
||||||
break;
|
break;
|
||||||
case '\0':
|
case '\0':
|
||||||
/* empty pattern */
|
/* empty pattern, reject */
|
||||||
goto no_repl;
|
goto no_repl;
|
||||||
default:
|
default:
|
||||||
tpat0 = pat;
|
tpat0 = pat;
|
||||||
/* silence gcc */
|
|
||||||
tpat1 = tpat2 = NULL;
|
|
||||||
}
|
}
|
||||||
if (gmatchx(null, tpat0, false)) {
|
if (gmatchx(null, tpat0, false)) {
|
||||||
/*
|
/*
|
||||||
* pattern matches
|
* pattern matches empty
|
||||||
* the empty string
|
* string => don't loop
|
||||||
*/
|
*/
|
||||||
if (tpat0 == pat)
|
stype &= ~0x80;
|
||||||
goto no_repl;
|
|
||||||
/* but is anchored */
|
|
||||||
s = shf_smprintf("%s%s",
|
|
||||||
tpat1, tpat2);
|
|
||||||
goto do_repl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare string on which to work */
|
/* prepare string on which to work */
|
||||||
strdupx(s, d, ATEMP);
|
strdupx(s, str_val(st->var), ATEMP);
|
||||||
sbeg = s;
|
sbeg = s;
|
||||||
|
|
||||||
/* first see if we have any match at all */
|
/* first see if we have any match at all */
|
||||||
@ -622,7 +606,6 @@ expand(
|
|||||||
goto again_repl;
|
goto again_repl;
|
||||||
end_repl:
|
end_repl:
|
||||||
afree(tpat1, ATEMP);
|
afree(tpat1, ATEMP);
|
||||||
do_repl:
|
|
||||||
x.str = s;
|
x.str = s;
|
||||||
no_repl:
|
no_repl:
|
||||||
afree(pat, ATEMP);
|
afree(pat, ATEMP);
|
||||||
|
28
mksh.1
28
mksh.1
@ -1,4 +1,4 @@
|
|||||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.366 2015/04/29 20:44:36 tg Exp $
|
.\" $MirOS: src/bin/mksh/mksh.1,v 1.367 2015/05/23 17:43:20 tg Exp $
|
||||||
.\" $OpenBSD: ksh.1,v 1.159 2015/03/25 12:10:52 jca Exp $
|
.\" $OpenBSD: ksh.1,v 1.159 2015/03/25 12:10:52 jca Exp $
|
||||||
.\"-
|
.\"-
|
||||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||||
@ -74,7 +74,7 @@
|
|||||||
.\" with -mandoc, it might implement .Mx itself, but we want to
|
.\" with -mandoc, it might implement .Mx itself, but we want to
|
||||||
.\" use our own definition. And .Dd must come *first*, always.
|
.\" use our own definition. And .Dd must come *first*, always.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: April 29 2015 $
|
.Dd $Mdocdate: May 23 2015 $
|
||||||
.\"
|
.\"
|
||||||
.\" Check which macro package we use, and do other -mdoc setup.
|
.\" Check which macro package we use, and do other -mdoc setup.
|
||||||
.\"
|
.\"
|
||||||
@ -1538,7 +1538,9 @@ is not needed, it is not evaluated.
|
|||||||
.Pp
|
.Pp
|
||||||
The following forms of parameter substitution can also be used (if
|
The following forms of parameter substitution can also be used (if
|
||||||
.Ar name
|
.Ar name
|
||||||
is an array, its element #0 will be substituted in a scalar context):
|
is an array, the element with the key
|
||||||
|
.Dq 0
|
||||||
|
will be substituted in scalar context):
|
||||||
.Pp
|
.Pp
|
||||||
.Bl -tag -width Ds -compact
|
.Bl -tag -width Ds -compact
|
||||||
.It Pf ${# Ns Ar name Ns \&}
|
.It Pf ${# Ns Ar name Ns \&}
|
||||||
@ -1628,7 +1630,7 @@ Cannot be applied to a vector.
|
|||||||
.Pf // Ar pattern / Ar string No }
|
.Pf // Ar pattern / Ar string No }
|
||||||
.Xc
|
.Xc
|
||||||
.Sm on
|
.Sm on
|
||||||
Like ${..#..} substitution, but it replaces the longest match of
|
Similar to ${..##..} substitution, but it replaces the longest match of
|
||||||
.Ar pattern ,
|
.Ar pattern ,
|
||||||
anchored anywhere in the value, with
|
anchored anywhere in the value, with
|
||||||
.Ar string .
|
.Ar string .
|
||||||
@ -1639,17 +1641,17 @@ begins with
|
|||||||
it is anchored at the beginning of the value; if it begins with
|
it is anchored at the beginning of the value; if it begins with
|
||||||
.Ql % ,
|
.Ql % ,
|
||||||
it is anchored at the end.
|
it is anchored at the end.
|
||||||
Patterns that are empty or consist only of wildcards are invalid.
|
Empty patterns cause no replacement to happen.
|
||||||
A single
|
A single leading
|
||||||
.Ql /
|
.Ql /
|
||||||
replaces the first occurence of the search
|
or use of a pattern that matches the empty string causes the
|
||||||
.Ar pattern ,
|
replacement to happen only once; two leading slashes cause
|
||||||
and two of them replace all occurences.
|
all occurrences of matches in the value to be replaced.
|
||||||
If
|
If the trailing
|
||||||
.Pf / Ar string
|
.Pf / Ar string
|
||||||
is omitted, the
|
is omitted, any matches of
|
||||||
.Ar pattern
|
.Ar pattern
|
||||||
is replaced by the empty string, i.e. deleted.
|
are replaced by the empty string, i.e. deleted.
|
||||||
Cannot be applied to a vector.
|
Cannot be applied to a vector.
|
||||||
Inefficiently implemented, may be slow.
|
Inefficiently implemented, may be slow.
|
||||||
.Pp
|
.Pp
|
||||||
@ -2010,7 +2012,7 @@ You can tell the shell not to count certain
|
|||||||
sequences (such as escape codes) by prefixing your prompt with a
|
sequences (such as escape codes) by prefixing your prompt with a
|
||||||
character (such as Ctrl-A) followed by a carriage return and then delimiting
|
character (such as Ctrl-A) followed by a carriage return and then delimiting
|
||||||
the escape codes with this character.
|
the escape codes with this character.
|
||||||
Any occurences of that character in the prompt are not printed.
|
Any occurrences of that character in the prompt are not printed.
|
||||||
By the way, don't blame me for
|
By the way, don't blame me for
|
||||||
this hack; it's derived from the original
|
this hack; it's derived from the original
|
||||||
.Xr ksh88 1 ,
|
.Xr ksh88 1 ,
|
||||||
|
4
sh.h
4
sh.h
@ -169,9 +169,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#ifdef EXTERN
|
||||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.729 2015/04/29 20:44:37 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.730 2015/05/23 17:43:22 tg Exp $");
|
||||||
#endif
|
#endif
|
||||||
#define MKSH_VERSION "R51 2015/04/29"
|
#define MKSH_VERSION "R51 2015/05/23"
|
||||||
|
|
||||||
/* arithmetic types: C implementation */
|
/* arithmetic types: C implementation */
|
||||||
#if !HAVE_CAN_INTTYPES
|
#if !HAVE_CAN_INTTYPES
|
||||||
|
Loading…
x
Reference in New Issue
Block a user