summaryrefslogtreecommitdiffstats
path: root/generic/tclDictObj.c
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2017-01-10 22:28:25 (GMT)
committersebres <sebres@users.sourceforge.net>2017-01-10 22:28:25 (GMT)
commit5afae758b98de2da47b30d6aa4b40a5d5a604fbc (patch)
tree9bea9e914a912fb419e1f480d397197c4362a28a /generic/tclDictObj.c
parent7b6cd1089c2d3a6eeb8f12b106af40c18017c8f3 (diff)
downloadtcl-5afae758b98de2da47b30d6aa4b40a5d5a604fbc.zip
tcl-5afae758b98de2da47b30d6aa4b40a5d5a604fbc.tar.gz
tcl-5afae758b98de2da47b30d6aa4b40a5d5a604fbc.tar.bz2
improve LocalizeFormat, internal caching of localized formats inside msgcat for locale and format objects
smart reference introduced in dict (smart pointer with 0 object reference but increase dict-reference, provide changeable locale dict)
Diffstat (limited to 'generic/tclDictObj.c')
-rw-r--r--generic/tclDictObj.c122
1 files changed, 90 insertions, 32 deletions
diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c
index 1115999..3944173 100644
--- a/generic/tclDictObj.c
+++ b/generic/tclDictObj.c
@@ -51,6 +51,8 @@ static int DictSetCmd(ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv);
static int DictSizeCmd(ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv);
+static int DictSmartRefCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const *objv);
static int DictUnsetCmd(ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv);
static int DictUpdateCmd(ClientData dummy, Tcl_Interp *interp,
@@ -98,6 +100,7 @@ static const EnsembleImplMap implementationMap[] = {
{"replace", DictReplaceCmd, NULL, NULL, NULL, 0 },
{"set", DictSetCmd, TclCompileDictSetCmd, NULL, NULL, 0 },
{"size", DictSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0 },
+ {"smartref",DictSmartRefCmd,NULL, NULL, NULL, 0 },
{"unset", DictUnsetCmd, TclCompileDictUnsetCmd, NULL, NULL, 0 },
{"update", DictUpdateCmd, TclCompileDictUpdateCmd, NULL, NULL, 0 },
{"values", DictValuesCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
@@ -142,7 +145,7 @@ typedef struct Dict {
* the entries in the order that they are
* created. */
int epoch; /* Epoch counter */
- size_t refCount; /* Reference counter (see above) */
+ int refcount; /* Reference counter (see above) */
Tcl_Obj *chain; /* Linked list used for invalidating the
* string representations of updated nested
* dictionaries. */
@@ -392,7 +395,7 @@ DupDictInternalRep(
newDict->epoch = 0;
newDict->chain = NULL;
- newDict->refCount = 1;
+ newDict->refcount = 1;
/*
* Store in the object.
@@ -427,7 +430,8 @@ FreeDictInternalRep(
{
Dict *dict = DICT(dictPtr);
- if (dict->refCount-- <= 1) {
+ dict->refcount--;
+ if (dict->refcount <= 0) {
DeleteDict(dict);
}
dictPtr->typePtr = NULL;
@@ -712,7 +716,7 @@ SetDictFromAny(
TclFreeIntRep(objPtr);
dict->epoch = 0;
dict->chain = NULL;
- dict->refCount = 1;
+ dict->refcount = 1;
DICT(objPtr) = dict;
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
objPtr->typePtr = &tclDictType;
@@ -1116,7 +1120,7 @@ Tcl_DictObjFirst(
searchPtr->dictionaryPtr = (Tcl_Dict) dict;
searchPtr->epoch = dict->epoch;
searchPtr->next = cPtr->nextPtr;
- dict->refCount++;
+ dict->refcount++;
if (keyPtrPtr != NULL) {
*keyPtrPtr = Tcl_GetHashKey(&dict->table, &cPtr->entry);
}
@@ -1230,7 +1234,8 @@ Tcl_DictObjDone(
if (searchPtr->epoch != -1) {
searchPtr->epoch = -1;
dict = (Dict *) searchPtr->dictionaryPtr;
- if (dict->refCount-- <= 1) {
+ dict->refcount--;
+ if (dict->refcount <= 0) {
DeleteDict(dict);
}
}
@@ -1382,7 +1387,7 @@ Tcl_NewDictObj(void)
InitChainTable(dict);
dict->epoch = 0;
dict->chain = NULL;
- dict->refCount = 1;
+ dict->refcount = 1;
DICT(dictPtr) = dict;
dictPtr->internalRep.twoPtrValue.ptr2 = NULL;
dictPtr->typePtr = &tclDictType;
@@ -1432,7 +1437,7 @@ Tcl_DbNewDictObj(
InitChainTable(dict);
dict->epoch = 0;
dict->chain = NULL;
- dict->refCount = 1;
+ dict->refcount = 1;
DICT(dictPtr) = dict;
dictPtr->internalRep.twoPtrValue.ptr2 = NULL;
dictPtr->typePtr = &tclDictType;
@@ -1957,6 +1962,77 @@ DictSizeCmd(
/*
*----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_DictObjSmartRef(
+ Tcl_Interp *interp,
+ Tcl_Obj *dictPtr)
+{
+ Tcl_Obj *result;
+ Dict *dict;
+
+ if (dictPtr->typePtr != &tclDictType
+ && SetDictFromAny(interp, dictPtr) != TCL_OK) {
+ return NULL;
+ }
+
+ dict = DICT(dictPtr);
+
+ result = Tcl_NewObj();
+ DICT(result) = dict;
+ dict->refcount++;
+ result->internalRep.twoPtrValue.ptr2 = NULL;
+ result->typePtr = &tclDictType;
+
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictSmartRefCmd --
+ *
+ * This function implements the "dict smartref" Tcl command. See the user
+ * documentation for details on what it does, and TIP#111 for the formal
+ * specification.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictSmartRefCmd(
+ ClientData dummy,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ Tcl_Obj *result;
+ Dict *dict;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "dictionary");
+ return TCL_ERROR;
+ }
+
+ result = Tcl_DictObjSmartRef(interp, objv[1]);
+ if (result == NULL) {
+ return TCL_ERROR;
+ }
+
+ Tcl_SetObjResult(interp, result);
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
*
* DictExistsCmd --
*
@@ -2280,7 +2356,7 @@ DictAppendCmd(
Tcl_Obj *const *objv)
{
Tcl_Obj *dictPtr, *valuePtr, *resultPtr;
- int allocatedDict = 0;
+ int i, allocatedDict = 0;
if (objc < 3) {
Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?value ...?");
@@ -2305,33 +2381,15 @@ DictAppendCmd(
if ((objc > 3) || (valuePtr == NULL)) {
/* Only go through append activites when something will change. */
- Tcl_Obj *appendObjPtr = NULL;
-
- if (objc > 3) {
- /* Something to append */
-
- if (objc == 4) {
- appendObjPtr = objv[3];
- } else if (TCL_OK != TclStringCatObjv(interp, /* inPlace */ 1,
- objc-3, objv+3, &appendObjPtr)) {
- return TCL_ERROR;
- }
- }
- if (appendObjPtr == NULL) {
- /* => (objc == 3) => (valuePtr == NULL) */
+ if (valuePtr == NULL) {
TclNewObj(valuePtr);
- } else if (valuePtr == NULL) {
- valuePtr = appendObjPtr;
- appendObjPtr = NULL;
+ } else if (Tcl_IsShared(valuePtr)) {
+ valuePtr = Tcl_DuplicateObj(valuePtr);
}
- if (appendObjPtr) {
- if (Tcl_IsShared(valuePtr)) {
- valuePtr = Tcl_DuplicateObj(valuePtr);
- }
-
- Tcl_AppendObjToObj(valuePtr, appendObjPtr);
+ for (i=3 ; i<objc ; i++) {
+ Tcl_AppendObjToObj(valuePtr, objv[i]);
}
Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr);