aboutsummaryrefslogtreecommitdiff
path: root/jim.c
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2020-12-20 08:58:50 +1000
committerSteve Bennett <steveb@workware.net.au>2020-12-26 18:08:29 +1000
commit058a5ef8474fb62f711d53e2fc8e2fa68fbb8996 (patch)
tree4b36cb4c1c12451a4d716b555c21437caffcd487 /jim.c
parent3627155c4a047bc491d45406b22a9038402ae964 (diff)
downloadjimtcl-058a5ef8474fb62f711d53e2fc8e2fa68fbb8996.zip
jimtcl-058a5ef8474fb62f711d53e2fc8e2fa68fbb8996.tar.gz
jimtcl-058a5ef8474fb62f711d53e2fc8e2fa68fbb8996.tar.bz2
core: commands that take an index now use integer expressions
This means that instead of just [list index 2+1], we can now do [list index end-$n*2+1] This applies to: lindex, linsert, lreplace, lset, lrange, lsort, regexp, regsub string index,first,last,range Also add tests for both direct integer expressions and indexes. Still needs doc update. Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jim.c')
-rw-r--r--jim.c52
1 files changed, 27 insertions, 25 deletions
diff --git a/jim.c b/jim.c
index 4124a4d..bd5a819 100644
--- a/jim.c
+++ b/jim.c
@@ -6088,7 +6088,7 @@ int Jim_GetWideExpr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr)
if (ret == JIM_OK) {
ret = Jim_GetWide(interp, Jim_GetResult(interp), widePtr);
}
- else {
+ if (ret != JIM_OK) {
/* XXX By doing this we throw away any more detailed message,
* but typical integer expressions won't be very complex
*/
@@ -7828,9 +7828,12 @@ static void UpdateStringOfIndex(struct Jim_Obj *objPtr)
static int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
{
- int idx, end = 0;
+ jim_wide idx;
+ int end = 0;
const char *str;
- char *endptr;
+ Jim_Obj *exprObj = objPtr;
+
+ JimPanic((objPtr->refCount == 0, "SetIndexFromAny() called with zero refcount object"));
/* Get the string representation */
str = Jim_String(objPtr);
@@ -7840,34 +7843,33 @@ static int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
end = 1;
str += 3;
idx = 0;
- }
- else {
- idx = jim_strtol(str, &endptr);
+ switch (*str) {
+ case '\0':
+ exprObj = NULL;
+ break;
- if (endptr == str) {
- goto badindex;
+ case '-':
+ case '+':
+ /* Create a temp object here for evaluation, but this only happens
+ * once unless the index object shimmers since the result is kept
+ */
+ exprObj = Jim_NewStringObj(interp, str, -1);
+ break;
+
+ default:
+ goto badindex;
}
- str = endptr;
}
-
- /* 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 (endptr == str) {
+ if (exprObj) {
+ int ret;
+ Jim_IncrRefCount(exprObj);
+ ret = Jim_GetWideExpr(interp, exprObj, &idx);
+ Jim_DecrRefCount(interp, exprObj);
+ if (ret != JIM_OK) {
goto badindex;
}
- str = endptr;
}
- /* The only thing left should be spaces */
- while (isspace(UCHAR(*str))) {
- str++;
- }
- if (*str) {
- goto badindex;
- }
if (end) {
if (idx > 0) {
idx = INT_MAX;
@@ -7889,7 +7891,7 @@ static int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
badindex:
Jim_SetResultFormatted(interp,
- "bad index \"%#s\": must be integer?[+-]integer? or end?[+-]integer?", objPtr);
+ "bad index \"%#s\": must be intexpr or end?[+-]intexpr?", objPtr);
return JIM_ERR;
}