aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2017-05-30 21:24:35 +1000
committerSteve Bennett <steveb@workware.net.au>2017-05-30 21:33:40 +1000
commit68b7a49c413b9a75e7a1958d80f0f18a3ab6e924 (patch)
tree69d45c7b05174ae796d0f16d6522207661d4b61a
parent8a0aae566304774210aaeaaac929efe3773b3c60 (diff)
downloadjimtcl-68b7a49c413b9a75e7a1958d80f0f18a3ab6e924.zip
jimtcl-68b7a49c413b9a75e7a1958d80f0f18a3ab6e924.tar.gz
jimtcl-68b7a49c413b9a75e7a1958d80f0f18a3ab6e924.tar.bz2
expr: Ensure that non-zero return codes are passed through
Non-zero return codes (e.g. break, continue, exit) were all being converted to the error code. Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim.c59
-rw-r--r--tests/misc.test13
2 files changed, 44 insertions, 28 deletions
diff --git a/jim.c b/jim.c
index f070526..9b9647e 100644
--- a/jim.c
+++ b/jim.c
@@ -7667,20 +7667,20 @@ typedef struct Jim_ExprOperator
unsigned char namelen;
} Jim_ExprOperator;
-static Jim_Obj *JimExprGetTerm(Jim_Interp *interp, struct JimExprNode *node);
+static int JimExprGetTerm(Jim_Interp *interp, struct JimExprNode *node, Jim_Obj **objPtrPtr);
static int JimExprGetTermBoolean(Jim_Interp *interp, struct JimExprNode *node);
static int JimExprEvalTermNode(Jim_Interp *interp, struct JimExprNode *node);
static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprNode *node)
{
int intresult = 1;
- int rc = JIM_OK;
+ int rc;
double dA, dC = 0;
jim_wide wA, wC = 0;
Jim_Obj *A;
- if ((A = JimExprGetTerm(interp, node->left)) == NULL) {
- return JIM_ERR;
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
}
if ((A->typePtr != &doubleObjType || A->bytes) && JimGetWideNoErr(interp, A, &wA) == JIM_OK) {
@@ -7770,8 +7770,8 @@ static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprNode *node)
Jim_Obj *A;
int rc;
- if ((A = JimExprGetTerm(interp, node->left)) == NULL) {
- return JIM_ERR;
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
}
rc = Jim_GetWide(interp, A, &wA);
@@ -7810,8 +7810,8 @@ static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprNode *node)
double dA, dC;
Jim_Obj *A;
- if ((A = JimExprGetTerm(interp, node->left)) == NULL) {
- return JIM_ERR;
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
}
rc = Jim_GetDouble(interp, A, &dA);
@@ -7878,17 +7878,19 @@ static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprNode *node)
static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprNode *node)
{
jim_wide wA, wB;
- int rc = JIM_ERR;
+ int rc;
Jim_Obj *A, *B;
- if ((A = JimExprGetTerm(interp, node->left)) == NULL) {
- return JIM_ERR;
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
}
- if ((B = JimExprGetTerm(interp, node->right)) == NULL) {
+ if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) {
Jim_DecrRefCount(interp, A);
- return JIM_ERR;
+ return rc;
}
+ rc = JIM_ERR;
+
if (Jim_GetWide(interp, A, &wA) == JIM_OK && Jim_GetWide(interp, B, &wB) == JIM_OK) {
jim_wide wC;
@@ -7978,12 +7980,12 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprNode *node)
jim_wide wA, wB, wC = 0;
Jim_Obj *A, *B;
- if ((A = JimExprGetTerm(interp, node->left)) == NULL) {
- return JIM_ERR;
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
}
- if ((B = JimExprGetTerm(interp, node->right)) == NULL) {
+ if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) {
Jim_DecrRefCount(interp, A);
- return JIM_ERR;
+ return rc;
}
if ((A->typePtr != &doubleObjType || A->bytes) &&
@@ -8184,13 +8186,14 @@ static int JimExprOpStrBin(Jim_Interp *interp, struct JimExprNode *node)
{
Jim_Obj *A, *B;
jim_wide wC;
+ int rc;
- if ((A = JimExprGetTerm(interp, node->left)) == NULL) {
- return JIM_ERR;
+ if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) {
+ return rc;
}
- if ((B = JimExprGetTerm(interp, node->right)) == NULL) {
+ if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) {
Jim_DecrRefCount(interp, A);
- return JIM_ERR;
+ return rc;
}
switch (node->type) {
@@ -8215,7 +8218,7 @@ static int JimExprOpStrBin(Jim_Interp *interp, struct JimExprNode *node)
Jim_DecrRefCount(interp, A);
Jim_DecrRefCount(interp, B);
- return JIM_OK;
+ return rc;
}
static int ExprBool(Jim_Interp *interp, Jim_Obj *obj)
@@ -9187,14 +9190,14 @@ static int JimExprEvalTermNode(Jim_Interp *interp, struct JimExprNode *node)
}
}
-static Jim_Obj *JimExprGetTerm(Jim_Interp *interp, struct JimExprNode *node)
+static int JimExprGetTerm(Jim_Interp *interp, struct JimExprNode *node, Jim_Obj **objPtrPtr)
{
- if (JimExprEvalTermNode(interp, node) == JIM_OK) {
- Jim_Obj *objPtr = Jim_GetResult(interp);
- Jim_IncrRefCount(objPtr);
- return objPtr;
+ int rc = JimExprEvalTermNode(interp, node);
+ if (rc == JIM_OK) {
+ *objPtrPtr = Jim_GetResult(interp);
+ Jim_IncrRefCount(*objPtrPtr);
}
- return NULL;
+ return rc;
}
static int JimExprGetTermBoolean(Jim_Interp *interp, struct JimExprNode *node)
diff --git a/tests/misc.test b/tests/misc.test
index 6eeb648..29bd977 100644
--- a/tests/misc.test
+++ b/tests/misc.test
@@ -475,6 +475,19 @@ test jimexpr-2.5 "double ** operator" {
expr {$result in {unsupported 8.0}}
} 1
+test jimexpr-2.6 "exit in expression" {
+ # The inner 'exit 0' should propagate through the if to
+ # the outer catch
+ catch -exit {
+ set x 1
+ if {[catch {exit 0}] == 1} {
+ set x 2
+ } else {
+ set x 3
+ }
+ }]
+} 6
+
# This one is for test coverage of an unusual case
test jimobj-1.1 "duplicate obj with no dupIntRepProc" {
proc "x x" {} { return 2 }