diff options
author | Steve Bennett <steveb@workware.net.au> | 2014-01-18 13:27:23 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2014-01-18 13:28:01 +1000 |
commit | 5e56e1547ceaa2ce77beac0317f72b9ebc945d0e (patch) | |
tree | 455bcc750463c2c5a39eb553e7f402ee41e9e11b | |
parent | e04991828210b4fee8cb84a334d28c242bd5e274 (diff) | |
download | jimtcl-5e56e1547ceaa2ce77beac0317f72b9ebc945d0e.zip jimtcl-5e56e1547ceaa2ce77beac0317f72b9ebc945d0e.tar.gz jimtcl-5e56e1547ceaa2ce77beac0317f72b9ebc945d0e.tar.bz2 |
jim.c: fix some dict/list shimmering issues
Only do fast dict->list conversion if there is no string rep
When converting list->dict, generate the string rep of a shared list to avoid
loss of info when converting to dict.
Also add a relevent test to dict.test
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | jim.c | 14 | ||||
-rw-r--r-- | tests/dict.test | 11 |
2 files changed, 19 insertions, 6 deletions
@@ -6313,11 +6313,11 @@ static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) return JIM_OK; } - /* Optimise dict -> list for unshared object. Note that this may only save a little time, but + /* Optimise dict -> list for object with no string rep. Note that this may only save a little time, but * it also preserves any source location of the dict elements * which can be very useful */ - if (Jim_IsDict(objPtr) && !Jim_IsShared(objPtr)) { + if (Jim_IsDict(objPtr) && objPtr->bytes == NULL) { Jim_Obj **listObjPtrPtr; int len; int i; @@ -7020,10 +7020,12 @@ static int SetDictFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) return JIM_OK; } - /* Get the string representation. Do this first so we don't - * change order in case of fast conversion to dict. - */ - Jim_String(objPtr); + if (Jim_IsList(objPtr) && Jim_IsShared(objPtr)) { + /* A shared list, so get the string representation now to avoid + * changing the order in case of fast conversion to dict. + */ + Jim_String(objPtr); + } /* For simplicity, convert a non-list object to a list and then to a dict */ listlen = Jim_ListLength(interp, objPtr); diff --git a/tests/dict.test b/tests/dict.test index 6387cd0..c0528e8 100644 --- a/tests/dict.test +++ b/tests/dict.test @@ -237,5 +237,16 @@ test dict-24.3 {dict/list shimmering with embedded nulls} { lassign $dictVar k v string length $v } {3} +test dict-24.4 {dict/list shimmering with lappend and foreach} { + set a [list 1 2 3 4] + + foreach b $a { + # convert to dict + dict size $a + # append to list + lappend a x y + } + llength $a +} 12 testreport |