summaryrefslogtreecommitdiffstats
path: root/generic/tkConfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkConfig.c')
-rw-r--r--generic/tkConfig.c136
1 files changed, 89 insertions, 47 deletions
diff --git a/generic/tkConfig.c b/generic/tkConfig.c
index ed47210..5262f58 100644
--- a/generic/tkConfig.c
+++ b/generic/tkConfig.c
@@ -48,7 +48,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
@@ -63,7 +63,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
@@ -100,6 +100,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
@@ -121,10 +123,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);
/*
@@ -134,9 +137,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 */
@@ -164,7 +167,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. */
{
@@ -172,7 +175,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;
@@ -186,13 +189,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);
}
/*
@@ -217,9 +219,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;
@@ -268,7 +270,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);
}
@@ -276,8 +278,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)
@@ -301,8 +303,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;
@@ -355,7 +357,10 @@ Tk_DeleteOptionTable(
}
}
Tcl_DeleteHashEntry(tablePtr->hashEntryPtr);
- ckfree((char *) tablePtr);
+ tablePtr->refCount2--;
+ if (tablePtr->refCount2 <= 0) {
+ ckfree(tablePtr);
+ }
}
/*
@@ -383,7 +388,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;
@@ -408,7 +413,7 @@ DestroyOptionHashTable(
Tk_DeleteOptionTable((Tk_OptionTable) tablePtr);
}
Tcl_DeleteHashTable(hashTablePtr);
- ckfree((char *) hashTablePtr);
+ ckfree(hashTablePtr);
}
/*
@@ -632,7 +637,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;
/*
@@ -710,7 +715,8 @@ DoObjConfig(
break;
}
case TK_OPTION_STRING: {
- char *newStr, *value;
+ char *newStr;
+ const char *value;
int length;
if (nullOK && ObjectIsEmpty(valuePtr)) {
@@ -719,7 +725,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;
@@ -733,7 +739,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;
}
@@ -930,7 +936,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,
@@ -1028,13 +1034,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;
/*
@@ -1121,13 +1127,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;
}
@@ -1149,7 +1155,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:
@@ -1182,9 +1189,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;
@@ -1221,11 +1228,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;
+}
/*
*--------------------------------------------------------------
@@ -1260,7 +1302,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). */
@@ -1304,9 +1346,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;
}
}
@@ -1317,7 +1358,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;
@@ -1383,7 +1424,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.
@@ -1393,7 +1434,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--) {
@@ -1433,6 +1474,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);
@@ -1484,7 +1526,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,
@@ -1527,7 +1569,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];
@@ -1573,7 +1615,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) {
@@ -1709,7 +1751,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);
}
@@ -2000,7 +2042,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);