aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2011-09-30 16:14:07 +1000
committerSteve Bennett <steveb@workware.net.au>2011-11-09 07:18:26 +1000
commit3d73f56904c634fde7f93bc64d1de91419c47c01 (patch)
tree733e5481889a9e77cc0ccb5f0f8dcc8e3a69cba2
parentc35132ec0e0faa80908d3abe29173720403a4349 (diff)
downloadjimtcl-3d73f56904c634fde7f93bc64d1de91419c47c01.zip
jimtcl-3d73f56904c634fde7f93bc64d1de91419c47c01.tar.gz
jimtcl-3d73f56904c634fde7f93bc64d1de91419c47c01.tar.bz2
Fix some dict unset cases
Behaviour is now identical to Tcl 8.6 Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim.c32
-rw-r--r--tests/dict.test24
2 files changed, 43 insertions, 13 deletions
diff --git a/jim.c b/jim.c
index 48a4e6f..fe35328 100644
--- a/jim.c
+++ b/jim.c
@@ -6618,9 +6618,10 @@ int Jim_DictKeysVector(Jim_Interp *interp, Jim_Obj *dictPtr,
for (i = 0; i < keyc; i++) {
Jim_Obj *objPtr;
- if (Jim_DictKey(interp, dictPtr, keyv[i], &objPtr, flags)
- != JIM_OK)
- return JIM_ERR;
+ int rc = Jim_DictKey(interp, dictPtr, keyv[i], &objPtr, flags);
+ if (rc != JIM_OK) {
+ return rc;
+ }
dictPtr = objPtr;
}
*objPtrPtr = dictPtr;
@@ -6643,10 +6644,10 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr,
Jim_Obj *varObjPtr, *objPtr, *dictObjPtr;
int shared, i;
- varObjPtr = objPtr =
- Jim_GetVariable(interp, varNamePtr, newObjPtr == NULL ? JIM_ERRMSG : JIM_NONE);
+ varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags);
if (objPtr == NULL) {
- if (newObjPtr == NULL) /* Cannot remove a key from non existing var */ {
+ if (newObjPtr == NULL && (flags & JIM_ERRMSG)) {
+ /* Cannot remove a key from non existing var */
return JIM_ERR;
}
varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0);
@@ -6657,7 +6658,7 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr,
}
if ((shared = Jim_IsShared(objPtr)))
varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr);
- for (i = 0; i < keyc - 1; i++) {
+ for (i = 0; i < keyc; i++) {
dictObjPtr = objPtr;
/* Check if it's a valid dictionary */
@@ -6666,6 +6667,17 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr,
goto err;
}
}
+
+ if (i == keyc - 1) {
+ /* Last key: Note that error on unset with missing last key is OK */
+ if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) {
+ if (newObjPtr || (flags & JIM_ERRMSG)) {
+ goto err;
+ }
+ }
+ break;
+ }
+
/* Check if the given key exists. */
Jim_InvalidateStringRep(dictObjPtr);
if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr,
@@ -6690,12 +6702,6 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr,
DictAddElement(interp, dictObjPtr, keyv[i], objPtr);
}
}
- /* Note error on unset with missing last key is OK */
- if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) {
- if (newObjPtr || (flags & JIM_ERRMSG)) {
- goto err;
- }
- }
Jim_InvalidateStringRep(objPtr);
Jim_InvalidateStringRep(varObjPtr);
if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) {
diff --git a/tests/dict.test b/tests/dict.test
index 31250b1..3a0218b 100644
--- a/tests/dict.test
+++ b/tests/dict.test
@@ -203,4 +203,28 @@ test dict-23.1 {dict unset missing last level} {
dict size $a
} 2
+test dict-23.2 {dict unset command} -returnCodes error -body {
+ set dictVar a
+ dict unset dictVar a
+} -cleanup {
+ unset dictVar
+} -result {invalid dictionary value: must be a list with an even number of elements}
+
+test dict-23.3 {dict unset command} -setup {
+ unset -nocomplain dictVar
+} -body {
+ list [info exists dictVar] [dict unset dictVar a] [info exists dictVar]
+} -cleanup {
+ unset dictVar
+} -result {0 {} 1}
+
+test dict-23.4 {dict unset command: write failure} -setup {
+ unset -nocomplain dictVar
+} -body {
+ set dictVar 1
+ dict unset dictVar a
+} -returnCodes error -cleanup {
+ unset dictVar
+} -result {invalid dictionary value: must be a list with an even number of elements}
+
testreport