aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2020-12-10 20:05:15 +1000
committerSteve Bennett <steveb@workware.net.au>2020-12-11 22:00:00 +1000
commit0490da395651936d844cce2e32d4972cc2ba985a (patch)
tree3a118717b441eef30618a9db6e2bfe84e709aaf1
parenta2816313da54dcadcdb8eecb3875fcc7373432ea (diff)
downloadjimtcl-0490da395651936d844cce2e32d4972cc2ba985a.zip
jimtcl-0490da395651936d844cce2e32d4972cc2ba985a.tar.gz
jimtcl-0490da395651936d844cce2e32d4972cc2ba985a.tar.bz2
list, string: support any number of +/-n for index
It is especially convenient to add -1 for something like: lindex $list end-$BACK-1 or: string range $str $p $p+$len-1 Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim.c7
-rw-r--r--jim_tcl.txt12
-rw-r--r--tests/jim.test28
3 files changed, 39 insertions, 8 deletions
diff --git a/jim.c b/jim.c
index 684905f..2ccd769 100644
--- a/jim.c
+++ b/jim.c
@@ -7815,16 +7815,17 @@ static int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
str = endptr;
}
- /* Now str may include or +<num> or -<num> */
- if (*str == '+' || *str == '-') {
+ /* Now str may include any number of +<num> or -<num> */
+ while (*str == '+' || *str == '-') {
int sign = (*str == '+' ? 1 : -1);
idx += sign * jim_strtol(++str, &endptr);
- if (str == endptr || *endptr) {
+ if (endptr == str) {
goto badindex;
}
str = endptr;
}
+
/* The only thing left should be spaces */
while (isspace(UCHAR(*str))) {
str++;
diff --git a/jim_tcl.txt b/jim_tcl.txt
index 73615c6..328aaab 100644
--- a/jim_tcl.txt
+++ b/jim_tcl.txt
@@ -55,6 +55,7 @@ RECENT CHANGES
Changes since 0.80
~~~~~~~~~~~~~~~~~~
1. TIP 582, comments allowed in expressions
+2. Indexes may contain any number of +n, -n
Changes between 0.79 and 0.80
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -655,17 +656,18 @@ The index may be one of the following forms:
A simple integer, where '0' refers to the first element of the string
or list.
-+integer+integer+ or::
-+integer-integer+::
- The sum or difference of the two integers. e.g. +2+3+ refers to the 5th element.
++integer+integer?...?+ or::
++integer-integer?...?+::
+ The sum or difference of the two or more integers. e.g. +2+3-1+ refers to the 4th element.
This is useful when used with (e.g.) +$i+1+ rather than the more verbose
+[expr {$i+1\}]+
+end+::
The last element of the string or list.
-+end-integer+::
- The 'nth-from-last' element of the string or list.
++end-integer?...?+::
+ The 'nth-from-last' element of the string or list. Again, one or more integers may
+ be added or subtracted. e.g. +end-3+1+
COMMAND SUMMARY
---------------
diff --git a/tests/jim.test b/tests/jim.test
index eaef8aa..ba76879 100644
--- a/tests/jim.test
+++ b/tests/jim.test
@@ -1837,6 +1837,34 @@ test lindex-17.1 {no index} {
lindex {a b c}
} {a b c}
+test lindex-18.1 {multiple +n} {
+ lindex {a b c d e f g} 1+1+1
+} {d}
+
+test lindex-18.2 {multiple +n/-n} {
+ lindex {a b c d e f g} 1+2-1
+} {c}
+
+test lindex-18.3 {end + multiple +n/-n} {
+ lindex {a b c d e f g} end-1-1
+} {e}
+
+test lindex-18.3 {end + multiple +n/-n} {
+ lindex {a b c d e f g} end-3+1
+} {e}
+
+test lindex-18.4 {multiple +/- in error} -body {
+ lindex {a b c d e f g} 1-x+3
+} -returnCodes error -match glob -result "bad index*"
+
+test lindex-18.5 {multiple +/- in error} -body {
+ lindex {a b c d e f g} 2-1+4x
+} -returnCodes error -match glob -result "bad index*"
+
+test lindex-18.6 {multiple +/- in error} -body {
+ lindex {a b c d e f g} end-3x-1
+} -returnCodes error -match glob -result "bad index*"
+
catch { unset lindex}
catch { unset minus }