aboutsummaryrefslogtreecommitdiff
path: root/jim.c
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2010-03-03 15:33:19 +1000
committerSteve Bennett <steveb@workware.net.au>2010-10-15 11:02:47 +1000
commit52b1ccb6859a2029e5b5a6d885e26a2a757ba0b1 (patch)
tree0da35287bda089c24c828b2614ab7ca9829e20c8 /jim.c
parentdbbc0daa570689105ee6a22af48395fd8dce4b0f (diff)
downloadjimtcl-52b1ccb6859a2029e5b5a6d885e26a2a757ba0b1.zip
jimtcl-52b1ccb6859a2029e5b5a6d885e26a2a757ba0b1.tar.gz
jimtcl-52b1ccb6859a2029e5b5a6d885e26a2a757ba0b1.tar.bz2
Fix lsort for large integers
The compare result may be a wide integer, so ensure that the sign is retaining when narrowing to an int Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jim.c')
-rw-r--r--jim.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/jim.c b/jim.c
index 609cdbc..d12af64 100644
--- a/jim.c
+++ b/jim.c
@@ -5284,6 +5284,18 @@ static void JimListGetElements(Jim_Interp *interp, Jim_Obj *listObj, int *listLe
*listVec = listObj->internalRep.listValue.ele;
}
+/* Sorting uses ints, but commands may return wide */
+static int JimSign(jim_wide w)
+{
+ if (w == 0) {
+ return 0;
+ }
+ else if (w < 0) {
+ return -1;
+ }
+ return 1;
+}
+
/* ListSortElements type values */
enum {JIM_LSORT_ASCII, JIM_LSORT_NOCASE, JIM_LSORT_INTEGER, JIM_LSORT_COMMAND};
@@ -5312,18 +5324,18 @@ static int ListSortInteger(Jim_Obj **lhsObj, Jim_Obj **rhsObj)
Jim_GetWide(sort_interp, *lhsObj, &lhs);
Jim_GetWide(sort_interp, *rhsObj, &rhs);
- return (int)(lhs - rhs) * sort_order;
+ return JimSign(lhs - rhs) * sort_order;
}
static int ListSortCommand(Jim_Obj **lhsObj, Jim_Obj **rhsObj)
{
Jim_Obj *compare_script;
- long ret = 0;
+ jim_wide ret = 0;
/* We have already had an error, so just compare pointers */
if (sort_result != JIM_OK) {
- return (long)lhsObj - (long)rhsObj;
+ return JimSign(lhsObj - rhsObj);
}
/* This must be a valid list */
@@ -5335,11 +5347,11 @@ static int ListSortCommand(Jim_Obj **lhsObj, Jim_Obj **rhsObj)
if (sort_result != JIM_OK) {
/* We have an error, so just compare pointers */
- return (long)lhsObj - (long)rhsObj;
+ return JimSign(lhsObj - rhsObj);
}
- Jim_GetLong(sort_interp, Jim_GetResult(sort_interp), &ret);
- return sort_order * ret;
+ Jim_GetWide(sort_interp, Jim_GetResult(sort_interp), &ret);
+ return JimSign(ret) * sort_order;
}
/* Sort a list *in place*. MUST be called with non-shared objects. */