diff options
Diffstat (limited to 'generic/tkConfig.c')
-rw-r--r-- | generic/tkConfig.c | 136 |
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); |