summaryrefslogtreecommitdiffstats
path: root/generic/tkConfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkConfig.c')
-rw-r--r--generic/tkConfig.c138
1 files changed, 90 insertions, 48 deletions
diff --git a/generic/tkConfig.c b/generic/tkConfig.c
index 368d0ce..ac5ff5d 100644
--- a/generic/tkConfig.c
+++ b/generic/tkConfig.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkConfig.c,v 1.26 2007/12/13 15:24:13 dgp Exp $
+ * RCS: @(#) $Id: tkConfig.c,v 1.33 2010/02/22 23:38:53 nijtmans Exp $
*/
/*
@@ -50,7 +50,7 @@
*/
typedef struct TkOption {
- CONST Tk_OptionSpec *specPtr;
+ const Tk_OptionSpec *specPtr;
/* The original spec from the template passed
* to Tk_CreateOptionTable.*/
Tk_Uid dbNameUID; /* The Uid form of the option database
@@ -65,7 +65,7 @@ typedef struct TkOption {
struct TkOption *synonymPtr;
/* For synonym options, this points to the
* master entry. */
- struct Tk_ObjCustomOption *custom;
+ const struct Tk_ObjCustomOption *custom;
/* For TK_OPTION_CUSTOM. */
} extra;
int flags; /* Miscellaneous flag values; see below for
@@ -102,6 +102,8 @@ typedef struct OptionTable {
* chain. */
int numOptions; /* The number of items in the options array
* below. */
+ int refCount2; /* Reference counter for controlling the freeing
+ * of the memory occupied by this OptionTable */
Option options[1]; /* Information about the individual options in
* the table. This must be the last field in
* the structure: the actual size of the array
@@ -123,10 +125,11 @@ static Tcl_Obj * GetConfigList(char *recordPtr,
Option *optionPtr, Tk_Window tkwin);
static Tcl_Obj * GetObjectForOption(char *recordPtr,
Option *optionPtr, Tk_Window tkwin);
-static Option * GetOption(CONST char *name, OptionTable *tablePtr);
+static Option * GetOption(const char *name, OptionTable *tablePtr);
static Option * GetOptionFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, OptionTable *tablePtr);
static int ObjectIsEmpty(Tcl_Obj *objPtr);
+static void FreeOptionInternalRep(Tcl_Obj *objPtr);
static int SetOptionFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
/*
@@ -136,9 +139,9 @@ static int SetOptionFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
* the internalPtr2 field points to the entry that matched.
*/
-Tcl_ObjType tkOptionObjType = {
+static const Tcl_ObjType optionObjType = {
"option", /* name */
- NULL, /* freeIntRepProc */
+ FreeOptionInternalRep, /* freeIntRepProc */
NULL, /* dupIntRepProc */
NULL, /* updateStringProc */
SetOptionFromAny /* setFromAnyProc */
@@ -166,7 +169,7 @@ Tk_OptionTable
Tk_CreateOptionTable(
Tcl_Interp *interp, /* Interpreter associated with the application
* in which this table will be used. */
- CONST Tk_OptionSpec *templatePtr)
+ const Tk_OptionSpec *templatePtr)
/* Static information about the configuration
* options. */
{
@@ -174,7 +177,7 @@ Tk_CreateOptionTable(
Tcl_HashEntry *hashEntryPtr;
int newEntry;
OptionTable *tablePtr;
- CONST Tk_OptionSpec *specPtr, *specPtr2;
+ const Tk_OptionSpec *specPtr, *specPtr2;
Option *optionPtr;
int numOptions, i;
@@ -188,13 +191,12 @@ Tk_CreateOptionTable(
* doesn't already exist.
*/
- hashTablePtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, OPTION_HASH_KEY,
- NULL);
+ hashTablePtr = Tcl_GetAssocData(interp, OPTION_HASH_KEY, NULL);
if (hashTablePtr == NULL) {
- hashTablePtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
+ hashTablePtr = ckalloc(sizeof(Tcl_HashTable));
Tcl_InitHashTable(hashTablePtr, TCL_ONE_WORD_KEYS);
Tcl_SetAssocData(interp, OPTION_HASH_KEY, DestroyOptionHashTable,
- (ClientData) hashTablePtr);
+ hashTablePtr);
}
/*
@@ -219,9 +221,9 @@ Tk_CreateOptionTable(
for (specPtr = templatePtr; specPtr->type != TK_OPTION_END; specPtr++) {
numOptions++;
}
- tablePtr = (OptionTable *) (ckalloc(sizeof(OptionTable)
- + (numOptions * sizeof(Option))));
+ tablePtr = ckalloc(sizeof(OptionTable) + (numOptions * sizeof(Option)));
tablePtr->refCount = 1;
+ tablePtr->refCount2 = 1;
tablePtr->hashEntryPtr = hashEntryPtr;
tablePtr->nextPtr = NULL;
tablePtr->numOptions = numOptions;
@@ -270,7 +272,7 @@ Tk_CreateOptionTable(
|| (specPtr->type == TK_OPTION_BORDER))
&& (specPtr->clientData != NULL)) {
optionPtr->extra.monoColorPtr =
- Tcl_NewStringObj((char *) specPtr->clientData, -1);
+ Tcl_NewStringObj(specPtr->clientData, -1);
Tcl_IncrRefCount(optionPtr->extra.monoColorPtr);
}
@@ -278,8 +280,8 @@ Tk_CreateOptionTable(
/*
* Get the custom parsing, etc., functions.
*/
- optionPtr->extra.custom =
- (Tk_ObjCustomOption *) specPtr->clientData;
+
+ optionPtr->extra.custom = specPtr->clientData;
}
}
if (((specPtr->type == TK_OPTION_STRING)
@@ -303,8 +305,8 @@ Tk_CreateOptionTable(
*/
if (specPtr->clientData != NULL) {
- tablePtr->nextPtr = (OptionTable *) Tk_CreateOptionTable(interp,
- (Tk_OptionSpec *) specPtr->clientData);
+ tablePtr->nextPtr = (OptionTable *)
+ Tk_CreateOptionTable(interp, specPtr->clientData);
}
return (Tk_OptionTable) tablePtr;
@@ -357,7 +359,10 @@ Tk_DeleteOptionTable(
}
}
Tcl_DeleteHashEntry(tablePtr->hashEntryPtr);
- ckfree((char *) tablePtr);
+ tablePtr->refCount2--;
+ if (tablePtr->refCount2 <= 0) {
+ ckfree(tablePtr);
+ }
}
/*
@@ -385,7 +390,7 @@ DestroyOptionHashTable(
ClientData clientData, /* The hash table we are destroying */
Tcl_Interp *interp) /* The interpreter we are destroying */
{
- Tcl_HashTable *hashTablePtr = (Tcl_HashTable *) clientData;
+ Tcl_HashTable *hashTablePtr = clientData;
Tcl_HashSearch search;
Tcl_HashEntry *hashEntryPtr;
OptionTable *tablePtr;
@@ -410,7 +415,7 @@ DestroyOptionHashTable(
Tk_DeleteOptionTable((Tk_OptionTable) tablePtr);
}
Tcl_DeleteHashTable(hashTablePtr);
- ckfree((char *) hashTablePtr);
+ ckfree(hashTablePtr);
}
/*
@@ -634,7 +639,7 @@ DoObjConfig(
Tk_SavedOption internal; /* Used to save the old internal
* representation of the value if
* savedOptionPtr is NULL. */
- CONST Tk_OptionSpec *specPtr;
+ const Tk_OptionSpec *specPtr;
int nullOK;
/*
@@ -712,7 +717,8 @@ DoObjConfig(
break;
}
case TK_OPTION_STRING: {
- char *newStr, *value;
+ char *newStr;
+ const char *value;
int length;
if (nullOK && ObjectIsEmpty(valuePtr)) {
@@ -721,7 +727,7 @@ DoObjConfig(
if (internalPtr != NULL) {
if (valuePtr != NULL) {
value = Tcl_GetStringFromObj(valuePtr, &length);
- newStr = ckalloc((unsigned) (length + 1));
+ newStr = ckalloc(length + 1);
strcpy(newStr, value);
} else {
newStr = NULL;
@@ -735,7 +741,7 @@ DoObjConfig(
int newValue;
if (Tcl_GetIndexFromObj(interp, valuePtr,
- (CONST char **) optionPtr->specPtr->clientData,
+ optionPtr->specPtr->clientData,
optionPtr->specPtr->optionName+1, 0, &newValue) != TCL_OK) {
return TCL_ERROR;
}
@@ -932,7 +938,7 @@ DoObjConfig(
break;
}
case TK_OPTION_CUSTOM: {
- Tk_ObjCustomOption *custom = optionPtr->extra.custom;
+ const Tk_ObjCustomOption *custom = optionPtr->extra.custom;
if (custom->setProc(custom->clientData, interp, tkwin,
&valuePtr, recordPtr, optionPtr->specPtr->internalOffset,
@@ -1030,13 +1036,13 @@ ObjectIsEmpty(
static Option *
GetOption(
- CONST char *name, /* String balue to be looked up in the option
+ const char *name, /* String balue to be looked up in the option
* table. */
OptionTable *tablePtr) /* Table in which to look up name. */
{
Option *bestPtr, *optionPtr;
OptionTable *tablePtr2;
- CONST char *p1, *p2;
+ const char *p1, *p2;
int count;
/*
@@ -1123,13 +1129,13 @@ GetOptionFromObj(
OptionTable *tablePtr) /* Table in which to look up objPtr. */
{
Option *bestPtr;
- char *name;
+ const char *name;
/*
* First, check to see if the object already has the answer cached.
*/
- if (objPtr->typePtr == &tkOptionObjType) {
+ if (objPtr->typePtr == &optionObjType) {
if (objPtr->internalRep.twoPtrValue.ptr1 == (void *) tablePtr) {
return (Option *) objPtr->internalRep.twoPtrValue.ptr2;
}
@@ -1151,7 +1157,8 @@ GetOptionFromObj(
}
objPtr->internalRep.twoPtrValue.ptr1 = (void *) tablePtr;
objPtr->internalRep.twoPtrValue.ptr2 = (void *) bestPtr;
- objPtr->typePtr = &tkOptionObjType;
+ objPtr->typePtr = &optionObjType;
+ tablePtr->refCount2++;
return bestPtr;
error:
@@ -1184,9 +1191,9 @@ GetOptionFromObj(
*----------------------------------------------------------------------
*/
-CONST Tk_OptionSpec *
+const Tk_OptionSpec *
TkGetOptionSpec(
- CONST char *name, /* String value to be looked up. */
+ const char *name, /* String value to be looked up. */
Tk_OptionTable optionTable) /* Table in which to look up name. */
{
Option *optionPtr;
@@ -1223,11 +1230,46 @@ SetOptionFromAny(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
register Tcl_Obj *objPtr) /* The object to convert. */
{
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
+ Tcl_AppendResult(interp,
"can't convert value to option except via GetOptionFromObj API",
- -1);
+ NULL);
return TCL_ERROR;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeOptionInternalRep --
+ *
+ * Part of the option Tcl object type implementation. Frees the storage
+ * associated with a option object's internal representation unless it
+ * is still in use.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The option object's internal rep is marked invalid and its memory
+ * gets freed unless it is still in use somewhere. In that case the
+ * cleanup is delayed until the last reference goes away.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeOptionInternalRep(
+ register Tcl_Obj *objPtr) /* Object whose internal rep to free. */
+{
+ register OptionTable *tablePtr = (OptionTable *) objPtr->internalRep.twoPtrValue.ptr1;
+
+ tablePtr->refCount2--;
+ if (tablePtr->refCount2 <= 0) {
+ ckfree(tablePtr);
+ }
+ objPtr->typePtr = NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
+ objPtr->internalRep.twoPtrValue.ptr2 = NULL;
+}
/*
*--------------------------------------------------------------
@@ -1262,7 +1304,7 @@ Tk_SetOptions(
char *recordPtr, /* The record to configure. */
Tk_OptionTable optionTable, /* Describes valid options. */
int objc, /* The number of elements in objv. */
- Tcl_Obj *CONST objv[], /* Contains one or more name-value pairs. */
+ Tcl_Obj *const objv[], /* Contains one or more name-value pairs. */
Tk_Window tkwin, /* Window associated with the thing being
* configured; needed for some options (such
* as colors). */
@@ -1306,9 +1348,8 @@ Tk_SetOptions(
if (objc < 2) {
if (interp != NULL) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "value for \"", Tcl_GetStringFromObj(*objv, NULL),
- "\" missing", NULL);
+ Tcl_AppendResult(interp, "value for \"",
+ Tcl_GetStringFromObj(*objv, NULL), "\" missing",NULL);
goto error;
}
}
@@ -1319,7 +1360,7 @@ Tk_SetOptions(
* more space.
*/
- newSavePtr = (Tk_SavedOptions *) ckalloc(sizeof(Tk_SavedOptions));
+ newSavePtr = ckalloc(sizeof(Tk_SavedOptions));
newSavePtr->recordPtr = recordPtr;
newSavePtr->tkwin = tkwin;
newSavePtr->numItems = 0;
@@ -1385,7 +1426,7 @@ Tk_RestoreSavedOptions(
* record. */
char *internalPtr; /* Points to internal value of option in
* record. */
- CONST Tk_OptionSpec *specPtr;
+ const Tk_OptionSpec *specPtr;
/*
* Be sure to restore the options in the opposite order they were set.
@@ -1395,7 +1436,7 @@ Tk_RestoreSavedOptions(
if (savePtr->nextPtr != NULL) {
Tk_RestoreSavedOptions(savePtr->nextPtr);
- ckfree((char *) savePtr->nextPtr);
+ ckfree(savePtr->nextPtr);
savePtr->nextPtr = NULL;
}
for (i = savePtr->numItems - 1; i >= 0; i--) {
@@ -1435,6 +1476,7 @@ Tk_RestoreSavedOptions(
if (specPtr->internalOffset >= 0) {
register char *ptr = (char *) &savePtr->items[i].internalForm;
+ CLANG_ASSERT(internalPtr);
switch (specPtr->type) {
case TK_OPTION_BOOLEAN:
*((int *) internalPtr) = *((int *) ptr);
@@ -1486,7 +1528,7 @@ Tk_RestoreSavedOptions(
*((Tk_Window *) internalPtr) = *((Tk_Window *) ptr);
break;
case TK_OPTION_CUSTOM: {
- Tk_ObjCustomOption *custom = optionPtr->extra.custom;
+ const Tk_ObjCustomOption *custom = optionPtr->extra.custom;
if (custom->restoreProc != NULL) {
custom->restoreProc(custom->clientData, savePtr->tkwin,
@@ -1529,7 +1571,7 @@ Tk_FreeSavedOptions(
if (savePtr->nextPtr != NULL) {
Tk_FreeSavedOptions(savePtr->nextPtr);
- ckfree((char *) savePtr->nextPtr);
+ ckfree(savePtr->nextPtr);
}
for (count = savePtr->numItems,
savedOptionPtr = &savePtr->items[savePtr->numItems-1];
@@ -1575,7 +1617,7 @@ Tk_FreeConfigOptions(
int count;
Tcl_Obj **oldPtrPtr, *oldPtr;
char *oldInternalPtr;
- CONST Tk_OptionSpec *specPtr;
+ const Tk_OptionSpec *specPtr;
for (tablePtr = (OptionTable *) optionTable; tablePtr != NULL;
tablePtr = tablePtr->nextPtr) {
@@ -1711,7 +1753,7 @@ FreeResources(
}
break;
case TK_OPTION_CUSTOM: {
- Tk_ObjCustomOption *custom = optionPtr->extra.custom;
+ const Tk_ObjCustomOption *custom = optionPtr->extra.custom;
if (internalFormExists && custom->freeProc != NULL) {
custom->freeProc(custom->clientData, tkwin, internalPtr);
}
@@ -2002,7 +2044,7 @@ GetObjectForOption(
break;
}
case TK_OPTION_CUSTOM: {
- Tk_ObjCustomOption *custom = optionPtr->extra.custom;
+ const Tk_ObjCustomOption *custom = optionPtr->extra.custom;
objPtr = custom->getProc(custom->clientData, tkwin, recordPtr,
optionPtr->specPtr->internalOffset);