From 9f4a3c6758a3a0b971f85c866080b98f9a4292ae Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" <nijtmans@users.sourceforge.net> Date: Sun, 27 Jan 2013 23:38:17 +0000 Subject: New experiment (ended), regarding non-shimmering "string length" --- generic/tclDictObj.c | 6 ++++++ generic/tclInt.h | 2 ++ generic/tclListObj.c | 1 + generic/tclStringObj.c | 11 +++++++++++ 4 files changed, 20 insertions(+) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index e602c9f..c235d9d 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -138,6 +138,8 @@ typedef struct ChainEntry { */ typedef struct Dict { + int numChars; /* The number of chars in the string. -1 means + * this value has not been calculated. */ Tcl_HashTable table; /* Object hash table to store mapping in. */ ChainEntry *entryChainHead; /* Linked list of all entries in the * dictionary. Used for doing traversal of the @@ -388,6 +390,7 @@ DupDictInternalRep( * Initialise other fields. */ + newDict->numChars = -1; newDict->epoch = 0; newDict->chain = NULL; newDict->refcount = 1; @@ -709,6 +712,7 @@ SetDictFromAny( */ TclFreeIntRep(objPtr); + dict->numChars = -1; dict->epoch = 0; dict->chain = NULL; dict->refcount = 1; @@ -1397,6 +1401,7 @@ Tcl_NewDictObj(void) Tcl_InvalidateStringRep(dictPtr); dict = ckalloc(sizeof(Dict)); InitChainTable(dict); + dict->numChars = -1; dict->epoch = 0; dict->chain = NULL; dict->refcount = 1; @@ -1446,6 +1451,7 @@ Tcl_DbNewDictObj( Tcl_InvalidateStringRep(dictPtr); dict = ckalloc(sizeof(Dict)); InitChainTable(dict); + dict->numChars = -1; dict->epoch = 0; dict->chain = NULL; dict->refcount = 1; diff --git a/generic/tclInt.h b/generic/tclInt.h index df1507d..74ca252 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2406,6 +2406,8 @@ typedef enum TclEolTranslation { */ typedef struct List { + int numChars; /* The number of chars in the string. -1 means + * this value has not been calculated. */ int refCount; int maxElemCount; /* Total number of element array slots. */ int elemCount; /* Current number of list elements. */ diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 6cbb10f..bdadaec 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -109,6 +109,7 @@ NewListIntRep( return NULL; } + listRepPtr->numChars = -1; listRepPtr->canonicalFlag = 0; listRepPtr->refCount = 0; listRepPtr->maxElemCount = objc; diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 64c661b..040c287 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -483,6 +483,17 @@ Tcl_GetCharLength( return length; } + if ((objPtr->typePtr == &tclDictType) + || (objPtr->typePtr == &tclListType)) { + List *list = objPtr->internalRep.twoPtrValue.ptr1; + if (list->numChars == -1) { + (void) TclGetString(objPtr); + TclNumUtfChars(numChars, objPtr->bytes, objPtr->length); + list->numChars = numChars; + } + return list->numChars; + } + /* * OK, need to work with the object as a string. */ -- cgit v0.12