ash: more general format ${var:EXPR:EXPR}
function old new delta subevalvar 1171 1202 +31 localcmd 364 366 +2 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
4f8079de87
commit
826360ff23
47
shell/ash.c
47
shell/ash.c
@ -6612,7 +6612,6 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
|||||||
char *loc;
|
char *loc;
|
||||||
char *rmesc, *rmescend;
|
char *rmesc, *rmescend;
|
||||||
char *str;
|
char *str;
|
||||||
IF_BASH_SUBSTR(int pos, len, orig_len;)
|
|
||||||
int amount, resetloc;
|
int amount, resetloc;
|
||||||
IF_BASH_PATTERN_SUBST(int workloc;)
|
IF_BASH_PATTERN_SUBST(int workloc;)
|
||||||
IF_BASH_PATTERN_SUBST(char *repl = NULL;)
|
IF_BASH_PATTERN_SUBST(char *repl = NULL;)
|
||||||
@ -6641,14 +6640,23 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
|
||||||
#if BASH_SUBSTR
|
#if BASH_SUBSTR
|
||||||
case VSSUBSTR:
|
case VSSUBSTR: {
|
||||||
//TODO: support more general format ${v:EXPR:EXPR},
|
int pos, len, orig_len;
|
||||||
// where EXPR follows $(()) rules
|
char *colon;
|
||||||
loc = str = stackblock() + strloc;
|
|
||||||
/* Read POS in ${var:POS:LEN} */
|
|
||||||
pos = atoi(loc); /* number(loc) errors out on "1:4" */
|
|
||||||
len = str - startp - 1;
|
|
||||||
|
|
||||||
|
loc = str = stackblock() + strloc;
|
||||||
|
|
||||||
|
# if !ENABLE_FEATURE_SH_MATH
|
||||||
|
# define ash_arith number
|
||||||
|
# endif
|
||||||
|
/* Read POS in ${var:POS:LEN} */
|
||||||
|
colon = strchr(loc, ':');
|
||||||
|
if (colon) *colon = '\0';
|
||||||
|
pos = ash_arith(loc);
|
||||||
|
if (colon) *colon = ':';
|
||||||
|
|
||||||
|
/* Read LEN in ${var:POS:LEN} */
|
||||||
|
len = str - startp - 1;
|
||||||
/* *loc != '\0', guaranteed by parser */
|
/* *loc != '\0', guaranteed by parser */
|
||||||
if (quotes) {
|
if (quotes) {
|
||||||
char *ptr;
|
char *ptr;
|
||||||
@ -6662,26 +6670,21 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
orig_len = len;
|
orig_len = len;
|
||||||
|
|
||||||
if (*loc++ == ':') {
|
if (*loc++ == ':') {
|
||||||
/* ${var::LEN} */
|
/* ${var::LEN} */
|
||||||
len = number(loc);
|
len = ash_arith(loc);
|
||||||
} else {
|
} else {
|
||||||
/* Skip POS in ${var:POS:LEN} */
|
/* Skip POS in ${var:POS:LEN} */
|
||||||
len = orig_len;
|
len = orig_len;
|
||||||
while (*loc && *loc != ':') {
|
while (*loc && *loc != ':') {
|
||||||
/* TODO?
|
|
||||||
* bash complains on: var=qwe; echo ${var:1a:123}
|
|
||||||
if (!isdigit(*loc))
|
|
||||||
ash_msg_and_raise_error(msg_illnum, str);
|
|
||||||
*/
|
|
||||||
loc++;
|
loc++;
|
||||||
}
|
}
|
||||||
if (*loc++ == ':') {
|
if (*loc++ == ':') {
|
||||||
len = number(loc);
|
len = ash_arith(loc);
|
||||||
}
|
}
|
||||||
//TODO: number() chokes on "-n". In bash, LEN=-n means strlen()-n
|
|
||||||
}
|
}
|
||||||
|
# undef ash_arith
|
||||||
|
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
/* ${VAR:$((-n)):l} starts n chars from the end */
|
/* ${VAR:$((-n)):l} starts n chars from the end */
|
||||||
pos = orig_len + pos;
|
pos = orig_len + pos;
|
||||||
@ -6689,12 +6692,16 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
|||||||
if ((unsigned)pos >= orig_len) {
|
if ((unsigned)pos >= orig_len) {
|
||||||
/* apart from obvious ${VAR:999999:l},
|
/* apart from obvious ${VAR:999999:l},
|
||||||
* covers ${VAR:$((-9999999)):l} - result is ""
|
* covers ${VAR:$((-9999999)):l} - result is ""
|
||||||
* (bash-compat)
|
* (bash compat)
|
||||||
*/
|
*/
|
||||||
pos = 0;
|
pos = 0;
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
if (len > (orig_len - pos))
|
if (len < 0) {
|
||||||
|
/* ${VAR:N:-M} sets LEN to strlen()-M */
|
||||||
|
len = (orig_len - pos) + len;
|
||||||
|
}
|
||||||
|
if ((unsigned)len > (orig_len - pos))
|
||||||
len = orig_len - pos;
|
len = orig_len - pos;
|
||||||
|
|
||||||
for (str = startp; pos; str++, pos--) {
|
for (str = startp; pos; str++, pos--) {
|
||||||
@ -6710,6 +6717,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
|||||||
amount = loc - expdest;
|
amount = loc - expdest;
|
||||||
STADJUST(amount, expdest);
|
STADJUST(amount, expdest);
|
||||||
return loc;
|
return loc;
|
||||||
|
}
|
||||||
#endif /* BASH_SUBSTR */
|
#endif /* BASH_SUBSTR */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6754,6 +6762,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
|||||||
#if BASH_PATTERN_SUBST
|
#if BASH_PATTERN_SUBST
|
||||||
workloc = expdest - (char *)stackblock();
|
workloc = expdest - (char *)stackblock();
|
||||||
if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
|
if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
|
||||||
|
int len;
|
||||||
char *idx, *end;
|
char *idx, *end;
|
||||||
|
|
||||||
if (!repl) {
|
if (!repl) {
|
||||||
|
23
shell/ash_test/ash-vars/var_bash1b.right
Normal file
23
shell/ash_test/ash-vars/var_bash1b.right
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
all |0123456
|
||||||
|
4: |456
|
||||||
|
4:2 |45
|
||||||
|
4:-1 |45
|
||||||
|
4:-2 |4
|
||||||
|
4:-3 |
|
||||||
|
-4: |3456
|
||||||
|
-4:2 |34
|
||||||
|
-4:-1 |345
|
||||||
|
-4:-2 |34
|
||||||
|
-4:-3 |3
|
||||||
|
-4:-4 |
|
||||||
|
-4:i=2 |34
|
||||||
|
-4:i=-2|34
|
||||||
|
-4:i=-3|3
|
||||||
|
-4:i=-4|
|
||||||
|
-5: |23456
|
||||||
|
-6: |123456
|
||||||
|
-7: |0123456
|
||||||
|
-8: |
|
||||||
|
-9: |
|
||||||
|
-9:-99 |
|
||||||
|
Ok:0
|
24
shell/ash_test/ash-vars/var_bash1b.tests
Executable file
24
shell/ash_test/ash-vars/var_bash1b.tests
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
set -- 0123456
|
||||||
|
echo "all |"$1
|
||||||
|
echo "4: |"${1:4}
|
||||||
|
echo "4:2 |"${1:4:2}
|
||||||
|
echo "4:-1 |"${1:4:-1}
|
||||||
|
echo "4:-2 |"${1:4:-2}
|
||||||
|
echo "4:-3 |"${1:4:-3}
|
||||||
|
echo "-4: |"${1: -4}
|
||||||
|
echo "-4:2 |"${1: -4:2}
|
||||||
|
echo "-4:-1 |"${1: -4:-1}
|
||||||
|
echo "-4:-2 |"${1: -4:-2}
|
||||||
|
echo "-4:-3 |"${1: -4:-3}
|
||||||
|
echo "-4:-4 |"${1: -4:-4}
|
||||||
|
i=2; echo "-4:i=2 |"${1: -4:i}
|
||||||
|
i=-2; echo "-4:i=-2|"${1: -4:i}
|
||||||
|
i=-3; echo "-4:i=-3|"${1: -4:i}
|
||||||
|
i=-4; echo "-4:i=-4|"${1: -4:i}
|
||||||
|
echo "-5: |"${1: -5}
|
||||||
|
echo "-6: |"${1: -6}
|
||||||
|
echo "-7: |"${1: -7}
|
||||||
|
echo "-8: |"${1: -8}
|
||||||
|
echo "-9: |"${1: -9}
|
||||||
|
echo "-9:-99 |"${1: -9:-99}
|
||||||
|
echo Ok:$?
|
Loading…
Reference in New Issue
Block a user