this is bash compatibility week, and by suggestion of actual users,
namely Dr. Robert “Pfeffer” Arnold (in this case, in FreeWRT), make a half-completed attempt at implementing ${foo:2:3} substring evals (of course, negatives can't work right now and that the numbers are in face expressions is something I only read later too – this is to be revisited later, but it's already late) don't depend on this behaviour yet though if someone wants to add more regression tests, feel free to…
This commit is contained in:
parent
0675b8f25b
commit
ca17798533
46
check.t
46
check.t
@ -1,4 +1,4 @@
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.117 2007/06/23 22:48:47 tg Exp $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.118 2007/06/27 23:12:58 tg Exp $
|
||||
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
||||
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
||||
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
||||
@ -7,7 +7,7 @@
|
||||
# http://www.research.att.com/~gsf/public/ifs.sh
|
||||
|
||||
expected-stdout:
|
||||
@(#)MIRBSD KSH R29 2007/06/22
|
||||
@(#)MIRBSD KSH R29 2007/06/27
|
||||
description:
|
||||
Check version of shell.
|
||||
category: pdksh
|
||||
@ -4030,3 +4030,45 @@ stdin:
|
||||
expected-stdout:
|
||||
5|a|$v|c d|$v|b|
|
||||
---
|
||||
name: varexpand-substr-1
|
||||
description:
|
||||
Check if bash-style substring expansion works
|
||||
when using positive numerics
|
||||
stdin:
|
||||
x=abcdefghi
|
||||
typeset -i y=123456789
|
||||
typeset -i 16 z=123456789 # 16#75bcd15
|
||||
print a ${x:2:3} ${y:2:3} ${z:2:3} a
|
||||
print b ${x::3} ${y::3} ${z::3} b
|
||||
print c ${x:2:} ${y:2:} ${z:2:} c
|
||||
print d ${x:2} ${y:2} ${z:2} d
|
||||
print e ${x:2:6} ${y:2:6} ${z:2:7} e
|
||||
print f ${x:2:7} ${y:2:7} ${z:2:8} f
|
||||
print g ${x:2:8} ${y:2:8} ${z:2:9} g
|
||||
expected-stdout:
|
||||
a cde 345 #75 a
|
||||
b abc 123 16# b
|
||||
c c
|
||||
d cdefghi 3456789 #75bcd15 d
|
||||
e cdefgh 345678 #75bcd1 e
|
||||
f cdefghi 3456789 #75bcd15 f
|
||||
g cdefghi 3456789 #75bcd15 g
|
||||
---
|
||||
name: varexpand-substr-2
|
||||
description:
|
||||
Check if bash-style substring expansion works
|
||||
when using negative numerics or expressions
|
||||
stdin:
|
||||
x=abcdefghi
|
||||
typeset -i y=123456789
|
||||
typeset -i 16 z=123456789 # 16#75bcd15
|
||||
n=2
|
||||
print a ${x:$n:3} ${y:$n:3} ${z:$n:3} a
|
||||
print b ${x:n:3} ${y:n:3} ${z:n:3} b
|
||||
print c ${x:(-2):1} ${y:(-2):1} ${z:(-2):1} c
|
||||
expected-fail: yes
|
||||
expected-stdout:
|
||||
a cde 345 #75 a
|
||||
b cde 345 #75 b
|
||||
c h 8 1 c
|
||||
---
|
||||
|
61
eval.c
61
eval.c
@ -2,7 +2,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.28 2007/06/06 23:28:14 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.29 2007/06/27 23:12:58 tg Exp $");
|
||||
|
||||
#ifdef MKSH_SMALL
|
||||
#define MKSH_NOPWNAM
|
||||
@ -311,6 +311,9 @@ expand(const char *cp, /* input word */
|
||||
if (stype)
|
||||
sp += slen;
|
||||
switch (stype & 0x7f) {
|
||||
case '0':
|
||||
/* XXX begin arithmetic eval. */
|
||||
break;
|
||||
case '#':
|
||||
case '%':
|
||||
/* ! DOBLANK,DOBRACE_,DOTILDE */
|
||||
@ -423,6 +426,39 @@ expand(const char *cp, /* input word */
|
||||
"parameter null or not set" :
|
||||
(debunk(s, s, strlen(s) + 1), s));
|
||||
}
|
||||
case '0':
|
||||
{
|
||||
char i, *s = Xrestpos(ds, dp, st->base);
|
||||
int from = 0, num = 0;
|
||||
/* bool fromend = false; */
|
||||
|
||||
/* XXX use evaluate() from expr.c
|
||||
XXX or directly parse as 2 exprs */
|
||||
/* if (*s == '-') {
|
||||
fromend = true;
|
||||
++s;
|
||||
} */
|
||||
while ((i = *s++) && i != ':')
|
||||
from = from * 10 + i - '0';
|
||||
if (i == ':') while ((i = *s++))
|
||||
num = num * 10 + i - '0';
|
||||
else
|
||||
num = -1;
|
||||
/* if (fromend) {
|
||||
int flen = strlen(x.str);
|
||||
|
||||
if (from < flen)
|
||||
x.str += flen - from;
|
||||
} else */
|
||||
x.str += from;
|
||||
from = strlen(x.str);
|
||||
if (num < 0 || num > from)
|
||||
num = from;
|
||||
dp = Xstring(ds, dp);
|
||||
XcheckN(ds, dp, num);
|
||||
memcpy(dp, x.str, num);
|
||||
dp += num;
|
||||
}
|
||||
}
|
||||
st = st->prev;
|
||||
type = XBASE;
|
||||
@ -742,7 +778,26 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||
stype = 0x80;
|
||||
c = word[slen + 0] == CHAR ? word[slen + 1] : 0;
|
||||
}
|
||||
if (ctype(c, C_SUBOP1)) {
|
||||
if (stype == 0x80 && (ksh_isdigit(c) || c == ':')) {
|
||||
const char *tp = word + slen + 2;
|
||||
bool had_colon = false;
|
||||
|
||||
stype |= '0';
|
||||
/* syntax check: minus, digits, one colon, digits */
|
||||
/* if (*tp == CHAR && tp[1] == '-')
|
||||
tp += 2; */
|
||||
while (*tp != EOS && *tp != CSUBST) {
|
||||
if (*tp != CHAR)
|
||||
return (-1);
|
||||
if (!ksh_isdigit(tp[1])) {
|
||||
if (!had_colon && tp[1] == ':')
|
||||
had_colon = true;
|
||||
else
|
||||
return (-1);
|
||||
}
|
||||
tp += 2;
|
||||
}
|
||||
} else if (ctype(c, C_SUBOP1)) {
|
||||
slen += 2;
|
||||
stype |= c;
|
||||
} else if (ctype(c, C_SUBOP2)) { /* Note: ksh88 allows :%, :%%, etc */
|
||||
@ -820,7 +875,7 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||
|
||||
c = stype&0x7f;
|
||||
/* test the compiler's code generator */
|
||||
if (ctype(c, C_SUBOP2) ||
|
||||
if (ctype(c, C_SUBOP2) || stype == (0x80 | '0') ||
|
||||
(((stype&0x80) ? *xp->str=='\0' : xp->str==null) ? /* undef? */
|
||||
c == '=' || c == '-' || c == '?' : c == '+'))
|
||||
state = XBASE; /* expand word instead of variable value */
|
||||
|
33
mksh.1
33
mksh.1
@ -1,7 +1,7 @@
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.89 2007/06/23 19:07:14 tg Exp $
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.90 2007/06/27 23:12:59 tg Exp $
|
||||
.\" $OpenBSD: ksh.1,v 1.120 2007/05/31 20:47:44 otto Exp $
|
||||
.\"
|
||||
.Dd June 23, 2007
|
||||
.Dd June 27, 2007
|
||||
.Dt MKSH 1
|
||||
.Os MirBSD
|
||||
.Sh NAME
|
||||
@ -1235,6 +1235,35 @@ of them result in the longest match.
|
||||
.Xc
|
||||
.Sm on
|
||||
Like ${..#..} substitution, but it deletes from the end of the value.
|
||||
.It Xo
|
||||
.Pf ${ Ar name : Ns Ar pos
|
||||
.Pf : Ns Ar len Ns }
|
||||
.Xc
|
||||
The first
|
||||
.Ar len
|
||||
bytes of
|
||||
.Ar name ,
|
||||
starting at position
|
||||
.Ar pos ,
|
||||
are substituted.
|
||||
Both
|
||||
.Ar pos
|
||||
and
|
||||
.Pf : Ns Ar len
|
||||
are optional.
|
||||
If
|
||||
.Ar pos
|
||||
.\"is negative, counting starts at the end of the string; if it
|
||||
is omitted, it defaults to 0.
|
||||
If
|
||||
.Ar len
|
||||
is omitted or greater than the length of the remaining string,
|
||||
all of it is substituted.
|
||||
.\"Both
|
||||
.\".Ar pos
|
||||
.\"and
|
||||
.\".Ar len
|
||||
.\"are evaluated as arithmetic expressions.
|
||||
.El
|
||||
.Pp
|
||||
The following special parameters are implicitly set by the shell and cannot be
|
||||
|
4
sh.h
4
sh.h
@ -8,8 +8,8 @@
|
||||
/* $OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $ */
|
||||
/* $OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $ */
|
||||
|
||||
#define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.150 2007/06/22 23:34:41 tg Exp $"
|
||||
#define MKSH_VERSION "R29 2007/06/22"
|
||||
#define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.151 2007/06/27 23:12:59 tg Exp $"
|
||||
#define MKSH_VERSION "R29 2007/06/27"
|
||||
|
||||
#if HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
|
Loading…
x
Reference in New Issue
Block a user