From e2c34f67078ecc7d451295421be581d956718989 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 27 Jan 2024 12:24:42 +0000 Subject: Work in progress: Implementing properties with more C for greater speed --- generic/tclOOBasic.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclOOInfo.c | 13 ++--- generic/tclOOInt.h | 1 + 3 files changed, 161 insertions(+), 7 deletions(-) diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 5a38dee..251ae34 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -1341,6 +1341,160 @@ TclOOCopyObjectCmd( return TCL_OK; } +static int +ReadProp( + Tcl_Interp *interp, + Object *oPtr, + Tcl_Obj *propObj) +{ + Tcl_Obj *args[] = { + Tcl_NewStringObj("my", 2), + Tcl_ObjPrintf("", TclGetString(propObj)) + }; + int code; + + Tcl_IncrRefCount(args[0]); + Tcl_IncrRefCount(args[1]); + code = TclOOPrivateObjectCmd(oPtr, interp, 2, args); + Tcl_DecrRefCount(args[0]); + Tcl_DecrRefCount(args[1]); + return code; +} + +static int +WriteProp( + Tcl_Interp *interp, + Object *oPtr, + Tcl_Obj *propObj, + Tcl_Obj *valueObj) +{ + Tcl_Obj *args[] = { + Tcl_NewStringObj("my", 2), + Tcl_ObjPrintf("", TclGetString(propObj)), + valueObj + }; + int code; + + Tcl_IncrRefCount(args[0]); + Tcl_IncrRefCount(args[1]); + Tcl_IncrRefCount(args[2]); + code = TclOOPrivateObjectCmd(oPtr, interp, 3, args); + Tcl_DecrRefCount(args[0]); + Tcl_DecrRefCount(args[1]); + Tcl_DecrRefCount(args[2]); + return code; +} + +/* Look up a property full name. */ +static Tcl_Obj * +GetPropertyName( + Tcl_Interp *interp, /* Context and error reporting. */ + Object *oPtr, /* Object to get property name from. */ + int writable, /* Are we looking for a writable property? */ + Tcl_Obj *namePtr) /* The name supplied by the user. */ +{ + int allocated; + Tcl_Size objc, index, i; + Tcl_Obj *listPtr = TclOOGetAllObjectProperties(oPtr, writable, &allocated); + Tcl_Obj **objv; + if (allocated) { + TclOOSortPropList(listPtr); + } + ListObjGetElements(listPtr, objc, objv); + char **tablePtr = TclStackAlloc(interp, sizeof(char*) * objc); + for (int i = 0; i < objc; i++) { + tablePtr[i] = TclGetString(objv[i]); + } + int result = Tcl_GetIndexFromObjStruct(interp, namePtr, tablePtr, + sizeof(char *), "property", TCL_INDEX_TEMP_TABLE, &index); + TclStackFree(interp, tablePtr); + if (result != TCL_OK) { + return NULL; + } + return objv[index]; +} + +int +TclOO_Configurable_Configure( + TCL_UNUSED(void *), + Tcl_Interp *interp, /* Interpreter used for the result, error + * reporting, etc. */ + Tcl_ObjectContext context, /* The object/call context. */ + Tcl_Size objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* The actual arguments. */ +{ + Object *oPtr = (Object *) Tcl_ObjectContextObject(context); + Tcl_Size skip = Tcl_ObjectContextSkippedArgs(context); + Tcl_Size numArgs = objc - skip; + Tcl_Obj *namePtr; + Tcl_Size i; + int code; + + if (numArgs == 0) { + /* + * Read all properties. + */ + + Tcl_Size namec; + int allocated = 0; + Tcl_Obj *listPtr = TclOOGetAllObjectProperties(oPtr, 0, &allocated); + Tcl_Obj *resultPtr = Tcl_NewObj(), **namev; + + if (allocated) { + TclOOSortPropList(listPtr); + } + ListObjGetElements(listPtr, namec, namev); + + for (i = 0; i < namec; ) { + code = ReadProp(interp, oPtr, namev[i]); + if (code != TCL_OK) { + Tcl_DecrRefCount(resultPtr); + return code; + } + Tcl_DictObjPut(NULL, resultPtr, namev[i], Tcl_GetObjResult(interp)); + if (++i >= namec) { + Tcl_SetObjResult(interp, resultPtr); + break; + } + Tcl_SetObjResult(interp, Tcl_NewObj()); + } + } else if (numArgs == 1) { + /* + * Read a single named property. + */ + + namePtr = GetPropertyName(interp, oPtr, 0, objv[skip]); + if (namePtr == NULL) { + return TCL_ERROR; + } + return ReadProp(interp, oPtr, namePtr); + } else if (numArgs % 2) { + /* + * Bad (odd > 1) number of arguments. + */ + + Tcl_WrongNumArgs(interp, skip, objv, "?-option value ...?"); + return TCL_ERROR; + } else { + /* + * Write properties. + */ + + objv += skip; + for (i = 0; i < numArgs; i += 2) { + namePtr = GetPropertyName(interp, oPtr, 1, objv[i]); + if (namePtr == NULL) { + return TCL_ERROR; + } + code = WriteProp(interp, oPtr, namePtr, objv[i + 1]); + if (code != TCL_OK) { + return code; + } + } + } + return TCL_OK; +} + /* * Local Variables: * mode: c diff --git a/generic/tclOOInfo.c b/generic/tclOOInfo.c index eba658b..bc04748 100644 --- a/generic/tclOOInfo.c +++ b/generic/tclOOInfo.c @@ -17,7 +17,6 @@ #include "tclOOInt.h" static inline Class * GetClassFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr); -static void SortPropList(Tcl_Obj *list); static Tcl_ObjCmdProc InfoObjectCallCmd; static Tcl_ObjCmdProc InfoObjectClassCmd; static Tcl_ObjCmdProc InfoObjectDefnCmd; @@ -1784,7 +1783,7 @@ InfoClassPropCmd( if (all) { result = TclOOGetAllClassProperties(clsPtr, writable, &allocated); if (allocated) { - SortPropList(result); + TclOOSortPropList(result); } } else { TclNewObj(result); @@ -1797,7 +1796,7 @@ InfoClassPropCmd( Tcl_ListObjAppendElement(NULL, result, propObj); } } - SortPropList(result); + TclOOSortPropList(result); } Tcl_SetObjResult(interp, result); return TCL_OK; @@ -1847,7 +1846,7 @@ InfoObjectPropCmd( if (all) { result = TclOOGetAllObjectProperties(oPtr, writable, &allocated); if (allocated) { - SortPropList(result); + TclOOSortPropList(result); } } else { TclNewObj(result); @@ -1860,7 +1859,7 @@ InfoObjectPropCmd( Tcl_ListObjAppendElement(NULL, result, propObj); } } - SortPropList(result); + TclOOSortPropList(result); } Tcl_SetObjResult(interp, result); return TCL_OK; @@ -1888,8 +1887,8 @@ PropNameCompare( return strcmp(Tcl_GetString(first), Tcl_GetString(second)); } -static void -SortPropList( +void +TclOOSortPropList( Tcl_Obj *list) { Tcl_Size ec; diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index 031b910..d9f4ed8 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -589,6 +589,7 @@ MODULE_SCOPE int TclOORemoveFromSubclasses(Class *subPtr, Class *superPtr); MODULE_SCOPE Tcl_Obj * TclOORenderCallChain(Tcl_Interp *interp, CallChain *callPtr); +MODULE_SCOPE void TclOOSortPropList(Tcl_Obj *listPtr); MODULE_SCOPE void TclOOStashContext(Tcl_Obj *objPtr, CallContext *contextPtr); MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr); -- cgit v0.12 From bdc4a8603dbdd158e1346b9a3700d27cbfa11423 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 27 Jan 2024 22:05:59 +0000 Subject: Now passing tests --- generic/tcl.h | 121 +++++++++++----------- generic/tclCompile.h | 100 ++++++++++--------- generic/tclEnsemble.c | 3 +- generic/tclIO.h | 8 +- generic/tclIORChan.c | 21 ++-- generic/tclIOUtil.c | 24 ++--- generic/tclInt.h | 250 ++++++++++++++++++++++++++-------------------- generic/tclLoad.c | 5 +- generic/tclNamesp.c | 3 +- generic/tclOO.c | 45 ++++++--- generic/tclOOBasic.c | 226 ++++++++++++++++++++++++++++++++--------- generic/tclOOCall.c | 25 ++--- generic/tclOODefineCmds.c | 8 +- generic/tclOOInfo.c | 7 +- generic/tclOOInt.h | 27 ++--- generic/tclOOMethod.c | 18 ++-- generic/tclOOScript.h | 103 +------------------ generic/tclProcess.c | 6 +- tools/tclOOScript.tcl | 145 +-------------------------- win/Makefile.in | 10 ++ win/tclWinConsole.c | 5 +- win/tclWinSock.c | 5 +- 22 files changed, 550 insertions(+), 615 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index 0f53228..2db88b1 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -453,7 +453,7 @@ typedef void (Tcl_ThreadCreateProc) (void *clientData); * Flags values passed to Tcl_RegExpExecObj. */ -#define TCL_REG_NOTBOL 0001 /* Beginning of string does not match ^. */ +#define TCL_REG_NOTBOL 0001 /* Beginning of string does not match ^. */ #define TCL_REG_NOTEOL 0002 /* End of string does not match $. */ /* @@ -464,9 +464,9 @@ typedef void (Tcl_ThreadCreateProc) (void *clientData); typedef struct Tcl_RegExpIndices { #if TCL_MAJOR_VERSION > 8 - Tcl_Size start; /* Character offset of first character in + Tcl_Size start; /* Character offset of first character in * match. */ - Tcl_Size end; /* Character offset of first character after + Tcl_Size end; /* Character offset of first character after * the match. */ #else long start; @@ -475,11 +475,11 @@ typedef struct Tcl_RegExpIndices { } Tcl_RegExpIndices; typedef struct Tcl_RegExpInfo { - Tcl_Size nsubs; /* Number of subexpressions in the compiled + Tcl_Size nsubs; /* Number of subexpressions in the compiled * expression. */ Tcl_RegExpIndices *matches; /* Array of nsubs match offset pairs. */ #if TCL_MAJOR_VERSION > 8 - Tcl_Size extendStart; /* The offset at which a subsequent match + Tcl_Size extendStart; /* The offset at which a subsequent match * might begin. */ #else long extendStart; @@ -617,26 +617,25 @@ typedef void (Tcl_FinalizeNotifierProc) (void *clientData); typedef void (Tcl_MainLoopProc) (void); /* Abstract List functions */ -typedef Tcl_Size (Tcl_ObjTypeLengthProc) (struct Tcl_Obj *listPtr); -typedef int (Tcl_ObjTypeIndexProc) (Tcl_Interp *interp, struct Tcl_Obj *listPtr, - Tcl_Size index, struct Tcl_Obj** elemObj); -typedef int (Tcl_ObjTypeSliceProc) (Tcl_Interp *interp, struct Tcl_Obj *listPtr, - Tcl_Size fromIdx, Tcl_Size toIdx, - struct Tcl_Obj **newObjPtr); -typedef int (Tcl_ObjTypeReverseProc) (Tcl_Interp *interp, struct Tcl_Obj *listPtr, - struct Tcl_Obj **newObjPtr); -typedef int (Tcl_ObjTypeGetElements) (Tcl_Interp *interp, struct Tcl_Obj *listPtr, - Tcl_Size *objcptr, struct Tcl_Obj ***objvptr); -typedef struct Tcl_Obj* (Tcl_ObjTypeSetElement) (Tcl_Interp *interp, struct Tcl_Obj *listPtr, - Tcl_Size indexCount, - struct Tcl_Obj *const indexArray[], - struct Tcl_Obj *valueObj); -typedef int (Tcl_ObjTypeReplaceProc) (Tcl_Interp *interp, struct Tcl_Obj *listObj, - Tcl_Size first, Tcl_Size numToDelete, - Tcl_Size numToInsert, - struct Tcl_Obj *const insertObjs[]); -typedef int (Tcl_ObjTypeInOperatorProc) (Tcl_Interp *interp, struct Tcl_Obj *valueObj, - struct Tcl_Obj *listObj, int *boolResult); +typedef Tcl_Size (Tcl_ObjTypeLengthProc) (struct Tcl_Obj *listPtr); +typedef int (Tcl_ObjTypeIndexProc) (Tcl_Interp *interp, + struct Tcl_Obj *listPtr, Tcl_Size index, struct Tcl_Obj** elemObj); +typedef int (Tcl_ObjTypeSliceProc) (Tcl_Interp *interp, + struct Tcl_Obj *listPtr, Tcl_Size fromIdx, Tcl_Size toIdx, + struct Tcl_Obj **newObjPtr); +typedef int (Tcl_ObjTypeReverseProc) (Tcl_Interp *interp, + struct Tcl_Obj *listPtr, struct Tcl_Obj **newObjPtr); +typedef int (Tcl_ObjTypeGetElements) (Tcl_Interp *interp, + struct Tcl_Obj *listPtr, Tcl_Size *objcptr, + struct Tcl_Obj ***objvptr); +typedef struct Tcl_Obj* (Tcl_ObjTypeSetElement) (Tcl_Interp *interp, + struct Tcl_Obj *listPtr, Tcl_Size indexCount, + struct Tcl_Obj *const indexArray[], struct Tcl_Obj *valueObj); +typedef int (Tcl_ObjTypeReplaceProc) (Tcl_Interp *interp, + struct Tcl_Obj *listObj, Tcl_Size first, Tcl_Size numToDelete, + Tcl_Size numToInsert, struct Tcl_Obj *const insertObjs[]); +typedef int (Tcl_ObjTypeInOperatorProc) (Tcl_Interp *interp, + struct Tcl_Obj *valueObj, struct Tcl_Obj *listObj, int *boolResult); #ifndef TCL_NO_DEPRECATED # define Tcl_PackageInitProc Tcl_LibraryInitProc @@ -667,26 +666,30 @@ typedef struct Tcl_ObjType { * to this type. Frees the internal rep of the * old type. Returns TCL_ERROR on failure. */ #if TCL_MAJOR_VERSION > 8 - size_t version; + size_t version; /* Version field for future-proofing. */ /* List emulation functions - ObjType Version 1 */ - Tcl_ObjTypeLengthProc *lengthProc; /* Return the [llength] of the - ** AbstractList */ - Tcl_ObjTypeIndexProc *indexProc; /* Return a value (Tcl_Obj) for - ** [lindex $al $index] */ - Tcl_ObjTypeSliceProc *sliceProc; /* Return an AbstractList for - ** [lrange $al $start $end] */ - Tcl_ObjTypeReverseProc *reverseProc; /* Return an AbstractList for - ** [lreverse $al] */ - Tcl_ObjTypeGetElements *getElementsProc; /* Return an objv[] of all elements in - ** the list */ - Tcl_ObjTypeSetElement *setElementProc; /* Replace the element at the indicie - ** with the given valueObj. */ - Tcl_ObjTypeReplaceProc *replaceProc; /* Replace subset with subset */ - Tcl_ObjTypeInOperatorProc *inOperProc; /* "in" and "ni" expr list - ** operation Determine if the given - ** string value matches an element in - ** the list */ + Tcl_ObjTypeLengthProc *lengthProc; + /* Return the [llength] of the AbstractList */ + Tcl_ObjTypeIndexProc *indexProc; + /* Return a value (Tcl_Obj) for + * [lindex $al $index] */ + Tcl_ObjTypeSliceProc *sliceProc; + /* Return an AbstractList for + * [lrange $al $start $end] */ + Tcl_ObjTypeReverseProc *reverseProc; + /* Return an AbstractList for [lreverse $al] */ + Tcl_ObjTypeGetElements *getElementsProc; + /* Return an objv[] of all elements in the list */ + Tcl_ObjTypeSetElement *setElementProc; + /* Replace the element at the indicies with the + * given valueObj. */ + Tcl_ObjTypeReplaceProc *replaceProc; + /* Replace sublist with sublist. */ + Tcl_ObjTypeInOperatorProc *inOperProc; + /* "in" and "ni" expr list operation. Determine + * if the given string value matches an element + * in the list. */ #endif } Tcl_ObjType; @@ -749,7 +752,8 @@ typedef struct Tcl_Obj { * corresponds to the type of the object's * internal rep. NULL indicates the object has * no internal rep (has no type). */ - Tcl_ObjInternalRep internalRep; /* The internal representation: */ + Tcl_ObjInternalRep internalRep; + /* The internal representation: */ } Tcl_Obj; @@ -841,11 +845,11 @@ typedef struct { Tcl_ObjCmdProc *objProc; /* Command's object-based function. */ void *objClientData; /* ClientData for object proc. */ Tcl_CmdProc *proc; /* Command's string-based function. */ - void *clientData; /* ClientData for string proc. */ + void *clientData; /* ClientData for string proc. */ Tcl_CmdDeleteProc *deleteProc; /* Function to call when command is * deleted. */ - void *deleteData; /* Value to pass to deleteProc (usually the + void *deleteData; /* Value to pass to deleteProc (usually the * same as clientData). */ Tcl_Namespace *namespacePtr;/* Points to the namespace that contains this * command. Note that Tcl_SetCmdInfo will not @@ -1077,7 +1081,7 @@ struct Tcl_HashEntry { * or NULL for end of chain. */ Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */ size_t hash; /* Hash value. */ - void *clientData; /* Application stores something here with + void *clientData; /* Application stores something here with * Tcl_SetHashValue. */ union { /* Key has one of these forms: */ char *oneWordValue; /* One-word value for key. */ @@ -1165,11 +1169,11 @@ struct Tcl_HashTable { Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; /* Bucket array used for small tables (to * avoid mallocs and frees). */ - Tcl_Size numBuckets; /* Total number of buckets allocated at + Tcl_Size numBuckets; /* Total number of buckets allocated at * **bucketPtr. */ - Tcl_Size numEntries; /* Total number of entries present in + Tcl_Size numEntries; /* Total number of entries present in * table. */ - Tcl_Size rebuildSize; /* Enlarge table when numEntries gets to be + Tcl_Size rebuildSize; /* Enlarge table when numEntries gets to be * this large. */ #if TCL_MAJOR_VERSION > 8 size_t mask; /* Mask value used in hashing function. */ @@ -1675,7 +1679,7 @@ typedef struct Tcl_Filesystem { * 'file attributes'. */ Tcl_FSFileAttrsSetProc *fileAttrsSetProc; /* Called by 'Tcl_FSFileAttrsSet()' and by - * 'file attributes'. */ + * 'file attributes'. */ Tcl_FSCreateDirectoryProc *createDirectoryProc; /* Called by 'Tcl_FSCreateDirectory()'. May be * NULL if the filesystem is read-only. */ @@ -1768,8 +1772,8 @@ typedef struct Tcl_Token { int type; /* Type of token, such as TCL_TOKEN_WORD; see * below for valid types. */ const char *start; /* First character in token. */ - Tcl_Size size; /* Number of bytes in token. */ - Tcl_Size numComponents; /* If this token is composed of other tokens, + Tcl_Size size; /* Number of bytes in token. */ + Tcl_Size numComponents; /* If this token is composed of other tokens, * this field tells how many of them there are * (including components of components, etc.). * The component tokens immediately follow @@ -1883,13 +1887,13 @@ typedef struct Tcl_Token { typedef struct Tcl_Parse { const char *commentStart; /* Pointer to # that begins the first of one * or more comments preceding the command. */ - Tcl_Size commentSize; /* Number of bytes in comments (up through + Tcl_Size commentSize; /* Number of bytes in comments (up through * newline character that terminates the last * comment). If there were no comments, this * field is 0. */ const char *commandStart; /* First character in first word of * command. */ - Tcl_Size commandSize; /* Number of bytes in command, including first + Tcl_Size commandSize; /* Number of bytes in command, including first * character of first word, up through the * terminating newline, close bracket, or * semicolon. */ @@ -1956,10 +1960,9 @@ typedef struct Tcl_EncodingType { Tcl_EncodingConvertProc *fromUtfProc; /* Function to convert from UTF-8 into * external encoding. */ - Tcl_FreeProc *freeProc; - /* If non-NULL, function to call when this + Tcl_FreeProc *freeProc; /* If non-NULL, function to call when this * encoding is deleted. */ - void *clientData; /* Arbitrary value associated with encoding + void *clientData; /* Arbitrary value associated with encoding * type. Passed to conversion functions. */ Tcl_Size nullSize; /* Number of zero bytes that signify * end-of-string in this encoding. This number @@ -2165,7 +2168,7 @@ typedef struct { * depends on type.*/ const char *helpStr; /* Documentation message describing this * option. */ - void *clientData; /* Word to pass to function callbacks. */ + void *clientData; /* Word to pass to function callbacks. */ } Tcl_ArgvInfo; /* diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 2ea2565..48196e3 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -89,20 +89,20 @@ typedef enum { typedef struct { ExceptionRangeType type; /* The kind of ExceptionRange. */ - Tcl_Size nestingLevel; /* Static depth of the exception range. Used + Tcl_Size nestingLevel; /* Static depth of the exception range. Used * to find the most deeply-nested range * surrounding a PC at runtime. */ - Tcl_Size codeOffset; /* Offset of the first instruction byte of the + Tcl_Size codeOffset; /* Offset of the first instruction byte of the * code range. */ - Tcl_Size numCodeBytes; /* Number of bytes in the code range. */ - Tcl_Size breakOffset; /* If LOOP_EXCEPTION_RANGE, the target PC + Tcl_Size numCodeBytes; /* Number of bytes in the code range. */ + Tcl_Size breakOffset; /* If LOOP_EXCEPTION_RANGE, the target PC * offset for a break command in the range. */ - Tcl_Size continueOffset; /* If LOOP_EXCEPTION_RANGE and not TCL_INDEX_NONE, the + Tcl_Size continueOffset; /* If LOOP_EXCEPTION_RANGE and not TCL_INDEX_NONE, the * target PC offset for a continue command in * the code range. Otherwise, ignore this * range when processing a continue * command. */ - Tcl_Size catchOffset; /* If a CATCH_EXCEPTION_RANGE, the target PC + Tcl_Size catchOffset; /* If a CATCH_EXCEPTION_RANGE, the target PC * offset for any "exception" in range. */ } ExceptionRange; @@ -118,11 +118,11 @@ typedef struct ExceptionAux { * one (see [for] next-clause) then we must * not pick up the range when scanning for a * target to continue to. */ - Tcl_Size stackDepth; /* The stack depth at the point where the + Tcl_Size stackDepth; /* The stack depth at the point where the * exception range was created. This is used * to calculate the number of POPs required to * restore the stack to its prior state. */ - Tcl_Size expandTarget; /* The number of expansions expected on the + Tcl_Size expandTarget; /* The number of expansions expected on the * auxData stack at the time the loop starts; * we can't currently discard them except by * doing INST_INVOKE_EXPANDED; this is a known @@ -135,14 +135,14 @@ typedef struct ExceptionAux { Tcl_Size numBreakTargets; /* The number of [break]s that want to be * targeted to the place where this loop * exception will be bound to. */ - TCL_HASH_TYPE *breakTargets; /* The offsets of the INST_JUMP4 instructions + TCL_HASH_TYPE *breakTargets;/* The offsets of the INST_JUMP4 instructions * issued by the [break]s that we must * update. Note that resizing a jump (via * TclFixupForwardJump) can cause the contents * of this array to be updated. When * numBreakTargets==0, this is NULL. */ Tcl_Size allocBreakTargets; /* The size of the breakTargets array. */ - Tcl_Size numContinueTargets; /* The number of [continue]s that want to be + Tcl_Size numContinueTargets;/* The number of [continue]s that want to be * targeted to the place where this loop * exception will be bound to. */ TCL_HASH_TYPE *continueTargets; /* The offsets of the INST_JUMP4 instructions @@ -151,7 +151,8 @@ typedef struct ExceptionAux { * TclFixupForwardJump) can cause the contents * of this array to be updated. When * numContinueTargets==0, this is NULL. */ - Tcl_Size allocContinueTargets; /* The size of the continueTargets array. */ + Tcl_Size allocContinueTargets; + /* The size of the continueTargets array. */ } ExceptionAux; /* @@ -163,10 +164,10 @@ typedef struct ExceptionAux { */ typedef struct { - Tcl_Size codeOffset; /* Offset of first byte of command code. */ - Tcl_Size numCodeBytes; /* Number of bytes for command's code. */ + Tcl_Size codeOffset; /* Offset of first byte of command code. */ + Tcl_Size numCodeBytes; /* Number of bytes for command's code. */ Tcl_Size srcOffset; /* Offset of first char of the command. */ - Tcl_Size numSrcBytes; /* Number of command source chars. */ + Tcl_Size numSrcBytes; /* Number of command source chars. */ } CmdLocation; /* @@ -182,10 +183,10 @@ typedef struct { typedef struct { Tcl_Size srcOffset; /* Command location to find the entry. */ - Tcl_Size nline; /* Number of words in the command */ - Tcl_Size *line; /* Line information for all words in the + Tcl_Size nline; /* Number of words in the command */ + Tcl_Size *line; /* Line information for all words in the * command. */ - Tcl_Size **next; /* Transient information used by the compiler + Tcl_Size **next; /* Transient information used by the compiler * for tracking of hidden continuation * lines. */ } ECL; @@ -198,8 +199,8 @@ typedef struct { Tcl_Obj *path; /* Path of the sourced file the command is * in. */ ECL *loc; /* Command word locations (lines). */ - Tcl_Size nloc; /* Number of allocated entries in 'loc'. */ - Tcl_Size nuloc; /* Number of used entries in 'loc'. */ + Tcl_Size nloc; /* Number of allocated entries in 'loc'. */ + Tcl_Size nuloc; /* Number of used entries in 'loc'. */ } ExtCmdLoc; /* @@ -290,21 +291,21 @@ typedef struct CompileEnv { * SetByteCodeFromAny. This pointer is not * owned by the CompileEnv and must not be * freed or changed by it. */ - Tcl_Size numSrcBytes; /* Number of bytes in source. */ + Tcl_Size numSrcBytes; /* Number of bytes in source. */ Proc *procPtr; /* If a procedure is being compiled, a pointer * to its Proc structure; otherwise NULL. Used * to compile local variables. Set from * information provided by ObjInterpProc in * tclProc.c. */ - Tcl_Size numCommands; /* Number of commands compiled. */ - Tcl_Size exceptDepth; /* Current exception range nesting level; TCL_INDEX_NONE + Tcl_Size numCommands; /* Number of commands compiled. */ + Tcl_Size exceptDepth; /* Current exception range nesting level; TCL_INDEX_NONE * if not in any range currently. */ - Tcl_Size maxExceptDepth; /* Max nesting level of exception ranges; TCL_INDEX_NONE + Tcl_Size maxExceptDepth; /* Max nesting level of exception ranges; TCL_INDEX_NONE * if no ranges have been compiled. */ - Tcl_Size maxStackDepth; /* Maximum number of stack elements needed to + Tcl_Size maxStackDepth; /* Maximum number of stack elements needed to * execute the code. Set by compilation * procedures before returning. */ - Tcl_Size currStackDepth; /* Current stack depth. */ + Tcl_Size currStackDepth; /* Current stack depth. */ LiteralTable localLitTable; /* Contains LiteralEntry's describing all Tcl * objects referenced by this compiled code. * Indexed by the string representations of @@ -333,7 +334,7 @@ typedef struct CompileEnv { * exceptArrayNext is the number of ranges and * (exceptArrayNext-1) is the index of the * current range's array entry. */ - Tcl_Size exceptArrayEnd; /* Index after the last ExceptionRange array + Tcl_Size exceptArrayEnd; /* Index after the last ExceptionRange array * entry. */ #if TCL_MAJOR_VERSION < 9 int mallocedExceptArray; @@ -379,7 +380,7 @@ typedef struct CompileEnv { /* TIP #280 */ ExtCmdLoc *extCmdMapPtr; /* Extended command location information for * 'info frame'. */ - Tcl_Size line; /* First line of the script, based on the + Tcl_Size line; /* First line of the script, based on the * invoking context, then the line of the * command currently compiled. */ int atCmdStart; /* Flag to say whether an INST_START_CMD @@ -388,11 +389,11 @@ typedef struct CompileEnv { * inefficient. If set to 2, that instruction * should not be issued at all (by the generic * part of the command compiler). */ - Tcl_Size expandCount; /* Number of INST_EXPAND_START instructions + Tcl_Size expandCount; /* Number of INST_EXPAND_START instructions * encountered that have not yet been paired * with a corresponding * INST_INVOKE_EXPANDED. */ - Tcl_Size *clNext; /* If not NULL, it refers to the next slot in + Tcl_Size *clNext; /* If not NULL, it refers to the next slot in * clLoc to check for an invisible * continuation line. */ } CompileEnv; @@ -427,7 +428,7 @@ typedef struct ByteCode { * procs are specific to an interpreter so the * code emitted will depend on the * interpreter. */ - Tcl_Size compileEpoch; /* Value of iPtr->compileEpoch when this + Tcl_Size compileEpoch; /* Value of iPtr->compileEpoch when this * ByteCode was compiled. Used to invalidate * code when, e.g., commands with compile * procs are redefined. */ @@ -459,17 +460,17 @@ typedef struct ByteCode { * itself. Does not include heap space for * literal Tcl objects or storage referenced * by AuxData entries. */ - Tcl_Size numCommands; /* Number of commands compiled. */ - Tcl_Size numSrcBytes; /* Number of source bytes compiled. */ - Tcl_Size numCodeBytes; /* Number of code bytes. */ - Tcl_Size numLitObjects; /* Number of objects in literal array. */ + Tcl_Size numCommands; /* Number of commands compiled. */ + Tcl_Size numSrcBytes; /* Number of source bytes compiled. */ + Tcl_Size numCodeBytes; /* Number of code bytes. */ + Tcl_Size numLitObjects; /* Number of objects in literal array. */ Tcl_Size numExceptRanges; /* Number of ExceptionRange array elems. */ Tcl_Size numAuxDataItems; /* Number of AuxData items. */ - Tcl_Size numCmdLocBytes; /* Number of bytes needed for encoded command + Tcl_Size numCmdLocBytes; /* Number of bytes needed for encoded command * location information. */ - Tcl_Size maxExceptDepth; /* Maximum nesting level of ExceptionRanges; + Tcl_Size maxExceptDepth; /* Maximum nesting level of ExceptionRanges; * TCL_INDEX_NONE if no ranges were compiled. */ - Tcl_Size maxStackDepth; /* Maximum number of stack elements needed to + Tcl_Size maxStackDepth; /* Maximum number of stack elements needed to * execute the code. */ unsigned char *codeStart; /* Points to the first byte of the code. This * is just after the final ByteCode member @@ -829,11 +830,11 @@ enum TclInstruction { INST_DICT_GET_DEF, - /* TIP 461 */ - INST_STR_LT, - INST_STR_GT, - INST_STR_LE, - INST_STR_GE, + /* TIP 461 */ + INST_STR_LT, + INST_STR_GT, + INST_STR_LE, + INST_STR_GE, INST_LREPLACE4, @@ -969,8 +970,8 @@ typedef struct JumpFixup { typedef struct JumpFixupArray { JumpFixup *fixup; /* Points to start of jump fixup array. */ - Tcl_Size next; /* Index of next free array entry. */ - Tcl_Size end; /* Index of last usable entry in array. */ + Tcl_Size next; /* Index of next free array entry. */ + Tcl_Size end; /* Index of last usable entry in array. */ int mallocedArray; /* 1 if array was expanded and fixups points * into the heap, else 0. */ JumpFixup staticFixupSpace[JUMPFIXUP_INIT_ENTRIES]; @@ -1004,9 +1005,9 @@ typedef struct ForeachVarList { typedef struct ForeachInfo { Tcl_Size numLists; /* The number of both the variable and value * lists of the foreach command. */ - Tcl_Size firstValueTemp; /* Index of the first temp var in a proc frame + Tcl_Size firstValueTemp; /* Index of the first temp var in a proc frame * used to point to a value list. */ - Tcl_Size loopCtTemp; /* Index of temp var in a proc frame holding + Tcl_Size loopCtTemp; /* Index of temp var in a proc frame holding * the loop's iteration count. Used to * determine next value list element to assign * each loop var. */ @@ -1041,7 +1042,8 @@ MODULE_SCOPE const AuxDataType tclJumptableInfoType; typedef struct { Tcl_Size length; /* Size of array */ - Tcl_Size varIndices[TCLFLEXARRAY]; /* Array of variable indices to manage when + Tcl_Size varIndices[TCLFLEXARRAY]; + /* Array of variable indices to manage when * processing the start and end of a [dict * update]. There is really more than one * entry, and the structure is allocated to @@ -1280,7 +1282,7 @@ MODULE_SCOPE int TclPushProcCallFrame(void *clientData, if (_delta == INT_MIN) { \ _delta = 1 - (i); \ } \ - TclAdjustStackDepth(_delta, envPtr); \ + TclAdjustStackDepth(_delta, envPtr); \ } \ } while (0) @@ -1394,7 +1396,7 @@ MODULE_SCOPE int TclPushProcCallFrame(void *clientData, #define TclEmitPush(objIndex, envPtr) \ do { \ - int _objIndexCopy = (objIndex); \ + int _objIndexCopy = (objIndex); \ if (_objIndexCopy <= 255) { \ TclEmitInstInt1(INST_PUSH1, _objIndexCopy, (envPtr)); \ } else { \ diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 8614171..f3a814c 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -1818,8 +1818,7 @@ NsEnsembleImplementationCmdNR( */ const char *subcmdName; /* Name of the subcommand or unique prefix of - * it (a non-unique prefix produces an error). - */ + * it (a non-unique prefix produces an error). */ char *fullName = NULL; /* Full name of the subcommand. */ Tcl_Size stringLength, i; Tcl_Size tableLength = ensemblePtr->subcommandTable.numEntries; diff --git a/generic/tclIO.h b/generic/tclIO.h index 08fff44..b8abcc6 100644 --- a/generic/tclIO.h +++ b/generic/tclIO.h @@ -39,12 +39,12 @@ typedef struct ChannelBuffer { Tcl_Size refCount; /* Current uses count */ Tcl_Size nextAdded; /* The next position into which a character * will be put in the buffer. */ - Tcl_Size nextRemoved; /* Position of next byte to be removed from + Tcl_Size nextRemoved; /* Position of next byte to be removed from * the buffer. */ Tcl_Size bufLength; /* How big is the buffer? */ struct ChannelBuffer *nextPtr; /* Next buffer in chain. */ - char buf[TCLFLEXARRAY]; /* Placeholder for real buffer. The real + char buf[TCLFLEXARRAY]; /* Placeholder for real buffer. The real * buffer occupies this space + bufSize-1 * bytes. This must be the last field in the * structure. */ @@ -96,7 +96,7 @@ typedef struct EventScriptRecord { typedef struct Channel { struct ChannelState *state; /* Split out state information */ - void *instanceData; /* Instance-specific data provided by creator + void *instanceData; /* Instance-specific data provided by creator * of channel. */ const Tcl_ChannelType *typePtr; /* Pointer to channel type structure. */ struct Channel *downChanPtr;/* Refers to channel this one was stacked @@ -215,7 +215,7 @@ typedef struct ChannelState { */ Tcl_Obj* chanMsg; - Tcl_Obj* unreportedMsg; /* Non-NULL if an error report was deferred + Tcl_Obj* unreportedMsg; /* Non-NULL if an error report was deferred * because it happened in the background. The * value is the chanMg, if any. #219's * companion to 'unreportedError'. */ diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index e8ce5f1..8d156d2 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -96,8 +96,7 @@ typedef struct { * Tcl level part of the channel. NULL here * signals the channel is dead because the * interpreter/thread containing its Tcl - * command is gone. - */ + * command is gone. */ #if TCL_THREADS Tcl_ThreadId thread; /* Thread the 'interp' belongs to. == Handler thread */ Tcl_ThreadId owner; /* Thread owning the structure. == Channel thread */ @@ -113,16 +112,12 @@ typedef struct { int dead; /* Boolean signal that some operations * should no longer be attempted. */ - Tcl_TimerToken readTimer; /* - A token for the timer that is scheduled in - order to call Tcl_NotifyChannel when the - channel is readable - */ - Tcl_TimerToken writeTimer; /* - A token for the timer that is scheduled in - order to call Tcl_NotifyChannel when the - channel is writable - */ + Tcl_TimerToken readTimer; /* A token for the timer that is scheduled in + * order to call Tcl_NotifyChannel when the + * channel is readable */ + Tcl_TimerToken writeTimer; /* A token for the timer that is scheduled in + * order to call Tcl_NotifyChannel when the + * channel is writable */ /* * Note regarding the usage of timers. @@ -266,7 +261,7 @@ typedef struct { struct ForwardParamInput { ForwardParamBase base; /* "Supertype". MUST COME FIRST. */ char *buf; /* O: Where to store the read bytes */ - Tcl_Size toRead; /* I: #bytes to read, + Tcl_Size toRead; /* I: #bytes to read, * O: #bytes actually read */ }; struct ForwardParamOutput { diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 921d79e..3a56abf 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -51,13 +51,11 @@ typedef struct FilesystemRecord { typedef struct { int initialized; size_t cwdPathEpoch; /* Compared with the global cwdPathEpoch to - * determine whether cwdPathPtr is stale. - */ + * determine whether cwdPathPtr is stale. */ size_t filesystemEpoch; Tcl_Obj *cwdPathPtr; /* A private copy of cwdPathPtr. Updated when * the value is accessed and cwdPathEpoch has - * changed. - */ + * changed. */ void *cwdClientData; FilesystemRecord *filesystemList; size_t claims; @@ -328,8 +326,8 @@ Tcl_Stat( /* Obsolete */ int Tcl_Access( - const char *path, /* Pathname of file to access (in current CP). - */ + const char *path, /* Pathname of file to access (in + * current CP). */ int mode) /* Permission setting. */ { int ret; @@ -1104,8 +1102,7 @@ FsAddMountsToGlobResult( Tcl_Obj *pathPtr, /* The directory that was searched. */ const char *pattern, /* Pattern to match mounts against. */ Tcl_GlobTypeData *types) /* Acceptable types. May be NULL. The - * directory flag is particularly significant. - */ + * directory flag is particularly significant. */ { Tcl_Size mLength, gLength, i; int dir = (types == NULL || (types->type & TCL_GLOB_TYPE_DIR)); @@ -3012,8 +3009,8 @@ Tcl_FSChdir( int Tcl_FSLoadFile( Tcl_Interp *interp, /* Used for error reporting. */ - Tcl_Obj *pathPtr, /* Pathname of the file containing the dynamic shared object. - */ + Tcl_Obj *pathPtr, /* Pathname of the file containing the dynamic + * shared object. */ const char *sym1, const char *sym2, /* Names of two functions to find in the * dynamic shared object. */ @@ -3647,9 +3644,7 @@ Tcl_FSUnloadFile( Tcl_Obj * Tcl_FSLink( Tcl_Obj *pathPtr, /* Pathaname of file. */ - Tcl_Obj *toPtr, /* - * NULL or the pathname of a file to link to. - */ + Tcl_Obj *toPtr, /* NULL or the pathname of a file to link to. */ int linkAction) /* Action to perform. */ { const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr); @@ -3954,8 +3949,7 @@ TclFSNonnativePathType( * the filesystem for this pathname when it is * an absolute pathname. */ Tcl_Size *driveNameLengthPtr,/* If not NULL, a place to store the length of - * the volume name if the pathname is absolute. - */ + * the volume name if the pathname is absolute. */ Tcl_Obj **driveNameRef) /* If not NULL, a place to store a pointer to * an object having its its refCount already * incremented, and contining the name of the diff --git a/generic/tclInt.h b/generic/tclInt.h index 77eebb8..fffd0eb 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -257,8 +257,8 @@ typedef struct Namespace { * synonym. */ char *fullName; /* The namespace's fully qualified name. This * starts with ::. */ - void *clientData; /* An arbitrary value associated with this - * namespace. */ + void *clientData; /* An arbitrary value associated with this + * namespace. (Used by TclOO!) */ Tcl_NamespaceDeleteProc *deleteProc; /* Procedure invoked when deleting the * namespace to, e.g., free clientData. */ @@ -279,7 +279,7 @@ typedef struct Namespace { #else unsigned long nsId; #endif - Tcl_Interp *interp; /* The interpreter containing this + Tcl_Interp *interp; /* The interpreter containing this * namespace. */ int flags; /* OR-ed combination of the namespace status * flags NS_DYING and NS_DEAD listed below. */ @@ -312,12 +312,12 @@ typedef struct Namespace { * registered using "namespace export". */ Tcl_Size maxExportPatterns; /* Number of export patterns for which space * is currently allocated. */ - Tcl_Size cmdRefEpoch; /* Incremented if a newly added command + Tcl_Size cmdRefEpoch; /* Incremented if a newly added command * shadows a command for which this namespace * has already cached a Command* pointer; this * causes all its cached Command* pointers to * be invalidated. */ - Tcl_Size resolverEpoch; /* Incremented whenever (a) the name + Tcl_Size resolverEpoch; /* Incremented whenever (a) the name * resolution rules change for this namespace * or (b) a newly added command shadows a * command that is compiled to bytecodes. This @@ -444,7 +444,7 @@ typedef struct EnsembleConfig { * if the command has been deleted (or never * existed; the global namespace never has an * ensemble command.) */ - Tcl_Size epoch; /* The epoch at which this ensemble's table of + Tcl_Size epoch; /* The epoch at which this ensemble's table of * exported commands is valid. */ char **subcommandArrayPtr; /* Array of ensemble subcommand names. At all * consistent points, this will have the same @@ -501,7 +501,7 @@ typedef struct EnsembleConfig { * core, presumably because the ensemble * itself has been updated. */ Tcl_Obj *parameterList; /* List of ensemble parameter names. */ - Tcl_Size numParameters; /* Cached number of parameters. This is either + Tcl_Size numParameters; /* Cached number of parameters. This is either * 0 (if the parameterList field is NULL) or * the length of the list in the parameterList * field. */ @@ -970,9 +970,9 @@ typedef struct CompiledLocal { /* Next compiler-recognized local variable for * this procedure, or NULL if this is the last * local. */ - Tcl_Size nameLength; /* The number of bytes in local variable's name. + Tcl_Size nameLength; /* The number of bytes in local variable's name. * Among others used to speed up var lookups. */ - Tcl_Size frameIndex; /* Index in the array of compiler-assigned + Tcl_Size frameIndex; /* Index in the array of compiler-assigned * variables in the procedure call frame. */ #if TCL_MAJOR_VERSION < 9 int flags; @@ -993,7 +993,7 @@ typedef struct CompiledLocal { * although only VAR_ARGUMENT, VAR_TEMPORARY, * and VAR_RESOLVED make sense. */ #endif - char name[TCLFLEXARRAY]; /* Name of the local variable starts here. If + char name[TCLFLEXARRAY]; /* Name of the local variable starts here. If * the name is NULL, this will just be '\0'. * The actual size of this field will be large * enough to hold the name. MUST BE THE LAST @@ -1055,7 +1055,7 @@ typedef struct Trace { #else Tcl_CmdObjTraceProc *proc; /* Procedure to call to trace command. */ #endif - void *clientData; /* Arbitrary value to pass to proc. */ + void *clientData; /* Arbitrary value to pass to proc. */ struct Trace *nextPtr; /* Next in list of traces for this interp. */ int flags; /* Flags governing the trace - see * Tcl_CreateObjTrace for details. */ @@ -1247,7 +1247,7 @@ typedef struct CallFrame { * If FRAME_IS_PROC is set, the frame was * pushed to execute a Tcl procedure and may * have local vars. */ - Tcl_Size objc; /* This and objv below describe the arguments + Tcl_Size objc; /* This and objv below describe the arguments * for this procedure call. */ Tcl_Obj *const *objv; /* Array of argument objects. */ struct CallFrame *callerPtr; @@ -1261,7 +1261,7 @@ typedef struct CallFrame { * callerPtr unless an "uplevel" command or * something equivalent was active in the * caller). */ - Tcl_Size level; /* Level of this procedure, for "uplevel" + Tcl_Size level; /* Level of this procedure, for "uplevel" * purposes (i.e. corresponds to nesting of * callerVarPtr's, not callerPtr's). 1 for * outermost procedure, 0 for top-level. */ @@ -1281,7 +1281,7 @@ typedef struct CallFrame { * recognized by the compiler. The compiler * emits code that refers to these variables * using an index into this array. */ - void *clientData; /* Pointer to some context that is used by + void *clientData; /* Pointer to some context that is used by * object systems. The meaning of the contents * of this field is defined by the code that * sets it, and it should only ever be set by @@ -1381,7 +1381,7 @@ typedef struct CmdFrame { } data; Tcl_Obj *cmdObj; const char *cmd; /* The executed command, if possible... */ - Tcl_Size len; /* ... and its length. */ + Tcl_Size len; /* ... and its length. */ const struct CFWordBC *litarg; /* Link to set of literal arguments which have * ben pushed on the lineLABCPtr stack by @@ -1391,16 +1391,16 @@ typedef struct CmdFrame { typedef struct CFWord { CmdFrame *framePtr; /* CmdFrame to access. */ - Tcl_Size word; /* Index of the word in the command. */ + Tcl_Size word; /* Index of the word in the command. */ Tcl_Size refCount; /* Number of times the word is on the * stack. */ } CFWord; typedef struct CFWordBC { CmdFrame *framePtr; /* CmdFrame to access. */ - Tcl_Size pc; /* Instruction pointer of a command in + Tcl_Size pc; /* Instruction pointer of a command in * ExtCmdLoc.loc[.] */ - Tcl_Size word; /* Index of word in + Tcl_Size word; /* Index of word in * ExtCmdLoc.loc[cmd]->line[.] */ struct CFWordBC *prevPtr; /* Previous entry in stack for same Tcl_Obj. */ struct CFWordBC *nextPtr; /* Next entry for same command call. See @@ -1429,7 +1429,7 @@ typedef struct CFWordBC { #define CLL_END (-1) typedef struct ContLineLoc { - Tcl_Size num; /* Number of entries in loc, not counting the + Tcl_Size num; /* Number of entries in loc, not counting the * final -1 marker entry. */ Tcl_Size loc[TCLFLEXARRAY];/* Table of locations, as character offsets. * The table is allocated as part of the @@ -1472,14 +1472,14 @@ typedef struct ContLineLoc { typedef Tcl_Obj * (GetFrameInfoValueProc)(void *clientData); typedef struct { const char *name; /* Name of this field. */ - GetFrameInfoValueProc *proc; /* Function to generate a Tcl_Obj* from the + GetFrameInfoValueProc *proc;/* Function to generate a Tcl_Obj* from the * clientData, or just use the clientData * directly (after casting) if NULL. */ - void *clientData; /* Context for above function, or Tcl_Obj* if + void *clientData; /* Context for above function, or Tcl_Obj* if * proc field is NULL. */ } ExtraFrameInfoField; typedef struct { - Tcl_Size length; /* Length of array. */ + Tcl_Size length; /* Length of array. */ ExtraFrameInfoField fields[2]; /* Really as long as necessary, but this is * long enough for nearly anything. */ @@ -1571,12 +1571,14 @@ typedef int (CompileHookProc)(Tcl_Interp *interp, */ typedef struct ExecStack { - struct ExecStack *prevPtr; - struct ExecStack *nextPtr; + struct ExecStack *prevPtr; /* Previous stack in list. */ + struct ExecStack *nextPtr; /* Next stack in list. */ Tcl_Obj **markerPtr; - Tcl_Obj **endPtr; - Tcl_Obj **tosPtr; + Tcl_Obj **endPtr; /* Where the end is. */ + Tcl_Obj **tosPtr; /* Where the top of stack is. */ Tcl_Obj *stackWords[TCLFLEXARRAY]; + /* The actual stack space, following this + * structure in memory. */ } ExecStack; /* @@ -1604,20 +1606,20 @@ typedef struct CoroutineData { * coroutine. */ CorContext caller; CorContext running; - Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ + Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ void *stackLevel; - Tcl_Size auxNumLevels; /* While the coroutine is running the + Tcl_Size auxNumLevels; /* While the coroutine is running the * numLevels of the create/resume command is * stored here; for suspended coroutines it * holds the nesting numLevels at yield. */ - Tcl_Size nargs; /* Number of args required for resuming this - * coroutine; COROUTINE_ARGUMENTS_SINGLE_OPTIONAL means "0 or 1" - * (default), COROUTINE_ARGUMENTS_ARBITRARY means "any" */ + Tcl_Size nargs; /* Number of args required for resuming this + * coroutine; COROUTINE_ARGUMENTS_SINGLE_OPTIONAL + * means "0 or 1" (default), + * COROUTINE_ARGUMENTS_ARBITRARY means "any" */ Tcl_Obj *yieldPtr; /* The command to yield to. Stored here in * order to reset splice point in * TclNRCoroutineActivateCallback if the - * coroutine is busy. - */ + * coroutine is busy. */ } CoroutineData; typedef struct ExecEnv { @@ -1691,10 +1693,10 @@ typedef struct LiteralTable { #ifdef TCL_COMPILE_STATS typedef struct ByteCodeStats { - size_t numExecutions; /* Number of ByteCodes executed. */ + size_t numExecutions; /* Number of ByteCodes executed. */ size_t numCompilations; /* Number of ByteCodes created. */ size_t numByteCodesFreed; /* Number of ByteCodes destroyed. */ - size_t instructionCount[256]; /* Number of times each instruction was + size_t instructionCount[256]; /* Number of times each instruction was * executed. */ double totalSrcBytes; /* Total source bytes ever compiled. */ @@ -1702,7 +1704,7 @@ typedef struct ByteCodeStats { double currentSrcBytes; /* Src bytes for all current ByteCodes. */ double currentByteCodeBytes;/* Code bytes in all current ByteCodes. */ - size_t srcCount[32]; /* Source size distribution: # of srcs of + size_t srcCount[32]; /* Source size distribution: # of srcs of * size [2**(n-1)..2**n), n in [0..32). */ size_t byteCodeCount[32]; /* ByteCode size distribution. */ size_t lifetimeCount[32]; /* ByteCode lifetime distribution (ms). */ @@ -1961,8 +1963,7 @@ typedef struct Interp { * enabled extensions check for a NULL pointer value * and for a TCL_STUBS_MAGIC value to verify they * are not [load]ing into one of those pre-stubs - * interps. - */ + * interps. */ TclHandle handle; /* Handle used to keep track of when this * interp is deleted. */ @@ -2098,7 +2099,8 @@ typedef struct Interp { /* First in list of active traces for interp, * or NULL if no active traces. */ - Tcl_Size tracesForbiddingInline; /* Count of traces (in the list headed by + Tcl_Size tracesForbiddingInline; + /* Count of traces (in the list headed by * tracePtr) that forbid inline bytecode * compilation. */ @@ -2128,7 +2130,7 @@ typedef struct Interp { * as flag values the same as the 'active' * field. */ - Tcl_Size cmdCount; /* Limit for how many commands to execute in + Tcl_Size cmdCount; /* Limit for how many commands to execute in * the interpreter. */ LimitHandler *cmdHandlers; /* Handlers to execute when the limit is @@ -2164,9 +2166,10 @@ typedef struct Interp { * *root* ensemble command? (Nested ensembles * don't rewrite this.) NULL if we're not * processing an ensemble. */ - Tcl_Size numRemovedObjs; /* How many arguments have been stripped off + Tcl_Size numRemovedObjs;/* How many arguments have been stripped off * because of ensemble processing. */ - Tcl_Size numInsertedObjs; /* How many of the current arguments were + Tcl_Size numInsertedObjs; + /* How many of the current arguments were * inserted by an ensemble. */ } ensembleRewrite; @@ -2226,8 +2229,7 @@ typedef struct Interp { * used by function ...() in the same file. * It does for the eval/direct path of script * execution what CompileEnv.clLoc does for - * the bytecode compiler. - */ + * the bytecode compiler. */ /* * TIP #268. The currently active selection mode, i.e. the package require * preferences. @@ -2299,7 +2301,7 @@ typedef struct Interp { Tcl_Obj *callLiteral; /* "CALL" literal for [info errorstack] */ Tcl_Obj *innerLiteral; /* "INNER" literal for [info errorstack] */ Tcl_Obj *innerContext; /* cached list for fast reallocation */ - int resetErrorStack; /* controls cleaning up of ::errorStack */ + int resetErrorStack; /* controls cleaning up of ::errorStack */ #ifdef TCL_COMPILE_STATS /* @@ -2565,17 +2567,17 @@ typedef enum TclEolTranslation { * */ typedef struct ListStore { - Tcl_Size firstUsed; /* Index of first slot in use within slots[] */ - Tcl_Size numUsed; /* Number of slots in use (starting firstUsed) */ - Tcl_Size numAllocated; /* Total number of slots[] array slots. */ - size_t refCount; /* Number of references to this instance */ - int flags; /* LISTSTORE_* flags */ - Tcl_Obj *slots[TCLFLEXARRAY]; /* Variable size array. Grown as needed */ + Tcl_Size firstUsed; /* Index of first slot in use within slots[] */ + Tcl_Size numUsed; /* Number of slots in use (starting firstUsed) */ + Tcl_Size numAllocated; /* Total number of slots[] array slots. */ + size_t refCount; /* Number of references to this instance */ + int flags; /* LISTSTORE_* flags */ + Tcl_Obj *slots[TCLFLEXARRAY]; /* Variable size array. Grown as needed */ } ListStore; -#define LISTSTORE_CANONICAL 0x1 /* All Tcl_Obj's referencing this - store have their string representation - derived from the list representation */ +#define LISTSTORE_CANONICAL 0x1 /* All Tcl_Obj's referencing this store have + * their string representation derived from + * the list representation. */ /* Max number of elements that can be contained in a list */ #define LIST_MAX \ @@ -2590,11 +2592,11 @@ typedef struct ListStore { * See comments above for ListStore */ typedef struct ListSpan { - Tcl_Size spanStart; /* Starting index of the span */ - Tcl_Size spanLength; /* Number of elements in the span */ - size_t refCount; /* Count of references to this span record */ + Tcl_Size spanStart; /* Starting index of the span */ + Tcl_Size spanLength; /* Number of elements in the span */ + size_t refCount; /* Count of references to this span record */ } ListSpan; -#ifndef LIST_SPAN_THRESHOLD /* May be set on build line */ +#ifndef LIST_SPAN_THRESHOLD /* May be set on build line */ #define LIST_SPAN_THRESHOLD 101 #endif @@ -2603,9 +2605,11 @@ typedef struct ListSpan { * See comments above for ListStore */ typedef struct ListRep { - ListStore *storePtr;/* element array shared amongst different lists */ - ListSpan *spanPtr; /* If not NULL, the span holds the range of slots - within *storePtr that contain this list elements. */ + ListStore *storePtr; /* Element array shared amongst different + * lists. */ + ListSpan *spanPtr; /* If not NULL, the span holds the range of + * slots within *storePtr that contain this + * list elements. */ } ListRep; /* @@ -2909,7 +2913,7 @@ typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, TCL_HASH_TYPE *len */ typedef struct ProcessGlobalValue { - Tcl_Size epoch; /* Epoch counter to detect changes in the + Tcl_Size epoch; /* Epoch counter to detect changes in the * global value. */ TCL_HASH_TYPE numBytes; /* Length of the global string. */ char *value; /* The global string value. */ @@ -2968,6 +2972,7 @@ typedef struct ProcessGlobalValue { /* *---------------------------------------------------------------------- + * * Common functions for calculating overallocation. Trivial but allows for * experimenting with growth factors without having to change code in * multiple places. See TclAttemptAllocElemsEx and similar for usage @@ -2977,23 +2982,29 @@ typedef struct ProcessGlobalValue { * *---------------------------------------------------------------------- */ + static inline Tcl_Size -TclUpsizeAlloc(TCL_UNUSED(Tcl_Size) /* oldSize. For future experiments with - * some growth algorithms that use this - * information. */, - Tcl_Size needed, - Tcl_Size limit) +TclUpsizeAlloc( + TCL_UNUSED(Tcl_Size), /* oldSize. For future experiments with + * some growth algorithms that use this + * information. */ + Tcl_Size needed, + Tcl_Size limit) { /* assert (oldCapacity < needed <= limit) */ if (needed < (limit - needed/2)) { return needed + needed / 2; - } - else { + } else { return limit; } } -static inline Tcl_Size TclUpsizeRetry(Tcl_Size needed, Tcl_Size lastAttempt) { - /* assert (needed < lastAttempt) */ + +static inline Tcl_Size +TclUpsizeRetry( + Tcl_Size needed, + Tcl_Size lastAttempt) +{ + /* assert (needed < lastAttempt) */ if (needed < lastAttempt - 1) { /* (needed+lastAttempt)/2 but that formula may overflow Tcl_Size */ return needed + (lastAttempt - needed) / 2; @@ -3001,37 +3012,64 @@ static inline Tcl_Size TclUpsizeRetry(Tcl_Size needed, Tcl_Size lastAttempt) { return needed; } } -MODULE_SCOPE void *TclAllocElemsEx(Tcl_Size elemCount, Tcl_Size elemSize, - Tcl_Size leadSize, Tcl_Size *capacityPtr); -MODULE_SCOPE void *TclReallocElemsEx(void *oldPtr, Tcl_Size elemCount, - Tcl_Size elemSize, Tcl_Size leadSize, - Tcl_Size *capacityPtr); -MODULE_SCOPE void *TclAttemptReallocElemsEx(void *oldPtr, - Tcl_Size elemCount, Tcl_Size elemSize, - Tcl_Size leadSize, Tcl_Size *capacityPtr); + +MODULE_SCOPE void * TclAllocElemsEx(Tcl_Size elemCount, Tcl_Size elemSize, + Tcl_Size leadSize, Tcl_Size *capacityPtr); +MODULE_SCOPE void * TclReallocElemsEx(void *oldPtr, Tcl_Size elemCount, + Tcl_Size elemSize, Tcl_Size leadSize, + Tcl_Size *capacityPtr); +MODULE_SCOPE void * TclAttemptReallocElemsEx(void *oldPtr, + Tcl_Size elemCount, Tcl_Size elemSize, + Tcl_Size leadSize, Tcl_Size *capacityPtr); + /* Alloc elemCount elements of size elemSize with leadSize header * returning actual capacity (in elements) in *capacityPtr. */ -static inline void *TclAttemptAllocElemsEx(Tcl_Size elemCount, Tcl_Size elemSize, - Tcl_Size leadSize, Tcl_Size *capacityPtr) { +static inline void * +TclAttemptAllocElemsEx( + Tcl_Size elemCount, + Tcl_Size elemSize, + Tcl_Size leadSize, + Tcl_Size *capacityPtr) +{ return TclAttemptReallocElemsEx( NULL, elemCount, elemSize, leadSize, capacityPtr); } + /* Alloc numByte bytes, returning actual capacity in *capacityPtr. */ -static inline void *TclAllocEx(Tcl_Size numBytes, Tcl_Size *capacityPtr) { +static inline void * +TclAllocEx( + Tcl_Size numBytes, + Tcl_Size *capacityPtr) +{ return TclAllocElemsEx(numBytes, 1, 0, capacityPtr); } + /* Alloc numByte bytes, returning actual capacity in *capacityPtr. */ static inline void * -TclAttemptAllocEx(Tcl_Size numBytes, Tcl_Size *capacityPtr) +TclAttemptAllocEx( + Tcl_Size numBytes, + Tcl_Size *capacityPtr) { return TclAttemptAllocElemsEx(numBytes, 1, 0, capacityPtr); } + /* Realloc numByte bytes, returning actual capacity in *capacityPtr. */ -static inline void *TclReallocEx(void *oldPtr, Tcl_Size numBytes, Tcl_Size *capacityPtr) { +static inline void * +TclReallocEx( + void *oldPtr, + Tcl_Size numBytes, + Tcl_Size *capacityPtr) +{ return TclReallocElemsEx(oldPtr, numBytes, 1, 0, capacityPtr); } + /* Realloc numByte bytes, returning actual capacity in *capacityPtr. */ -static inline void *TclAttemptReallocEx(void *oldPtr, Tcl_Size numBytes, Tcl_Size *capacityPtr) { +static inline void * +TclAttemptReallocEx( + void *oldPtr, + Tcl_Size numBytes, + Tcl_Size *capacityPtr) +{ return TclAttemptReallocElemsEx(oldPtr, numBytes, 1, 0, capacityPtr); } @@ -3052,13 +3090,12 @@ MODULE_SCOPE TclPlatformType tclPlatform; MODULE_SCOPE Tcl_Encoding tclIdentityEncoding; MODULE_SCOPE Tcl_Encoding tclUtf8Encoding; -MODULE_SCOPE int -TclEncodingProfileNameToId(Tcl_Interp *interp, - const char *profileName, - int *profilePtr); +MODULE_SCOPE int TclEncodingProfileNameToId(Tcl_Interp *interp, + const char *profileName, + int *profilePtr); MODULE_SCOPE const char *TclEncodingProfileIdToName(Tcl_Interp *interp, - int profileId); -MODULE_SCOPE void TclGetEncodingProfiles(Tcl_Interp *interp); + int profileId); +MODULE_SCOPE void TclGetEncodingProfiles(Tcl_Interp *interp); /* * TIP #233 (Virtualized Time) @@ -3178,7 +3215,7 @@ typedef struct ForIterData { Tcl_Obj *body; /* Loop body. */ Tcl_Obj *next; /* Loop step script, NULL for 'while'. */ const char *msg; /* Error message part. */ - Tcl_Size word; /* Index of the body script in the command */ + Tcl_Size word; /* Index of the body script in the command */ } ForIterData; /* TIP #357 - Structure doing the bookkeeping of handles for Tcl_LoadFile @@ -3458,7 +3495,7 @@ MODULE_SCOPE int TclNewArithSeriesObj(Tcl_Interp *interp, Tcl_Obj **arithSeriesP MODULE_SCOPE Tcl_Obj * TclNewFSPathObj(Tcl_Obj *dirPtr, const char *addStrRep, Tcl_Size len); MODULE_SCOPE void TclpAlertNotifier(void *clientData); -MODULE_SCOPE void *TclpNotifierData(void); +MODULE_SCOPE void * TclpNotifierData(void); MODULE_SCOPE void TclpServiceModeHook(int mode); MODULE_SCOPE void TclpSetTimer(const Tcl_Time *timePtr); MODULE_SCOPE int TclpWaitForEvent(const Tcl_Time *timePtr); @@ -3487,7 +3524,7 @@ MODULE_SCOPE Tcl_Size TclpFindVariable(const char *name, Tcl_Size *lengthPtr); MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr, TCL_HASH_TYPE *lengthPtr, Tcl_Encoding *encodingPtr); MODULE_SCOPE void TclpInitLock(void); -MODULE_SCOPE void *TclpInitNotifier(void); +MODULE_SCOPE void * TclpInitNotifier(void); MODULE_SCOPE void TclpInitPlatform(void); MODULE_SCOPE void TclpInitUnlock(void); MODULE_SCOPE Tcl_Obj * TclpObjListVolumes(void); @@ -3575,7 +3612,7 @@ MODULE_SCOPE Tcl_Size TclTrimLeft(const char *bytes, Tcl_Size numBytes, MODULE_SCOPE Tcl_Size TclTrimRight(const char *bytes, Tcl_Size numBytes, const char *trim, Tcl_Size numTrim); MODULE_SCOPE const char*TclGetCommandTypeName(Tcl_Command command); -MODULE_SCOPE int TclObjInterpProc(void *clientData, +MODULE_SCOPE int TclObjInterpProc(void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE void TclRegisterCommandTypeName( @@ -3607,13 +3644,13 @@ MODULE_SCOPE double TclpWideClickInMicrosec(void); #else # ifdef _WIN32 # define TCL_WIDE_CLICKS 1 -MODULE_SCOPE long long TclpGetWideClicks(void); +MODULE_SCOPE long long TclpGetWideClicks(void); MODULE_SCOPE double TclpWideClickInMicrosec(void); # define TclpWideClicksToNanoseconds(clicks) \ ((double)(clicks) * TclpWideClickInMicrosec() * 1000) # endif #endif -MODULE_SCOPE long long TclpGetMicroseconds(void); +MODULE_SCOPE long long TclpGetMicroseconds(void); MODULE_SCOPE int TclZlibInit(Tcl_Interp *interp); MODULE_SCOPE void * TclpThreadCreateKey(void); @@ -4004,13 +4041,13 @@ MODULE_SCOPE int TclFullFinalizationRequested(void); * TIP #542 */ -MODULE_SCOPE size_t TclUniCharLen(const Tcl_UniChar *uniStr); -MODULE_SCOPE int TclUniCharNcmp(const Tcl_UniChar *ucs, - const Tcl_UniChar *uct, size_t numChars); -MODULE_SCOPE int TclUniCharNcasecmp(const Tcl_UniChar *ucs, - const Tcl_UniChar *uct, size_t numChars); -MODULE_SCOPE int TclUniCharCaseMatch(const Tcl_UniChar *uniStr, - const Tcl_UniChar *uniPattern, int nocase); +MODULE_SCOPE size_t TclUniCharLen(const Tcl_UniChar *uniStr); +MODULE_SCOPE int TclUniCharNcmp(const Tcl_UniChar *ucs, + const Tcl_UniChar *uct, size_t numChars); +MODULE_SCOPE int TclUniCharNcasecmp(const Tcl_UniChar *ucs, + const Tcl_UniChar *uct, size_t numChars); +MODULE_SCOPE int TclUniCharCaseMatch(const Tcl_UniChar *uniStr, + const Tcl_UniChar *uniPattern, int nocase); /* @@ -4049,7 +4086,7 @@ MODULE_SCOPE void TclProcessCreated(Tcl_Pid pid); MODULE_SCOPE TclProcessWaitStatus TclProcessWait(Tcl_Pid pid, int options, int *codePtr, Tcl_Obj **msgObjPtr, Tcl_Obj **errorObjPtr); -MODULE_SCOPE int TclClose(Tcl_Interp *, Tcl_Channel chan); +MODULE_SCOPE int TclClose(Tcl_Interp *, Tcl_Channel chan); /* * TIP #508: [array default] @@ -4070,7 +4107,8 @@ MODULE_SCOPE Tcl_Size TclIndexDecode(int encoded, Tcl_Size endValue); /* * Error message utility functions */ -MODULE_SCOPE int TclCommandWordLimitError(Tcl_Interp *interp, Tcl_Size count); +MODULE_SCOPE int TclCommandWordLimitError( + Tcl_Interp *interp, Tcl_Size count); #endif /* TCL_MAJOR_VERSION > 8 */ diff --git a/generic/tclLoad.c b/generic/tclLoad.c index a2d1919..ac0d00d 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -1107,9 +1107,8 @@ TclGetLoadedLibraries( * NULL, return info about all interps; * otherwise, just return info about this * interpreter. */ - const char *prefix) /* Prefix or NULL. If NULL, return info - * for all prefixes. - */ + const char *prefix) /* Prefix or NULL. If NULL, return info + * for all prefixes. */ { Tcl_Interp *target; LoadedLibrary *libraryPtr; diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index a0668be..41abf98 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -4928,8 +4928,7 @@ TclLogCommandInfo( const char *command, /* First character in command that generated * the error. */ Tcl_Size length, /* Number of bytes in command (< 0 means use - * all bytes up to first null byte). - */ + * all bytes up to first null byte). */ const unsigned char *pc, /* Current pc of bytecode execution context */ Tcl_Obj **tosPtr) /* Current stack of bytecode execution * context */ diff --git a/generic/tclOO.c b/generic/tclOO.c index 1d72fb0..7a57105 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -120,6 +120,9 @@ static const DeclaredClassMethod objMethods[] = { DCM("new", 1, TclOO_Class_New), DCM("createWithNamespace", 0, TclOO_Class_CreateNs), {NULL, 0, {0, NULL, NULL, NULL, NULL}} +}, cfgMethods[] = { + DCM("configure", 1, TclOO_Configurable_Configure), + {NULL, 0, {0, NULL, NULL, NULL, NULL}} }; /* @@ -427,6 +430,18 @@ InitFoundation( } /* + * Make the configurable class and install its standard defined method. + */ + + Tcl_Object cfgCls = Tcl_NewObjectInstance(interp, + (Tcl_Class) fPtr->classCls, + "::oo::configuresupport::configurable", NULL, -1, NULL, 0); + for (i = 0 ; cfgMethods[i].name ; i++) { + TclOONewBasicMethod(interp, ((Object *) cfgCls)->classPtr, + &cfgMethods[i]); + } + + /* * Evaluate the remaining definitions, which are a compiled-in Tcl script. */ @@ -457,11 +472,11 @@ InitClassSystemRoots( fPtr->objectCls = &fakeCls; /* referenced in TclOOAllocClass to increment the refCount. */ fakeCls.thisPtr = &fakeObject; - fakeObject.refCount = 0; /* Do not increment an uninitialized value. */ + fakeObject.refCount = 0; // Do not increment an uninitialized value. fPtr->objectCls = TclOOAllocClass(interp, AllocObject(interp, "object", (Namespace *)fPtr->ooNs, NULL)); - /* Corresponding TclOODecrRefCount in KillFoudation */ + // Corresponding TclOODecrRefCount in KillFoundation AddRef(fPtr->objectCls->thisPtr); /* @@ -486,7 +501,7 @@ InitClassSystemRoots( fPtr->classCls = TclOOAllocClass(interp, AllocObject(interp, "class", (Namespace *)fPtr->ooNs, NULL)); - /* Corresponding TclOODecrRefCount in KillFoudation */ + // Corresponding TclOODecrRefCount in KillFoundation AddRef(fPtr->classCls->thisPtr); /* @@ -576,8 +591,8 @@ DeletedHelpersNamespace( static void KillFoundation( TCL_UNUSED(void *), - Tcl_Interp *interp) /* The interpreter containing the OO system - * foundation. */ + Tcl_Interp *interp) /* The interpreter containing the OO system + * foundation. */ { Foundation *fPtr = GetFoundation(interp); @@ -791,7 +806,7 @@ SquelchCachedName( static void MyDeleted( - void *clientData) /* Reference to the object whose [my] has been + void *clientData) /* Reference to the object whose [my] has been * squelched. */ { Object *oPtr = (Object *)clientData; @@ -822,7 +837,7 @@ MyClassDeleted( static void ObjectRenamedTrace( - void *clientData, /* The object being deleted. */ + void *clientData, /* The object being deleted. */ TCL_UNUSED(Tcl_Interp *), TCL_UNUSED(const char *) /*oldName*/, TCL_UNUSED(const char *) /*newName*/, @@ -1135,7 +1150,7 @@ TclOOReleaseClassContents( static void ObjectNamespaceDeleted( - void *clientData) /* Pointer to the class whose namespace is + void *clientData) /* Pointer to the class whose namespace is * being deleted. */ { Object *oPtr = (Object *)clientData; @@ -1235,7 +1250,7 @@ ObjectNamespaceDeleted( * methods on the object. */ - /* TODO: Should this be protected with a !IsRoot() condition? */ + // TODO: Should this be protected with a !IsRoot() condition? TclOORemoveFromInstances(oPtr, oPtr->selfCls); if (oPtr->mixins.num > 0) { @@ -1715,10 +1730,10 @@ Tcl_NewObjectInstance( const char *nsNameStr, /* Name of namespace to create inside object, * or NULL to ask the code to pick its own * unique name. */ - Tcl_Size objc, /* Number of arguments. Negative value means + Tcl_Size objc, /* Number of arguments. Negative value means * do not call constructor. */ Tcl_Obj *const *objv, /* Argument list. */ - Tcl_Size skip) /* Number of arguments to _not_ pass to the + Tcl_Size skip) /* Number of arguments to _not_ pass to the * constructor. */ { Class *classPtr = (Class *) cls; @@ -1783,10 +1798,10 @@ TclNRNewObjectInstance( const char *nsNameStr, /* Name of namespace to create inside object, * or NULL to ask the code to pick its own * unique name. */ - Tcl_Size objc, /* Number of arguments. Negative value means + Tcl_Size objc, /* Number of arguments. Negative value means * do not call constructor. */ Tcl_Obj *const *objv, /* Argument list. */ - Tcl_Size skip, /* Number of arguments to _not_ pass to the + Tcl_Size skip, /* Number of arguments to _not_ pass to the * constructor. */ Tcl_Object *objectPtr) /* Place to write the object reference upon * successful allocation. */ @@ -2604,7 +2619,7 @@ TclOOInvokeObject( * (PRIVATE_METHOD), or a *really* private * context (any other value; conventionally * 0). */ - Tcl_Size objc, /* Number of arguments. */ + Tcl_Size objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Array of argument objects. It is assumed * that the name of the method to invoke will * be at index 1. */ @@ -2675,7 +2690,7 @@ int TclOOObjectCmdCore( Object *oPtr, /* The object being invoked. */ Tcl_Interp *interp, /* The interpreter containing the object. */ - Tcl_Size objc, /* How many arguments are being passed in. */ + Tcl_Size objc, /* How many arguments are being passed in. */ Tcl_Obj *const *objv, /* The array of arguments. */ int flags, /* Whether this is an invocation through the * public or the private command interface. */ diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 251ae34..0e642ef 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -1341,8 +1341,22 @@ TclOOCopyObjectCmd( return TCL_OK; } +/* + * ---------------------------------------------------------------------- + * + * TclOO_Configurable_Configure -- + * + * Implementation of the oo::configurable->configure method. + * + * ---------------------------------------------------------------------- + */ + +/* + * Ugly thunks to read and write a property by calling the right method in + * the right way. + */ static int -ReadProp( +ReadProperty( Tcl_Interp *interp, Object *oPtr, Tcl_Obj *propObj) @@ -1358,11 +1372,22 @@ ReadProp( code = TclOOPrivateObjectCmd(oPtr, interp, 2, args); Tcl_DecrRefCount(args[0]); Tcl_DecrRefCount(args[1]); - return code; + switch (code) { + case TCL_BREAK: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "property getter for %s did a break", TclGetString(propObj))); + return TCL_ERROR; + case TCL_CONTINUE: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "property getter for %s did a continue", TclGetString(propObj))); + return TCL_ERROR; + default: + return code; + } } static int -WriteProp( +WriteProperty( Tcl_Interp *interp, Object *oPtr, Tcl_Obj *propObj, @@ -1382,117 +1407,226 @@ WriteProp( Tcl_DecrRefCount(args[0]); Tcl_DecrRefCount(args[1]); Tcl_DecrRefCount(args[2]); - return code; + switch (code) { + case TCL_BREAK: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "property setter for %s did a break", TclGetString(propObj))); + return TCL_ERROR; + case TCL_CONTINUE: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "property setter for %s did a continue", TclGetString(propObj))); + return TCL_ERROR; + default: + return code; + } } +/* Short-term cache for GetPropertyName(). */ +struct Cache { + Tcl_Obj *listPtr; /* Holds references to names. */ + char *names[TCLFLEXARRAY]; /* NULL-terminated table of names. */ +}; + +enum GPNFlags { + GPN_WRITABLE = 1, /* Are we looking for a writable property? */ + GPN_FALLING_BACK = 2 /* Are we doing a recursive call to determine + * if the property is of the other type? */ +}; + /* Look up a property full name. */ static Tcl_Obj * GetPropertyName( Tcl_Interp *interp, /* Context and error reporting. */ Object *oPtr, /* Object to get property name from. */ - int writable, /* Are we looking for a writable property? */ - Tcl_Obj *namePtr) /* The name supplied by the user. */ + int flags, /* Are we looking for a writable property? + * Can we do a fallback message? + * See GPNFlags for possible values */ + Tcl_Obj *namePtr, /* The name supplied by the user. */ + struct Cache **cachePtr) /* Where to cache the table, if the caller + * wants that. The contents are to be freed + * with Tcl_Free if the cache is used. */ { - int allocated; Tcl_Size objc, index, i; - Tcl_Obj *listPtr = TclOOGetAllObjectProperties(oPtr, writable, &allocated); + Tcl_Obj *listPtr = TclOOGetAllObjectProperties( + oPtr, flags & GPN_WRITABLE); Tcl_Obj **objv; - if (allocated) { - TclOOSortPropList(listPtr); - } - ListObjGetElements(listPtr, objc, objv); - char **tablePtr = TclStackAlloc(interp, sizeof(char*) * objc); - for (int i = 0; i < objc; i++) { - tablePtr[i] = TclGetString(objv[i]); + struct Cache *tablePtr; + + (void) Tcl_ListObjGetElements(NULL, listPtr, &objc, &objv); + if (cachePtr && *cachePtr) { + tablePtr = *cachePtr; + } else { + tablePtr = (struct Cache *) Tcl_Alloc( + offsetof(struct Cache, names) + sizeof(char *) * (objc + 1)); + + for (i = 0; i < objc; i++) { + tablePtr->names[i] = TclGetString(objv[i]); + } + tablePtr->names[objc] = NULL; + if (cachePtr) { + /* + * Have a cache, but nothing in it so far. + * + * We cache the list here so it doesn't vanish from under our + * feet if a property implementation does something crazy like + * changing the set of properties. The type of copy this does + * means that the copy holds the references to the names in the + * table. + */ + tablePtr->listPtr = TclListObjCopy(NULL, listPtr); + Tcl_IncrRefCount(tablePtr->listPtr); + *cachePtr = tablePtr; + } else { + tablePtr->listPtr = NULL; + } } - int result = Tcl_GetIndexFromObjStruct(interp, namePtr, tablePtr, + int result = Tcl_GetIndexFromObjStruct(interp, namePtr, tablePtr->names, sizeof(char *), "property", TCL_INDEX_TEMP_TABLE, &index); - TclStackFree(interp, tablePtr); + if (result == TCL_ERROR && !(flags & GPN_FALLING_BACK)) { + /* + * If property can be accessed the other way, use a special message. + * We use a recursive call to look this up. + */ + + Tcl_InterpState foo = Tcl_SaveInterpState(interp, result); + Tcl_Obj *otherName = GetPropertyName(interp, oPtr, + flags ^ (GPN_WRITABLE | GPN_FALLING_BACK), namePtr, NULL); + result = Tcl_RestoreInterpState(interp, foo); + if (otherName != NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "property \"%s\" is %s only", + TclGetString(otherName), + (flags & GPN_WRITABLE) ? "read" : "write")); + } + } + if (!cachePtr) { + Tcl_Free(tablePtr); + } if (result != TCL_OK) { return NULL; } return objv[index]; } +/* Release the cache made by GetPropertyName(). */ +static void +ReleasePropertyNameCache( + struct Cache **cachePtr) +{ + if (*cachePtr) { + struct Cache *tablePtr = *cachePtr; + if (tablePtr->listPtr) { + Tcl_DecrRefCount(tablePtr->listPtr); + } + Tcl_Free(tablePtr); + *cachePtr = NULL; + } +} + int TclOO_Configurable_Configure( TCL_UNUSED(void *), Tcl_Interp *interp, /* Interpreter used for the result, error * reporting, etc. */ Tcl_ObjectContext context, /* The object/call context. */ - Tcl_Size objc, /* Number of arguments. */ + int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { Object *oPtr = (Object *) Tcl_ObjectContextObject(context); Tcl_Size skip = Tcl_ObjectContextSkippedArgs(context); - Tcl_Size numArgs = objc - skip; Tcl_Obj *namePtr; - Tcl_Size i; - int code; + Tcl_Size i, namec; + int code = TCL_OK; - if (numArgs == 0) { + objc -= skip; + if ((objc & 1) && (objc != 1)) { + /* + * Bad (odd > 1) number of arguments. + */ + + Tcl_WrongNumArgs(interp, skip, objv, "?-option value ...?"); + return TCL_ERROR; + } + + objv += skip; + if (objc == 0) { /* * Read all properties. */ - Tcl_Size namec; - int allocated = 0; - Tcl_Obj *listPtr = TclOOGetAllObjectProperties(oPtr, 0, &allocated); + Tcl_Obj *listPtr = TclOOGetAllObjectProperties(oPtr, 0); Tcl_Obj *resultPtr = Tcl_NewObj(), **namev; - if (allocated) { - TclOOSortPropList(listPtr); - } + Tcl_IncrRefCount(listPtr); ListObjGetElements(listPtr, namec, namev); for (i = 0; i < namec; ) { - code = ReadProp(interp, oPtr, namev[i]); + code = ReadProperty(interp, oPtr, namev[i]); if (code != TCL_OK) { Tcl_DecrRefCount(resultPtr); - return code; + break; } - Tcl_DictObjPut(NULL, resultPtr, namev[i], Tcl_GetObjResult(interp)); + Tcl_DictObjPut(NULL, resultPtr, namev[i], + Tcl_GetObjResult(interp)); if (++i >= namec) { Tcl_SetObjResult(interp, resultPtr); break; } Tcl_SetObjResult(interp, Tcl_NewObj()); } - } else if (numArgs == 1) { + Tcl_DecrRefCount(listPtr); + return code; + } else if (objc == 1) { /* * Read a single named property. */ - namePtr = GetPropertyName(interp, oPtr, 0, objv[skip]); + namePtr = GetPropertyName(interp, oPtr, 0, objv[0], NULL); if (namePtr == NULL) { return TCL_ERROR; } - return ReadProp(interp, oPtr, namePtr); - } else if (numArgs % 2) { + return ReadProperty(interp, oPtr, namePtr); + } else if (objc == 2) { /* - * Bad (odd > 1) number of arguments. + * Special case for writing to one property. Saves fiddling with the + * cache in this common case. */ - Tcl_WrongNumArgs(interp, skip, objv, "?-option value ...?"); - return TCL_ERROR; + namePtr = GetPropertyName(interp, oPtr, GPN_WRITABLE, objv[0], NULL); + if (namePtr == NULL) { + return TCL_ERROR; + } + code = WriteProperty(interp, oPtr, namePtr, objv[1]); + if (code == TCL_OK) { + Tcl_ResetResult(interp); + } + return code; } else { /* - * Write properties. + * Write properties. Slightly tricky because we want to cache the + * table of property names. */ + struct Cache *cache = NULL; - objv += skip; - for (i = 0; i < numArgs; i += 2) { - namePtr = GetPropertyName(interp, oPtr, 1, objv[i]); + code = TCL_OK; + for (i = 0; i < objc; i += 2) { + namePtr = GetPropertyName(interp, oPtr, GPN_WRITABLE, objv[i], + &cache); if (namePtr == NULL) { - return TCL_ERROR; + code = TCL_ERROR; + break; } - code = WriteProp(interp, oPtr, namePtr, objv[i + 1]); + code = WriteProperty(interp, oPtr, namePtr, objv[i + 1]); if (code != TCL_OK) { - return code; + break; } } + if (code == TCL_OK) { + Tcl_ResetResult(interp); + } + ReleasePropertyNameCache(&cache); + return code; } - return TCL_OK; } /* diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c index 7695483..773bb56 100644 --- a/generic/tclOOCall.c +++ b/generic/tclOOCall.c @@ -25,7 +25,7 @@ struct ChainBuilder { CallChain *callChainPtr; /* The call chain being built. */ - size_t filterLength; /* Number of entries in the call chain that + size_t filterLength; /* Number of entries in the call chain that * are due to processing filters and not the * main call chain. */ Object *oPtr; /* The object that we are building the chain @@ -309,7 +309,7 @@ FreeMethodNameRep( int TclOOInvokeContext( - void *clientData, /* The method call context. */ + void *clientData, /* The method call context. */ Tcl_Interp *interp, /* Interpreter for error reporting, and many * other sorts of context handling (e.g., * commands, variables) depending on method @@ -678,7 +678,7 @@ CmpStr( static void AddClassMethodNames( Class *clsPtr, /* Class to get method names from. */ - int flags, /* Whether we are interested in just the + int flags, /* Whether we are interested in just the * public method names. */ Tcl_HashTable *const namesPtr, /* Reference to the hash table to put the @@ -2039,8 +2039,9 @@ AddSimpleClassDefineNamespaces( static inline void AddDefinitionNamespaceToChain( - Class *const definerCls, /* What class defines this entry. */ - Tcl_Obj *const namespaceName, /* The name for this entry (or NULL, a + Class *const definerCls, /* What class defines this entry. */ + Tcl_Obj *const namespaceName, + /* The name for this entry (or NULL, a * no-op). */ DefineChain *const definePtr, /* The define chain to add the method @@ -2290,9 +2291,8 @@ TclOOGetAllClassProperties( * * TclOOGetAllObjectProperties -- * - * Get the list of all properties known to a object, including to its - * classes. Manages a cache so this operation is usually cheap. - * The order of properties in the resulting list is undefined. + * Get the sorted list of all properties known to a object, including to its + * its classes. Manages a cache so this operation is usually cheap. * * ---------------------------------------------------------------------- */ @@ -2300,12 +2300,9 @@ TclOOGetAllClassProperties( Tcl_Obj * TclOOGetAllObjectProperties( Object *oPtr, /* The object to inspect. Must exist. */ - int writable, /* Whether to get writable properties. If + int writable) /* Whether to get writable properties. If * false, readable properties will be returned * instead. */ - int *allocated) /* Address of variable to set to true if a - * Tcl_Obj was allocated and may be safely - * modified by the caller. */ { Tcl_HashTable hashTable; FOREACH_HASH_DECLS; @@ -2319,12 +2316,10 @@ TclOOGetAllObjectProperties( if (oPtr->properties.epoch == oPtr->fPtr->epoch) { if (writable) { if (oPtr->properties.allWritableCache) { - *allocated = 0; return oPtr->properties.allWritableCache; } } else { if (oPtr->properties.allReadableCache) { - *allocated = 0; return oPtr->properties.allReadableCache; } } @@ -2334,7 +2329,6 @@ TclOOGetAllObjectProperties( * Gather the information. Unsorted! (Caller will sort.) */ - *allocated = 1; Tcl_InitObjHashTable(&hashTable); FindObjectProps(oPtr, writable, &hashTable); TclNewObj(result); @@ -2342,6 +2336,7 @@ TclOOGetAllObjectProperties( Tcl_ListObjAppendElement(NULL, result, propName); } Tcl_DeleteHashTable(&hashTable); + TclOOSortPropList(result); /* * Cache the information. diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 1a0bb43..7112039 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -330,7 +330,7 @@ TclOOObjectSetFilters( */ Tcl_Obj **filtersList; - int size = sizeof(Tcl_Obj *) * numFilters; /* should be size_t */ + size_t size = sizeof(Tcl_Obj *) * numFilters; if (oPtr->filters.num == 0) { filtersList = (Tcl_Obj **)Tcl_Alloc(size); @@ -345,7 +345,7 @@ TclOOObjectSetFilters( oPtr->filters.num = numFilters; oPtr->flags &= ~USE_CLASS_CACHE; } - BumpInstanceEpoch(oPtr); /* Only this object can be affected. */ + BumpInstanceEpoch(oPtr); // Only this object can be affected. } /* @@ -389,7 +389,7 @@ TclOOClassSetFilters( */ Tcl_Obj **filtersList; - int size = sizeof(Tcl_Obj *) * numFilters; /* should be size_t */ + size_t size = sizeof(Tcl_Obj *) * numFilters; if (classPtr->filters.num == 0) { filtersList = (Tcl_Obj **)Tcl_Alloc(size); @@ -1119,7 +1119,7 @@ MagicDefinitionInvoke( Tcl_GetCommandFullName(interp, cmd, obj2Ptr); } Tcl_ListObjAppendElement(NULL, objPtr, obj2Ptr); - /* TODO: overflow? */ + // TODO: overflow? Tcl_ListObjReplace(NULL, objPtr, 1, 0, objc - offset, objv + offset); TclListObjGetElementsM(NULL, objPtr, &dummy, &objs); diff --git a/generic/tclOOInfo.c b/generic/tclOOInfo.c index bc04748..958e330 100644 --- a/generic/tclOOInfo.c +++ b/generic/tclOOInfo.c @@ -1810,7 +1810,7 @@ InfoObjectPropCmd( Tcl_Obj *const objv[]) { Object *oPtr; - int i, idx, all = 0, writable = 0, allocated = 0; + int i, idx, all = 0, writable = 0; Tcl_Obj *result, *propObj; if (objc < 2) { @@ -1844,10 +1844,7 @@ InfoObjectPropCmd( */ if (all) { - result = TclOOGetAllObjectProperties(oPtr, writable, &allocated); - if (allocated) { - TclOOSortPropList(result); - } + result = TclOOGetAllObjectProperties(oPtr, writable); } else { TclNewObj(result); if (writable) { diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index d9f4ed8..b35cd13 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -209,9 +209,9 @@ typedef struct Object { * references; this mechanism exists to * avoid Tcl_Preserve. */ int flags; - Tcl_Size creationEpoch; /* Unique value to make comparisons of objects + Tcl_Size creationEpoch; /* Unique value to make comparisons of objects * easier. */ - Tcl_Size epoch; /* Per-object epoch, incremented when the way + Tcl_Size epoch; /* Per-object epoch, incremented when the way * an object should resolve call chains is * changed. */ Tcl_HashTable *metadataPtr; /* Mapping from pointers to metadata type to @@ -472,7 +472,7 @@ typedef struct { *---------------------------------------------------------------- */ -MODULE_SCOPE int TclOOInit(Tcl_Interp *interp); +MODULE_SCOPE int TclOOInit(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc TclOODefineObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOObjDefObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineConstructorObjCmd; @@ -507,6 +507,7 @@ MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_Eval; MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_LinkVar; MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_Unknown; MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_VarName; +MODULE_SCOPE Tcl_MethodCallProc TclOO_Configurable_Configure; /* * Private definitions, some of which perhaps ought to be exposed properly or @@ -518,17 +519,17 @@ MODULE_SCOPE void TclOOAddToMixinSubs(Class *subPtr, Class *mixinPtr); MODULE_SCOPE void TclOOAddToSubclasses(Class *subPtr, Class *superPtr); MODULE_SCOPE Class * TclOOAllocClass(Tcl_Interp *interp, Object *useThisObj); -MODULE_SCOPE int TclMethodIsType(Tcl_Method method, - const Tcl_MethodType *typePtr, - void **clientDataPtr); +MODULE_SCOPE int TclMethodIsType(Tcl_Method method, + const Tcl_MethodType *typePtr, + void **clientDataPtr); MODULE_SCOPE Tcl_Method TclNewInstanceMethod(Tcl_Interp *interp, - Tcl_Object object, Tcl_Obj *nameObj, - int flags, const Tcl_MethodType *typePtr, - void *clientData); + Tcl_Object object, Tcl_Obj *nameObj, + int flags, const Tcl_MethodType *typePtr, + void *clientData); MODULE_SCOPE Tcl_Method TclNewMethod(Tcl_Interp *interp, Tcl_Class cls, - Tcl_Obj *nameObj, int flags, - const Tcl_MethodType *typePtr, - void *clientData); + Tcl_Obj *nameObj, int flags, + const Tcl_MethodType *typePtr, + void *clientData); MODULE_SCOPE int TclNRNewObjectInstance(Tcl_Interp *interp, Tcl_Class cls, const char *nameStr, const char *nsNameStr, Tcl_Size objc, @@ -550,7 +551,7 @@ MODULE_SCOPE void TclOODelMethodRef(Method *method); MODULE_SCOPE Tcl_Obj * TclOOGetAllClassProperties(Class *clsPtr, int writable, int *allocated); MODULE_SCOPE Tcl_Obj * TclOOGetAllObjectProperties(Object *oPtr, - int writable, int *allocated); + int writable); MODULE_SCOPE CallContext *TclOOGetCallContext(Object *oPtr, Tcl_Obj *methodNameObj, int flags, Object *contextObjPtr, Class *contextClsPtr, diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c index 4711695..f1d96f0 100644 --- a/generic/tclOOMethod.c +++ b/generic/tclOOMethod.c @@ -536,7 +536,7 @@ TclOOMakeProcInstanceMethod( * NULL. */ const Tcl_MethodType *typePtr, /* The type of the method to create. */ - void *clientData, /* The per-method type-specific data. */ + void *clientData, /* The per-method type-specific data. */ Proc **procPtrPtr) /* A pointer to the variable in which to write * the procedure record reference. Presumably * inside the structure indicated by the @@ -649,7 +649,7 @@ TclOOMakeProcMethod( * NULL. */ const Tcl_MethodType *typePtr, /* The type of the method to create. */ - void *clientData, /* The per-method type-specific data. */ + void *clientData, /* The per-method type-specific data. */ Proc **procPtrPtr) /* A pointer to the variable in which to write * the procedure record reference. Presumably * inside the structure indicated by the @@ -744,7 +744,7 @@ TclOOMakeProcMethod( static int InvokeProcedureMethod( - void *clientData, /* Pointer to some per-method context. */ + void *clientData, /* Pointer to some per-method context. */ Tcl_Interp *interp, Tcl_ObjectContext context, /* The method calling context. */ int objc, /* Number of arguments. */ @@ -1038,7 +1038,7 @@ ProcedureMethodVarResolver( Tcl_Interp *interp, const char *varName, Tcl_Namespace *contextNs, - TCL_UNUSED(int) /*flags*/, /* Ignoring variable access flags (???) */ + TCL_UNUSED(int) /*flags*/, // Ignoring variable access flags (???) Tcl_Var *varPtr) { int result; @@ -1257,7 +1257,7 @@ RenderDeclarerName( * ---------------------------------------------------------------------- */ -/* TODO: Check whether Tcl_AppendLimitedToObj() can work here. */ +// TODO: Check whether Tcl_AppendLimitedToObj() can work here. #define LIMIT 60 #define ELLIPSIFY(str,len) \ @@ -1267,7 +1267,7 @@ static void MethodErrorHandler( Tcl_Interp *interp, TCL_UNUSED(Tcl_Obj *) /*methodNameObj*/) - /* We pull the method name out of context instead of from argument */ + // We pull the method name out of context instead of from argument { Tcl_Size nameLen, objectNameLen; CallContext *contextPtr = (CallContext *)((Interp *) interp)->varFramePtr->clientData; @@ -1299,7 +1299,7 @@ static void ConstructorErrorHandler( Tcl_Interp *interp, TCL_UNUSED(Tcl_Obj *) /*methodNameObj*/) - /* Ignore. We know it is the constructor. */ + // Ignore. We know it is the constructor. { CallContext *contextPtr = (CallContext *)((Interp *) interp)->varFramePtr->clientData; Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; @@ -1329,7 +1329,7 @@ static void DestructorErrorHandler( Tcl_Interp *interp, TCL_UNUSED(Tcl_Obj *) /*methodNameObj*/) - /* Ignore. We know it is the destructor. */ + // Ignore. We know it is the destructor. { CallContext *contextPtr = (CallContext *)((Interp *) interp)->varFramePtr->clientData; Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; @@ -1545,7 +1545,7 @@ TclOONewForwardMethod( static int InvokeForwardMethod( - void *clientData, /* Pointer to some per-method context. */ + void *clientData, /* Pointer to some per-method context. */ Tcl_Interp *interp, Tcl_ObjectContext context, /* The method calling context. */ int objc, /* Number of arguments. */ diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index eb6a96e..1903b49 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -364,108 +364,7 @@ static const char *tclOOSetupScript = "\t\t\t::namespace path ::oo::objdefine\n" "\t\t\t::namespace export property\n" "\t\t}\n" -"\t\tproc ReadAll {object my} {\n" -"\t\t\tset result {}\n" -"\t\t\tforeach prop [info object properties $object -all -readable] {\n" -"\t\t\t\ttry {\n" -"\t\t\t\t\tdict set result $prop [$my ]\n" -"\t\t\t\t} on error {msg opt} {\n" -"\t\t\t\t\tdict set opt -level 2\n" -"\t\t\t\t\treturn -options $opt $msg\n" -"\t\t\t\t} on return {msg opt} {\n" -"\t\t\t\t\tdict incr opt -level 2\n" -"\t\t\t\t\treturn -options $opt $msg\n" -"\t\t\t\t} on break {} {\n" -"\t\t\t\t\treturn -code error -level 2 -errorcode {TCLOO SHENANIGANS} \\\n" -"\t\t\t\t\t\t\"property getter for $prop did a break\"\n" -"\t\t\t\t} on continue {} {\n" -"\t\t\t\t\treturn -code error -level 2 -errorcode {TCLOO SHENANIGANS} \\\n" -"\t\t\t\t\t\t\"property getter for $prop did a continue\"\n" -"\t\t\t\t}\n" -"\t\t\t}\n" -"\t\t\treturn $result\n" -"\t\t}\n" -"\t\tproc ReadOne {object my propertyName} {\n" -"\t\t\tset props [info object properties $object -all -readable]\n" -"\t\t\ttry {\n" -"\t\t\t\tset prop [prefix match -message \"property\" $props $propertyName]\n" -"\t\t\t} on error {msg} {\n" -"\t\t\t\tcatch {\n" -"\t\t\t\t\tset wps [info object properties $object -all -writable]\n" -"\t\t\t\t\tset wprop [prefix match $wps $propertyName]\n" -"\t\t\t\t\tset msg \"property \\\"$wprop\\\" is write only\"\n" -"\t\t\t\t}\n" -"\t\t\t\treturn -code error -level 2 -errorcode [list \\\n" -"\t\t\t\t\t\tTCL LOOKUP INDEX property $propertyName] $msg\n" -"\t\t\t}\n" -"\t\t\ttry {\n" -"\t\t\t\tset value [$my ]\n" -"\t\t\t} on error {msg opt} {\n" -"\t\t\t\tdict set opt -level 2\n" -"\t\t\t\treturn -options $opt $msg\n" -"\t\t\t} on return {msg opt} {\n" -"\t\t\t\tdict incr opt -level 2\n" -"\t\t\t\treturn -options $opt $msg\n" -"\t\t\t} on break {} {\n" -"\t\t\t\treturn -code error -level 2 -errorcode {TCLOO SHENANIGANS} \\\n" -"\t\t\t\t\t\"property getter for $prop did a break\"\n" -"\t\t\t} on continue {} {\n" -"\t\t\t\treturn -code error -level 2 -errorcode {TCLOO SHENANIGANS} \\\n" -"\t\t\t\t\t\"property getter for $prop did a continue\"\n" -"\t\t\t}\n" -"\t\t\treturn $value\n" -"\t\t}\n" -"\t\tproc WriteMany {object my setterMap} {\n" -"\t\t\tset props [info object properties $object -all -writable]\n" -"\t\t\tforeach {prop value} $setterMap {\n" -"\t\t\t\ttry {\n" -"\t\t\t\t\tset prop [prefix match -message \"property\" $props $prop]\n" -"\t\t\t\t} on error {msg} {\n" -"\t\t\t\t\tcatch {\n" -"\t\t\t\t\t\tset rps [info object properties $object -all -readable]\n" -"\t\t\t\t\t\tset rprop [prefix match $rps $prop]\n" -"\t\t\t\t\t\tset msg \"property \\\"$rprop\\\" is read only\"\n" -"\t\t\t\t\t}\n" -"\t\t\t\t\treturn -code error -level 2 -errorcode [list \\\n" -"\t\t\t\t\t\t\tTCL LOOKUP INDEX property $prop] $msg\n" -"\t\t\t\t}\n" -"\t\t\t\ttry {\n" -"\t\t\t\t\t$my $value\n" -"\t\t\t\t} on error {msg opt} {\n" -"\t\t\t\t\tdict set opt -level 2\n" -"\t\t\t\t\treturn -options $opt $msg\n" -"\t\t\t\t} on return {msg opt} {\n" -"\t\t\t\t\tdict incr opt -level 2\n" -"\t\t\t\t\treturn -options $opt $msg\n" -"\t\t\t\t} on break {} {\n" -"\t\t\t\t\treturn -code error -level 2 -errorcode {TCLOO SHENANIGANS} \\\n" -"\t\t\t\t\t\t\"property setter for $prop did a break\"\n" -"\t\t\t\t} on continue {} {\n" -"\t\t\t\t\treturn -code error -level 2 -errorcode {TCLOO SHENANIGANS} \\\n" -"\t\t\t\t\t\t\"property setter for $prop did a continue\"\n" -"\t\t\t\t}\n" -"\t\t\t}\n" -"\t\t\treturn\n" -"\t\t}\n" -"\t\t::oo::class create configurable {\n" -"\t\t\tprivate variable my\n" -"\t\t\tmethod configure -export args {\n" -"\t\t\t\t::if {![::info exists my]} {\n" -"\t\t\t\t\t::set my [::namespace which my]\n" -"\t\t\t\t}\n" -"\t\t\t\t::if {[::llength $args] == 0} {\n" -"\t\t\t\t\t::oo::configuresupport::ReadAll [self] $my\n" -"\t\t\t\t} elseif {[::llength $args] == 1} {\n" -"\t\t\t\t\t::oo::configuresupport::ReadOne [self] $my \\\n" -"\t\t\t\t\t\t[::lindex $args 0]\n" -"\t\t\t\t} elseif {[::llength $args] % 2 == 0} {\n" -"\t\t\t\t\t::oo::configuresupport::WriteMany [self] $my $args\n" -"\t\t\t\t} else {\n" -"\t\t\t\t\t::return -code error -errorcode {TCL WRONGARGS} \\\n" -"\t\t\t\t\t\t[::format {wrong # args: should be \"%s\"} \\\n" -"\t\t\t\t\t\t\t\"[self] configure \?-option value ...\?\"]\n" -"\t\t\t\t}\n" -"\t\t\t}\n" +"\t\t::oo::define configurable {\n" "\t\t\tdefinitionnamespace -instance configurableobject\n" "\t\t\tdefinitionnamespace -class configurableclass\n" "\t\t}\n" diff --git a/generic/tclProcess.c b/generic/tclProcess.c index b16c73d..83ae4d6 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -192,8 +192,7 @@ WaitProcessStatus( * - errno in case of error. * - non-zero exit code for abormal exit. * - signal number if killed or suspended. - * - Tcl_WaitPid status in all other cases. - */ + * - Tcl_WaitPid status in all other cases. */ Tcl_Obj **msgObjPtr, /* If non-NULL, will receive error message. */ Tcl_Obj **errorObjPtr) /* If non-NULL, will receive error code. */ { @@ -864,8 +863,7 @@ TclProcessWait( * - errno in case of error. * - non-zero exit code for abormal exit. * - signal number if killed or suspended. - * - Tcl_WaitPid status in all other cases. - */ + * - Tcl_WaitPid status in all other cases. */ Tcl_Obj **msgObjPtr, /* If non-NULL, will receive error message. */ Tcl_Obj **errorObjPtr) /* If non-NULL, will receive error code. */ { diff --git a/tools/tclOOScript.tcl b/tools/tclOOScript.tcl index 4591a1b..2843dff 100644 --- a/tools/tclOOScript.tcl +++ b/tools/tclOOScript.tcl @@ -612,156 +612,15 @@ # ------------------------------------------------------------------ # - # oo::configuresupport::ReadAll -- - # - # The implementation of [$o configure] with no extra arguments. - # - # ------------------------------------------------------------------ - - proc ReadAll {object my} { - set result {} - foreach prop [info object properties $object -all -readable] { - try { - dict set result $prop [$my ] - } on error {msg opt} { - dict set opt -level 2 - return -options $opt $msg - } on return {msg opt} { - dict incr opt -level 2 - return -options $opt $msg - } on break {} { - return -code error -level 2 -errorcode {TCLOO SHENANIGANS} \ - "property getter for $prop did a break" - } on continue {} { - return -code error -level 2 -errorcode {TCLOO SHENANIGANS} \ - "property getter for $prop did a continue" - } - } - return $result - } - - # ------------------------------------------------------------------ - # - # oo::configuresupport::ReadOne -- - # - # The implementation of [$o configure -prop] with that single - # extra argument. - # - # ------------------------------------------------------------------ - - proc ReadOne {object my propertyName} { - set props [info object properties $object -all -readable] - try { - set prop [prefix match -message "property" $props $propertyName] - } on error {msg} { - catch { - set wps [info object properties $object -all -writable] - set wprop [prefix match $wps $propertyName] - set msg "property \"$wprop\" is write only" - } - return -code error -level 2 -errorcode [list \ - TCL LOOKUP INDEX property $propertyName] $msg - } - try { - set value [$my ] - } on error {msg opt} { - dict set opt -level 2 - return -options $opt $msg - } on return {msg opt} { - dict incr opt -level 2 - return -options $opt $msg - } on break {} { - return -code error -level 2 -errorcode {TCLOO SHENANIGANS} \ - "property getter for $prop did a break" - } on continue {} { - return -code error -level 2 -errorcode {TCLOO SHENANIGANS} \ - "property getter for $prop did a continue" - } - return $value - } - - # ------------------------------------------------------------------ - # - # oo::configuresupport::WriteMany -- - # - # The implementation of [$o configure -prop val ?-prop val...?]. - # - # ------------------------------------------------------------------ - - proc WriteMany {object my setterMap} { - set props [info object properties $object -all -writable] - foreach {prop value} $setterMap { - try { - set prop [prefix match -message "property" $props $prop] - } on error {msg} { - catch { - set rps [info object properties $object -all -readable] - set rprop [prefix match $rps $prop] - set msg "property \"$rprop\" is read only" - } - return -code error -level 2 -errorcode [list \ - TCL LOOKUP INDEX property $prop] $msg - } - try { - $my $value - } on error {msg opt} { - dict set opt -level 2 - return -options $opt $msg - } on return {msg opt} { - dict incr opt -level 2 - return -options $opt $msg - } on break {} { - return -code error -level 2 -errorcode {TCLOO SHENANIGANS} \ - "property setter for $prop did a break" - } on continue {} { - return -code error -level 2 -errorcode {TCLOO SHENANIGANS} \ - "property setter for $prop did a continue" - } - } - return - } - - # ------------------------------------------------------------------ - # # oo::configuresupport::configurable -- # # The class that contains the implementation of the actual # 'configure' method (mixed into actually configurable classes). - # Great care needs to be taken in these methods as they are - # potentially used in classes where the current namespace is set - # up very strangely. + # The 'configure' method is in tclOOBasic.c. # # ------------------------------------------------------------------ - ::oo::class create configurable { - private variable my - # - # configure -- - # Method for providing client access to the property mechanism. - # Has a user-facing API similar to that of [chan configure]. - # - method configure -export args { - ::if {![::info exists my]} { - ::set my [::namespace which my] - } - ::if {[::llength $args] == 0} { - # Read all properties - ::oo::configuresupport::ReadAll [self] $my - } elseif {[::llength $args] == 1} { - # Read a single property - ::oo::configuresupport::ReadOne [self] $my \ - [::lindex $args 0] - } elseif {[::llength $args] % 2 == 0} { - # Set properties, one or several - ::oo::configuresupport::WriteMany [self] $my $args - } else { - # Invalid call - ::return -code error -errorcode {TCL WRONGARGS} \ - [::format {wrong # args: should be "%s"} \ - "[self] configure ?-option value ...?"] - } - } - + ::oo::define configurable { definitionnamespace -instance configurableobject definitionnamespace -class configurableclass } diff --git a/win/Makefile.in b/win/Makefile.in index 877c4f3..b79d808 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -103,6 +103,7 @@ GENERIC_DIR = $(TOP_DIR)/generic WIN_DIR = $(TOP_DIR)/win COMPAT_DIR = $(TOP_DIR)/compat PKGS_DIR = $(TOP_DIR)/pkgs +TOOL_DIR = $(TOP_DIR)/tools ZLIB_DIR = $(COMPAT_DIR)/zlib MINIZIP_DIR = $(ZLIB_DIR)/contrib/minizip TOMMATH_DIR = $(TOP_DIR)/libtommath @@ -1133,6 +1134,11 @@ $(GENERIC_DIR)/tclStubInit.c: $(GENERIC_DIR)/tcl.decls \ @echo "Developers may want to run \"make genstubs\" to regenerate." @echo "This warning can be safely ignored, do not report as a bug!" +$(GENERIC_DIR)/tclOOScript.h: $(TOOL_DIR)/tclOOScript.tcl + @echo "Warning: tclOOScript.h may be out of date." + @echo "Developers may want to run \"make genscript\" to regenerate." + @echo "This warning can be safely ignored, do not report as a bug!" + genstubs: $(TCL_EXE) "$(ROOT_DIR_NATIVE)/tools/genStubs.tcl" \ "$(GENERIC_DIR_NATIVE)" \ @@ -1143,6 +1149,10 @@ genstubs: "$(GENERIC_DIR_NATIVE)" \ "$(GENERIC_DIR_NATIVE)/tclOO.decls" +genscript: + $(TCL_EXE) $(ROOT_DIR_NATIVE)/tools/makeHeader.tcl \ + $(ROOT_DIR_NATIVE)/tools/tclOOScript.tcl $(GENERIC_DIR)/tclOOScript.h + # # This target creates the HTML folder for Tcl & Tk and places it in # DISTDIR/html. It uses the tcltk-man2html.tcl tool from the Tcl group's tool diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index 5b30fc4..dfaf7331d 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -1468,10 +1468,9 @@ ConsoleEventProc( static void ConsoleWatchProc( - void *instanceData, /* Console state. */ + void *instanceData, /* Console state. */ int newMask) /* What events to watch for, one of - * of TCL_READABLE, TCL_WRITABLE - */ + * of TCL_READABLE, TCL_WRITABLE */ { ConsoleChannelInfo **nextPtrPtr, *ptr; ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData; diff --git a/win/tclWinSock.c b/win/tclWinSock.c index f54d8a1..f83a293 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -2899,10 +2899,9 @@ NewSocketInfo(SOCKET socket) static int WaitForSocketEvent( - TcpState *statePtr, /* Information about this socket. */ + TcpState *statePtr, /* Information about this socket. */ int events, /* Events to look for. May be one of - * FD_READ or FD_WRITE. - */ + * FD_READ or FD_WRITE. */ int *errorCodePtr) /* Where to store errors? */ { int result = 1; -- cgit v0.12 From 67bcf9f38698bc89119e3790e9583ded6087fe34 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 27 Jan 2024 22:09:37 +0000 Subject: Change back memory management to how I wanted it to be --- generic/tclOOBasic.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 0e642ef..4553e50 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -1456,7 +1456,7 @@ GetPropertyName( if (cachePtr && *cachePtr) { tablePtr = *cachePtr; } else { - tablePtr = (struct Cache *) Tcl_Alloc( + tablePtr = (struct Cache *) TclStackAlloc(interp, offsetof(struct Cache, names) + sizeof(char *) * (objc + 1)); for (i = 0; i < objc; i++) { @@ -1500,7 +1500,7 @@ GetPropertyName( } } if (!cachePtr) { - Tcl_Free(tablePtr); + TclStackFree(interp, tablePtr); } if (result != TCL_OK) { return NULL; @@ -1511,6 +1511,7 @@ GetPropertyName( /* Release the cache made by GetPropertyName(). */ static void ReleasePropertyNameCache( + Tcl_Interp *interp, struct Cache **cachePtr) { if (*cachePtr) { @@ -1518,7 +1519,7 @@ ReleasePropertyNameCache( if (tablePtr->listPtr) { Tcl_DecrRefCount(tablePtr->listPtr); } - Tcl_Free(tablePtr); + TclStackFree(interp, tablePtr); *cachePtr = NULL; } } @@ -1624,7 +1625,7 @@ TclOO_Configurable_Configure( if (code == TCL_OK) { Tcl_ResetResult(interp); } - ReleasePropertyNameCache(&cache); + ReleasePropertyNameCache(interp, &cache); return code; } } -- cgit v0.12 From 0122c974de70dc32f5dc43ca4951ce53f91fc7ce Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 27 Jan 2024 23:16:53 +0000 Subject: win/Makefile/in tinkering --- win/Makefile.in | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/win/Makefile.in b/win/Makefile.in index b79d808..faf8d4b 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -119,6 +119,7 @@ TCL_LIBRARY_NATIVE = $(shell $(CYGPATH) '$(TCL_LIBRARY)') GENERIC_DIR_NATIVE = $(shell $(CYGPATH) '$(GENERIC_DIR)') WIN_DIR_NATIVE = $(shell $(CYGPATH) '$(WIN_DIR)') ROOT_DIR_NATIVE = $(shell $(CYGPATH) '$(ROOT_DIR)') +TOOL_DIR_NATIVE = $(shell $(CYGPATH) '$(TOOL_DIR)') SCRIPT_INSTALL_DIR_NATIVE = $(shell $(CYGPATH) '$(SCRIPT_INSTALL_DIR)') INCLUDE_INSTALL_DIR_NATIVE = $(shell $(CYGPATH) '$(INCLUDE_INSTALL_DIR)') MAN_INSTALL_DIR_NATIVE = $(shell $(CYGPATH) '$(MAN_INSTALL_DIR)') @@ -1140,18 +1141,19 @@ $(GENERIC_DIR)/tclOOScript.h: $(TOOL_DIR)/tclOOScript.tcl @echo "This warning can be safely ignored, do not report as a bug!" genstubs: - $(TCL_EXE) "$(ROOT_DIR_NATIVE)/tools/genStubs.tcl" \ + $(TCL_EXE) "$(TOOL_DIR_NATIVE)/genStubs.tcl" \ "$(GENERIC_DIR_NATIVE)" \ "$(GENERIC_DIR_NATIVE)/tcl.decls" \ "$(GENERIC_DIR_NATIVE)/tclInt.decls" \ "$(GENERIC_DIR_NATIVE)/tclTomMath.decls" - $(TCL_EXE) "$(ROOT_DIR_NATIVE)/tools/genStubs.tcl" \ + $(TCL_EXE) "$(TOOL_DIR_NATIVE)/genStubs.tcl" \ "$(GENERIC_DIR_NATIVE)" \ "$(GENERIC_DIR_NATIVE)/tclOO.decls" genscript: - $(TCL_EXE) $(ROOT_DIR_NATIVE)/tools/makeHeader.tcl \ - $(ROOT_DIR_NATIVE)/tools/tclOOScript.tcl $(GENERIC_DIR)/tclOOScript.h + $(TCL_EXE) "$(TOOL_DIR_NATIVE)/makeHeader.tcl" \ + "$(TOOL_DIR_NATIVE)/tclOOScript.tcl" \ + "$(GENERIC_DIR_NATIVE)/tclOOScript.h" # # This target creates the HTML folder for Tcl & Tk and places it in -- cgit v0.12 From d3740313f4eeff8e01611628a28248dce3374a10 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 28 Jan 2024 15:40:29 +0000 Subject: Property implementations: not plugged into Tcl level yet --- generic/tclOOBasic.c | 271 +++++++++++++++++++++++++++++++++++++++++++-------- generic/tclOOInt.h | 6 ++ generic/tclVar.c | 12 +-- 3 files changed, 243 insertions(+), 46 deletions(-) diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 4553e50..f8c9eb5 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -720,34 +720,22 @@ TclOO_Object_LinkVar( /* * ---------------------------------------------------------------------- * - * TclOO_Object_VarName -- + * LookupObjectVar -- * - * Implementation of the oo::object->varname method. + * Look up a variable in an object. Tricky because of private variables. * * ---------------------------------------------------------------------- */ -int -TclOO_Object_VarName( - TCL_UNUSED(void *), - Tcl_Interp *interp, /* Interpreter in which to create the object; - * also used for error reporting. */ - Tcl_ObjectContext context, /* The object/call context. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const *objv) /* The actual arguments. */ +static Tcl_Var +LookupObjectVar( + Tcl_Interp *interp, + Tcl_Object object, + Tcl_Obj *varName, + Tcl_Var *aryPtr) { - Var *varPtr, *aryVar; - Tcl_Obj *varNamePtr, *argPtr; - CallFrame *framePtr = ((Interp *) interp)->varFramePtr; - const char *arg; - - if ((int)Tcl_ObjectContextSkippedArgs(context)+1 != objc) { - Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, - "varName"); - return TCL_ERROR; - } - argPtr = objv[objc-1]; - arg = TclGetString(argPtr); + const char *arg = TclGetString(varName); + Tcl_Obj *varNamePtr; /* * Convert the variable name to fully-qualified form if it wasn't already. @@ -759,10 +747,10 @@ TclOO_Object_VarName( */ if (arg[0] == ':' && arg[1] == ':') { - varNamePtr = argPtr; + varNamePtr = varName; } else { - Tcl_Namespace *namespacePtr = - Tcl_GetObjectNamespace(Tcl_ObjectContextObject(context)); + Tcl_Namespace *namespacePtr = Tcl_GetObjectNamespace(object); + CallFrame *framePtr = ((Interp *) interp)->varFramePtr; /* * Private method handling. [TIP 500] @@ -775,7 +763,7 @@ TclOO_Object_VarName( */ if (framePtr->isProcCallFrame & FRAME_IS_METHOD) { - Object *oPtr = (Object *) Tcl_ObjectContextObject(context); + Object *oPtr = (Object *) object; CallContext *callerContext = (CallContext *)framePtr->clientData; Method *mPtr = callerContext->callPtr->chain[ callerContext->index].mPtr; @@ -785,8 +773,8 @@ TclOO_Object_VarName( if (mPtr->declaringObjectPtr == oPtr) { FOREACH_STRUCT(pvPtr, oPtr->privateVariables) { if (!strcmp(TclGetString(pvPtr->variableObj), - TclGetString(argPtr))) { - argPtr = pvPtr->fullNameObj; + TclGetString(varName))) { + varName = pvPtr->fullNameObj; break; } } @@ -807,8 +795,8 @@ TclOO_Object_VarName( if (isInstance) { FOREACH_STRUCT(pvPtr, clsPtr->privateVariables) { if (!strcmp(TclGetString(pvPtr->variableObj), - TclGetString(argPtr))) { - argPtr = pvPtr->fullNameObj; + TclGetString(varName))) { + varName = pvPtr->fullNameObj; break; } } @@ -816,16 +804,53 @@ TclOO_Object_VarName( } } + // The namespace isn't the global one; necessarily true for any object! varNamePtr = Tcl_NewStringObj(namespacePtr->fullName, -1); Tcl_AppendToObj(varNamePtr, "::", 2); - Tcl_AppendObjToObj(varNamePtr, argPtr); + Tcl_AppendObjToObj(varNamePtr, varName); } Tcl_IncrRefCount(varNamePtr); - varPtr = TclObjLookupVar(interp, varNamePtr, NULL, - TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG, "refer to", 1, 1, &aryVar); + Tcl_Var var = (Tcl_Var) TclObjLookupVar(interp, varNamePtr, NULL, + TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG, "refer to", 1, 1, + (Var **) aryPtr); Tcl_DecrRefCount(varNamePtr); + if (var == NULL) { + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", arg, (void *) NULL); + } + return var; +} + +/* + * ---------------------------------------------------------------------- + * + * TclOO_Object_VarName -- + * + * Implementation of the oo::object->varname method. + * + * ---------------------------------------------------------------------- + */ + +int +TclOO_Object_VarName( + TCL_UNUSED(void *), + Tcl_Interp *interp, /* Interpreter in which to create the object; + * also used for error reporting. */ + Tcl_ObjectContext context, /* The object/call context. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* The actual arguments. */ +{ + Tcl_Var varPtr, aryVar; + Tcl_Obj *varNamePtr; + + if ((int) Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { + Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, + "varName"); + return TCL_ERROR; + } + + varPtr = LookupObjectVar(interp, Tcl_ObjectContextObject(context), + objv[objc - 1], &aryVar); if (varPtr == NULL) { - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", arg, (void *)NULL); return TCL_ERROR; } @@ -836,18 +861,16 @@ TclOO_Object_VarName( TclNewObj(varNamePtr); if (aryVar != NULL) { - Tcl_GetVariableFullName(interp, (Tcl_Var) aryVar, varNamePtr); + Tcl_GetVariableFullName(interp, aryVar, varNamePtr); /* * WARNING! This code pokes inside the implementation of hash tables! */ - Tcl_AppendToObj(varNamePtr, "(", -1); - Tcl_AppendObjToObj(varNamePtr, ((VarInHash *) - varPtr)->entry.key.objPtr); - Tcl_AppendToObj(varNamePtr, ")", -1); + Tcl_AppendPrintfToObj(varNamePtr, "(%s)", Tcl_GetString( + ((VarInHash *) varPtr)->entry.key.objPtr)); } else { - Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, varNamePtr); + Tcl_GetVariableFullName(interp, varPtr, varNamePtr); } Tcl_SetObjResult(interp, varNamePtr); return TCL_OK; @@ -1631,6 +1654,174 @@ TclOO_Configurable_Configure( } /* + * ---------------------------------------------------------------------- + * + * Configurable_Getter, Configurable_Setter -- + * + * Standard property implementation. The clientData is a simple Tcl_Obj* + * that contains the name of the property. + * + * TclOOImplementObjectProperty, TclOOImplementClassProperty -- + * + * Installs a basic property implementation for a property, either on + * an instance or on a class. It's up to the code that calls these + * to ensure that the property name is syntactically valid. + * + * ---------------------------------------------------------------------- + */ + +static int +Configurable_Getter( + void *clientData, /* Which property to read. + * Actually a Tcl_Obj* reference. */ + Tcl_Interp *interp, /* Interpreter used for the result, error + * reporting, etc. */ + Tcl_ObjectContext context, /* The object/call context. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* The actual arguments. */ +{ + Tcl_Obj *propNamePtr = (Tcl_Obj *) clientData; + Tcl_Var varPtr, aryVar; + Tcl_Obj *valuePtr; + + if ((int) Tcl_ObjectContextSkippedArgs(context) != objc) { + Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), + objv, NULL); + return TCL_ERROR; + } + + varPtr = LookupObjectVar(interp, Tcl_ObjectContextObject(context), + propNamePtr, &aryVar); + if (varPtr == NULL) { + return TCL_ERROR; + } + + valuePtr = TclPtrGetVar(interp, varPtr, aryVar, propNamePtr, NULL, + TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG); + if (valuePtr == NULL) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, valuePtr); + return TCL_OK; +} + +static int +Configurable_Setter( + void *clientData, /* Which property to write. + * Actually a Tcl_Obj* reference. */ + Tcl_Interp *interp, /* Interpreter used for the result, error + * reporting, etc. */ + Tcl_ObjectContext context, /* The object/call context. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* The actual arguments. */ +{ + Tcl_Obj *propNamePtr = (Tcl_Obj *) clientData; + Tcl_Var varPtr, aryVar; + + if ((int) Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { + Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), + objv, "value"); + return TCL_ERROR; + } + + varPtr = LookupObjectVar(interp, Tcl_ObjectContextObject(context), + propNamePtr, &aryVar); + if (varPtr == NULL) { + return TCL_ERROR; + } + + if (TclPtrSetVar(interp, varPtr, aryVar, propNamePtr, NULL, + objv[objc - 1], TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { + return TCL_ERROR; + } + return TCL_OK; +} + +// Simple support functions +void DetailsDeleter( + void *clientData) +{ + // Just drop the reference count + Tcl_Obj *propNamePtr = (Tcl_Obj *) clientData; + Tcl_DecrRefCount(propNamePtr); +} + +int DetailsCloner( + TCL_UNUSED(Tcl_Interp *), + void *oldClientData, + void **newClientData) +{ + // Just add another reference to this name; easy! + Tcl_Obj *propNamePtr = (Tcl_Obj *) oldClientData; + Tcl_IncrRefCount(propNamePtr); + *newClientData = propNamePtr; + return TCL_OK; +} + +// Method descriptors +static Tcl_MethodType GetterType = { + TCL_OO_METHOD_VERSION_1, + "PropertyGetter", + Configurable_Getter, + DetailsDeleter, + DetailsCloner +}; + +static Tcl_MethodType SetterType = { + TCL_OO_METHOD_VERSION_1, + "PropertySetter", + Configurable_Setter, + DetailsDeleter, + DetailsCloner +}; + +void +TclOOImplementObjectProperty( + Tcl_Object targetObject, + Tcl_Obj *propNamePtr, + int installGetter, + int installSetter) +{ + if (installGetter) { + Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_IncrRefCount(methodName); + Tcl_IncrRefCount(propNamePtr); + TclNewInstanceMethod(NULL, targetObject, methodName, 0, &GetterType, propNamePtr); + Tcl_DecrRefCount(methodName); + } + if (installSetter) { + Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_IncrRefCount(methodName); + Tcl_IncrRefCount(propNamePtr); + TclNewInstanceMethod(NULL, targetObject, methodName, 0, &SetterType, propNamePtr); + Tcl_DecrRefCount(methodName); + } +} + +void +TclOOImplementClassProperty( + Tcl_Class targetClass, + Tcl_Obj *propNamePtr, + int installGetter, + int installSetter) +{ + if (installGetter) { + Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_IncrRefCount(methodName); + Tcl_IncrRefCount(propNamePtr); + TclNewMethod(NULL, targetClass, methodName, 0, &GetterType, propNamePtr); + Tcl_DecrRefCount(methodName); + } + if (installSetter) { + Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_IncrRefCount(methodName); + Tcl_IncrRefCount(propNamePtr); + TclNewMethod(NULL, targetClass, methodName, 0, &SetterType, propNamePtr); + Tcl_DecrRefCount(methodName); + } +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index b35cd13..9f1b5fd 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -569,6 +569,12 @@ MODULE_SCOPE size_t TclOOGetSortedClassMethodList(Class *clsPtr, MODULE_SCOPE int TclOOGetSortedMethodList(Object *oPtr, Object *contextObj, Class *contextCls, int flags, const char ***stringsPtr); +MODULE_SCOPE void TclOOImplementObjectProperty(Tcl_Object targetObject, + Tcl_Obj *propNamePtr, int installGetter, + int installSetter); +MODULE_SCOPE void TclOOImplementClassProperty(Tcl_Class targetObject, + Tcl_Obj *propNamePtr, int installGetter, + int installSetter); MODULE_SCOPE int TclOOInit(Tcl_Interp *interp); MODULE_SCOPE void TclOOInitInfo(Tcl_Interp *interp); MODULE_SCOPE int TclOOInvokeContext(void *clientData, diff --git a/generic/tclVar.c b/generic/tclVar.c index 125091a..490c369 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -1277,10 +1277,10 @@ Tcl_Obj * Tcl_ObjGetVar2( Tcl_Interp *interp, /* Command interpreter in which variable is to * be looked up. */ - Tcl_Obj *part1Ptr, /* Points to an object holding the name of an + Tcl_Obj *part1Ptr, /* Points to an object holding the name of an * array (if part2 is non-NULL) or the name of * a variable. */ - Tcl_Obj *part2Ptr, /* If non-null, points to an object holding + Tcl_Obj *part2Ptr, /* If non-null, points to an object holding * the name of an element in the array * part1Ptr. */ int flags) /* OR-ed combination of TCL_GLOBAL_ONLY and @@ -1336,7 +1336,7 @@ TclPtrGetVar( * the name of a variable. */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ - int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and + int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ { if (varPtr == NULL) { @@ -1375,14 +1375,14 @@ Tcl_Obj * TclPtrGetVarIdx( Tcl_Interp *interp, /* Command interpreter in which variable is to * be looked up. */ - Var *varPtr, /* The variable to be read.*/ + Var *varPtr, /* The variable to be read.*/ Var *arrayPtr, /* NULL for scalar variables, pointer to the * containing array otherwise. */ Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or * the name of a variable. */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ - int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and + int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ int index) /* Index into the local variable table of the * variable, or -1. Only used when part1Ptr is @@ -1483,7 +1483,7 @@ TclPtrGetVarIdx( int Tcl_SetObjCmd( TCL_UNUSED(void *), - Tcl_Interp *interp,/* Current interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { -- cgit v0.12 From cb5a0a9107587122d5d90c6eb9b0a03de774d84f Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 28 Jan 2024 19:15:28 +0000 Subject: Property implementation 'definitions', not yet plumbed into documented API --- generic/tclOO.c | 4 + generic/tclOOBasic.c | 12 +- generic/tclOODefineCmds.c | 365 +++++++++++++++++++++++----------------------- generic/tclOOInt.h | 1 + 4 files changed, 191 insertions(+), 191 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 7a57105..7e39858 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -440,6 +440,10 @@ InitFoundation( TclOONewBasicMethod(interp, ((Object *) cfgCls)->classPtr, &cfgMethods[i]); } + Tcl_CreateObjCommand(interp, "::oo::configuresupport::StdObjectProperties", + TclOOInstallStdPropertyImpls, (void *) 1, NULL); + Tcl_CreateObjCommand(interp, "::oo::configuresupport::StdClassProperties", + TclOOInstallStdPropertyImpls, (void *) 0, NULL); /* * Evaluate the remaining definitions, which are a compiled-in Tcl script. diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index f8c9eb5..2b4f220 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -1778,19 +1778,19 @@ static Tcl_MethodType SetterType = { void TclOOImplementObjectProperty( Tcl_Object targetObject, - Tcl_Obj *propNamePtr, + Tcl_Obj *propNamePtr, /* Property name, without leading - */ int installGetter, int installSetter) { if (installGetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); Tcl_IncrRefCount(methodName); Tcl_IncrRefCount(propNamePtr); TclNewInstanceMethod(NULL, targetObject, methodName, 0, &GetterType, propNamePtr); Tcl_DecrRefCount(methodName); } if (installSetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); Tcl_IncrRefCount(methodName); Tcl_IncrRefCount(propNamePtr); TclNewInstanceMethod(NULL, targetObject, methodName, 0, &SetterType, propNamePtr); @@ -1801,19 +1801,19 @@ TclOOImplementObjectProperty( void TclOOImplementClassProperty( Tcl_Class targetClass, - Tcl_Obj *propNamePtr, + Tcl_Obj *propNamePtr, /* Property name, without leading - */ int installGetter, int installSetter) { if (installGetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); Tcl_IncrRefCount(methodName); Tcl_IncrRefCount(propNamePtr); TclNewMethod(NULL, targetClass, methodName, 0, &GetterType, propNamePtr); Tcl_DecrRefCount(methodName); } if (installSetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); Tcl_IncrRefCount(methodName); Tcl_IncrRefCount(propNamePtr); TclNewMethod(NULL, targetClass, methodName, 0, &SetterType, propNamePtr); diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 7112039..3c4bbdd 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -955,6 +955,23 @@ TclOOGetDefineCmdContext( } return object; } + +static Class * +GetClassDefineCmdContext( + Tcl_Interp *interp) +{ + Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + if (oPtr == NULL) { + return NULL; + } + if (!oPtr->classPtr) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "attempt to misuse API", -1)); + Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); + return NULL; + } + return oPtr->classPtr; +} /* * ---------------------------------------------------------------------- @@ -1585,27 +1602,17 @@ TclOODefineConstructorObjCmd( int objc, Tcl_Obj *const *objv) { - Object *oPtr; - Class *clsPtr; + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Method method; Tcl_Size bodyLength; - if (objc != 3) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "arguments body"); return TCL_ERROR; } - /* - * Extract and validate the context, which is the class that we wish to - * modify. - */ - - oPtr = (Object *) TclOOGetDefineCmdContext(interp); - if (oPtr == NULL) { - return TCL_ERROR; - } - clsPtr = oPtr->classPtr; - (void)Tcl_GetStringFromObj(objv[2], &bodyLength); if (bodyLength > 0) { /* @@ -1660,21 +1667,13 @@ TclOODefineDefnNsObjCmd( NULL }; int kind = 0; - Object *oPtr; + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Namespace *nsPtr; Tcl_Obj *nsNamePtr, **storagePtr; - oPtr = (Object *) TclOOGetDefineCmdContext(interp); - if (oPtr == NULL) { - return TCL_ERROR; - } - if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); + if (clsPtr == NULL) { return TCL_ERROR; - } - if (oPtr->flags & (ROOT_OBJECT | ROOT_CLASS)) { + } else if (clsPtr->thisPtr->flags & (ROOT_OBJECT | ROOT_CLASS)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not modify the definition namespace of the root classes", -1)); @@ -1710,9 +1709,9 @@ TclOODefineDefnNsObjCmd( */ if (kind) { - storagePtr = &oPtr->classPtr->objDefinitionNs; + storagePtr = &clsPtr->objDefinitionNs; } else { - storagePtr = &oPtr->classPtr->clsDefinitionNs; + storagePtr = &clsPtr->clsDefinitionNs; } if (*storagePtr != NULL) { Tcl_DecrRefCount(*storagePtr); @@ -1796,21 +1795,17 @@ TclOODefineDestructorObjCmd( int objc, Tcl_Obj *const *objv) { - Object *oPtr; - Class *clsPtr; Tcl_Method method; Tcl_Size bodyLength; + Class *clsPtr = GetClassDefineCmdContext(interp); - if (objc != 2) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "body"); return TCL_ERROR; } - oPtr = (Object *) TclOOGetDefineCmdContext(interp); - if (oPtr == NULL) { - return TCL_ERROR; - } - clsPtr = oPtr->classPtr; (void)Tcl_GetStringFromObj(objv[1], &bodyLength); if (bodyLength > 0) { @@ -2376,26 +2371,20 @@ ClassFilterGet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Obj *resultObj, *filterObj; Tcl_Size i; - if (Tcl_ObjectContextSkippedArgs(context) != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } TclNewObj(resultObj); - FOREACH(filterObj, oPtr->classPtr->filters) { + FOREACH(filterObj, clsPtr->filters) { Tcl_ListObjAppendElement(NULL, resultObj, filterObj); } Tcl_SetObjResult(interp, resultObj); @@ -2410,30 +2399,25 @@ ClassFilterSet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Size filterc; Tcl_Obj **filterv; - if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "filterList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } else if (TclListObjGetElementsM(interp, objv[0], &filterc, + if (TclListObjGetElementsM(interp, objv[0], &filterc, &filterv) != TCL_OK) { return TCL_ERROR; } - TclOOClassSetFilters(interp, oPtr->classPtr, filterc, filterv); + TclOOClassSetFilters(interp, clsPtr, filterc, filterv); return TCL_OK; } @@ -2456,27 +2440,21 @@ ClassMixinGet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Obj *resultObj; Class *mixinPtr; Tcl_Size i; - if (Tcl_ObjectContextSkippedArgs(context) != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } TclNewObj(resultObj); - FOREACH(mixinPtr, oPtr->classPtr->mixins) { + FOREACH(mixinPtr, clsPtr->mixins) { Tcl_ListObjAppendElement(NULL, resultObj, TclOOObjectName(interp, mixinPtr->thisPtr)); } @@ -2493,7 +2471,7 @@ ClassMixinSet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Size mixinc, i; Tcl_Obj **mixinv; Class **mixins; /* The references to the classes to actually @@ -2503,21 +2481,16 @@ ClassMixinSet( * values and keys are always pointers. */ int isNew; - if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "mixinList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } else if (TclListObjGetElementsM(interp, objv[0], &mixinc, + if (TclListObjGetElementsM(interp, objv[0], &mixinc, &mixinv) != TCL_OK) { return TCL_ERROR; } @@ -2539,7 +2512,7 @@ ClassMixinSet( Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS",NULL); goto freeAndError; } - if (TclOOIsReachable(oPtr->classPtr, mixins[i])) { + if (TclOOIsReachable(clsPtr, mixins[i])) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not mix a class into itself", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", (void *)NULL); @@ -2547,7 +2520,7 @@ ClassMixinSet( } } - TclOOClassSetMixins(interp, oPtr->classPtr, mixinc, mixins); + TclOOClassSetMixins(interp, clsPtr, mixinc, mixins); Tcl_DeleteHashTable(&uniqueCheck); TclStackFree(interp, mixins); return TCL_OK; @@ -2577,27 +2550,21 @@ ClassSuperGet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Obj *resultObj; Class *superPtr; Tcl_Size i; - if (Tcl_ObjectContextSkippedArgs(context) != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } TclNewObj(resultObj); - FOREACH(superPtr, oPtr->classPtr->superclasses) { + FOREACH(superPtr, clsPtr->superclasses) { Tcl_ListObjAppendElement(NULL, resultObj, TclOOObjectName(interp, superPtr->thisPtr)); } @@ -2613,27 +2580,23 @@ ClassSuperSet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Size superc, j; Tcl_Size i; Tcl_Obj **superv; Class **superclasses, *superPtr; - if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "superclassList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } else if (oPtr == oPtr->fPtr->objectCls->thisPtr) { + Foundation *fPtr = clsPtr->thisPtr->fPtr; + if (clsPtr == fPtr->objectCls) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not modify the superclass of the root object", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); @@ -2658,10 +2621,10 @@ ClassSuperSet( if (superc == 0) { superclasses = (Class **)Tcl_Realloc(superclasses, sizeof(Class *)); - if (TclOOIsReachable(oPtr->fPtr->classCls, oPtr->classPtr)) { - superclasses[0] = oPtr->fPtr->classCls; + if (TclOOIsReachable(fPtr->classCls, clsPtr)) { + superclasses[0] = fPtr->classCls; } else { - superclasses[0] = oPtr->fPtr->objectCls; + superclasses[0] = fPtr->objectCls; } superc = 1; AddRef(superclasses[0]->thisPtr); @@ -2681,7 +2644,7 @@ ClassSuperSet( goto failedAfterAlloc; } } - if (TclOOIsReachable(oPtr->classPtr, superclasses[i])) { + if (TclOOIsReachable(clsPtr, superclasses[i])) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to form circular dependency graph", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "CIRCULARITY", (void *)NULL); @@ -2709,19 +2672,19 @@ ClassSuperSet( * subclass list. */ - if (oPtr->classPtr->superclasses.num != 0) { - FOREACH(superPtr, oPtr->classPtr->superclasses) { - TclOORemoveFromSubclasses(oPtr->classPtr, superPtr); + if (clsPtr->superclasses.num != 0) { + FOREACH(superPtr, clsPtr->superclasses) { + TclOORemoveFromSubclasses(clsPtr, superPtr); TclOODecrRefCount(superPtr->thisPtr); } - Tcl_Free(oPtr->classPtr->superclasses.list); + Tcl_Free(clsPtr->superclasses.list); } - oPtr->classPtr->superclasses.list = superclasses; - oPtr->classPtr->superclasses.num = superc; - FOREACH(superPtr, oPtr->classPtr->superclasses) { - TclOOAddToSubclasses(oPtr->classPtr, superPtr); + clsPtr->superclasses.list = superclasses; + clsPtr->superclasses.num = superc; + FOREACH(superPtr, clsPtr->superclasses) { + TclOOAddToSubclasses(clsPtr, superPtr); } - BumpGlobalEpoch(interp, oPtr->classPtr); + BumpGlobalEpoch(interp, clsPtr); return TCL_OK; } @@ -2745,35 +2708,29 @@ ClassVarsGet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Obj *resultObj; Tcl_Size i; - if (Tcl_ObjectContextSkippedArgs(context) != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } TclNewObj(resultObj); if (IsPrivateDefine(interp)) { PrivateVariableMapping *privatePtr; - FOREACH_STRUCT(privatePtr, oPtr->classPtr->privateVariables) { + FOREACH_STRUCT(privatePtr, clsPtr->privateVariables) { Tcl_ListObjAppendElement(NULL, resultObj, privatePtr->variableObj); } } else { Tcl_Obj *variableObj; - FOREACH(variableObj, oPtr->classPtr->variables) { + FOREACH(variableObj, clsPtr->variables) { Tcl_ListObjAppendElement(NULL, resultObj, variableObj); } } @@ -2789,26 +2746,21 @@ ClassVarsSet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Size i; Tcl_Size varc; Tcl_Obj **varv; - if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "filterList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } else if (TclListObjGetElementsM(interp, objv[0], &varc, + if (TclListObjGetElementsM(interp, objv[0], &varc, &varv) != TCL_OK) { return TCL_ERROR; } @@ -2833,10 +2785,10 @@ ClassVarsSet( } if (IsPrivateDefine(interp)) { - InstallPrivateVariableMapping(&oPtr->classPtr->privateVariables, - varc, varv, oPtr->classPtr->thisPtr->creationEpoch); + InstallPrivateVariableMapping(&clsPtr->privateVariables, + varc, varv, clsPtr->thisPtr->creationEpoch); } else { - InstallStandardVariableMapping(&oPtr->classPtr->variables, varc, varv); + InstallStandardVariableMapping(&clsPtr->variables, varc, varv); } return TCL_OK; } @@ -3243,26 +3195,20 @@ ClassRPropsGet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Obj *resultObj, *propNameObj; int i; - if (Tcl_ObjectContextSkippedArgs(context) != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } TclNewObj(resultObj); - FOREACH(propNameObj, oPtr->classPtr->properties.readable) { + FOREACH(propNameObj, clsPtr->properties.readable) { Tcl_ListObjAppendElement(NULL, resultObj, propNameObj); } Tcl_SetObjResult(interp, resultObj); @@ -3277,31 +3223,26 @@ ClassRPropsSet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Size varc; Tcl_Obj **varv; - if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "filterList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } else if (Tcl_ListObjGetElements(interp, objv[0], &varc, + if (Tcl_ListObjGetElements(interp, objv[0], &varc, &varv) != TCL_OK) { return TCL_ERROR; } - InstallReadableProps(&oPtr->classPtr->properties, varc, varv); - BumpGlobalEpoch(interp, oPtr->classPtr); + InstallReadableProps(&clsPtr->properties, varc, varv); + BumpGlobalEpoch(interp, clsPtr); return TCL_OK; } @@ -3440,26 +3381,20 @@ ClassWPropsGet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Obj *resultObj, *propNameObj; int i; - if (Tcl_ObjectContextSkippedArgs(context) != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } TclNewObj(resultObj); - FOREACH(propNameObj, oPtr->classPtr->properties.writable) { + FOREACH(propNameObj, clsPtr->properties.writable) { Tcl_ListObjAppendElement(NULL, resultObj, propNameObj); } Tcl_SetObjResult(interp, resultObj); @@ -3474,31 +3409,26 @@ ClassWPropsSet( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + Class *clsPtr = GetClassDefineCmdContext(interp); Tcl_Size varc; Tcl_Obj **varv; - if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { + if (clsPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "propertyList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); - if (oPtr == NULL) { - return TCL_ERROR; - } else if (!oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (void *)NULL); - return TCL_ERROR; - } else if (Tcl_ListObjGetElements(interp, objv[0], &varc, + if (Tcl_ListObjGetElements(interp, objv[0], &varc, &varv) != TCL_OK) { return TCL_ERROR; } - InstallWritableProps(&oPtr->classPtr->properties, varc, varv); - BumpGlobalEpoch(interp, oPtr->classPtr); + InstallWritableProps(&clsPtr->properties, varc, varv); + BumpGlobalEpoch(interp, clsPtr); return TCL_OK; } @@ -3561,6 +3491,71 @@ ObjWPropsSet( return TCL_OK; } +int +TclOOInstallStdPropertyImpls( + void *useInstance, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const *objv) +{ + int readable, writable; + Tcl_Obj *propName; + const char *name, *reason; + Tcl_Size len; + char flag = TCL_DONT_QUOTE_HASH; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "propName readable writable"); + return TCL_ERROR; + } + propName = objv[1]; + name = Tcl_GetStringFromObj(propName, &len); + if (Tcl_StringMatch("-*", name)) { + reason = "must not begin with -"; + goto badProp; + } + if (TclScanElement(name, len, &flag) != len) { + reason = "must be a simple word"; + goto badProp; + } + if (Tcl_StringMatch("*::*", name)) { + reason = "must not contain namespace separators"; + goto badProp; + } + if (Tcl_StringMatch("*[()]*", name)) { + reason = "must not contain parentheses"; + goto badProp; + } + if (Tcl_GetBooleanFromObj(interp, objv[2], &readable) != TCL_OK) { + return TCL_ERROR; + } + if (Tcl_GetBooleanFromObj(interp, objv[3], &writable) != TCL_OK) { + return TCL_ERROR; + } + + if (useInstance) { + Tcl_Object object = TclOOGetDefineCmdContext(interp); + if (!object) { + return TCL_ERROR; + } + TclOOImplementObjectProperty(object, propName, readable, writable); + } else { + Tcl_Class cls = (Tcl_Class) GetClassDefineCmdContext(interp); + if (!cls) { + return TCL_ERROR; + } + TclOOImplementClassProperty(cls, propName, readable, writable); + } + return TCL_OK; + + badProp: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad property name \"%s\": %s", name, reason)); + Tcl_SetErrorCode(interp, "TCLOO", "PROPERTY_FORMAT", NULL); + return TCL_ERROR; +} + + /* * Local Variables: * mode: c diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index 9f1b5fd..f4d1b45 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -488,6 +488,7 @@ MODULE_SCOPE Tcl_ObjCmdProc TclOODefineClassObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineSelfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineObjSelfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefinePrivateObjCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclOOInstallStdPropertyImpls; MODULE_SCOPE Tcl_ObjCmdProc TclOOUnknownDefinition; MODULE_SCOPE Tcl_ObjCmdProc TclOOCopyObjectCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOONextObjCmd; -- cgit v0.12 From 4c5e0a69a96b5d587173bcc6c8ebfbc333ed9e8a Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 28 Jan 2024 21:56:08 +0000 Subject: Plug implementation in... and fix the silly bugs --- generic/tclOODefineCmds.c | 6 +++--- generic/tclOOScript.h | 45 +++++++++++++++++-------------------------- tools/makeHeader.tcl | 1 + tools/tclOOScript.tcl | 49 +++++++++++++++++++---------------------------- 4 files changed, 42 insertions(+), 59 deletions(-) diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 3c4bbdd..86503c6 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -3510,7 +3510,7 @@ TclOOInstallStdPropertyImpls( } propName = objv[1]; name = Tcl_GetStringFromObj(propName, &len); - if (Tcl_StringMatch("-*", name)) { + if (Tcl_StringMatch(name, "-*")) { reason = "must not begin with -"; goto badProp; } @@ -3518,11 +3518,11 @@ TclOOInstallStdPropertyImpls( reason = "must be a simple word"; goto badProp; } - if (Tcl_StringMatch("*::*", name)) { + if (Tcl_StringMatch(name, "*::*")) { reason = "must not contain namespace separators"; goto badProp; } - if (Tcl_StringMatch("*[()]*", name)) { + if (Tcl_StringMatch(name, "*[()]*")) { reason = "must not contain parentheses"; goto badProp; } diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 1903b49..c6a60a6 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -260,32 +260,11 @@ static const char *tclOOSetupScript = "\t}\n" "\t::namespace eval configuresupport {\n" "\t\tnamespace path ::tcl\n" -"\t\tproc PropertyImpl {readslot writeslot args} {\n" +"\t\tproc PropertyImpl {stdInstaller readslot writeslot args} {\n" "\t\t\tfor {set i 0} {$i < [llength $args]} {incr i} {\n" "\t\t\t\tset prop [lindex $args $i]\n" -"\t\t\t\tif {[string match \"-*\" $prop]} {\n" -"\t\t\t\t\treturn -code error -level 2 \\\n" -"\t\t\t\t\t\t-errorcode {TCLOO PROPERTY_FORMAT} \\\n" -"\t\t\t\t\t\t\"bad property name \\\"$prop\\\": must not begin with -\"\n" -"\t\t\t\t}\n" -"\t\t\t\tif {$prop ne [list $prop]} {\n" -"\t\t\t\t\treturn -code error -level 2 \\\n" -"\t\t\t\t\t\t-errorcode {TCLOO PROPERTY_FORMAT} \\\n" -"\t\t\t\t\t\t\"bad property name \\\"$prop\\\": must be a simple word\"\n" -"\t\t\t\t}\n" -"\t\t\t\tif {[string first \"::\" $prop] != -1} {\n" -"\t\t\t\t\treturn -code error -level 2 \\\n" -"\t\t\t\t\t\t-errorcode {TCLOO PROPERTY_FORMAT} \\\n" -"\t\t\t\t\t\t\"bad property name \\\"$prop\\\": must not contain namespace separators\"\n" -"\t\t\t\t}\n" -"\t\t\t\tif {[string match {*[()]*} $prop]} {\n" -"\t\t\t\t\treturn -code error -level 2 \\\n" -"\t\t\t\t\t\t-errorcode {TCLOO PROPERTY_FORMAT} \\\n" -"\t\t\t\t\t\t\"bad property name \\\"$prop\\\": must not contain parentheses\"\n" -"\t\t\t\t}\n" "\t\t\t\tset realprop [string cat \"-\" $prop]\n" -"\t\t\t\tset getter [format {::set [my varname %s]} $prop]\n" -"\t\t\t\tset setter [format {::set [my varname %s] $value} $prop]\n" +"\t\t\t\tunset -nocomplain getter setter\n" "\t\t\t\tset kind readwrite\n" "\t\t\t\twhile {[set next [lindex $args [expr {$i + 1}]]\n" "\t\t\t\t\t\tstring match \"-*\" $next]} {\n" @@ -324,29 +303,40 @@ static const char *tclOOSetupScript = "\t\t\t\t}\n" "\t\t\t\tset reader \n" "\t\t\t\tset writer \n" +"\t\t\t\tset addReader [expr {$kind ne \"writable\" && ![info exist getter]}]\n" +"\t\t\t\tset addWriter [expr {$kind ne \"readable\" && ![info exist setter]}]\n" +"\t\t\t\ttry {\n" +"\t\t\t\t\tuplevel 2 [list $stdInstaller $prop $addReader $addWriter]\n" +"\t\t\t\t} on error {msg opt} {\n" +"\t\t\t\t\treturn -code error -level 2 \\\n" +"\t\t\t\t\t\t\t-errorcode [dict get $opt -errorcode] $msg\n" +"\t\t\t\t}\n" "\t\t\t\tswitch $kind {\n" "\t\t\t\t\treadable {\n" "\t\t\t\t\t\tuplevel 2 [list $readslot -append $realprop]\n" "\t\t\t\t\t\tuplevel 2 [list $writeslot -remove $realprop]\n" -"\t\t\t\t\t\tuplevel 2 [list method $reader -unexport {} $getter]\n" "\t\t\t\t\t}\n" "\t\t\t\t\twritable {\n" "\t\t\t\t\t\tuplevel 2 [list $readslot -remove $realprop]\n" "\t\t\t\t\t\tuplevel 2 [list $writeslot -append $realprop]\n" -"\t\t\t\t\t\tuplevel 2 [list method $writer -unexport {value} $setter]\n" "\t\t\t\t\t}\n" "\t\t\t\t\treadwrite {\n" "\t\t\t\t\t\tuplevel 2 [list $readslot -append $realprop]\n" "\t\t\t\t\t\tuplevel 2 [list $writeslot -append $realprop]\n" -"\t\t\t\t\t\tuplevel 2 [list method $reader -unexport {} $getter]\n" -"\t\t\t\t\t\tuplevel 2 [list method $writer -unexport {value} $setter]\n" "\t\t\t\t\t}\n" "\t\t\t\t}\n" +"\t\t\t\tif {[info exist getter]} {\n" +"\t\t\t\t\tuplevel 2 [list method $reader -unexport {} $getter]\n" +"\t\t\t\t}\n" +"\t\t\t\tif {[info exist setter]} {\n" +"\t\t\t\t\tuplevel 2 [list method $writer -unexport {value} $setter]\n" +"\t\t\t\t}\n" "\t\t\t}\n" "\t\t}\n" "\t\tnamespace eval configurableclass {\n" "\t\t\t::proc property args {\n" "\t\t\t\t::oo::configuresupport::PropertyImpl \\\n" +"\t\t\t\t\t::oo::configuresupport::StdClassProperties \\\n" "\t\t\t\t\t::oo::configuresupport::readableproperties \\\n" "\t\t\t\t\t::oo::configuresupport::writableproperties {*}$args\n" "\t\t\t}\n" @@ -357,6 +347,7 @@ static const char *tclOOSetupScript = "\t\tnamespace eval configurableobject {\n" "\t\t\t::proc property args {\n" "\t\t\t\t::oo::configuresupport::PropertyImpl \\\n" +"\t\t\t\t\t::oo::configuresupport::StdObjectProperties \\\n" "\t\t\t\t\t::oo::configuresupport::objreadableproperties \\\n" "\t\t\t\t\t::oo::configuresupport::objwritableproperties {*}$args\n" "\t\t\t}\n" diff --git a/tools/makeHeader.tcl b/tools/makeHeader.tcl index 17526e0..e20e336 100644 --- a/tools/makeHeader.tcl +++ b/tools/makeHeader.tcl @@ -108,6 +108,7 @@ namespace eval makeHeader { proc updateTemplateFile {headerFile scriptLines} { set f [open $headerFile "r+"] try { + chan configure $f -translation {auto lf} set content [split [chan read -nonewline $f] "\n"] updateTemplate content [stripSurround $scriptLines] chan seek $f 0 diff --git a/tools/tclOOScript.tcl b/tools/tclOOScript.tcl index 2843dff..cbceb39 100644 --- a/tools/tclOOScript.tcl +++ b/tools/tclOOScript.tcl @@ -486,36 +486,15 @@ # # ------------------------------------------------------------------ - proc PropertyImpl {readslot writeslot args} { + proc PropertyImpl {stdInstaller readslot writeslot args} { for {set i 0} {$i < [llength $args]} {incr i} { # Parse the property name set prop [lindex $args $i] - if {[string match "-*" $prop]} { - return -code error -level 2 \ - -errorcode {TCLOO PROPERTY_FORMAT} \ - "bad property name \"$prop\": must not begin with -" - } - if {$prop ne [list $prop]} { - return -code error -level 2 \ - -errorcode {TCLOO PROPERTY_FORMAT} \ - "bad property name \"$prop\": must be a simple word" - } - if {[string first "::" $prop] != -1} { - return -code error -level 2 \ - -errorcode {TCLOO PROPERTY_FORMAT} \ - "bad property name \"$prop\": must not contain namespace separators" - } - if {[string match {*[()]*} $prop]} { - return -code error -level 2 \ - -errorcode {TCLOO PROPERTY_FORMAT} \ - "bad property name \"$prop\": must not contain parentheses" - } set realprop [string cat "-" $prop] - set getter [format {::set [my varname %s]} $prop] - set setter [format {::set [my varname %s] $value} $prop] + unset -nocomplain getter setter set kind readwrite - # Parse the extra options + # Parse the extra options for the property while {[set next [lindex $args [expr {$i + 1}]] string match "-*" $next]} { set arg [lindex $args [incr i 2]] @@ -552,27 +531,37 @@ } } - # Install the option + # Install the property set reader set writer + set addReader [expr {$kind ne "writable" && ![info exist getter]}] + set addWriter [expr {$kind ne "readable" && ![info exist setter]}] + try { + uplevel 2 [list $stdInstaller $prop $addReader $addWriter] + } on error {msg opt} { + return -code error -level 2 \ + -errorcode [dict get $opt -errorcode] $msg + } switch $kind { readable { uplevel 2 [list $readslot -append $realprop] uplevel 2 [list $writeslot -remove $realprop] - uplevel 2 [list method $reader -unexport {} $getter] } writable { uplevel 2 [list $readslot -remove $realprop] uplevel 2 [list $writeslot -append $realprop] - uplevel 2 [list method $writer -unexport {value} $setter] } readwrite { uplevel 2 [list $readslot -append $realprop] uplevel 2 [list $writeslot -append $realprop] - uplevel 2 [list method $reader -unexport {} $getter] - uplevel 2 [list method $writer -unexport {value} $setter] } } + if {[info exist getter]} { + uplevel 2 [list method $reader -unexport {} $getter] + } + if {[info exist setter]} { + uplevel 2 [list method $writer -unexport {value} $setter] + } } } @@ -589,6 +578,7 @@ namespace eval configurableclass { ::proc property args { ::oo::configuresupport::PropertyImpl \ + ::oo::configuresupport::StdClassProperties \ ::oo::configuresupport::readableproperties \ ::oo::configuresupport::writableproperties {*}$args } @@ -601,6 +591,7 @@ namespace eval configurableobject { ::proc property args { ::oo::configuresupport::PropertyImpl \ + ::oo::configuresupport::StdObjectProperties \ ::oo::configuresupport::objreadableproperties \ ::oo::configuresupport::objwritableproperties {*}$args } -- cgit v0.12 From 318bf8e4a833d34867c9287cb70d009c4051f3a9 Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 29 Jan 2024 20:48:15 +0000 Subject: Add doc comments --- generic/tclOOBasic.c | 48 +++++++++++++++++++++++++++++------------------ generic/tclOODefineCmds.c | 28 ++++++++++++++++++++++++++- generic/tclOOInt.h | 2 +- 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 2b4f220..2732036 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -1777,46 +1777,58 @@ static Tcl_MethodType SetterType = { void TclOOImplementObjectProperty( - Tcl_Object targetObject, + Tcl_Object targetObject, /* What to install into. */ Tcl_Obj *propNamePtr, /* Property name, without leading - */ - int installGetter, - int installSetter) + int installGetter, /* Whether to install a standard getter. */ + int installSetter) /* Whether to install a standard setter. */ { if (installGetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf( + "", TclGetString(propNamePtr)); + // Don't know if TclNewInstanceMethod will retain a ref to the method name Tcl_IncrRefCount(methodName); - Tcl_IncrRefCount(propNamePtr); - TclNewInstanceMethod(NULL, targetObject, methodName, 0, &GetterType, propNamePtr); + Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter + TclNewInstanceMethod( + NULL, targetObject, methodName, 0, &GetterType, propNamePtr); Tcl_DecrRefCount(methodName); } if (installSetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf( + "", TclGetString(propNamePtr)); + // Don't know if TclNewInstanceMethod will retain a ref to the method name Tcl_IncrRefCount(methodName); - Tcl_IncrRefCount(propNamePtr); - TclNewInstanceMethod(NULL, targetObject, methodName, 0, &SetterType, propNamePtr); + Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter + TclNewInstanceMethod( + NULL, targetObject, methodName, 0, &SetterType, propNamePtr); Tcl_DecrRefCount(methodName); } } void TclOOImplementClassProperty( - Tcl_Class targetClass, + Tcl_Class targetClass, /* What to install into. */ Tcl_Obj *propNamePtr, /* Property name, without leading - */ - int installGetter, - int installSetter) + int installGetter, /* Whether to install a standard getter. */ + int installSetter) /* Whether to install a standard setter. */ { if (installGetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf( + "", TclGetString(propNamePtr)); + // Don't know if TclNewMethod will retain a ref to the method name Tcl_IncrRefCount(methodName); - Tcl_IncrRefCount(propNamePtr); - TclNewMethod(NULL, targetClass, methodName, 0, &GetterType, propNamePtr); + Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter + TclNewMethod( + NULL, targetClass, methodName, 0, &GetterType, propNamePtr); Tcl_DecrRefCount(methodName); } if (installSetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf("", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf( + "", TclGetString(propNamePtr)); + // Don't know if TclNewMethod will retain a ref to the method name Tcl_IncrRefCount(methodName); - Tcl_IncrRefCount(propNamePtr); - TclNewMethod(NULL, targetClass, methodName, 0, &SetterType, propNamePtr); + Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter + TclNewMethod( + NULL, targetClass, methodName, 0, &SetterType, propNamePtr); Tcl_DecrRefCount(methodName); } } diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 86503c6..1ab099f 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -3491,6 +3491,21 @@ ObjWPropsSet( return TCL_OK; } +/* + * ---------------------------------------------------------------------- + * + * TclOOInstallStdPropertyImpls -- + * + * Implementations of the "StdClassProperties" hidden definition for + * classes and the "StdObjectProperties" hidden definition for + * instances. Both are located in the ::oo::configuresupport namespace. + * + * Validates a (dashless) property name, and installs implementation + * methods if asked to do so (readable and writable flags). + * + * ---------------------------------------------------------------------- + */ + int TclOOInstallStdPropertyImpls( void *useInstance, @@ -3504,6 +3519,14 @@ TclOOInstallStdPropertyImpls( Tcl_Size len; char flag = TCL_DONT_QUOTE_HASH; + /* + * Parse the arguments and validate the property name. Note that just + * calling TclScanElement() is cheaper than actually formatting a list + * and comparing the string version of that with the original, as + * TclScanElement() is one of the core parts of doing that; this skips + * a whole load of irrelevant memory allocations! + */ + if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "propName readable writable"); return TCL_ERROR; @@ -3533,6 +3556,10 @@ TclOOInstallStdPropertyImpls( return TCL_ERROR; } + /* + * Install the implementations... if asked to do so. + */ + if (useInstance) { Tcl_Object object = TclOOGetDefineCmdContext(interp); if (!object) { @@ -3554,7 +3581,6 @@ TclOOInstallStdPropertyImpls( Tcl_SetErrorCode(interp, "TCLOO", "PROPERTY_FORMAT", NULL); return TCL_ERROR; } - /* * Local Variables: diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index f4d1b45..d0f9858 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -47,7 +47,7 @@ typedef struct Method { * special flag record which is just used for * the setting of the flags field. */ Tcl_Size refCount; - void *clientData; /* Type-specific data. */ + void *clientData; /* Type-specific data. */ Tcl_Obj *namePtr; /* Name of the method. */ struct Object *declaringObjectPtr; /* The object that declares this method, or -- cgit v0.12 From 3389b582e203479619e667d55c99b74f1bb1942e Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 23 May 2024 13:18:18 +0000 Subject: [154f0982f2] Update createWithNamespace to error on namespace creation failure --- generic/tclOO.c | 20 ++++++++++++++++---- tests/oo.test | 13 +++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 86c4087..1580abd 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -610,6 +610,10 @@ KillFoundation( * call TclOOAddToSubclasses() to add it to the right class's list of * subclasses. * + * Returns: + * Pointer to the object structure created, or NULL if a specific + * namespace was asked for but couldn't be created. + * * ---------------------------------------------------------------------- */ @@ -652,11 +656,16 @@ AllocObject( if (nsNameStr != NULL) { oPtr->namespacePtr = Tcl_CreateNamespace(interp, nsNameStr, oPtr, NULL); - if (oPtr->namespacePtr != NULL) { - creationEpoch = ++fPtr->tsdPtr->nsCount; - goto configNamespace; + if (oPtr->namespacePtr == NULL) { + /* + * Couldn't make the specific namespace. Report as an error. + * [Bug 154f0982f2] + */ + ckfree(oPtr); + return NULL; } - Tcl_ResetResult(interp); + creationEpoch = ++fPtr->tsdPtr->nsCount; + goto configNamespace; } while (1) { @@ -1783,6 +1792,9 @@ TclNewObjectInstanceCommon( */ oPtr = AllocObject(interp, simpleName, nsPtr, nsNameStr); + if (oPtr == NULL) { + return NULL; + } oPtr->selfCls = classPtr; AddRef(classPtr->thisPtr); TclOOAddToInstances(oPtr, classPtr); diff --git a/tests/oo.test b/tests/oo.test index 366f4d3..c940011 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -1685,6 +1685,19 @@ test oo-11.6.4 { rename obj1 {} } +test oo-11.7 {Bug 154f0982f2: createWithNamespace and an existing namespace} -setup { + oo::class create Aclass { + self export createWithNamespace + method ns {} {namespace current} + } +} -body { + namespace eval test_oo117 {variable name [namespace current]} + list [Aclass createWithNamespace aInstance $test_oo117::name] [aInstance ns] +} -returnCodes error -cleanup { + Aclass destroy + catch {namespace delete test_oo117} +} -result {can't create namespace "::test_oo117": already exists} + test oo-12.1 {OO: filters} { oo::class create Aclass Aclass create Aobject -- cgit v0.12 From 351ab9f3bf86ea2d971416a759964c836e91c1b9 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 23 May 2024 13:21:45 +0000 Subject: Clarify docs --- doc/class.n | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/class.n b/doc/class.n index 198ae41..b68af5d 100644 --- a/doc/class.n +++ b/doc/class.n @@ -83,8 +83,11 @@ resolved within the calling context's namespace if not fully qualified), passing the arguments, \fIarg ...\fR, to the constructor, and (if that returns a successful result) returning the fully qualified name of the created object (the result of the constructor is ignored). The name of the instance's -internal namespace will be \fInsName\fR unless that namespace already exists -(when an arbitrary name will be chosen instead). If the constructor fails +internal namespace will be \fInsName\fR; +.VS +it is an error if that namespace cannot be created. +.VE +If the constructor fails (i.e., returns a non-OK result) then the object is destroyed and the error message is the result of this method call. .SH EXAMPLES -- cgit v0.12 From e4b60844a84cdb26d69254221e8f861c0fff9441 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 18 Jul 2024 15:38:06 +0000 Subject: Fix small bug --- generic/tclOOBasic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 9ab801b..34cc272 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -858,7 +858,7 @@ TclOO_Object_VarName( /* * The variable reference must not disappear too soon. [Bug 74b6110204] */ - TclSetVarNamespaceVar(varPtr); + TclSetVarNamespaceVar((Var *) varPtr); /* * Now that we've pinned down what variable we're really talking about -- cgit v0.12 From 45c7196b90df84956d42085872cf90da5231ff40 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 18 Jul 2024 15:43:48 +0000 Subject: Correction to error code --- generic/tclOODefineCmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 77835e9..9e4f879 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -3571,7 +3571,7 @@ TclOOInstallStdPropertyImpls( badProp: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad property name \"%s\": %s", name, reason)); - Tcl_SetErrorCode(interp, "TCLOO", "PROPERTY_FORMAT", NULL); + Tcl_SetErrorCode(interp, "TCL", "OO", "PROPERTY_FORMAT", NULL); return TCL_ERROR; } -- cgit v0.12 From ca664dbbb7df6849b3d9740658055c42a32438ce Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 18 Jul 2024 16:03:53 +0000 Subject: Improve some comments --- tools/tclOOScript.tcl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/tclOOScript.tcl b/tools/tclOOScript.tcl index 6b44ba7..3e80981 100644 --- a/tools/tclOOScript.tcl +++ b/tools/tclOOScript.tcl @@ -480,9 +480,16 @@ # ------------------------------------------------------------------ # - # oo::configuresupport -- + # oo::configuresupport::PropertyImpl -- # - # A metaclass that is used to make classes that can be configured. + # The implementation of the [property] configuration command. + # This assumes there are two stack frames above it to care about, + # first the hull [property] command (in the correct context for + # what is being confgured) and then the context scope of + # [oo::define] or [oo::objdefine]. + # + # TODO: + # Convert to C code. # # ------------------------------------------------------------------ -- cgit v0.12 From 02624d13497c5ea225dff6ed4aa62ed8a56c69f9 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 19 Jul 2024 08:52:07 +0000 Subject: Slightly simpler script --- generic/tclOOScript.h | 44 ++++++++++++++++++++++---------------------- tools/tclOOScript.tcl | 44 ++++++++++++++++++++++---------------------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 374c11d..7538d48 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -269,11 +269,11 @@ static const char *tclOOSetupScript = "\t\t\t\twhile {[set next [lindex $args [expr {$i + 1}]]\n" "\t\t\t\t\t\tstring match \"-*\" $next]} {\n" "\t\t\t\t\tset arg [lindex $args [incr i 2]]\n" -"\t\t\t\t\tswitch [prefix match -error [list -level 2 -errorcode \\\n" +"\t\t\t\t\tswitch [prefix match -error [list -level 1 -errorcode \\\n" "\t\t\t\t\t\t\t[list TCL LOOKUP INDEX option $next]] {-get -kind -set} $next] {\n" "\t\t\t\t\t\t-get {\n" "\t\t\t\t\t\t\tif {$i >= [llength $args]} {\n" -"\t\t\t\t\t\t\t\treturn -code error -level 2 \\\n" +"\t\t\t\t\t\t\t\treturn -code error -level 1 \\\n" "\t\t\t\t\t\t\t\t\t-errorcode {TCL WRONGARGS} \\\n" "\t\t\t\t\t\t\t\t\t\"missing body to go with -get option\"\n" "\t\t\t\t\t\t\t}\n" @@ -281,7 +281,7 @@ static const char *tclOOSetupScript = "\t\t\t\t\t\t}\n" "\t\t\t\t\t\t-set {\n" "\t\t\t\t\t\t\tif {$i >= [llength $args]} {\n" -"\t\t\t\t\t\t\t\treturn -code error -level 2 \\\n" +"\t\t\t\t\t\t\t\treturn -code error -level 1 \\\n" "\t\t\t\t\t\t\t\t\t-errorcode {TCL WRONGARGS} \\\n" "\t\t\t\t\t\t\t\t\t\"missing body to go with -set option\"\n" "\t\t\t\t\t\t\t}\n" @@ -289,7 +289,7 @@ static const char *tclOOSetupScript = "\t\t\t\t\t\t}\n" "\t\t\t\t\t\t-kind {\n" "\t\t\t\t\t\t\tif {$i >= [llength $args]} {\n" -"\t\t\t\t\t\t\t\treturn -code error -level 2\\\n" +"\t\t\t\t\t\t\t\treturn -code error -level 1 \\\n" "\t\t\t\t\t\t\t\t\t-errorcode {TCL WRONGARGS} \\\n" "\t\t\t\t\t\t\t\t\t\"missing kind value to go with -kind option\"\n" "\t\t\t\t\t\t\t}\n" @@ -306,51 +306,51 @@ static const char *tclOOSetupScript = "\t\t\t\tset addReader [expr {$kind ne \"writable\" && ![info exist getter]}]\n" "\t\t\t\tset addWriter [expr {$kind ne \"readable\" && ![info exist setter]}]\n" "\t\t\t\ttry {\n" -"\t\t\t\t\tuplevel 2 [list $stdInstaller $prop $addReader $addWriter]\n" +"\t\t\t\t\tuplevel 1 [list $stdInstaller $prop $addReader $addWriter]\n" "\t\t\t\t} on error {msg opt} {\n" -"\t\t\t\t\treturn -code error -level 2 \\\n" +"\t\t\t\t\treturn -code error -level 1 \\\n" "\t\t\t\t\t\t\t-errorcode [dict get $opt -errorcode] $msg\n" "\t\t\t\t}\n" "\t\t\t\tswitch $kind {\n" "\t\t\t\t\treadable {\n" -"\t\t\t\t\t\tuplevel 2 [list $readslot -append $realprop]\n" -"\t\t\t\t\t\tuplevel 2 [list $writeslot -remove $realprop]\n" +"\t\t\t\t\t\tuplevel 1 [list $readslot -append $realprop]\n" +"\t\t\t\t\t\tuplevel 1 [list $writeslot -remove $realprop]\n" "\t\t\t\t\t}\n" "\t\t\t\t\twritable {\n" -"\t\t\t\t\t\tuplevel 2 [list $readslot -remove $realprop]\n" -"\t\t\t\t\t\tuplevel 2 [list $writeslot -append $realprop]\n" +"\t\t\t\t\t\tuplevel 1 [list $readslot -remove $realprop]\n" +"\t\t\t\t\t\tuplevel 1 [list $writeslot -append $realprop]\n" "\t\t\t\t\t}\n" "\t\t\t\t\treadwrite {\n" -"\t\t\t\t\t\tuplevel 2 [list $readslot -append $realprop]\n" -"\t\t\t\t\t\tuplevel 2 [list $writeslot -append $realprop]\n" +"\t\t\t\t\t\tuplevel 1 [list $readslot -append $realprop]\n" +"\t\t\t\t\t\tuplevel 1 [list $writeslot -append $realprop]\n" "\t\t\t\t\t}\n" "\t\t\t\t}\n" "\t\t\t\tif {[info exist getter]} {\n" -"\t\t\t\t\tuplevel 2 [list method $reader -unexport {} $getter]\n" +"\t\t\t\t\tuplevel 1 [list method $reader -unexport {} $getter]\n" "\t\t\t\t}\n" "\t\t\t\tif {[info exist setter]} {\n" -"\t\t\t\t\tuplevel 2 [list method $writer -unexport {value} $setter]\n" +"\t\t\t\t\tuplevel 1 [list method $writer -unexport {value} $setter]\n" "\t\t\t\t}\n" "\t\t\t}\n" "\t\t}\n" "\t\tnamespace eval configurableclass {\n" -"\t\t\t::proc property args {\n" -"\t\t\t\t::oo::configuresupport::PropertyImpl \\\n" +"\t\t\t::interp alias \\\n" +"\t\t\t\t\t{} ::oo::configuresupport::configurableclass::property {} \\\n" +"\t\t\t\t\t::oo::configuresupport::PropertyImpl \\\n" "\t\t\t\t\t::oo::configuresupport::StdClassProperties \\\n" "\t\t\t\t\t::oo::configuresupport::readableproperties \\\n" -"\t\t\t\t\t::oo::configuresupport::writableproperties {*}$args\n" -"\t\t\t}\n" +"\t\t\t\t\t::oo::configuresupport::writableproperties\n" "\t\t\t::proc properties args {::tailcall property {*}$args}\n" "\t\t\t::namespace path ::oo::define\n" "\t\t\t::namespace export property\n" "\t\t}\n" "\t\tnamespace eval configurableobject {\n" -"\t\t\t::proc property args {\n" -"\t\t\t\t::oo::configuresupport::PropertyImpl \\\n" +"\t\t\t::interp alias \\\n" +"\t\t\t\t\t{} ::oo::configuresupport::configurableobject::property {} \\\n" +"\t\t\t\t\t::oo::configuresupport::PropertyImpl \\\n" "\t\t\t\t\t::oo::configuresupport::StdObjectProperties \\\n" "\t\t\t\t\t::oo::configuresupport::objreadableproperties \\\n" -"\t\t\t\t\t::oo::configuresupport::objwritableproperties {*}$args\n" -"\t\t\t}\n" +"\t\t\t\t\t::oo::configuresupport::objwritableproperties\n" "\t\t\t::proc properties args {::tailcall property {*}$args}\n" "\t\t\t::namespace path ::oo::objdefine\n" "\t\t\t::namespace export property\n" diff --git a/tools/tclOOScript.tcl b/tools/tclOOScript.tcl index 3e80981..95ffbde 100644 --- a/tools/tclOOScript.tcl +++ b/tools/tclOOScript.tcl @@ -505,11 +505,11 @@ while {[set next [lindex $args [expr {$i + 1}]] string match "-*" $next]} { set arg [lindex $args [incr i 2]] - switch [prefix match -error [list -level 2 -errorcode \ + switch [prefix match -error [list -level 1 -errorcode \ [list TCL LOOKUP INDEX option $next]] {-get -kind -set} $next] { -get { if {$i >= [llength $args]} { - return -code error -level 2 \ + return -code error -level 1 \ -errorcode {TCL WRONGARGS} \ "missing body to go with -get option" } @@ -517,7 +517,7 @@ } -set { if {$i >= [llength $args]} { - return -code error -level 2 \ + return -code error -level 1 \ -errorcode {TCL WRONGARGS} \ "missing body to go with -set option" } @@ -525,7 +525,7 @@ } -kind { if {$i >= [llength $args]} { - return -code error -level 2\ + return -code error -level 1 \ -errorcode {TCL WRONGARGS} \ "missing kind value to go with -kind option" } @@ -544,30 +544,30 @@ set addReader [expr {$kind ne "writable" && ![info exist getter]}] set addWriter [expr {$kind ne "readable" && ![info exist setter]}] try { - uplevel 2 [list $stdInstaller $prop $addReader $addWriter] + uplevel 1 [list $stdInstaller $prop $addReader $addWriter] } on error {msg opt} { - return -code error -level 2 \ + return -code error -level 1 \ -errorcode [dict get $opt -errorcode] $msg } switch $kind { readable { - uplevel 2 [list $readslot -append $realprop] - uplevel 2 [list $writeslot -remove $realprop] + uplevel 1 [list $readslot -append $realprop] + uplevel 1 [list $writeslot -remove $realprop] } writable { - uplevel 2 [list $readslot -remove $realprop] - uplevel 2 [list $writeslot -append $realprop] + uplevel 1 [list $readslot -remove $realprop] + uplevel 1 [list $writeslot -append $realprop] } readwrite { - uplevel 2 [list $readslot -append $realprop] - uplevel 2 [list $writeslot -append $realprop] + uplevel 1 [list $readslot -append $realprop] + uplevel 1 [list $writeslot -append $realprop] } } if {[info exist getter]} { - uplevel 2 [list method $reader -unexport {} $getter] + uplevel 1 [list method $reader -unexport {} $getter] } if {[info exist setter]} { - uplevel 2 [list method $writer -unexport {value} $setter] + uplevel 1 [list method $writer -unexport {value} $setter] } } } @@ -583,12 +583,12 @@ # ------------------------------------------------------------------ namespace eval configurableclass { - ::proc property args { - ::oo::configuresupport::PropertyImpl \ + ::interp alias \ + {} ::oo::configuresupport::configurableclass::property {} \ + ::oo::configuresupport::PropertyImpl \ ::oo::configuresupport::StdClassProperties \ ::oo::configuresupport::readableproperties \ - ::oo::configuresupport::writableproperties {*}$args - } + ::oo::configuresupport::writableproperties # Plural alias just in case; deliberately NOT documented! ::proc properties args {::tailcall property {*}$args} ::namespace path ::oo::define @@ -596,12 +596,12 @@ } namespace eval configurableobject { - ::proc property args { - ::oo::configuresupport::PropertyImpl \ + ::interp alias \ + {} ::oo::configuresupport::configurableobject::property {} \ + ::oo::configuresupport::PropertyImpl \ ::oo::configuresupport::StdObjectProperties \ ::oo::configuresupport::objreadableproperties \ - ::oo::configuresupport::objwritableproperties {*}$args - } + ::oo::configuresupport::objwritableproperties # Plural alias just in case; deliberately NOT documented! ::proc properties args {::tailcall property {*}$args} ::namespace path ::oo::objdefine -- cgit v0.12 From 50b2e426aad22f02d31e592e0ae71ad73b662d8f Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 19 Jul 2024 09:03:26 +0000 Subject: Improve some documentation (for myself) --- tools/tclOOScript.tcl | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/tools/tclOOScript.tcl b/tools/tclOOScript.tcl index 95ffbde..22f0e91 100644 --- a/tools/tclOOScript.tcl +++ b/tools/tclOOScript.tcl @@ -483,14 +483,40 @@ # oo::configuresupport::PropertyImpl -- # # The implementation of the [property] configuration command. - # This assumes there are two stack frames above it to care about, - # first the hull [property] command (in the correct context for - # what is being confgured) and then the context scope of - # [oo::define] or [oo::objdefine]. + # This assumes there is a context scope of [oo::define] or + # [oo::objdefine] as the stack frame that is up one level. # # TODO: # Convert to C code. # + # Arguments: + # stdInstaller + # How to install a property implementation of the right type. + # Must be evaluated in the definition scope. + # readslot + # Slot of readable properties. + # Must be evaluated in the definition scope. + # writeslot + # Slot of writable properties. + # Must be evaluated in the definition scope. + # args + # Arguments supplied by user. See user documentation. + # + # Results: + # None + # + # Errors: + # TCL WRONGARGS + # if an argument is missing. + # TCL LOOKUP INDEX + # if an option or property kind can't be parsed. + # TCL OO PROPERTY_FORMAT + # if an property name is illegal. + # + # Side effects: + # Adjusts properties. Declares non-exported methods with special + # names. + # # ------------------------------------------------------------------ proc PropertyImpl {stdInstaller readslot writeslot args} { -- cgit v0.12 From d1d60243ce313f9106156751ae34ecd431cd1deb Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 20 Jul 2024 21:42:43 +0000 Subject: Make the [property] definition itself go to C --- generic/tclOO.c | 10 +- generic/tclOODefineCmds.c | 354 ++++++++++++++++++++++++++++++++++++++++++---- generic/tclOOInt.h | 14 +- generic/tclOOScript.h | 92 +----------- tools/tclOOScript.tcl | 152 ++------------------ 5 files changed, 364 insertions(+), 258 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 5ceae4e..8ae30e9 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -441,9 +441,15 @@ InitFoundation( &cfgMethods[i]); } Tcl_CreateObjCommand(interp, "::oo::configuresupport::StdObjectProperties", - TclOOInstallStdPropertyImpls, (void *) 1, NULL); + TclOOInstallStdPropertyImplsCmd, (void *) 1, NULL); Tcl_CreateObjCommand(interp, "::oo::configuresupport::StdClassProperties", - TclOOInstallStdPropertyImpls, (void *) 0, NULL); + TclOOInstallStdPropertyImplsCmd, (void *) 0, NULL); + Tcl_CreateObjCommand(interp, + "::oo::configuresupport::configurableobject::property", + TclOOPropertyDefinitionCmd, (void *) 1, NULL); + Tcl_CreateObjCommand(interp, + "::oo::configuresupport::configurableclass::property", + TclOOPropertyDefinitionCmd, (void *) 0, NULL); /* * Evaluate the remaining definitions, which are a compiled-in Tcl script. diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 9e4f879..5f784d9 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -75,6 +75,9 @@ static inline Tcl_Namespace *GetNamespaceInOuterContext(Tcl_Interp *interp, static inline int InitDefineContext(Tcl_Interp *interp, Tcl_Namespace *namespacePtr, Object *oPtr, int objc, Tcl_Obj *const objv[]); +static int InstallStdPropertyImpls(void *useInstance, + Tcl_Interp *interp, Tcl_Obj *propName, + int readable, int writable); static inline void RecomputeClassCacheFlag(Object *oPtr); static int RenameDeleteMethod(Tcl_Interp *interp, Object *oPtr, int useClass, Tcl_Obj *const fromPtr, @@ -3487,7 +3490,286 @@ ObjWPropsSet( /* * ---------------------------------------------------------------------- * - * TclOOInstallStdPropertyImpls -- + * TclOORegisterProperty, TclOORegisterInstanceProperty -- + * + * Helpers to add or remove a name from the property slots of a class or + * instance. + * + * BuildPropertyList -- + * + * Helper for the helpers. Scans a property list and does the filtering + * or adding of the property to add or remove + * + * ---------------------------------------------------------------------- + */ + +static int +BuildPropertyList( + PropertyList *propsList, /* Property list to scan. */ + Tcl_Obj *propName, /* Property to add/remove. */ + int addingProp, /* True if we're adding, false if removing. */ + Tcl_Obj *listObj) /* The list of property names we're building */ +{ + int present = 0, changed = 0, i; + Tcl_Obj *other; + + Tcl_SetListObj(listObj, 0, NULL); + FOREACH(other, *propsList) { + if (strcmp(TclGetString(propName), TclGetString(other)) == 0) { + present = 1; + if (!addingProp) { + changed = 1; + continue; + } + } + Tcl_ListObjAppendElement(NULL, listObj, other); + } + if (!present && addingProp) { + Tcl_ListObjAppendElement(NULL, listObj, propName); + changed = 1; + } + return changed; +} + +void +TclOORegisterInstanceProperty( + Object *oPtr, /* Object that owns the property slots. */ + Tcl_Obj *propName, /* Property to add/remove. Must include the + * hyphen if one is desired; this is the value + * that is actually placed in the slot. */ + int registerReader, /* True if we're adding the property name to + * the readable property slot. False if we're + * removing the property name from the slot. */ + int registerWriter) /* True if we're adding the property name to + * the writable property slot. False if we're + * removing the property name from the slot. */ +{ + Tcl_Obj *listObj = Tcl_NewObj(); /* Working buffer. */ + Tcl_Obj **objv; + Tcl_Size count; + + if (BuildPropertyList(&oPtr->properties.readable, propName, registerReader, + listObj)) { + TclListObjGetElements(NULL, listObj, &count, &objv); + InstallReadableProps(&oPtr->properties, count, objv); + } + + if (BuildPropertyList(&oPtr->properties.writable, propName, registerWriter, + listObj)) { + TclListObjGetElements(NULL, listObj, &count, &objv); + InstallWritableProps(&oPtr->properties, count, objv); + } + Tcl_DecrRefCount(listObj); +} + +void +TclOORegisterProperty( + Class *clsPtr, /* Class that owns the property slots. */ + Tcl_Obj *propName, /* Property to add/remove. Must include the + * hyphen if one is desired; this is the value + * that is actually placed in the slot. */ + int registerReader, /* True if we're adding the property name to + * the readable property slot. False if we're + * removing the property name from the slot. */ + int registerWriter) /* True if we're adding the property name to + * the writable property slot. False if we're + * removing the property name from the slot. */ +{ + Tcl_Obj *listObj = Tcl_NewObj(); /* Working buffer. */ + Tcl_Obj **objv; + Tcl_Size count; + int changed = 0; + + if (BuildPropertyList(&clsPtr->properties.readable, propName, + registerReader, listObj)) { + TclListObjGetElements(NULL, listObj, &count, &objv); + InstallReadableProps(&clsPtr->properties, count, objv); + changed = 1; + } + + if (BuildPropertyList(&clsPtr->properties.writable, propName, + registerWriter, listObj)) { + TclListObjGetElements(NULL, listObj, &count, &objv); + InstallWritableProps(&clsPtr->properties, count, objv); + changed = 1; + } + Tcl_DecrRefCount(listObj); + if (changed) { + BumpGlobalEpoch(clsPtr->thisPtr->fPtr->interp, clsPtr); + } +} + +/* + * ---------------------------------------------------------------------- + * + * TclOOPropertyDefinitionCmd -- + * + * Implementation of the "property" definition for classes and instances + * governed by the [oo::configurable] metaclass. + * + * ---------------------------------------------------------------------- + */ + +int +TclOOPropertyDefinitionCmd( + void *useInstance, /* NULL for class, non-NULL for object. */ + Tcl_Interp *interp, /* For error reporting and lookup. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* Arguments. */ +{ + int i; + const char *const options[] = { + "-get", "-kind", "-set", NULL + }; + enum Options { + OPT_GET, OPT_KIND, OPT_SET + }; + const char *const kinds[] = { + "readable", "readwrite", "writable", NULL + }; + enum Kinds { + KIND_RO, KIND_RW, KIND_WO + }; + Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + + if (oPtr == NULL) { + return TCL_ERROR; + } + if (!useInstance && !oPtr->classPtr) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "attempt to misuse API", -1)); + Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); + return TCL_ERROR; + } + + for (i = 1; i < objc; i++) { + Tcl_Obj *propObj = objv[i], *nextObj, *argObj, *hyphenated; + Tcl_Obj *getterScript = NULL, *setterScript = NULL; + + /* + * Parse the extra options for the property. + */ + + int kind = KIND_RW; + while (i + 1 < objc) { + int option; + + nextObj = objv[i + 1]; + if (TclGetString(nextObj)[0] != '-') { + break; + } + if (Tcl_GetIndexFromObj(interp, nextObj, options, "option", 0, + &option) != TCL_OK) { + return TCL_ERROR; + } + if (i + 2 >= objc) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "missing %s to go with %s option", + (option == OPT_KIND ? "kind value" : "body"), + options[option])); + Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); + return TCL_ERROR; + } + argObj = objv[i + 2]; + i += 2; + switch (option) { + case OPT_GET: + getterScript = argObj; + break; + case OPT_SET: + setterScript = argObj; + break; + case OPT_KIND: + if (Tcl_GetIndexFromObj(interp, argObj, kinds, "kind", 0, + &kind) != TCL_OK) { + return TCL_ERROR; + } + break; + } + } + + /* + * Install the property. Note that InstallStdPropertyImpls + * validates the property name as well. + */ + + if (InstallStdPropertyImpls(useInstance, interp, propObj, + kind != KIND_WO && getterScript == NULL, + kind != KIND_RO && setterScript == NULL) != TCL_OK) { + return TCL_ERROR; + } + + hyphenated = Tcl_ObjPrintf("-%s", TclGetString(propObj)); + Tcl_IncrRefCount(hyphenated); + if (useInstance) { + TclOORegisterInstanceProperty(oPtr, hyphenated, + kind != KIND_WO, kind != KIND_RO); + } else { + TclOORegisterProperty(oPtr->classPtr, hyphenated, + kind != KIND_WO, kind != KIND_RO); + } + Tcl_DecrRefCount(hyphenated); + + /* + * Create property implementation methods by using the right + * back-end API, but only if the user has given us the bodies of the + * methods we'll make. + */ + + if (getterScript != NULL) { + Tcl_Obj *getterName = Tcl_ObjPrintf("", + TclGetString(propObj)); + Tcl_Obj *argsPtr = Tcl_NewObj(); + Method *mPtr; + + Tcl_IncrRefCount(getterName); + Tcl_IncrRefCount(argsPtr); + Tcl_IncrRefCount(getterScript); + if (useInstance) { + mPtr = TclOONewProcInstanceMethod(interp, oPtr, 0, + getterName, argsPtr, getterScript, NULL); + } else { + mPtr = TclOONewProcMethod(interp, oPtr->classPtr, 0, + getterName, argsPtr, getterScript, NULL); + } + Tcl_DecrRefCount(getterName); + Tcl_DecrRefCount(argsPtr); + Tcl_DecrRefCount(getterScript); + if (mPtr == NULL) { + return TCL_ERROR; + } + } + if (setterScript != NULL) { + Tcl_Obj *setterName = Tcl_ObjPrintf("", + TclGetString(propObj)); + Tcl_Obj *argsPtr = Tcl_NewStringObj("value", -1); + Method *mPtr; + + Tcl_IncrRefCount(setterName); + Tcl_IncrRefCount(argsPtr); + Tcl_IncrRefCount(setterScript); + if (useInstance) { + mPtr = TclOONewProcInstanceMethod(interp, oPtr, 0, + setterName, argsPtr, setterScript, NULL); + } else { + mPtr = TclOONewProcMethod(interp, oPtr->classPtr, 0, + setterName, argsPtr, setterScript, NULL); + } + Tcl_DecrRefCount(setterName); + Tcl_DecrRefCount(argsPtr); + Tcl_DecrRefCount(setterScript); + if (mPtr == NULL) { + return TCL_ERROR; + } + } + } + return TCL_OK; +} + +/* + * ---------------------------------------------------------------------- + * + * InstallStdPropertyImpls, TclOOInstallStdPropertyImplsCmd -- * * Implementations of the "StdClassProperties" hidden definition for * classes and the "StdObjectProperties" hidden definition for @@ -3499,32 +3781,26 @@ ObjWPropsSet( * ---------------------------------------------------------------------- */ -int -TclOOInstallStdPropertyImpls( +static int +InstallStdPropertyImpls( void *useInstance, Tcl_Interp *interp, - int objc, - Tcl_Obj *const *objv) + Tcl_Obj *propName, + int readable, + int writable) { - int readable, writable; - Tcl_Obj *propName; const char *name, *reason; Tcl_Size len; char flag = TCL_DONT_QUOTE_HASH; /* - * Parse the arguments and validate the property name. Note that just - * calling TclScanElement() is cheaper than actually formatting a list - * and comparing the string version of that with the original, as - * TclScanElement() is one of the core parts of doing that; this skips - * a whole load of irrelevant memory allocations! + * Validate the property name. Note that just calling TclScanElement() is + * cheaper than actually formatting a list and comparing the string + * version of that with the original, as TclScanElement() is one of the + * core parts of doing that; this skips a whole load of irrelevant memory + * allocations! */ - if (objc != 4) { - Tcl_WrongNumArgs(interp, 1, objv, "propName readable writable"); - return TCL_ERROR; - } - propName = objv[1]; name = Tcl_GetStringFromObj(propName, &len); if (Tcl_StringMatch(name, "-*")) { reason = "must not begin with -"; @@ -3542,12 +3818,6 @@ TclOOInstallStdPropertyImpls( reason = "must not contain parentheses"; goto badProp; } - if (Tcl_GetBooleanFromObj(interp, objv[2], &readable) != TCL_OK) { - return TCL_ERROR; - } - if (Tcl_GetBooleanFromObj(interp, objv[3], &writable) != TCL_OK) { - return TCL_ERROR; - } /* * Install the implementations... if asked to do so. @@ -3572,7 +3842,43 @@ TclOOInstallStdPropertyImpls( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad property name \"%s\": %s", name, reason)); Tcl_SetErrorCode(interp, "TCL", "OO", "PROPERTY_FORMAT", NULL); - return TCL_ERROR; + return TCL_ERROR; +} + +int +TclOOInstallStdPropertyImplsCmd( + void *useInstance, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const *objv) +{ + int readable, writable; + Tcl_Obj *propName; + + /* + * Parse the arguments. + */ + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "propName readable writable"); + return TCL_ERROR; + } + propName = objv[1]; + if (Tcl_GetBooleanFromObj(interp, objv[2], &readable) != TCL_OK) { + return TCL_ERROR; + } + if (Tcl_GetBooleanFromObj(interp, objv[3], &writable) != TCL_OK) { + return TCL_ERROR; + } + + + /* + * Validate the property name and install the implementations... if asked + * to do so. + */ + + return InstallStdPropertyImpls(useInstance, interp, propName, readable, + writable); } /* diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index 07408f8..c31c461 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -169,16 +169,15 @@ typedef struct { typedef LIST_STATIC(Tcl_Obj *) VariableNameList; typedef LIST_STATIC(PrivateVariableMapping) PrivateVariableList; +typedef LIST_STATIC(Tcl_Obj *) PropertyList; /* * This type is used in various places. */ typedef struct { - LIST_STATIC(Tcl_Obj *) readable; - /* The readable properties slot. */ - LIST_STATIC(Tcl_Obj *) writable; - /* The writable properties slot. */ + PropertyList readable; /* The readable properties slot. */ + PropertyList writable; /* The writable properties slot. */ Tcl_Obj *allReadableCache; /* The cache of all readable properties * exposed by this object or class (in its * stereotypical instancs). Contains a sorted @@ -498,7 +497,8 @@ MODULE_SCOPE Tcl_ObjCmdProc TclOODefineClassObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineSelfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineObjSelfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefinePrivateObjCmd; -MODULE_SCOPE Tcl_ObjCmdProc TclOOInstallStdPropertyImpls; +MODULE_SCOPE Tcl_ObjCmdProc TclOOInstallStdPropertyImplsCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclOOPropertyDefinitionCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOUnknownDefinition; MODULE_SCOPE Tcl_ObjCmdProc TclOOCopyObjectCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOONextObjCmd; @@ -611,6 +611,10 @@ MODULE_SCOPE void TclOOSortPropList(Tcl_Obj *listPtr); MODULE_SCOPE void TclOOStashContext(Tcl_Obj *objPtr, CallContext *contextPtr); MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr); +MODULE_SCOPE void TclOORegisterProperty(Class *clsPtr, + Tcl_Obj *propName, int mayRead, int mayWrite); +MODULE_SCOPE void TclOORegisterInstanceProperty(Object *oPtr, + Tcl_Obj *propName, int mayRead, int mayWrite); /* * Include all the private API, generated from tclOO.decls. diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 7538d48..98fa20e 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -258,99 +258,13 @@ static const char *tclOOSetupScript = "\t\tsuperclass class\n" "\t\tunexport create createWithNamespace new\n" "\t}\n" -"\t::namespace eval configuresupport {\n" -"\t\tnamespace path ::tcl\n" -"\t\tproc PropertyImpl {stdInstaller readslot writeslot args} {\n" -"\t\t\tfor {set i 0} {$i < [llength $args]} {incr i} {\n" -"\t\t\t\tset prop [lindex $args $i]\n" -"\t\t\t\tset realprop [string cat \"-\" $prop]\n" -"\t\t\t\tunset -nocomplain getter setter\n" -"\t\t\t\tset kind readwrite\n" -"\t\t\t\twhile {[set next [lindex $args [expr {$i + 1}]]\n" -"\t\t\t\t\t\tstring match \"-*\" $next]} {\n" -"\t\t\t\t\tset arg [lindex $args [incr i 2]]\n" -"\t\t\t\t\tswitch [prefix match -error [list -level 1 -errorcode \\\n" -"\t\t\t\t\t\t\t[list TCL LOOKUP INDEX option $next]] {-get -kind -set} $next] {\n" -"\t\t\t\t\t\t-get {\n" -"\t\t\t\t\t\t\tif {$i >= [llength $args]} {\n" -"\t\t\t\t\t\t\t\treturn -code error -level 1 \\\n" -"\t\t\t\t\t\t\t\t\t-errorcode {TCL WRONGARGS} \\\n" -"\t\t\t\t\t\t\t\t\t\"missing body to go with -get option\"\n" -"\t\t\t\t\t\t\t}\n" -"\t\t\t\t\t\t\tset getter $arg\n" -"\t\t\t\t\t\t}\n" -"\t\t\t\t\t\t-set {\n" -"\t\t\t\t\t\t\tif {$i >= [llength $args]} {\n" -"\t\t\t\t\t\t\t\treturn -code error -level 1 \\\n" -"\t\t\t\t\t\t\t\t\t-errorcode {TCL WRONGARGS} \\\n" -"\t\t\t\t\t\t\t\t\t\"missing body to go with -set option\"\n" -"\t\t\t\t\t\t\t}\n" -"\t\t\t\t\t\t\tset setter $arg\n" -"\t\t\t\t\t\t}\n" -"\t\t\t\t\t\t-kind {\n" -"\t\t\t\t\t\t\tif {$i >= [llength $args]} {\n" -"\t\t\t\t\t\t\t\treturn -code error -level 1 \\\n" -"\t\t\t\t\t\t\t\t\t-errorcode {TCL WRONGARGS} \\\n" -"\t\t\t\t\t\t\t\t\t\"missing kind value to go with -kind option\"\n" -"\t\t\t\t\t\t\t}\n" -"\t\t\t\t\t\t\tset kind [prefix match -message \"kind\" -error [list \\\n" -"\t\t\t\t\t\t\t\t\t-level 2 \\\n" -"\t\t\t\t\t\t\t\t\t-errorcode [list TCL LOOKUP INDEX kind $arg]] {\n" -"\t\t\t\t\t\t\t\treadable readwrite writable\n" -"\t\t\t\t\t\t\t} $arg]\n" -"\t\t\t\t\t\t}\n" -"\t\t\t\t\t}\n" -"\t\t\t\t}\n" -"\t\t\t\tset reader \n" -"\t\t\t\tset writer \n" -"\t\t\t\tset addReader [expr {$kind ne \"writable\" && ![info exist getter]}]\n" -"\t\t\t\tset addWriter [expr {$kind ne \"readable\" && ![info exist setter]}]\n" -"\t\t\t\ttry {\n" -"\t\t\t\t\tuplevel 1 [list $stdInstaller $prop $addReader $addWriter]\n" -"\t\t\t\t} on error {msg opt} {\n" -"\t\t\t\t\treturn -code error -level 1 \\\n" -"\t\t\t\t\t\t\t-errorcode [dict get $opt -errorcode] $msg\n" -"\t\t\t\t}\n" -"\t\t\t\tswitch $kind {\n" -"\t\t\t\t\treadable {\n" -"\t\t\t\t\t\tuplevel 1 [list $readslot -append $realprop]\n" -"\t\t\t\t\t\tuplevel 1 [list $writeslot -remove $realprop]\n" -"\t\t\t\t\t}\n" -"\t\t\t\t\twritable {\n" -"\t\t\t\t\t\tuplevel 1 [list $readslot -remove $realprop]\n" -"\t\t\t\t\t\tuplevel 1 [list $writeslot -append $realprop]\n" -"\t\t\t\t\t}\n" -"\t\t\t\t\treadwrite {\n" -"\t\t\t\t\t\tuplevel 1 [list $readslot -append $realprop]\n" -"\t\t\t\t\t\tuplevel 1 [list $writeslot -append $realprop]\n" -"\t\t\t\t\t}\n" -"\t\t\t\t}\n" -"\t\t\t\tif {[info exist getter]} {\n" -"\t\t\t\t\tuplevel 1 [list method $reader -unexport {} $getter]\n" -"\t\t\t\t}\n" -"\t\t\t\tif {[info exist setter]} {\n" -"\t\t\t\t\tuplevel 1 [list method $writer -unexport {value} $setter]\n" -"\t\t\t\t}\n" -"\t\t\t}\n" -"\t\t}\n" -"\t\tnamespace eval configurableclass {\n" -"\t\t\t::interp alias \\\n" -"\t\t\t\t\t{} ::oo::configuresupport::configurableclass::property {} \\\n" -"\t\t\t\t\t::oo::configuresupport::PropertyImpl \\\n" -"\t\t\t\t\t::oo::configuresupport::StdClassProperties \\\n" -"\t\t\t\t\t::oo::configuresupport::readableproperties \\\n" -"\t\t\t\t\t::oo::configuresupport::writableproperties\n" +"\tnamespace eval configuresupport {\n" +"\t\t::namespace eval configurableclass {\n" "\t\t\t::proc properties args {::tailcall property {*}$args}\n" "\t\t\t::namespace path ::oo::define\n" "\t\t\t::namespace export property\n" "\t\t}\n" -"\t\tnamespace eval configurableobject {\n" -"\t\t\t::interp alias \\\n" -"\t\t\t\t\t{} ::oo::configuresupport::configurableobject::property {} \\\n" -"\t\t\t\t\t::oo::configuresupport::PropertyImpl \\\n" -"\t\t\t\t\t::oo::configuresupport::StdObjectProperties \\\n" -"\t\t\t\t\t::oo::configuresupport::objreadableproperties \\\n" -"\t\t\t\t\t::oo::configuresupport::objwritableproperties\n" +"\t\t::namespace eval configurableobject {\n" "\t\t\t::proc properties args {::tailcall property {*}$args}\n" "\t\t\t::namespace path ::oo::objdefine\n" "\t\t\t::namespace export property\n" diff --git a/tools/tclOOScript.tcl b/tools/tclOOScript.tcl index 22f0e91..fc0927c 100644 --- a/tools/tclOOScript.tcl +++ b/tools/tclOOScript.tcl @@ -470,134 +470,20 @@ # * objreadableproperties # * objwritableproperties # - # Those are all slot implementations that provide access to the C layer + # These are all slot implementations that provide access to the C layer # of property support (i.e., very fast cached lookup of property names). # + # * StdClassProperties + # * StdObjectPropertes + # + # These cause very fast basic implementation methods for a property + # following the standard model of property implementation naming. + # Property schemes that use other models (such as to be more Tk-like) + # should not use these (or the oo::cconfigurable metaclass). + # # ---------------------------------------------------------------------- - ::namespace eval configuresupport { - namespace path ::tcl - - # ------------------------------------------------------------------ - # - # oo::configuresupport::PropertyImpl -- - # - # The implementation of the [property] configuration command. - # This assumes there is a context scope of [oo::define] or - # [oo::objdefine] as the stack frame that is up one level. - # - # TODO: - # Convert to C code. - # - # Arguments: - # stdInstaller - # How to install a property implementation of the right type. - # Must be evaluated in the definition scope. - # readslot - # Slot of readable properties. - # Must be evaluated in the definition scope. - # writeslot - # Slot of writable properties. - # Must be evaluated in the definition scope. - # args - # Arguments supplied by user. See user documentation. - # - # Results: - # None - # - # Errors: - # TCL WRONGARGS - # if an argument is missing. - # TCL LOOKUP INDEX - # if an option or property kind can't be parsed. - # TCL OO PROPERTY_FORMAT - # if an property name is illegal. - # - # Side effects: - # Adjusts properties. Declares non-exported methods with special - # names. - # - # ------------------------------------------------------------------ - - proc PropertyImpl {stdInstaller readslot writeslot args} { - for {set i 0} {$i < [llength $args]} {incr i} { - # Parse the property name - set prop [lindex $args $i] - set realprop [string cat "-" $prop] - unset -nocomplain getter setter - set kind readwrite - - # Parse the extra options for the property - while {[set next [lindex $args [expr {$i + 1}]] - string match "-*" $next]} { - set arg [lindex $args [incr i 2]] - switch [prefix match -error [list -level 1 -errorcode \ - [list TCL LOOKUP INDEX option $next]] {-get -kind -set} $next] { - -get { - if {$i >= [llength $args]} { - return -code error -level 1 \ - -errorcode {TCL WRONGARGS} \ - "missing body to go with -get option" - } - set getter $arg - } - -set { - if {$i >= [llength $args]} { - return -code error -level 1 \ - -errorcode {TCL WRONGARGS} \ - "missing body to go with -set option" - } - set setter $arg - } - -kind { - if {$i >= [llength $args]} { - return -code error -level 1 \ - -errorcode {TCL WRONGARGS} \ - "missing kind value to go with -kind option" - } - set kind [prefix match -message "kind" -error [list \ - -level 2 \ - -errorcode [list TCL LOOKUP INDEX kind $arg]] { - readable readwrite writable - } $arg] - } - } - } - - # Install the property - set reader - set writer - set addReader [expr {$kind ne "writable" && ![info exist getter]}] - set addWriter [expr {$kind ne "readable" && ![info exist setter]}] - try { - uplevel 1 [list $stdInstaller $prop $addReader $addWriter] - } on error {msg opt} { - return -code error -level 1 \ - -errorcode [dict get $opt -errorcode] $msg - } - switch $kind { - readable { - uplevel 1 [list $readslot -append $realprop] - uplevel 1 [list $writeslot -remove $realprop] - } - writable { - uplevel 1 [list $readslot -remove $realprop] - uplevel 1 [list $writeslot -append $realprop] - } - readwrite { - uplevel 1 [list $readslot -append $realprop] - uplevel 1 [list $writeslot -append $realprop] - } - } - if {[info exist getter]} { - uplevel 1 [list method $reader -unexport {} $getter] - } - if {[info exist setter]} { - uplevel 1 [list method $writer -unexport {value} $setter] - } - } - } - + namespace eval configuresupport { # ------------------------------------------------------------------ # # oo::configuresupport::configurableclass, @@ -605,29 +491,19 @@ # # Namespaces used as implementation vectors for oo::define and # oo::objdefine when the class/instance is configurable. + # Note that these also contain commands implemented in C, + # especially the [property] definition command. # # ------------------------------------------------------------------ - namespace eval configurableclass { - ::interp alias \ - {} ::oo::configuresupport::configurableclass::property {} \ - ::oo::configuresupport::PropertyImpl \ - ::oo::configuresupport::StdClassProperties \ - ::oo::configuresupport::readableproperties \ - ::oo::configuresupport::writableproperties + ::namespace eval configurableclass { # Plural alias just in case; deliberately NOT documented! ::proc properties args {::tailcall property {*}$args} ::namespace path ::oo::define ::namespace export property } - namespace eval configurableobject { - ::interp alias \ - {} ::oo::configuresupport::configurableobject::property {} \ - ::oo::configuresupport::PropertyImpl \ - ::oo::configuresupport::StdObjectProperties \ - ::oo::configuresupport::objreadableproperties \ - ::oo::configuresupport::objwritableproperties + ::namespace eval configurableobject { # Plural alias just in case; deliberately NOT documented! ::proc properties args {::tailcall property {*}$args} ::namespace path ::oo::objdefine -- cgit v0.12 From ebe53cb73a0e487f29c84a18ce59ae281f6cdb3c Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 21 Jul 2024 14:14:42 +0000 Subject: Tidying up the properties code --- generic/tclOOBasic.c | 26 ++- generic/tclOODefineCmds.c | 416 ++++++++++++++++++++++++---------------------- 2 files changed, 226 insertions(+), 216 deletions(-) diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 34cc272..e8b4e13 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -1678,8 +1678,9 @@ TclOO_Configurable_Configure( static int Configurable_Getter( - void *clientData, /* Which property to read. - * Actually a Tcl_Obj* reference. */ + void *clientData, /* Which property to read. Actually a Tcl_Obj* + * reference that is the name of the variable + * in the cpntext object. */ Tcl_Interp *interp, /* Interpreter used for the result, error * reporting, etc. */ Tcl_ObjectContext context, /* The object/call context. */ @@ -1713,8 +1714,9 @@ Configurable_Getter( static int Configurable_Setter( - void *clientData, /* Which property to write. - * Actually a Tcl_Obj* reference. */ + void *clientData, /* Which property to write. Actually a Tcl_Obj* + * reference that is the name of the variable + * in the cpntext object. */ Tcl_Interp *interp, /* Interpreter used for the result, error * reporting, etc. */ Tcl_ObjectContext context, /* The object/call context. */ @@ -1791,22 +1793,18 @@ TclOOImplementObjectProperty( if (installGetter) { Tcl_Obj *methodName = Tcl_ObjPrintf( "", TclGetString(propNamePtr)); - // Don't know if TclNewInstanceMethod will retain a ref to the method name - Tcl_IncrRefCount(methodName); Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter TclNewInstanceMethod( NULL, targetObject, methodName, 0, &GetterType, propNamePtr); - Tcl_DecrRefCount(methodName); + Tcl_BounceRefCount(methodName); } if (installSetter) { Tcl_Obj *methodName = Tcl_ObjPrintf( "", TclGetString(propNamePtr)); - // Don't know if TclNewInstanceMethod will retain a ref to the method name - Tcl_IncrRefCount(methodName); Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter TclNewInstanceMethod( NULL, targetObject, methodName, 0, &SetterType, propNamePtr); - Tcl_DecrRefCount(methodName); + Tcl_BounceRefCount(methodName); } } @@ -1820,22 +1818,18 @@ TclOOImplementClassProperty( if (installGetter) { Tcl_Obj *methodName = Tcl_ObjPrintf( "", TclGetString(propNamePtr)); - // Don't know if TclNewMethod will retain a ref to the method name - Tcl_IncrRefCount(methodName); Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter TclNewMethod( NULL, targetClass, methodName, 0, &GetterType, propNamePtr); - Tcl_DecrRefCount(methodName); + Tcl_BounceRefCount(methodName); } if (installSetter) { Tcl_Obj *methodName = Tcl_ObjPrintf( "", TclGetString(propNamePtr)); - // Don't know if TclNewMethod will retain a ref to the method name - Tcl_IncrRefCount(methodName); Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter TclNewMethod( NULL, targetClass, methodName, 0, &SetterType, propNamePtr); - Tcl_DecrRefCount(methodName); + Tcl_BounceRefCount(methodName); } } diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 5f784d9..d3ec410 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -82,52 +82,72 @@ static inline void RecomputeClassCacheFlag(Object *oPtr); static int RenameDeleteMethod(Tcl_Interp *interp, Object *oPtr, int useClass, Tcl_Obj *const fromPtr, Tcl_Obj *const toPtr); -static int ClassFilterGet(void *clientData, +static int ClassFilter_Get(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ClassFilterSet(void *clientData, +static int ClassFilter_Set(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ClassMixinGet(void *clientData, +static int ClassMixin_Get(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ClassMixinSet(void *clientData, +static int ClassMixin_Set(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ClassSuperGet(void *clientData, +static int ClassSuper_Get(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ClassSuperSet(void *clientData, +static int ClassSuper_Set(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ClassVarsGet(void *clientData, +static int ClassVars_Get(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ClassVarsSet(void *clientData, +static int ClassVars_Set(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static Tcl_MethodCallProc ClassRPropsGet, ClassRPropsSet; -static Tcl_MethodCallProc ClassWPropsGet, ClassWPropsSet; -static int ObjFilterGet(void *clientData, +static int ObjFilter_Get(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ObjFilterSet(void *clientData, +static int ObjFilter_Set(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ObjMixinGet(void *clientData, +static int ObjMixin_Get(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ObjMixinSet(void *clientData, +static int ObjMixin_Set(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ObjVarsGet(void *clientData, +static int ObjVars_Get(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ObjVarsSet(void *clientData, +static int ObjVars_Set(void *clientData, + Tcl_Interp *interp, Tcl_ObjectContext context, + int objc, Tcl_Obj *const *objv); +static int Configurable_ClassReadableProps_Get(void *clientData, + Tcl_Interp *interp, Tcl_ObjectContext context, + int objc, Tcl_Obj *const *objv); +static int Configurable_ClassReadableProps_Set(void *clientData, + Tcl_Interp *interp, Tcl_ObjectContext context, + int objc, Tcl_Obj *const *objv); +static int Configurable_ClassWritableProps_Get(void *clientData, + Tcl_Interp *interp, Tcl_ObjectContext context, + int objc, Tcl_Obj *const *objv); +static int Configurable_ClassWritableProps_Set(void *clientData, + Tcl_Interp *interp, Tcl_ObjectContext context, + int objc, Tcl_Obj *const *objv); +static int Configurable_ObjectReadableProps_Get(void *clientData, + Tcl_Interp *interp, Tcl_ObjectContext context, + int objc, Tcl_Obj *const *objv); +static int Configurable_ObjectReadableProps_Set(void *clientData, + Tcl_Interp *interp, Tcl_ObjectContext context, + int objc, Tcl_Obj *const *objv); +static int Configurable_ObjectWritableProps_Get(void *clientData, + Tcl_Interp *interp, Tcl_ObjectContext context, + int objc, Tcl_Obj *const *objv); +static int Configurable_ObjectWritableProps_Set(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static Tcl_MethodCallProc ObjRPropsGet, ObjRPropsSet; -static Tcl_MethodCallProc ObjWPropsGet, ObjWPropsSet; static int ResolveClass(void *clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); @@ -137,21 +157,25 @@ static int ResolveClass(void *clientData, */ static const struct DeclaredSlot slots[] = { - SLOT("define::filter", ClassFilterGet, ClassFilterSet, NULL), - SLOT("define::mixin", ClassMixinGet, ClassMixinSet, ResolveClass), - SLOT("define::superclass", ClassSuperGet, ClassSuperSet, ResolveClass), - SLOT("define::variable", ClassVarsGet, ClassVarsSet, NULL), - SLOT("objdefine::filter", ObjFilterGet, ObjFilterSet, NULL), - SLOT("objdefine::mixin", ObjMixinGet, ObjMixinSet, ResolveClass), - SLOT("objdefine::variable", ObjVarsGet, ObjVarsSet, NULL), + SLOT("define::filter", ClassFilter_Get, ClassFilter_Set, NULL), + SLOT("define::mixin", ClassMixin_Get, ClassMixin_Set, ResolveClass), + SLOT("define::superclass", ClassSuper_Get, ClassSuper_Set, ResolveClass), + SLOT("define::variable", ClassVars_Get, ClassVars_Set, NULL), + SLOT("objdefine::filter", ObjFilter_Get, ObjFilter_Set, NULL), + SLOT("objdefine::mixin", ObjMixin_Get, ObjMixin_Set, ResolveClass), + SLOT("objdefine::variable", ObjVars_Get, ObjVars_Set, NULL), SLOT("configuresupport::readableproperties", - ClassRPropsGet, ClassRPropsSet, NULL), + Configurable_ClassReadableProps_Get, + Configurable_ClassReadableProps_Set, NULL), SLOT("configuresupport::writableproperties", - ClassWPropsGet, ClassWPropsSet, NULL), + Configurable_ClassWritableProps_Get, + Configurable_ClassWritableProps_Set, NULL), SLOT("configuresupport::objreadableproperties", - ObjRPropsGet, ObjRPropsSet, NULL), + Configurable_ObjectReadableProps_Get, + Configurable_ObjectReadableProps_Set, NULL), SLOT("configuresupport::objwritableproperties", - ObjWPropsGet, ObjWPropsSet, NULL), + Configurable_ObjectWritableProps_Get, + Configurable_ObjectWritableProps_Set, NULL), {NULL, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}} }; @@ -612,10 +636,12 @@ InstallPrivateVariableMapping( if (varc == 0) { Tcl_Free(pvlPtr->list); } else if (i) { - pvlPtr->list = (PrivateVariableMapping *)Tcl_Realloc(pvlPtr->list, - sizeof(PrivateVariableMapping) * varc); + pvlPtr->list = (PrivateVariableMapping *) + Tcl_Realloc(pvlPtr->list, + sizeof(PrivateVariableMapping) * varc); } else { - pvlPtr->list = (PrivateVariableMapping *)Tcl_Alloc(sizeof(PrivateVariableMapping) * varc); + pvlPtr->list = (PrivateVariableMapping *) + Tcl_Alloc(sizeof(PrivateVariableMapping) * varc); } } @@ -780,7 +806,8 @@ TclOOUnknownDefinition( } hPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); while (hPtr != NULL) { - const char *nameStr = (const char *)Tcl_GetHashKey(&nsPtr->cmdTable, hPtr); + const char *nameStr = (const char *) + Tcl_GetHashKey(&nsPtr->cmdTable, hPtr); if (strncmp(soughtStr, nameStr, soughtLen) == 0) { if (matchedStr != NULL) { @@ -2208,7 +2235,8 @@ TclOODefineUnexportObjCmd( if (isInstanceUnexport) { if (!oPtr->methodsPtr) { - oPtr->methodsPtr = (Tcl_HashTable *)Tcl_Alloc(sizeof(Tcl_HashTable)); + oPtr->methodsPtr = (Tcl_HashTable *) + Tcl_Alloc(sizeof(Tcl_HashTable)); Tcl_InitObjHashTable(oPtr->methodsPtr); oPtr->flags &= ~USE_CLASS_CACHE; } @@ -2330,9 +2358,6 @@ TclOODefineSlots( if (slotCls == NULL) { return TCL_ERROR; } - Tcl_IncrRefCount(getName); - Tcl_IncrRefCount(setName); - Tcl_IncrRefCount(resolveName); for (slotInfoPtr = slots ; slotInfoPtr->name ; slotInfoPtr++) { Tcl_Object slotObject = Tcl_NewObjectInstance(fPtr->interp, (Tcl_Class) slotCls, slotInfoPtr->name, NULL, TCL_INDEX_NONE, NULL, 0); @@ -2349,16 +2374,16 @@ TclOODefineSlots( &slotInfoPtr->resolverType, NULL); } } - Tcl_DecrRefCount(getName); - Tcl_DecrRefCount(setName); - Tcl_DecrRefCount(resolveName); + Tcl_BounceRefCount(getName); + Tcl_BounceRefCount(setName); + Tcl_BounceRefCount(resolveName); return TCL_OK; } /* * ---------------------------------------------------------------------- * - * ClassFilterGet, ClassFilterSet -- + * ClassFilter_Get, ClassFilter_Set -- * * Implementation of the "filter" slot accessors of the "oo::define" * command. @@ -2367,7 +2392,7 @@ TclOODefineSlots( */ static int -ClassFilterGet( +ClassFilter_Get( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2395,7 +2420,7 @@ ClassFilterGet( } static int -ClassFilterSet( +ClassFilter_Set( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2427,7 +2452,7 @@ ClassFilterSet( /* * ---------------------------------------------------------------------- * - * ClassMixinGet, ClassMixinSet -- + * ClassMixin_Get, ClassMixin_Set -- * * Implementation of the "mixin" slot accessors of the "oo::define" * command. @@ -2436,7 +2461,7 @@ ClassFilterSet( */ static int -ClassMixinGet( +ClassMixin_Get( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2467,7 +2492,7 @@ ClassMixinGet( } static int -ClassMixinSet( +ClassMixin_Set( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2536,7 +2561,7 @@ ClassMixinSet( /* * ---------------------------------------------------------------------- * - * ClassSuperGet, ClassSuperSet -- + * ClassSuper_Get, ClassSuper_Set -- * * Implementation of the "superclass" slot accessors of the "oo::define" * command. @@ -2545,7 +2570,7 @@ ClassMixinSet( */ static int -ClassSuperGet( +ClassSuper_Get( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2575,7 +2600,7 @@ ClassSuperGet( } static int -ClassSuperSet( +ClassSuper_Set( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2694,7 +2719,7 @@ ClassSuperSet( /* * ---------------------------------------------------------------------- * - * ClassVarsGet, ClassVarsSet -- + * ClassVars_Get, ClassVars_Set -- * * Implementation of the "variable" slot accessors of the "oo::define" * command. @@ -2703,7 +2728,7 @@ ClassSuperSet( */ static int -ClassVarsGet( +ClassVars_Get( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2741,7 +2766,7 @@ ClassVarsGet( } static int -ClassVarsSet( +ClassVars_Set( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2797,7 +2822,7 @@ ClassVarsSet( /* * ---------------------------------------------------------------------- * - * ObjectFilterGet, ObjectFilterSet -- + * ObjFilter_Get, ObjFilter_Set -- * * Implementation of the "filter" slot accessors of the "oo::objdefine" * command. @@ -2806,7 +2831,7 @@ ClassVarsSet( */ static int -ObjFilterGet( +ObjFilter_Get( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2834,7 +2859,7 @@ ObjFilterGet( } static int -ObjFilterSet( +ObjFilter_Set( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2864,7 +2889,7 @@ ObjFilterSet( /* * ---------------------------------------------------------------------- * - * ObjectMixinGet, ObjectMixinSet -- + * ObjMixin_Get, ObjMixin_Set -- * * Implementation of the "mixin" slot accessors of the "oo::objdefine" * command. @@ -2873,7 +2898,7 @@ ObjFilterSet( */ static int -ObjMixinGet( +ObjMixin_Get( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2905,7 +2930,7 @@ ObjMixinGet( } static int -ObjMixinSet( +ObjMixin_Set( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -2966,7 +2991,7 @@ ObjMixinSet( /* * ---------------------------------------------------------------------- * - * ObjectVarsGet, ObjectVarsSet -- + * ObjVars_Get, ObjVars_Set -- * * Implementation of the "variable" slot accessors of the "oo::objdefine" * command. @@ -2975,7 +3000,7 @@ ObjMixinSet( */ static int -ObjVarsGet( +ObjVars_Get( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -3013,7 +3038,7 @@ ObjVarsGet( } static int -ObjVarsSet( +ObjVars_Set( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -3120,73 +3145,151 @@ ResolveClass( /* * ---------------------------------------------------------------------- * - * ClassRPropsGet, ClassRPropsSet, ObjRPropsGet, ObjRPropsSet -- + * SetPropertyList -- * - * Implementations of the "readableproperties" slot accessors for classes - * and instances. + * Helper for writing a property list (which is actually a set). * * ---------------------------------------------------------------------- */ - -static void -InstallReadableProps( - PropertyStorage *props, - Tcl_Size objc, - Tcl_Obj *const objv[]) +static inline void +SetPropertyList( + PropertyList *propList, /* The property list to write. Replaces the + * property list's contents. */ + Tcl_Size objc, /* Number of property names. */ + Tcl_Obj *const objv[]) /* Property names. */ { - Tcl_Obj *propObj; Tcl_Size i, n; + Tcl_Obj *propObj; int created; Tcl_HashTable uniqueTable; - if (props->allReadableCache) { - Tcl_DecrRefCount(props->allReadableCache); - props->allReadableCache = NULL; - } - for (i=0 ; ireadable) { + FOREACH(propObj, *propList) { Tcl_DecrRefCount(propObj); } if (i != objc) { if (objc == 0) { - Tcl_Free(props->readable.list); + Tcl_Free(propList->list); } else if (i) { - props->readable.list = (Tcl_Obj **)Tcl_Realloc(props->readable.list, - sizeof(Tcl_Obj *) * objc); + propList->list = (Tcl_Obj **) + Tcl_Realloc(propList->list, sizeof(Tcl_Obj *) * objc); } else { - props->readable.list = (Tcl_Obj **)Tcl_Alloc(sizeof(Tcl_Obj *) * objc); + propList->list = (Tcl_Obj **) + Tcl_Alloc(sizeof(Tcl_Obj *) * objc); } } - props->readable.num = 0; + propList->num = 0; if (objc > 0) { Tcl_InitObjHashTable(&uniqueTable); for (i=n=0 ; ireadable.list[n++] = objv[i]; + propList->list[n++] = objv[i]; } else { Tcl_DecrRefCount(objv[i]); } } - props->readable.num = n; + propList->num = n; /* * Shouldn't be necessary, but maintain num/list invariant. */ if (n != objc) { - props->readable.list = (Tcl_Obj **)Tcl_Realloc(props->readable.list, - sizeof(Tcl_Obj *) * n); + propList->list = (Tcl_Obj **) + Tcl_Realloc(propList->list, sizeof(Tcl_Obj *) * n); } Tcl_DeleteHashTable(&uniqueTable); } } + +/* + * ---------------------------------------------------------------------- + * + * InstallReadableProps -- + * + * Helper for writing the readable property list (which is actually a set) + * that includes flushing the name cache. + * + * ---------------------------------------------------------------------- + */ +static inline void +InstallReadableProps( + PropertyStorage *props, /* Which property list to install into. */ + Tcl_Size objc, /* Number of property names. */ + Tcl_Obj *const objv[]) /* Property names. */ +{ + if (props->allReadableCache) { + Tcl_DecrRefCount(props->allReadableCache); + props->allReadableCache = NULL; + } + + SetPropertyList(&props->readable, objc, objv); +} + +/* + * ---------------------------------------------------------------------- + * + * InstallWritableProps -- + * + * Helper for writing the writable property list (which is actually a set) + * that includes flushing the name cache. + * + * ---------------------------------------------------------------------- + */ +static inline void +InstallWritableProps( + PropertyStorage *props, /* Which property list to install into. */ + Tcl_Size objc, /* Number of property names. */ + Tcl_Obj *const objv[]) /* Property names. */ +{ + if (props->allWritableCache) { + Tcl_DecrRefCount(props->allWritableCache); + props->allWritableCache = NULL; + } + + SetPropertyList(&props->writable, objc, objv); +} + +/* + * ---------------------------------------------------------------------- + * + * GetPropertyList -- + * + * Helper for reading a property list. + * + * ---------------------------------------------------------------------- + */ +static inline Tcl_Obj * +GetPropertyList( + PropertyList *propList) /* The property list to read. */ +{ + Tcl_Obj *resultObj, *propNameObj; + Tcl_Size i; + + TclNewObj(resultObj); + FOREACH(propNameObj, *propList) { + Tcl_ListObjAppendElement(NULL, resultObj, propNameObj); + } + return resultObj; +} + +/* + * ---------------------------------------------------------------------- + * + * Configurable_ClassReadableProps_Get, Configurable_ClassReadableProps_Set, + * Configurable_ObjectReadableProps_Get, Configurable_ObjectReadableProps_Set -- + * + * Implementations of the "readableproperties" slot accessors for classes + * and instances. + * + * ---------------------------------------------------------------------- + */ static int -ClassRPropsGet( +Configurable_ClassReadableProps_Get( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -3194,8 +3297,6 @@ ClassRPropsGet( Tcl_Obj *const *objv) { Class *clsPtr = GetClassDefineCmdContext(interp); - Tcl_Obj *resultObj, *propNameObj; - int i; if (clsPtr == NULL) { return TCL_ERROR; @@ -3205,16 +3306,12 @@ ClassRPropsGet( return TCL_ERROR; } - TclNewObj(resultObj); - FOREACH(propNameObj, clsPtr->properties.readable) { - Tcl_ListObjAppendElement(NULL, resultObj, propNameObj); - } - Tcl_SetObjResult(interp, resultObj); + Tcl_SetObjResult(interp, GetPropertyList(&clsPtr->properties.readable)); return TCL_OK; } static int -ClassRPropsSet( +Configurable_ClassReadableProps_Set( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -3244,7 +3341,7 @@ ClassRPropsSet( } static int -ObjRPropsGet( +Configurable_ObjectReadableProps_Get( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -3252,28 +3349,21 @@ ObjRPropsGet( Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); - Tcl_Obj *resultObj, *propNameObj; - int i; - if (Tcl_ObjectContextSkippedArgs(context) != objc) { + if (oPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } - if (oPtr == NULL) { - return TCL_ERROR; - } - TclNewObj(resultObj); - FOREACH(propNameObj, oPtr->properties.readable) { - Tcl_ListObjAppendElement(NULL, resultObj, propNameObj); - } - Tcl_SetObjResult(interp, resultObj); + Tcl_SetObjResult(interp, GetPropertyList(&oPtr->properties.readable)); return TCL_OK; } static int -ObjRPropsSet( +Configurable_ObjectReadableProps_Set( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -3305,7 +3395,8 @@ ObjRPropsSet( /* * ---------------------------------------------------------------------- * - * ClassWPropsGet, ClassWPropsSet, ObjWPropsGet, ObjWPropsSet -- + * Configurable_ClassWritableProps_Get, Configurable_ClassWritableProps_Set, + * Configurable_ObjectWritableProps_Get, Configurable_ObjectWritableProps_Set -- * * Implementations of the "writableproperties" slot accessors for classes * and instances. @@ -3313,65 +3404,8 @@ ObjRPropsSet( * ---------------------------------------------------------------------- */ -static void -InstallWritableProps( - PropertyStorage *props, - Tcl_Size objc, - Tcl_Obj *const objv[]) -{ - Tcl_Obj *propObj; - Tcl_Size i, n; - int created; - Tcl_HashTable uniqueTable; - - if (props->allWritableCache) { - Tcl_DecrRefCount(props->allWritableCache); - props->allWritableCache = NULL; - } - - for (i=0 ; iwritable) { - Tcl_DecrRefCount(propObj); - } - if (i != objc) { - if (objc == 0) { - Tcl_Free(props->writable.list); - } else if (i) { - props->writable.list = (Tcl_Obj **)Tcl_Realloc(props->writable.list, - sizeof(Tcl_Obj *) * objc); - } else { - props->writable.list = (Tcl_Obj **)Tcl_Alloc(sizeof(Tcl_Obj *) * objc); - } - } - props->writable.num = 0; - if (objc > 0) { - Tcl_InitObjHashTable(&uniqueTable); - for (i=n=0 ; iwritable.list[n++] = objv[i]; - } else { - Tcl_DecrRefCount(objv[i]); - } - } - props->writable.num = n; - - /* - * Shouldn't be necessary, but maintain num/list invariant. - */ - - if (n != objc) { - props->writable.list = (Tcl_Obj **)Tcl_Realloc(props->writable.list, - sizeof(Tcl_Obj *) * n); - } - Tcl_DeleteHashTable(&uniqueTable); - } -} - static int -ClassWPropsGet( +Configurable_ClassWritableProps_Get( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -3379,8 +3413,6 @@ ClassWPropsGet( Tcl_Obj *const *objv) { Class *clsPtr = GetClassDefineCmdContext(interp); - Tcl_Obj *resultObj, *propNameObj; - int i; if (clsPtr == NULL) { return TCL_ERROR; @@ -3390,16 +3422,12 @@ ClassWPropsGet( return TCL_ERROR; } - TclNewObj(resultObj); - FOREACH(propNameObj, clsPtr->properties.writable) { - Tcl_ListObjAppendElement(NULL, resultObj, propNameObj); - } - Tcl_SetObjResult(interp, resultObj); + Tcl_SetObjResult(interp, GetPropertyList(&clsPtr->properties.writable)); return TCL_OK; } static int -ClassWPropsSet( +Configurable_ClassWritableProps_Set( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -3429,7 +3457,7 @@ ClassWPropsSet( } static int -ObjWPropsGet( +Configurable_ObjectWritableProps_Get( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -3437,28 +3465,21 @@ ObjWPropsGet( Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); - Tcl_Obj *resultObj, *propNameObj; - int i; - if (Tcl_ObjectContextSkippedArgs(context) != objc) { + if (oPtr == NULL) { + return TCL_ERROR; + } else if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } - if (oPtr == NULL) { - return TCL_ERROR; - } - TclNewObj(resultObj); - FOREACH(propNameObj, oPtr->properties.writable) { - Tcl_ListObjAppendElement(NULL, resultObj, propNameObj); - } - Tcl_SetObjResult(interp, resultObj); + Tcl_SetObjResult(interp, GetPropertyList(&oPtr->properties.writable)); return TCL_OK; } static int -ObjWPropsSet( +Configurable_ObjectWritableProps_Set( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, @@ -3559,7 +3580,7 @@ TclOORegisterInstanceProperty( TclListObjGetElements(NULL, listObj, &count, &objv); InstallWritableProps(&oPtr->properties, count, objv); } - Tcl_DecrRefCount(listObj); + Tcl_BounceRefCount(listObj); } void @@ -3593,7 +3614,7 @@ TclOORegisterProperty( InstallWritableProps(&clsPtr->properties, count, objv); changed = 1; } - Tcl_DecrRefCount(listObj); + Tcl_BounceRefCount(listObj); if (changed) { BumpGlobalEpoch(clsPtr->thisPtr->fPtr->interp, clsPtr); } @@ -3700,7 +3721,6 @@ TclOOPropertyDefinitionCmd( } hyphenated = Tcl_ObjPrintf("-%s", TclGetString(propObj)); - Tcl_IncrRefCount(hyphenated); if (useInstance) { TclOORegisterInstanceProperty(oPtr, hyphenated, kind != KIND_WO, kind != KIND_RO); @@ -3708,7 +3728,7 @@ TclOOPropertyDefinitionCmd( TclOORegisterProperty(oPtr->classPtr, hyphenated, kind != KIND_WO, kind != KIND_RO); } - Tcl_DecrRefCount(hyphenated); + Tcl_BounceRefCount(hyphenated); /* * Create property implementation methods by using the right @@ -3722,8 +3742,6 @@ TclOOPropertyDefinitionCmd( Tcl_Obj *argsPtr = Tcl_NewObj(); Method *mPtr; - Tcl_IncrRefCount(getterName); - Tcl_IncrRefCount(argsPtr); Tcl_IncrRefCount(getterScript); if (useInstance) { mPtr = TclOONewProcInstanceMethod(interp, oPtr, 0, @@ -3732,8 +3750,8 @@ TclOOPropertyDefinitionCmd( mPtr = TclOONewProcMethod(interp, oPtr->classPtr, 0, getterName, argsPtr, getterScript, NULL); } - Tcl_DecrRefCount(getterName); - Tcl_DecrRefCount(argsPtr); + Tcl_BounceRefCount(getterName); + Tcl_BounceRefCount(argsPtr); Tcl_DecrRefCount(getterScript); if (mPtr == NULL) { return TCL_ERROR; @@ -3745,8 +3763,6 @@ TclOOPropertyDefinitionCmd( Tcl_Obj *argsPtr = Tcl_NewStringObj("value", -1); Method *mPtr; - Tcl_IncrRefCount(setterName); - Tcl_IncrRefCount(argsPtr); Tcl_IncrRefCount(setterScript); if (useInstance) { mPtr = TclOONewProcInstanceMethod(interp, oPtr, 0, @@ -3755,8 +3771,8 @@ TclOOPropertyDefinitionCmd( mPtr = TclOONewProcMethod(interp, oPtr->classPtr, 0, setterName, argsPtr, setterScript, NULL); } - Tcl_DecrRefCount(setterName); - Tcl_DecrRefCount(argsPtr); + Tcl_BounceRefCount(setterName); + Tcl_BounceRefCount(argsPtr); Tcl_DecrRefCount(setterScript); if (mPtr == NULL) { return TCL_ERROR; -- cgit v0.12 From dc1bc43683064aeeeadb9eb05dac8c30cc138b30 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 21 Jul 2024 16:43:47 +0000 Subject: Reduce number of allocations on property access path. --- generic/tclOO.c | 3 +++ generic/tclOOBasic.c | 51 ++++++++++++++++++++++++++------------------------- generic/tclOOInt.h | 1 + 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 8ae30e9..b6f9497 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -338,11 +338,13 @@ InitFoundation( TclNewLiteralStringObj(fPtr->destructorName, ""); TclNewLiteralStringObj(fPtr->clonedName, ""); TclNewLiteralStringObj(fPtr->defineName, "::oo::define"); + TclNewLiteralStringObj(fPtr->myName, "my"); Tcl_IncrRefCount(fPtr->unknownMethodNameObj); Tcl_IncrRefCount(fPtr->constructorName); Tcl_IncrRefCount(fPtr->destructorName); Tcl_IncrRefCount(fPtr->clonedName); Tcl_IncrRefCount(fPtr->defineName); + Tcl_IncrRefCount(fPtr->myName); Tcl_CreateObjCommand(interp, "::oo::UnknownDefinition", TclOOUnknownDefinition, NULL, NULL); TclNewLiteralStringObj(namePtr, "::oo::UnknownDefinition"); @@ -611,6 +613,7 @@ KillFoundation( TclDecrRefCount(fPtr->destructorName); TclDecrRefCount(fPtr->clonedName); TclDecrRefCount(fPtr->defineName); + TclDecrRefCount(fPtr->myName); TclOODecrRefCount(fPtr->objectCls->thisPtr); TclOODecrRefCount(fPtr->classCls->thisPtr); diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index e8b4e13..2f2583d 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -23,6 +23,18 @@ static Tcl_NRPostProc DecrRefsPostClassConstructor; static Tcl_NRPostProc FinalizeConstruction; static Tcl_NRPostProc FinalizeEval; static Tcl_NRPostProc NextRestoreFrame; + +/* Short-term cache for GetPropertyName(). */ +typedef struct GPNCache { + Tcl_Obj *listPtr; /* Holds references to names. */ + char *names[TCLFLEXARRAY]; /* NULL-terminated table of names. */ +} GPNCache; + +enum GPNFlags { + GPN_WRITABLE = 1, /* Are we looking for a writable property? */ + GPN_FALLING_BACK = 2 /* Are we doing a recursive call to determine + * if the property is of the other type? */ +}; /* * ---------------------------------------------------------------------- @@ -1382,16 +1394,17 @@ TclOOCopyObjectCmd( /* * Ugly thunks to read and write a property by calling the right method in - * the right way. + * the right way. Note that we MUST be correct in holding references to Tcl_Obj + * values, as this is potentially a call into user code. */ -static int +static inline int ReadProperty( Tcl_Interp *interp, Object *oPtr, Tcl_Obj *propObj) { Tcl_Obj *args[] = { - Tcl_NewStringObj("my", 2), + oPtr->fPtr->myName, Tcl_ObjPrintf("", TclGetString(propObj)) }; int code; @@ -1415,7 +1428,7 @@ ReadProperty( } } -static int +static inline int WriteProperty( Tcl_Interp *interp, Object *oPtr, @@ -1423,7 +1436,7 @@ WriteProperty( Tcl_Obj *valueObj) { Tcl_Obj *args[] = { - Tcl_NewStringObj("my", 2), + oPtr->fPtr->myName, Tcl_ObjPrintf("", TclGetString(propObj)), valueObj }; @@ -1450,18 +1463,6 @@ WriteProperty( } } -/* Short-term cache for GetPropertyName(). */ -struct Cache { - Tcl_Obj *listPtr; /* Holds references to names. */ - char *names[TCLFLEXARRAY]; /* NULL-terminated table of names. */ -}; - -enum GPNFlags { - GPN_WRITABLE = 1, /* Are we looking for a writable property? */ - GPN_FALLING_BACK = 2 /* Are we doing a recursive call to determine - * if the property is of the other type? */ -}; - /* Look up a property full name. */ static Tcl_Obj * GetPropertyName( @@ -1471,7 +1472,7 @@ GetPropertyName( * Can we do a fallback message? * See GPNFlags for possible values */ Tcl_Obj *namePtr, /* The name supplied by the user. */ - struct Cache **cachePtr) /* Where to cache the table, if the caller + GPNCache **cachePtr) /* Where to cache the table, if the caller * wants that. The contents are to be freed * with Tcl_Free if the cache is used. */ { @@ -1479,14 +1480,14 @@ GetPropertyName( Tcl_Obj *listPtr = TclOOGetAllObjectProperties( oPtr, flags & GPN_WRITABLE); Tcl_Obj **objv; - struct Cache *tablePtr; + GPNCache *tablePtr; (void) Tcl_ListObjGetElements(NULL, listPtr, &objc, &objv); if (cachePtr && *cachePtr) { tablePtr = *cachePtr; } else { - tablePtr = (struct Cache *) TclStackAlloc(interp, - offsetof(struct Cache, names) + sizeof(char *) * (objc + 1)); + tablePtr = (GPNCache *) TclStackAlloc(interp, + offsetof(GPNCache, names) + sizeof(char *) * (objc + 1)); for (i = 0; i < objc; i++) { tablePtr->names[i] = TclGetString(objv[i]); @@ -1538,13 +1539,13 @@ GetPropertyName( } /* Release the cache made by GetPropertyName(). */ -static void +static inline void ReleasePropertyNameCache( Tcl_Interp *interp, - struct Cache **cachePtr) + GPNCache **cachePtr) { if (*cachePtr) { - struct Cache *tablePtr = *cachePtr; + GPNCache *tablePtr = *cachePtr; if (tablePtr->listPtr) { Tcl_DecrRefCount(tablePtr->listPtr); } @@ -1636,7 +1637,7 @@ TclOO_Configurable_Configure( * Write properties. Slightly tricky because we want to cache the * table of property names. */ - struct Cache *cache = NULL; + GPNCache *cache = NULL; code = TCL_OK; for (i = 0; i < objc; i += 2) { diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index c31c461..124953d 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -402,6 +402,7 @@ typedef struct Foundation { Tcl_Obj *clonedName; /* Shared object containing the name of a * "" pseudo-constructor. */ Tcl_Obj *defineName; /* Fully qualified name of oo::define. */ + Tcl_Obj *myName; /* The "my" shared object. */ } Foundation; /* -- cgit v0.12 From b96569028387bed872c2070fc1b25583ec62074a Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 29 Jul 2024 08:58:56 +0000 Subject: Factor out CmdFrame init and fix bug with body line numbers --- generic/tclOOMethod.c | 163 +++++++++++++++++++------------------------------- tests/oo.test | 70 ++++++++++++++++++++++ 2 files changed, 132 insertions(+), 101 deletions(-) diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c index 6f14198..f60b1c2 100644 --- a/generic/tclOOMethod.c +++ b/generic/tclOOMethod.c @@ -502,45 +502,20 @@ TclOONewProcMethod( /* * ---------------------------------------------------------------------- * - * TclOOMakeProcInstanceMethod -- + * InitCmdFrame -- * - * The guts of the code to make a procedure-like method for an object. - * Split apart so that it is easier for other extensions to reuse (in - * particular, it frees them from having to pry so deeply into Tcl's - * guts). + * Set up a CmdFrame to record the source location for a procedure + * method. Assumes that the body is the last argument to the command + * creating the method, a good assumption because putting the body + * elsewhere is ugly. * * ---------------------------------------------------------------------- */ - -Tcl_Method -TclOOMakeProcInstanceMethod( - Tcl_Interp *interp, /* The interpreter containing the object. */ - Object *oPtr, /* The object to modify. */ - int flags, /* Whether this is a public method. */ - Tcl_Obj *nameObj, /* The name of the method, which _must not_ be - * NULL. */ - Tcl_Obj *argsObj, /* The formal argument list for the method, - * which _must not_ be NULL. */ - Tcl_Obj *bodyObj, /* The body of the method, which _must not_ be - * NULL. */ - const Tcl_MethodType *typePtr, - /* The type of the method to create. */ - void *clientData, /* The per-method type-specific data. */ - Proc **procPtrPtr) /* A pointer to the variable in which to write - * the procedure record reference. Presumably - * inside the structure indicated by the - * pointer in clientData. */ +static inline void +InitCmdFrame( + Interp *iPtr, /* Where source locations are recorded. */ + Proc *procPtr) /* Guts of the method being made. */ { - Interp *iPtr = (Interp *) interp; - Proc *procPtr; - - if (TclCreateProc(interp, NULL, TclGetString(nameObj), argsObj, bodyObj, - procPtrPtr) != TCL_OK) { - return NULL; - } - procPtr = *procPtrPtr; - procPtr->cmdPtr = NULL; - if (iPtr->cmdFramePtr) { CmdFrame context = *iPtr->cmdFramePtr; @@ -565,20 +540,23 @@ TclOOMakeProcInstanceMethod( if (context.type == TCL_LOCATION_SOURCE) { /* * We can account for source location within a proc only if the - * proc body was not created by substitution. + * proc body was not created by substitution. This is where we + * assume that the body is the last argument; the index of the body + * is NOT a fixed count of arguments in because of the alternate + * form of [oo::define]/[oo::objdefine]. * (FIXME: check that this is sane and correct!) */ - if (context.line - && (context.nline >= 4) && (context.line[3] >= 0)) { + if (context.line && context.nline > 1 + && (context.line[context.nline - 1] >= 0)) { int isNew; CmdFrame *cfPtr = (CmdFrame *)Tcl_Alloc(sizeof(CmdFrame)); Tcl_HashEntry *hPtr; cfPtr->level = -1; cfPtr->type = context.type; - cfPtr->line = (Tcl_Size *)Tcl_Alloc(sizeof(Tcl_Size)); - cfPtr->line[0] = context.line[3]; + cfPtr->line = (Tcl_Size *) Tcl_Alloc(sizeof(Tcl_Size)); + cfPtr->line[0] = context.line[context.nline - 1]; cfPtr->nline = 1; cfPtr->framePtr = NULL; cfPtr->nextPtr = NULL; @@ -602,7 +580,51 @@ TclOOMakeProcInstanceMethod( Tcl_DecrRefCount(context.data.eval.path); context.data.eval.path = NULL; } + }} + +/* + * ---------------------------------------------------------------------- + * + * TclOOMakeProcInstanceMethod -- + * + * The guts of the code to make a procedure-like method for an object. + * Split apart so that it is easier for other extensions to reuse (in + * particular, it frees them from having to pry so deeply into Tcl's + * guts). + * + * ---------------------------------------------------------------------- + */ + +Tcl_Method +TclOOMakeProcInstanceMethod( + Tcl_Interp *interp, /* The interpreter containing the object. */ + Object *oPtr, /* The object to modify. */ + int flags, /* Whether this is a public method. */ + Tcl_Obj *nameObj, /* The name of the method, which _must not_ be + * NULL. */ + Tcl_Obj *argsObj, /* The formal argument list for the method, + * which _must not_ be NULL. */ + Tcl_Obj *bodyObj, /* The body of the method, which _must not_ be + * NULL. */ + const Tcl_MethodType *typePtr, + /* The type of the method to create. */ + void *clientData, /* The per-method type-specific data. */ + Proc **procPtrPtr) /* A pointer to the variable in which to write + * the procedure record reference. Presumably + * inside the structure indicated by the + * pointer in clientData. */ +{ + Interp *iPtr = (Interp *) interp; + Proc *procPtr; + + if (TclCreateProc(interp, NULL, TclGetString(nameObj), argsObj, bodyObj, + procPtrPtr) != TCL_OK) { + return NULL; } + procPtr = *procPtrPtr; + procPtr->cmdPtr = NULL; + + InitCmdFrame(iPtr, procPtr); return TclNewInstanceMethod(interp, (Tcl_Object) oPtr, nameObj, flags, typePtr, clientData); @@ -654,68 +676,7 @@ TclOOMakeProcMethod( procPtr = *procPtrPtr; procPtr->cmdPtr = NULL; - if (iPtr->cmdFramePtr) { - CmdFrame context = *iPtr->cmdFramePtr; - - if (context.type == TCL_LOCATION_BC) { - /* - * Retrieve source information from the bytecode, if possible. If - * the information is retrieved successfully, context.type will be - * TCL_LOCATION_SOURCE and the reference held by - * context.data.eval.path will be counted. - */ - - TclGetSrcInfoForPc(&context); - } else if (context.type == TCL_LOCATION_SOURCE) { - /* - * The copy into 'context' up above has created another reference - * to 'context.data.eval.path'; account for it. - */ - - Tcl_IncrRefCount(context.data.eval.path); - } - - if (context.type == TCL_LOCATION_SOURCE) { - /* - * We can account for source location within a proc only if the - * proc body was not created by substitution. - * (FIXME: check that this is sane and correct!) - */ - - if (context.line - && (context.nline >= 4) && (context.line[3] >= 0)) { - int isNew; - CmdFrame *cfPtr = (CmdFrame *)Tcl_Alloc(sizeof(CmdFrame)); - Tcl_HashEntry *hPtr; - - cfPtr->level = -1; - cfPtr->type = context.type; - cfPtr->line = (Tcl_Size *)Tcl_Alloc(sizeof(Tcl_Size)); - cfPtr->line[0] = context.line[3]; - cfPtr->nline = 1; - cfPtr->framePtr = NULL; - cfPtr->nextPtr = NULL; - - cfPtr->data.eval.path = context.data.eval.path; - Tcl_IncrRefCount(cfPtr->data.eval.path); - - cfPtr->cmd = NULL; - cfPtr->len = 0; - - hPtr = Tcl_CreateHashEntry(iPtr->linePBodyPtr, - procPtr, &isNew); - Tcl_SetHashValue(hPtr, cfPtr); - } - - /* - * 'context' is going out of scope; account for the reference that - * it's holding to the path name. - */ - - Tcl_DecrRefCount(context.data.eval.path); - context.data.eval.path = NULL; - } - } + InitCmdFrame(iPtr, procPtr); return TclNewMethod(interp, (Tcl_Class) clsPtr, nameObj, flags, typePtr, clientData); diff --git a/tests/oo.test b/tests/oo.test index 769a96b..6f8d5b5 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -3620,6 +3620,76 @@ test oo-22.6 {OO and coroutines and info frame: Bug 87271f7cd6} -body { catch {B destroy} } -match glob -result {{* method Work class ::A *} {* method Work class ::A *}} WorkerBase destroy +test oo-22.7 {oo::define and info frame: correct argument line} -setup { + oo::class create C { + variable base + constructor {info} {set base [dict get $info line]} + method Relative {} { + set info [next] + if {![dict exists $info file]} { + error "no file-relative line info: $info" + } + expr {[dict get $info line] - $base} + } + filter Relative + } +} -body { + C create o [info frame 0] + oo::define C { + method line1 {} {info frame 0} + method line2 { + } {info frame 0} + method line3 { + } { + info frame 0 + } + } + oo::define C method line4 {} {info frame 0} + oo::define C method line5 { + } {info frame 0} + oo::define C method line6 { + } { + info frame 0 + } + list [o line1] [o line2] [o line3] [o line4] [o line5] [o line6] +} -cleanup { + C destroy +} -result {2 4 7 10 12 15} +test oo-22.8 {oo::objdefine and info frame: correct argument line} -setup { + oo::class create C { + variable base + constructor {info} {set base [dict get $info line]} + method Relative {} { + set info [next] + if {![dict exists $info file]} { + error "no file-relative line info: $info" + } + expr {[dict get $info line] - $base} + } + filter Relative + } +} -body { + C create o [info frame 0] + oo::objdefine o { + method line1 {} {info frame 0} + method line2 { + } {info frame 0} + method line3 { + } { + info frame 0 + } + } + oo::objdefine o method line4 {} {info frame 0} + oo::objdefine o method line5 { + } {info frame 0} + oo::objdefine o method line6 { + } { + info frame 0 + } + list [o line1] [o line2] [o line3] [o line4] [o line5] [o line6] +} -cleanup { + C destroy +} -result {2 4 7 10 12 15} # Prove that the issue in [Bug 1865054] isn't an issue any more test oo-23.1 {Self-like derivation; complex case!} -setup { -- cgit v0.12 From 2ec6708224853911b1636d5ff3976a6a60ab331b Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 1 Aug 2024 15:38:25 +0000 Subject: Use Tcl's internal API a bit better --- generic/tclOO.c | 269 +++++++++++++++++++++++++--------------------- generic/tclOO.h | 29 ++--- generic/tclOOBasic.c | 70 ++++++------ generic/tclOOCall.c | 170 ++++++++++++++--------------- generic/tclOODefineCmds.c | 105 ++++++++++-------- generic/tclOOInfo.c | 126 +++++++++++++++------- generic/tclOOInt.h | 243 +++++++++++++++++++++-------------------- generic/tclOOMethod.c | 128 +++++++++++----------- 8 files changed, 620 insertions(+), 520 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index b6f9497..288b7f2 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -67,8 +67,6 @@ static int CloneClassMethod(Tcl_Interp *interp, Class *clsPtr, Method **newMPtrPtr); static int CloneObjectMethod(Tcl_Interp *interp, Object *oPtr, Method *mPtr, Tcl_Obj *namePtr); -static void DeletedDefineNamespace(void *clientData); -static void DeletedObjdefNamespace(void *clientData); static void DeletedHelpersNamespace(void *clientData); static Tcl_NRPostProc FinalizeAlloc; static Tcl_NRPostProc FinalizeNext; @@ -291,6 +289,37 @@ TclOOGetFoundation( /* * ---------------------------------------------------------------------- * + * CreateCmdInNS -- + * + * Create a command in a namespace. Supports setting various + * implementation functions, but not a deletion callback or a clientData; + * it's suitable for use-cases in this file, no more. + * + * ---------------------------------------------------------------------- + */ +static inline void +CreateCmdInNS( + Tcl_Interp *interp, + Tcl_Namespace *namespacePtr, + const char *name, + Tcl_ObjCmdProc *cmdProc, + Tcl_ObjCmdProc *nreProc, + CompileProc *compileProc) +{ + Command *cmdPtr; + + if (cmdProc == NULL && nreProc == NULL) { + Tcl_Panic("must supply at least one implementation function"); + } + cmdPtr = (Command *) TclCreateObjCommandInNs(interp, name, + namespacePtr, cmdProc, NULL, NULL); + cmdPtr->nreProc = nreProc; + cmdPtr->compileProc = compileProc; +} + +/* + * ---------------------------------------------------------------------- + * * InitFoundation -- * * Set up the core of the OO core class system. This is a structure @@ -305,12 +334,11 @@ InitFoundation( Tcl_Interp *interp) { static Tcl_ThreadDataKey tsdKey; - ThreadLocalData *tsdPtr = - (ThreadLocalData *)Tcl_GetThreadData(&tsdKey, sizeof(ThreadLocalData)); - Foundation *fPtr = (Foundation *)Tcl_Alloc(sizeof(Foundation)); + ThreadLocalData *tsdPtr = (ThreadLocalData *) + Tcl_GetThreadData(&tsdKey, sizeof(ThreadLocalData)); + Foundation *fPtr = (Foundation *) Tcl_Alloc(sizeof(Foundation)); + Tcl_Namespace *define, *objdef, *cfg; Tcl_Obj *namePtr; - Tcl_DString buffer; - Command *cmdPtr; size_t i; /* @@ -324,15 +352,14 @@ InitFoundation( fPtr->interp = interp; fPtr->ooNs = Tcl_CreateNamespace(interp, "::oo", fPtr, NULL); Tcl_Export(interp, fPtr->ooNs, "[a-z]*", 1); - fPtr->defineNs = Tcl_CreateNamespace(interp, "::oo::define", fPtr, - DeletedDefineNamespace); - fPtr->objdefNs = Tcl_CreateNamespace(interp, "::oo::objdefine", fPtr, - DeletedObjdefNamespace); + define = Tcl_CreateNamespace(interp, "::oo::define", fPtr, NULL); + objdef = Tcl_CreateNamespace(interp, "::oo::objdefine", fPtr, NULL); fPtr->helpersNs = Tcl_CreateNamespace(interp, "::oo::Helpers", fPtr, DeletedHelpersNamespace); - Tcl_CreateNamespace(interp, "::oo::configuresupport", NULL, NULL); + cfg = Tcl_CreateNamespace(interp, "::oo::configuresupport", NULL, NULL); fPtr->epoch = 1; fPtr->tsdPtr = tsdPtr; + TclNewLiteralStringObj(fPtr->unknownMethodNameObj, "unknown"); TclNewLiteralStringObj(fPtr->constructorName, ""); TclNewLiteralStringObj(fPtr->destructorName, ""); @@ -345,30 +372,25 @@ InitFoundation( Tcl_IncrRefCount(fPtr->clonedName); Tcl_IncrRefCount(fPtr->defineName); Tcl_IncrRefCount(fPtr->myName); - Tcl_CreateObjCommand(interp, "::oo::UnknownDefinition", + + TclCreateObjCommandInNs(interp, "UnknownDefinition", fPtr->ooNs, TclOOUnknownDefinition, NULL, NULL); TclNewLiteralStringObj(namePtr, "::oo::UnknownDefinition"); - Tcl_SetNamespaceUnknownHandler(interp, fPtr->defineNs, namePtr); - Tcl_SetNamespaceUnknownHandler(interp, fPtr->objdefNs, namePtr); + Tcl_SetNamespaceUnknownHandler(interp, define, namePtr); + Tcl_SetNamespaceUnknownHandler(interp, objdef, namePtr); + Tcl_BounceRefCount(namePtr); /* * Create the subcommands in the oo::define and oo::objdefine spaces. */ - Tcl_DStringInit(&buffer); for (i = 0 ; defineCmds[i].name ; i++) { - TclDStringAppendLiteral(&buffer, "::oo::define::"); - Tcl_DStringAppend(&buffer, defineCmds[i].name, -1); - Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer), + TclCreateObjCommandInNs(interp, defineCmds[i].name, define, defineCmds[i].objProc, INT2PTR(defineCmds[i].flag), NULL); - Tcl_DStringFree(&buffer); } for (i = 0 ; objdefCmds[i].name ; i++) { - TclDStringAppendLiteral(&buffer, "::oo::objdefine::"); - Tcl_DStringAppend(&buffer, objdefCmds[i].name, -1); - Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer), + TclCreateObjCommandInNs(interp, objdefCmds[i].name, objdef, objdefCmds[i].objProc, INT2PTR(objdefCmds[i].flag), NULL); - Tcl_DStringFree(&buffer); } Tcl_CallWhenDeleted(interp, KillFoundation, NULL); @@ -384,10 +406,10 @@ InitFoundation( */ for (i = 0 ; objMethods[i].name ; i++) { - TclOONewBasicMethod(interp, fPtr->objectCls, &objMethods[i]); + TclOONewBasicMethod(fPtr->objectCls, &objMethods[i]); } for (i = 0 ; clsMethods[i].name ; i++) { - TclOONewBasicMethod(interp, fPtr->classCls, &clsMethods[i]); + TclOONewBasicMethod(fPtr->classCls, &clsMethods[i]); } /* @@ -399,7 +421,8 @@ InitFoundation( TclNewLiteralStringObj(namePtr, "new"); TclNewInstanceMethod(interp, (Tcl_Object) fPtr->classCls->thisPtr, namePtr /* keeps ref */, 0 /* private */, NULL, NULL); - fPtr->classCls->constructorPtr = (Method *) TclNewMethod(interp, + Tcl_BounceRefCount(namePtr); + fPtr->classCls->constructorPtr = (Method *) TclNewMethod( (Tcl_Class) fPtr->classCls, NULL, 0, &classConstructor, NULL); /* @@ -407,20 +430,17 @@ InitFoundation( * ensemble. */ - cmdPtr = (Command *) Tcl_NRCreateCommand(interp, "::oo::Helpers::next", - NULL, TclOONextObjCmd, NULL, NULL); - cmdPtr->compileProc = TclCompileObjectNextCmd; - cmdPtr = (Command *) Tcl_NRCreateCommand(interp, "::oo::Helpers::nextto", - NULL, TclOONextToObjCmd, NULL, NULL); - cmdPtr->compileProc = TclCompileObjectNextToCmd; - cmdPtr = (Command *) Tcl_CreateObjCommand(interp, "::oo::Helpers::self", - TclOOSelfObjCmd, NULL, NULL); - cmdPtr->compileProc = TclCompileObjectSelfCmd; - Tcl_CreateObjCommand(interp, "::oo::define", TclOODefineObjCmd, NULL, - NULL); - Tcl_CreateObjCommand(interp, "::oo::objdefine", TclOOObjDefObjCmd, NULL, - NULL); - Tcl_CreateObjCommand(interp, "::oo::copy", TclOOCopyObjectCmd, NULL,NULL); + CreateCmdInNS(interp, fPtr->helpersNs, "next", + NULL, TclOONextObjCmd, TclCompileObjectNextCmd); + CreateCmdInNS(interp, fPtr->helpersNs, "nextto", + NULL, TclOONextToObjCmd, TclCompileObjectNextToCmd); + CreateCmdInNS(interp, fPtr->helpersNs, "self", + TclOOSelfObjCmd, NULL, TclCompileObjectSelfCmd); + + CreateCmdInNS(interp, fPtr->ooNs, "define", TclOODefineObjCmd, NULL, NULL); + CreateCmdInNS(interp, fPtr->ooNs, "objdefine", TclOOObjDefObjCmd, NULL, NULL); + CreateCmdInNS(interp, fPtr->ooNs, "copy", TclOOCopyObjectCmd, NULL, NULL); + TclOOInitInfo(interp); /* @@ -439,13 +459,17 @@ InitFoundation( (Tcl_Class) fPtr->classCls, "::oo::configuresupport::configurable", NULL, -1, NULL, 0); for (i = 0 ; cfgMethods[i].name ; i++) { - TclOONewBasicMethod(interp, ((Object *) cfgCls)->classPtr, - &cfgMethods[i]); + TclOONewBasicMethod(((Object *) cfgCls)->classPtr, &cfgMethods[i]); } - Tcl_CreateObjCommand(interp, "::oo::configuresupport::StdObjectProperties", + TclCreateObjCommandInNs(interp, "StdObjectProperties", cfg, TclOOInstallStdPropertyImplsCmd, (void *) 1, NULL); - Tcl_CreateObjCommand(interp, "::oo::configuresupport::StdClassProperties", + TclCreateObjCommandInNs(interp, "StdClassProperties", cfg, TclOOInstallStdPropertyImplsCmd, (void *) 0, NULL); + + /* + * Don't have handles to these namespaces, so use Tcl_CreateObjCommand. + */ + Tcl_CreateObjCommand(interp, "::oo::configuresupport::configurableobject::property", TclOOPropertyDefinitionCmd, (void *) 1, NULL); @@ -487,7 +511,7 @@ InitClassSystemRoots( fakeObject.refCount = 0; // Do not increment an uninitialized value. fPtr->objectCls = TclOOAllocClass(interp, - AllocObject(interp, "object", (Namespace *)fPtr->ooNs, NULL)); + AllocObject(interp, "object", (Namespace *) fPtr->ooNs, NULL)); // Corresponding TclOODecrRefCount in KillFoundation AddRef(fPtr->objectCls->thisPtr); @@ -512,7 +536,7 @@ InitClassSystemRoots( Tcl_IncrRefCount(defNsName); fPtr->classCls = TclOOAllocClass(interp, - AllocObject(interp, "class", (Namespace *)fPtr->ooNs, NULL)); + AllocObject(interp, "class", (Namespace *) fPtr->ooNs, NULL)); // Corresponding TclOODecrRefCount in KillFoundation AddRef(fPtr->classCls->thisPtr); @@ -554,37 +578,19 @@ InitClassSystemRoots( /* * ---------------------------------------------------------------------- * - * DeletedDefineNamespace, DeletedObjdefNamespace, DeletedHelpersNamespace -- + * DeletedHelpersNamespace -- * - * Simple helpers used to clear fields of the foundation when they no + * Simple helper used to clear fields of the foundation when they no * longer hold useful information. * * ---------------------------------------------------------------------- */ static void -DeletedDefineNamespace( - void *clientData) -{ - Foundation *fPtr = (Foundation *)clientData; - - fPtr->defineNs = NULL; -} - -static void -DeletedObjdefNamespace( - void *clientData) -{ - Foundation *fPtr = (Foundation *)clientData; - - fPtr->objdefNs = NULL; -} - -static void DeletedHelpersNamespace( void *clientData) { - Foundation *fPtr = (Foundation *)clientData; + Foundation *fPtr = (Foundation *) clientData; fPtr->helpersNs = NULL; } @@ -618,6 +624,12 @@ KillFoundation( TclOODecrRefCount(fPtr->classCls->thisPtr); Tcl_Free(fPtr); + + /* + * Don't leave the interpreter field pointing to freed data. + */ + + ((Interp *) interp)->objectFoundation = NULL; } /* @@ -657,7 +669,7 @@ AllocObject( CommandTrace *tracePtr; size_t creationEpoch; - oPtr = (Object *)Tcl_Alloc(sizeof(Object)); + oPtr = (Object *) Tcl_Alloc(sizeof(Object)); memset(oPtr, 0, sizeof(Object)); /* @@ -684,7 +696,8 @@ AllocObject( while (1) { char objName[10 + TCL_INTEGER_SPACE]; - snprintf(objName, sizeof(objName), "::oo::Obj%" TCL_Z_MODIFIER "u", ++fPtr->tsdPtr->nsCount); + snprintf(objName, sizeof(objName), "::oo::Obj%" TCL_Z_MODIFIER "u", + ++fPtr->tsdPtr->nsCount); oPtr->namespacePtr = Tcl_CreateNamespace(interp, objName, oPtr, NULL); if (oPtr->namespacePtr != NULL) { creationEpoch = fPtr->tsdPtr->nsCount; @@ -753,13 +766,13 @@ AllocObject( if (!nameStr) { nameStr = oPtr->namespacePtr->name; - nsPtr = (Namespace *)oPtr->namespacePtr; + nsPtr = (Namespace *) oPtr->namespacePtr; if (nsPtr->parentPtr != NULL) { nsPtr = nsPtr->parentPtr; } } oPtr->command = TclCreateObjCommandInNs(interp, nameStr, - (Tcl_Namespace *)nsPtr, TclOOPublicObjectCmd, oPtr, NULL); + (Tcl_Namespace *) nsPtr, TclOOPublicObjectCmd, oPtr, NULL); /* * Add the NRE command and trace directly. While this breaks a number of @@ -768,7 +781,8 @@ AllocObject( cmdPtr = (Command *) oPtr->command; cmdPtr->nreProc = PublicNRObjectCmd; - cmdPtr->tracePtr = tracePtr = (CommandTrace *)Tcl_Alloc(sizeof(CommandTrace)); + cmdPtr->tracePtr = tracePtr = (CommandTrace *) + Tcl_Alloc(sizeof(CommandTrace)); tracePtr->traceProc = ObjectRenamedTrace; tracePtr->clientData = oPtr; tracePtr->flags = TCL_TRACE_RENAME|TCL_TRACE_DELETE; @@ -822,7 +836,7 @@ MyDeleted( void *clientData) /* Reference to the object whose [my] has been * squelched. */ { - Object *oPtr = (Object *)clientData; + Object *oPtr = (Object *) clientData; oPtr->myCommand = NULL; } @@ -831,7 +845,7 @@ static void MyClassDeleted( void *clientData) { - Object *oPtr = (Object *)clientData; + Object *oPtr = (Object *) clientData; oPtr->myclassCommand = NULL; } @@ -856,7 +870,7 @@ ObjectRenamedTrace( TCL_UNUSED(const char *) /*newName*/, int flags) /* Why was the object deleted? */ { - Object *oPtr = (Object *)clientData; + Object *oPtr = (Object *) clientData; /* * If this is a rename and not a delete of the object, we just flush the @@ -1166,7 +1180,7 @@ ObjectNamespaceDeleted( void *clientData) /* Pointer to the class whose namespace is * being deleted. */ { - Object *oPtr = (Object *)clientData; + Object *oPtr = (Object *) clientData; Foundation *fPtr = oPtr->fPtr; FOREACH_HASH_DECLS; Class *mixinPtr; @@ -1248,14 +1262,14 @@ ObjectNamespaceDeleted( * as well. */ - Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command); + Tcl_DeleteCommandFromToken(interp, oPtr->command); } if (oPtr->myclassCommand) { - Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->myclassCommand); + Tcl_DeleteCommandFromToken(interp, oPtr->myclassCommand); } if (oPtr->myCommand) { - Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->myCommand); + Tcl_DeleteCommandFromToken(interp, oPtr->myCommand); } /* @@ -1372,7 +1386,7 @@ ObjectNamespaceDeleted( * Delete the object structure itself. */ - TclNsDecrRefCount((Namespace *)oPtr->namespacePtr); + TclNsDecrRefCount((Namespace *) oPtr->namespacePtr); oPtr->namespacePtr = NULL; TclOODecrRefCount(oPtr->selfCls->thisPtr); oPtr->selfCls = NULL; @@ -1477,10 +1491,12 @@ TclOOAddToInstances( if (clsPtr->instances.num >= clsPtr->instances.size) { clsPtr->instances.size += ALLOC_CHUNK; if (clsPtr->instances.size == ALLOC_CHUNK) { - clsPtr->instances.list = (Object **)Tcl_Alloc(sizeof(Object *) * ALLOC_CHUNK); + clsPtr->instances.list = (Object **) + Tcl_Alloc(sizeof(Object *) * ALLOC_CHUNK); } else { - clsPtr->instances.list = (Object **)Tcl_Realloc(clsPtr->instances.list, - sizeof(Object *) * clsPtr->instances.size); + clsPtr->instances.list = (Object **) + Tcl_Realloc(clsPtr->instances.list, + sizeof(Object *) * clsPtr->instances.size); } } clsPtr->instances.list[clsPtr->instances.num++] = oPtr; @@ -1578,10 +1594,12 @@ TclOOAddToSubclasses( if (superPtr->subclasses.num >= superPtr->subclasses.size) { superPtr->subclasses.size += ALLOC_CHUNK; if (superPtr->subclasses.size == ALLOC_CHUNK) { - superPtr->subclasses.list = (Class **)Tcl_Alloc(sizeof(Class *) * ALLOC_CHUNK); + superPtr->subclasses.list = (Class **) + Tcl_Alloc(sizeof(Class *) * ALLOC_CHUNK); } else { - superPtr->subclasses.list = (Class **)Tcl_Realloc(superPtr->subclasses.list, - sizeof(Class *) * superPtr->subclasses.size); + superPtr->subclasses.list = (Class **) + Tcl_Realloc(superPtr->subclasses.list, + sizeof(Class *) * superPtr->subclasses.size); } } superPtr->subclasses.list[superPtr->subclasses.num++] = subPtr; @@ -1644,10 +1662,12 @@ TclOOAddToMixinSubs( if (superPtr->mixinSubs.num >= superPtr->mixinSubs.size) { superPtr->mixinSubs.size += ALLOC_CHUNK; if (superPtr->mixinSubs.size == ALLOC_CHUNK) { - superPtr->mixinSubs.list = (Class **)Tcl_Alloc(sizeof(Class *) * ALLOC_CHUNK); + superPtr->mixinSubs.list = (Class **) + Tcl_Alloc(sizeof(Class *) * ALLOC_CHUNK); } else { - superPtr->mixinSubs.list = (Class **)Tcl_Realloc(superPtr->mixinSubs.list, - sizeof(Class *) * superPtr->mixinSubs.size); + superPtr->mixinSubs.list = (Class **) + Tcl_Realloc(superPtr->mixinSubs.list, + sizeof(Class *) * superPtr->mixinSubs.size); } } superPtr->mixinSubs.list[superPtr->mixinSubs.num++] = subPtr; @@ -1692,7 +1712,7 @@ TclOOAllocClass( * representation. */ { Foundation *fPtr = GetFoundation(interp); - Class *clsPtr = (Class *)Tcl_Alloc(sizeof(Class)); + Class *clsPtr = (Class *) Tcl_Alloc(sizeof(Class)); memset(clsPtr, 0, sizeof(Class)); clsPtr->thisPtr = useThisObj; @@ -1709,7 +1729,7 @@ TclOOAllocClass( */ clsPtr->superclasses.num = 1; - clsPtr->superclasses.list = (Class **)Tcl_Alloc(sizeof(Class *)); + clsPtr->superclasses.list = (Class **) Tcl_Alloc(sizeof(Class *)); clsPtr->superclasses.list[0] = fPtr->objectCls; AddRef(fPtr->objectCls->thisPtr); @@ -1937,10 +1957,10 @@ FinalizeAlloc( Tcl_Interp *interp, int result) { - CallContext *contextPtr = (CallContext *)data[0]; - Object *oPtr = (Object *)data[1]; - Tcl_InterpState state = (Tcl_InterpState)data[2]; - Tcl_Object *objectPtr = (Tcl_Object *)data[3]; + CallContext *contextPtr = (CallContext *) data[0]; + Object *oPtr = (Object *) data[1]; + Tcl_InterpState state = (Tcl_InterpState) data[2]; + Tcl_Object *objectPtr = (Tcl_Object *) data[3]; /* * Ensure an error if the object was deleted in the constructor. Don't @@ -2161,11 +2181,12 @@ Tcl_CopyObjectInstance( TclOODecrRefCount(superPtr->thisPtr); } if (cls2Ptr->superclasses.num) { - cls2Ptr->superclasses.list = (Class **)Tcl_Realloc(cls2Ptr->superclasses.list, - sizeof(Class *) * clsPtr->superclasses.num); + cls2Ptr->superclasses.list = (Class **) + Tcl_Realloc(cls2Ptr->superclasses.list, + sizeof(Class *) * clsPtr->superclasses.num); } else { - cls2Ptr->superclasses.list = - (Class **)Tcl_Alloc(sizeof(Class *) * clsPtr->superclasses.num); + cls2Ptr->superclasses.list = (Class **) + Tcl_Alloc(sizeof(Class *) * clsPtr->superclasses.num); } memcpy(cls2Ptr->superclasses.list, clsPtr->superclasses.list, sizeof(Class *) * clsPtr->superclasses.num); @@ -2359,7 +2380,7 @@ CloneClassMethod( Method *m2Ptr; if (mPtr->typePtr == NULL) { - m2Ptr = (Method *) TclNewMethod(interp, (Tcl_Class) clsPtr, + m2Ptr = (Method *) TclNewMethod((Tcl_Class) clsPtr, namePtr, mPtr->flags & PUBLIC_METHOD, NULL, NULL); } else if (mPtr->typePtr->cloneProc) { void *newClientData; @@ -2368,11 +2389,11 @@ CloneClassMethod( &newClientData) != TCL_OK) { return TCL_ERROR; } - m2Ptr = (Method *) TclNewMethod(interp, (Tcl_Class) clsPtr, + m2Ptr = (Method *) TclNewMethod((Tcl_Class) clsPtr, namePtr, mPtr->flags & PUBLIC_METHOD, mPtr->typePtr, newClientData); } else { - m2Ptr = (Method *) TclNewMethod(interp, (Tcl_Class) clsPtr, + m2Ptr = (Method *) TclNewMethod((Tcl_Class) clsPtr, namePtr, mPtr->flags & PUBLIC_METHOD, mPtr->typePtr, mPtr->clientData); } @@ -2459,7 +2480,8 @@ Tcl_ClassSetMetadata( if (metadata == NULL) { return; } - clsPtr->metadataPtr = (Tcl_HashTable *)Tcl_Alloc(sizeof(Tcl_HashTable)); + clsPtr->metadataPtr = (Tcl_HashTable *) + Tcl_Alloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(clsPtr->metadataPtr, TCL_ONE_WORD_KEYS); } @@ -2539,7 +2561,7 @@ Tcl_ObjectSetMetadata( if (metadata == NULL) { return; } - oPtr->metadataPtr = (Tcl_HashTable *)Tcl_Alloc(sizeof(Tcl_HashTable)); + oPtr->metadataPtr = (Tcl_HashTable *) Tcl_Alloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(oPtr->metadataPtr, TCL_ONE_WORD_KEYS); } @@ -2588,7 +2610,7 @@ TclOOPublicObjectCmd( int objc, Tcl_Obj *const *objv) { - return Tcl_NRCallObjProc(interp, PublicNRObjectCmd, clientData,objc,objv); + return Tcl_NRCallObjProc(interp, PublicNRObjectCmd, clientData, objc, objv); } static int @@ -2598,8 +2620,8 @@ PublicNRObjectCmd( int objc, Tcl_Obj *const *objv) { - return TclOOObjectCmdCore((Object *)clientData, interp, objc, objv, PUBLIC_METHOD, - NULL); + return TclOOObjectCmdCore((Object *) clientData, interp, objc, objv, + PUBLIC_METHOD, NULL); } int @@ -2609,7 +2631,7 @@ TclOOPrivateObjectCmd( int objc, Tcl_Obj *const *objv) { - return Tcl_NRCallObjProc(interp, PrivateNRObjectCmd,clientData,objc,objv); + return Tcl_NRCallObjProc(interp, PrivateNRObjectCmd, clientData, objc, objv); } static int @@ -2619,7 +2641,7 @@ PrivateNRObjectCmd( int objc, Tcl_Obj *const *objv) { - return TclOOObjectCmdCore((Object *)clientData, interp, objc, objv, 0, NULL); + return TclOOObjectCmdCore((Object *) clientData, interp, objc, objv, 0, NULL); } int @@ -2680,7 +2702,7 @@ MyClassNRObjCmd( int objc, Tcl_Obj *const *objv) { - Object *oPtr = (Object *)clientData; + Object *oPtr = (Object *) clientData; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "methodName ?arg ...?"); @@ -2739,7 +2761,7 @@ TclOOObjectCmdCore( */ if (framePtr->isProcCallFrame & FRAME_IS_METHOD) { - CallContext *callerContextPtr = (CallContext *)framePtr->clientData; + CallContext *callerContextPtr = (CallContext *) framePtr->clientData; Method *callerMethodPtr = callerContextPtr->callPtr->chain[callerContextPtr->index].mPtr; @@ -2816,8 +2838,7 @@ TclOOObjectCmdCore( if (startCls != NULL) { for (; contextPtr->index < contextPtr->callPtr->numChain; contextPtr->index++) { - struct MInvoke *miPtr = - &contextPtr->callPtr->chain[contextPtr->index]; + MInvoke *miPtr = &contextPtr->callPtr->chain[contextPtr->index]; if (miPtr->isFilter) { continue; @@ -2856,7 +2877,7 @@ FinalizeObjectCall( * structure. */ - TclOODeleteContext((CallContext *)data[0]); + TclOODeleteContext((CallContext *) data[0]); return result; } @@ -3012,7 +3033,7 @@ FinalizeNext( TCL_UNUSED(Tcl_Interp *), int result) { - CallContext *contextPtr = (CallContext *)data[0]; + CallContext *contextPtr = (CallContext *) data[0]; /* * Restore the call chain context index as we've finished the inner invoke @@ -3053,7 +3074,7 @@ Tcl_GetObjectFromObj( goto notAnObject; } } - return (Tcl_Object)cmdPtr->objClientData; + return (Tcl_Object) cmdPtr->objClientData; notAnObject: Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -3169,49 +3190,49 @@ Tcl_Object Tcl_ObjectContextObject( Tcl_ObjectContext context) { - return (Tcl_Object) ((CallContext *)context)->oPtr; + return (Tcl_Object) ((CallContext *) context)->oPtr; } Tcl_Size Tcl_ObjectContextSkippedArgs( Tcl_ObjectContext context) { - return ((CallContext *)context)->skip; + return ((CallContext *) context)->skip; } Tcl_Namespace * Tcl_GetObjectNamespace( Tcl_Object object) { - return ((Object *)object)->namespacePtr; + return ((Object *) object)->namespacePtr; } Tcl_Command Tcl_GetObjectCommand( Tcl_Object object) { - return ((Object *)object)->command; + return ((Object *) object)->command; } Tcl_Class Tcl_GetObjectAsClass( Tcl_Object object) { - return (Tcl_Class) ((Object *)object)->classPtr; + return (Tcl_Class) ((Object *) object)->classPtr; } int Tcl_ObjectDeleted( Tcl_Object object) { - return ((Object *)object)->command == NULL; + return ((Object *) object)->command == NULL; } Tcl_Object Tcl_GetClassAsObject( Tcl_Class clazz) { - return (Tcl_Object) ((Class *)clazz)->thisPtr; + return (Tcl_Object) ((Class *) clazz)->thisPtr; } Tcl_ObjectMapMethodNameProc * diff --git a/generic/tclOO.h b/generic/tclOO.h index 7cda876..7adf559 100644 --- a/generic/tclOO.h +++ b/generic/tclOO.h @@ -81,7 +81,7 @@ typedef int (Tcl_ObjectMapMethodNameProc)(Tcl_Interp *interp, * how to create a clone of it (when the object or class is copied). */ -typedef struct { +typedef struct Tcl_MethodType { int version; /* Structure version field. Always to be equal * to TCL_OO_METHOD_VERSION_(1|CURRENT) in * declarations. */ @@ -99,7 +99,7 @@ typedef struct { } Tcl_MethodType; #if TCL_MAJOR_VERSION > 8 -typedef struct { +typedef struct Tcl_MethodType2 { int version; /* Structure version field. Always to be equal * to TCL_OO_METHOD_VERSION_2 in * declarations. */ @@ -124,19 +124,21 @@ typedef struct { * This allows new versions of the structure to be introduced without breaking * binary compatibility. */ - -#define TCL_OO_METHOD_VERSION_1 1 -#define TCL_OO_METHOD_VERSION_2 2 -#define TCL_OO_METHOD_VERSION_CURRENT 1 +enum TclOOMethodVersion { + TCL_OO_METHOD_VERSION_1 = 1, + TCL_OO_METHOD_VERSION_2 = 2 +}; +#define TCL_OO_METHOD_VERSION_CURRENT TCL_OO_METHOD_VERSION_1 /* * Visibility constants for the flags parameter to Tcl_NewMethod and * Tcl_NewInstanceMethod. */ - -#define TCL_OO_METHOD_PUBLIC 1 -#define TCL_OO_METHOD_UNEXPORTED 0 -#define TCL_OO_METHOD_PRIVATE 0x20 +enum TclOOMethodVisibilityFlags { + TCL_OO_METHOD_PUBLIC = 1, + TCL_OO_METHOD_UNEXPORTED = 0, + TCL_OO_METHOD_PRIVATE = 0x20 +}; /* * The type of some object (or class) metadata. This describes how to delete @@ -144,7 +146,7 @@ typedef struct { * clone of it (when the object or class is copied). */ -typedef struct { +typedef struct Tcl_ObjectMetadataType { int version; /* Structure version field. Always to be equal * to TCL_OO_METADATA_VERSION_CURRENT in * declarations. */ @@ -163,7 +165,10 @@ typedef struct { * without breaking binary compatibility. */ -#define TCL_OO_METADATA_VERSION_CURRENT 1 +enum TclOOMetadataVersion { + TCL_OO_METADATA_VERSION_1 = 1 +}; +#define TCL_OO_METADATA_VERSION_CURRENT TCL_OO_METADATA_VERSION_1 /* * Include all the public API, generated from tclOO.decls. diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 2f2583d..cfb7cb5 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -68,7 +68,7 @@ FinalizeConstruction( Tcl_Interp *interp, int result) { - Object *oPtr = (Object *)data[0]; + Object *oPtr = (Object *) data[0]; if (result != TCL_OK) { return result; @@ -99,11 +99,11 @@ TclOO_Class_Constructor( Tcl_Obj **invoke, *nameObj; size_t skip = Tcl_ObjectContextSkippedArgs(context); - if ((size_t)objc > skip + 1) { + if ((size_t) objc > skip + 1) { Tcl_WrongNumArgs(interp, skip, objv, "?definitionScript?"); return TCL_ERROR; - } else if ((size_t)objc == skip) { + } else if ((size_t) objc == skip) { return TCL_OK; } @@ -112,17 +112,17 @@ TclOO_Class_Constructor( * here (and the class definition delegate doesn't run any constructors). */ - nameObj = Tcl_NewStringObj(oPtr->namespacePtr->fullName, -1); - Tcl_AppendToObj(nameObj, ":: oo ::delegate", -1); + nameObj = Tcl_ObjPrintf("%s:: oo ::delegate", + oPtr->namespacePtr->fullName); Tcl_NewObjectInstance(interp, (Tcl_Class) oPtr->fPtr->classCls, TclGetString(nameObj), NULL, -1, NULL, -1); - Tcl_DecrRefCount(nameObj); + Tcl_BounceRefCount(nameObj); /* * Delegate to [oo::define] to do the work. */ - invoke = (Tcl_Obj **)Tcl_Alloc(3 * sizeof(Tcl_Obj *)); + invoke = (Tcl_Obj **) TclStackAlloc(interp, 3 * sizeof(Tcl_Obj *)); invoke[0] = oPtr->fPtr->defineName; invoke[1] = TclOOObjectName(interp, oPtr); invoke[2] = objv[objc-1]; @@ -152,8 +152,8 @@ DecrRefsPostClassConstructor( Tcl_Interp *interp, int result) { - Tcl_Obj **invoke = (Tcl_Obj **)data[0]; - Object *oPtr = (Object *)data[1]; + Tcl_Obj **invoke = (Tcl_Obj **) data[0]; + Object *oPtr = (Object *) data[1]; Tcl_InterpState saved; int code; @@ -168,7 +168,7 @@ DecrRefsPostClassConstructor( code = Tcl_EvalObjv(interp, 2, invoke, 0); TclDecrRefCount(invoke[0]); TclDecrRefCount(invoke[1]); - Tcl_Free(invoke); + TclStackFree(interp, invoke); if (code != TCL_OK) { Tcl_DiscardInterpState(saved); return code; @@ -380,7 +380,7 @@ TclOO_Object_Destroy( Object *oPtr = (Object *) Tcl_ObjectContextObject(context); CallContext *contextPtr; - if (objc != (int)Tcl_ObjectContextSkippedArgs(context)) { + if (objc != (int) Tcl_ObjectContextSkippedArgs(context)) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; @@ -410,7 +410,7 @@ AfterNRDestructor( Tcl_Interp *interp, int result) { - CallContext *contextPtr = (CallContext *)data[0]; + CallContext *contextPtr = (CallContext *) data[0]; if (contextPtr->oPtr->command) { Tcl_DeleteCommandFromToken(interp, contextPtr->oPtr->command); @@ -445,7 +445,7 @@ TclOO_Object_Eval( Tcl_Obj *scriptPtr; CmdFrame *invoker; - if ((size_t)objc < skip + 1) { + if ((size_t) objc < skip + 1) { Tcl_WrongNumArgs(interp, skip, objv, "arg ?arg ...?"); return TCL_ERROR; } @@ -474,7 +474,7 @@ TclOO_Object_Eval( * object when it decrements its refcount after eval'ing it. */ - if ((size_t)objc != skip+1) { + if ((size_t) objc != skip+1) { scriptPtr = Tcl_ConcatObj(objc-skip, objv+skip); invoker = NULL; } else { @@ -498,7 +498,7 @@ FinalizeEval( int result) { if (result == TCL_ERROR) { - Object *oPtr = (Object *)data[0]; + Object *oPtr = (Object *) data[0]; const char *namePtr; if (oPtr) { @@ -556,7 +556,7 @@ TclOO_Object_Unknown( * name without an error). */ - if ((size_t)objc < skip+1) { + if ((size_t) objc < skip + 1) { Tcl_WrongNumArgs(interp, skip, objv, "method ?arg ...?"); return TCL_ERROR; } @@ -567,7 +567,7 @@ TclOO_Object_Unknown( */ if (framePtr->isProcCallFrame & FRAME_IS_METHOD) { - CallContext *callerContext = (CallContext *)framePtr->clientData; + CallContext *callerContext = (CallContext *) framePtr->clientData; Method *mPtr = callerContext->callPtr->chain[ callerContext->index].mPtr; @@ -621,7 +621,7 @@ TclOO_Object_Unknown( Tcl_AppendToObj(errorMsg, " or ", -1); } Tcl_AppendToObj(errorMsg, methodNames[i], -1); - Tcl_Free((void *)methodNames); + Tcl_Free((void *) methodNames); Tcl_SetObjResult(interp, errorMsg); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[skip]), (char *)NULL); @@ -777,7 +777,7 @@ LookupObjectVar( if (framePtr->isProcCallFrame & FRAME_IS_METHOD) { Object *oPtr = (Object *) object; - CallContext *callerContext = (CallContext *)framePtr->clientData; + CallContext *callerContext = (CallContext *) framePtr->clientData; Method *mPtr = callerContext->callPtr->chain[ callerContext->index].mPtr; PrivateVariableMapping *pvPtr; @@ -818,9 +818,8 @@ LookupObjectVar( } // The namespace isn't the global one; necessarily true for any object! - varNamePtr = Tcl_NewStringObj(namespacePtr->fullName, -1); - Tcl_AppendToObj(varNamePtr, "::", 2); - Tcl_AppendObjToObj(varNamePtr, varName); + varNamePtr = Tcl_ObjPrintf("%s::%s", + namespacePtr->fullName, TclGetString(varName)); } Tcl_IncrRefCount(varNamePtr); Tcl_Var var = (Tcl_Var) TclObjLookupVar(interp, varNamePtr, NULL, @@ -930,7 +929,7 @@ TclOONextObjCmd( Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", (char *)NULL); return TCL_ERROR; } - context = (Tcl_ObjectContext)framePtr->clientData; + context = (Tcl_ObjectContext) framePtr->clientData; /* * Invoke the (advanced) method call context in the caller context. Note @@ -970,7 +969,7 @@ TclOONextToObjCmd( Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", (char *)NULL); return TCL_ERROR; } - contextPtr = (CallContext *)framePtr->clientData; + contextPtr = (CallContext *) framePtr->clientData; /* * Sanity check the arguments; we need the first one to refer to a class. @@ -984,7 +983,7 @@ TclOONextToObjCmd( if (object == NULL) { return TCL_ERROR; } - classPtr = ((Object *)object)->classPtr; + classPtr = ((Object *) object)->classPtr; if (classPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" is not a class", TclGetString(objv[1]))); @@ -999,7 +998,7 @@ TclOONextToObjCmd( */ for (i=contextPtr->index+1 ; icallPtr->numChain ; i++) { - struct MInvoke *miPtr = contextPtr->callPtr->chain + i; + MInvoke *miPtr = &contextPtr->callPtr->chain[i]; if (!miPtr->isFilter && miPtr->mPtr->declaringClassPtr == classPtr) { /* @@ -1030,7 +1029,7 @@ TclOONextToObjCmd( } for (i=contextPtr->index ; i != TCL_INDEX_NONE ; i--) { - struct MInvoke *miPtr = contextPtr->callPtr->chain + i; + MInvoke *miPtr = &contextPtr->callPtr->chain[i]; if (!miPtr->isFilter && miPtr->mPtr->declaringClassPtr == classPtr) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -1055,9 +1054,9 @@ NextRestoreFrame( int result) { Interp *iPtr = (Interp *) interp; - CallContext *contextPtr = (CallContext *)data[1]; + CallContext *contextPtr = (CallContext *) data[1]; - iPtr->varFramePtr = (CallFrame *)data[0]; + iPtr->varFramePtr = (CallFrame *) data[0]; if (contextPtr != NULL) { contextPtr->index = PTR2UINT(data[2]); } @@ -1110,7 +1109,7 @@ TclOOSelfObjCmd( return TCL_ERROR; } - contextPtr = (CallContext*)framePtr->clientData; + contextPtr = (CallContext *) framePtr->clientData; /* * Now we do "conventional" argument parsing for a while. Note that no @@ -1165,7 +1164,7 @@ TclOOSelfObjCmd( Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", (char *)NULL); return TCL_ERROR; } else { - struct MInvoke *miPtr = &CurrentlyInvoked(contextPtr); + MInvoke *miPtr = &CurrentlyInvoked(contextPtr); Object *oPtr; const char *type; @@ -1191,7 +1190,8 @@ TclOOSelfObjCmd( Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", (char *)NULL); return TCL_ERROR; } else { - CallContext *callerPtr = (CallContext *)framePtr->callerVarPtr->clientData; + CallContext *callerPtr = (CallContext *) + framePtr->callerVarPtr->clientData; Method *mPtr = callerPtr->callPtr->chain[callerPtr->index].mPtr; Object *declarerPtr; @@ -1820,16 +1820,14 @@ TclOOImplementClassProperty( Tcl_Obj *methodName = Tcl_ObjPrintf( "", TclGetString(propNamePtr)); Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter - TclNewMethod( - NULL, targetClass, methodName, 0, &GetterType, propNamePtr); + TclNewMethod(targetClass, methodName, 0, &GetterType, propNamePtr); Tcl_BounceRefCount(methodName); } if (installSetter) { Tcl_Obj *methodName = Tcl_ObjPrintf( "", TclGetString(propNamePtr)); Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter - TclNewMethod( - NULL, targetClass, methodName, 0, &SetterType, propNamePtr); + TclNewMethod(targetClass, methodName, 0, &SetterType, propNamePtr); Tcl_BounceRefCount(methodName); } } diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c index e1cf778..27d8233 100644 --- a/generic/tclOOCall.c +++ b/generic/tclOOCall.c @@ -19,30 +19,29 @@ #include /* - * Structure containing a CallContext and any other values needed only during - * the construction of the CallContext. + * Structure containing a CallChain and any other values needed only during + * the construction of the CallChain. */ - -struct ChainBuilder { +typedef struct ChainBuilder { CallChain *callChainPtr; /* The call chain being built. */ size_t filterLength; /* Number of entries in the call chain that * are due to processing filters and not the * main call chain. */ Object *oPtr; /* The object that we are building the chain * for. */ -}; +} ChainBuilder; /* * Structures used for traversing the class hierarchy to find out where * definitions are supposed to be done. */ -typedef struct { +typedef struct DefineEntry { Class *definerCls; Tcl_Obj *namespaceName; } DefineEntry; -typedef struct { +typedef struct DefineChain { DefineEntry *list; int num; int size; @@ -51,15 +50,17 @@ typedef struct { /* * Extra flags used for call chain management. */ +enum CallChainFlags { + DEFINITE_PROTECTED = 0x100000, + DEFINITE_PUBLIC = 0x200000, + KNOWN_STATE = (DEFINITE_PROTECTED | DEFINITE_PUBLIC), + SPECIAL = (CONSTRUCTOR | DESTRUCTOR | FORCE_UNKNOWN), + BUILDING_MIXINS = 0x400000, + TRAVERSED_MIXIN = 0x800000, + OBJECT_MIXIN = 0x1000000, + DEFINE_FOR_CLASS = 0x2000000 +}; -#define DEFINITE_PROTECTED 0x100000 -#define DEFINITE_PUBLIC 0x200000 -#define KNOWN_STATE (DEFINITE_PROTECTED | DEFINITE_PUBLIC) -#define SPECIAL (CONSTRUCTOR | DESTRUCTOR | FORCE_UNKNOWN) -#define BUILDING_MIXINS 0x400000 -#define TRAVERSED_MIXIN 0x800000 -#define OBJECT_MIXIN 0x1000000 -#define DEFINE_FOR_CLASS 0x2000000 #define MIXIN_CONSISTENT(flags) \ (((flags) & OBJECT_MIXIN) || \ !((flags) & BUILDING_MIXINS) == !((flags) & TRAVERSED_MIXIN)) @@ -87,11 +88,19 @@ typedef struct { (((flags) & TRUE_PRIVATE_METHOD) != 0) /* + * Name the bits used in the names table values. + */ +enum NameTableValues { + IN_LIST = 1, /* Seen an implementation. */ + NO_IMPLEMENTATION = 2 /* Seen, but not implemented yet. */ +}; + +/* * Function declarations for things defined in this file. */ static void AddClassFiltersToCallContext(Object *const oPtr, - Class *clsPtr, struct ChainBuilder *const cbPtr, + Class *clsPtr, ChainBuilder *const cbPtr, Tcl_HashTable *const doneFilters, int flags); static void AddClassMethodNames(Class *clsPtr, int flags, Tcl_HashTable *const namesPtr, @@ -100,12 +109,12 @@ static inline void AddDefinitionNamespaceToChain(Class *const definerCls, Tcl_Obj *const namespaceName, DefineChain *const definePtr, int flags); static inline void AddMethodToCallChain(Method *const mPtr, - struct ChainBuilder *const cbPtr, + ChainBuilder *const cbPtr, Tcl_HashTable *const doneFilters, Class *const filterDecl, int flags); static inline int AddInstancePrivateToCallContext(Object *const oPtr, Tcl_Obj *const methodNameObj, - struct ChainBuilder *const cbPtr, int flags); + ChainBuilder *const cbPtr, int flags); static inline void AddStandardMethodName(int flags, Tcl_Obj *namePtr, Method *mPtr, Tcl_HashTable *namesPtr); static inline void AddPrivateMethodNames(Tcl_HashTable *methodsTablePtr, @@ -113,18 +122,18 @@ static inline void AddPrivateMethodNames(Tcl_HashTable *methodsTablePtr, static inline int AddSimpleChainToCallContext(Object *const oPtr, Class *const contextCls, Tcl_Obj *const methodNameObj, - struct ChainBuilder *const cbPtr, + ChainBuilder *const cbPtr, Tcl_HashTable *const doneFilters, int flags, Class *const filterDecl); static int AddPrivatesFromClassChainToCallContext(Class *classPtr, Class *const contextCls, Tcl_Obj *const methodNameObj, - struct ChainBuilder *const cbPtr, + ChainBuilder *const cbPtr, Tcl_HashTable *const doneFilters, int flags, Class *const filterDecl); static int AddSimpleClassChainToCallContext(Class *classPtr, Tcl_Obj *const methodNameObj, - struct ChainBuilder *const cbPtr, + ChainBuilder *const cbPtr, Tcl_HashTable *const doneFilters, int flags, Class *const filterDecl); static void AddSimpleClassDefineNamespaces(Class *classPtr, @@ -281,16 +290,16 @@ DupMethodNameRep( Tcl_Obj *srcPtr, Tcl_Obj *dstPtr) { - StashCallChain(dstPtr, - (CallChain *)TclFetchInternalRep(srcPtr, &methodNameType)->twoPtrValue.ptr1); + StashCallChain(dstPtr, (CallChain *) + TclFetchInternalRep(srcPtr, &methodNameType)->twoPtrValue.ptr1); } static void FreeMethodNameRep( Tcl_Obj *objPtr) { - TclOODeleteChain( - (CallChain *)TclFetchInternalRep(objPtr, &methodNameType)->twoPtrValue.ptr1); + TclOODeleteChain((CallChain *) + TclFetchInternalRep(objPtr, &methodNameType)->twoPtrValue.ptr1); } /* @@ -316,7 +325,7 @@ TclOOInvokeContext( int objc, /* The number of arguments. */ Tcl_Obj *const objv[]) /* The arguments as actually seen. */ { - CallContext *const contextPtr = (CallContext *)clientData; + CallContext *const contextPtr = (CallContext *) clientData; Method *const mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; const int isFilter = contextPtr->callPtr->chain[contextPtr->index].isFilter; @@ -375,7 +384,7 @@ TclOOInvokeContext( return (mPtr->typePtr->callProc)(mPtr->clientData, interp, (Tcl_ObjectContext) contextPtr, objc, objv); } - return ((Tcl_MethodCallProc2 *)(void *)(mPtr->typePtr->callProc))(mPtr->clientData, interp, + return (mPtr->type2Ptr->callProc)(mPtr->clientData, interp, (Tcl_ObjectContext) contextPtr, objc, objv); } @@ -385,7 +394,7 @@ SetFilterFlags( TCL_UNUSED(Tcl_Interp *), int result) { - CallContext *contextPtr = (CallContext *)data[0]; + CallContext *contextPtr = (CallContext *) data[0]; contextPtr->oPtr->flags |= FILTER_HANDLING; return result; @@ -397,7 +406,7 @@ ResetFilterFlags( TCL_UNUSED(Tcl_Interp *), int result) { - CallContext *contextPtr = (CallContext *)data[0]; + CallContext *contextPtr = (CallContext *) data[0]; contextPtr->oPtr->flags &= ~FILTER_HANDLING; return result; @@ -409,7 +418,7 @@ FinalizeMethodRefs( TCL_UNUSED(Tcl_Interp *), int result) { - CallContext *contextPtr = (CallContext *)data[0]; + CallContext *contextPtr = (CallContext *) data[0]; Tcl_Size i; for (i = 0 ; i < contextPtr->callPtr->numChain ; i++) { @@ -460,12 +469,6 @@ TclOOGetSortedMethodList( Tcl_InitHashTable(&examinedClasses, TCL_ONE_WORD_KEYS); /* - * Name the bits used in the names table values. - */ -#define IN_LIST 1 -#define NO_IMPLEMENTATION 2 - - /* * Process method names due to the object. */ @@ -619,7 +622,7 @@ SortMethodNames( * sorted when it is long enough to matter. */ - strings = (const char **)Tcl_Alloc(sizeof(char *) * namesPtr->numEntries); + strings = (const char **) Tcl_Alloc(sizeof(char *) * namesPtr->numEntries); FOREACH_HASH(namePtr, isWanted, namesPtr) { if (!WANT_PUBLIC(flags) || (PTR2INT(isWanted) & IN_LIST)) { if (PTR2INT(isWanted) & NO_IMPLEMENTATION) { @@ -641,7 +644,7 @@ SortMethodNames( } *stringsPtr = strings; } else { - Tcl_Free((void *)strings); + Tcl_Free((void *) strings); *stringsPtr = NULL; } return i; @@ -808,9 +811,6 @@ AddStandardMethodName( } } } - -#undef IN_LIST -#undef NO_IMPLEMENTATION /* * ---------------------------------------------------------------------- @@ -830,8 +830,7 @@ AddInstancePrivateToCallContext( Object *const oPtr, /* Object to add call chain entries for. */ Tcl_Obj *const methodName, /* Name of method to add the call chain * entries for. */ - struct ChainBuilder *const cbPtr, - /* Where to add the call chain entries. */ + ChainBuilder *const cbPtr, /* Where to add the call chain entries. */ int flags) /* What sort of call chain are we building. */ { Tcl_HashEntry *hPtr; @@ -841,7 +840,7 @@ AddInstancePrivateToCallContext( if (oPtr->methodsPtr) { hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, methodName); if (hPtr != NULL) { - mPtr = (Method *)Tcl_GetHashValue(hPtr); + mPtr = (Method *) Tcl_GetHashValue(hPtr); if (IS_PRIVATE(mPtr)) { AddMethodToCallChain(mPtr, cbPtr, NULL, NULL, flags); donePrivate = 1; @@ -873,8 +872,7 @@ AddSimpleChainToCallContext( Tcl_Obj *const methodNameObj, /* Name of method to add the call chain * entries for. */ - struct ChainBuilder *const cbPtr, - /* Where to add the call chain entries. */ + ChainBuilder *const cbPtr, /* Where to add the call chain entries. */ Tcl_HashTable *const doneFilters, /* Where to record what call chain entries * have been processed. */ @@ -892,7 +890,7 @@ AddSimpleChainToCallContext( hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, methodNameObj); if (hPtr != NULL) { - mPtr = (Method *)Tcl_GetHashValue(hPtr); + mPtr = (Method *) Tcl_GetHashValue(hPtr); if (!IS_PRIVATE(mPtr)) { if (WANT_PUBLIC(flags)) { if (!IS_PUBLIC(mPtr)) { @@ -922,7 +920,7 @@ AddSimpleChainToCallContext( if (oPtr->methodsPtr && !blockedUnexported) { hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, methodNameObj); if (hPtr != NULL) { - mPtr = (Method *)Tcl_GetHashValue(hPtr); + mPtr = (Method *) Tcl_GetHashValue(hPtr); if (!IS_PRIVATE(mPtr)) { AddMethodToCallChain(mPtr, cbPtr, doneFilters, filterDecl, flags); @@ -960,8 +958,7 @@ static inline void AddMethodToCallChain( Method *const mPtr, /* Actual method implementation to add to call * chain (or NULL, a no-op). */ - struct ChainBuilder *const cbPtr, - /* The call chain to add the method + ChainBuilder *const cbPtr, /* The call chain to add the method * implementation to. */ Tcl_HashTable *const doneFilters, /* Where to record what filters have been @@ -1046,13 +1043,13 @@ AddMethodToCallChain( */ if (callPtr->numChain == CALL_CHAIN_STATIC_SIZE) { - callPtr->chain = - (struct MInvoke *)Tcl_Alloc(sizeof(struct MInvoke) * (callPtr->numChain + 1)); + callPtr->chain = (MInvoke *) + Tcl_Alloc(sizeof(MInvoke) * (callPtr->numChain + 1)); memcpy(callPtr->chain, callPtr->staticChain, - sizeof(struct MInvoke) * callPtr->numChain); + sizeof(MInvoke) * callPtr->numChain); } else if (callPtr->numChain > CALL_CHAIN_STATIC_SIZE) { - callPtr->chain = (struct MInvoke *)Tcl_Realloc(callPtr->chain, - sizeof(struct MInvoke) * (callPtr->numChain + 1)); + callPtr->chain = (MInvoke *) Tcl_Realloc(callPtr->chain, + sizeof(MInvoke) * (callPtr->numChain + 1)); } callPtr->chain[i].mPtr = mPtr; callPtr->chain[i].isFilter = (doneFilters != NULL); @@ -1178,7 +1175,7 @@ TclOOGetCallContext( { CallContext *contextPtr; CallChain *callPtr; - struct ChainBuilder cb; + ChainBuilder cb; Tcl_Size i, count; int doFilters, donePrivate = 0; Tcl_HashEntry *hPtr; @@ -1224,7 +1221,7 @@ TclOOGetCallContext( const int reuseMask = (WANT_PUBLIC(flags) ? ~0 : ~PUBLIC_METHOD); if ((irPtr = TclFetchInternalRep(cacheInThisObj, &methodNameType))) { - callPtr = (CallChain *)irPtr->twoPtrValue.ptr1; + callPtr = (CallChain *) irPtr->twoPtrValue.ptr1; if (IsStillValid(callPtr, oPtr, flags, reuseMask)) { callPtr->refCount++; goto returnContext; @@ -1257,7 +1254,7 @@ TclOOGetCallContext( } if (hPtr != NULL && Tcl_GetHashValue(hPtr) != NULL) { - callPtr = (CallChain *)Tcl_GetHashValue(hPtr); + callPtr = (CallChain *) Tcl_GetHashValue(hPtr); if (IsStillValid(callPtr, oPtr, flags, reuseMask)) { callPtr->refCount++; goto returnContext; @@ -1269,7 +1266,7 @@ TclOOGetCallContext( doFilters = 1; } - callPtr = (CallChain *)Tcl_Alloc(sizeof(CallChain)); + callPtr = (CallChain *) Tcl_Alloc(sizeof(CallChain)); InitCallChain(callPtr, oPtr, flags); cb.callChainPtr = callPtr; @@ -1374,8 +1371,8 @@ TclOOGetCallContext( int isNew; if (oPtr->flags & USE_CLASS_CACHE) { if (oPtr->selfCls->classChainCache == NULL) { - oPtr->selfCls->classChainCache = - (Tcl_HashTable *)Tcl_Alloc(sizeof(Tcl_HashTable)); + oPtr->selfCls->classChainCache = (Tcl_HashTable *) + Tcl_Alloc(sizeof(Tcl_HashTable)); Tcl_InitObjHashTable(oPtr->selfCls->classChainCache); } @@ -1383,7 +1380,8 @@ TclOOGetCallContext( methodNameObj, &isNew); } else { if (oPtr->chainCache == NULL) { - oPtr->chainCache = (Tcl_HashTable *)Tcl_Alloc(sizeof(Tcl_HashTable)); + oPtr->chainCache = (Tcl_HashTable *) + Tcl_Alloc(sizeof(Tcl_HashTable)); Tcl_InitObjHashTable(oPtr->chainCache); } @@ -1409,7 +1407,8 @@ TclOOGetCallContext( } returnContext: - contextPtr = (CallContext *)TclStackAlloc(oPtr->fPtr->interp, sizeof(CallContext)); + contextPtr = (CallContext *) + TclStackAlloc(oPtr->fPtr->interp, sizeof(CallContext)); contextPtr->oPtr = oPtr; /* @@ -1447,7 +1446,7 @@ TclOOGetStereotypeCallChain( * FILTER_HANDLING are useful. */ { CallChain *callPtr; - struct ChainBuilder cb; + ChainBuilder cb; Tcl_Size count; Foundation *fPtr = clsPtr->thisPtr->fPtr; Tcl_HashEntry *hPtr; @@ -1489,7 +1488,7 @@ TclOOGetStereotypeCallChain( if (hPtr != NULL && Tcl_GetHashValue(hPtr) != NULL) { const int reuseMask = (WANT_PUBLIC(flags) ? ~0 : ~PUBLIC_METHOD); - callPtr = (CallChain *)Tcl_GetHashValue(hPtr); + callPtr = (CallChain *) Tcl_GetHashValue(hPtr); if (IsStillValid(callPtr, &obj, flags, reuseMask)) { callPtr->refCount++; return callPtr; @@ -1501,7 +1500,7 @@ TclOOGetStereotypeCallChain( hPtr = NULL; } - callPtr = (CallChain *)Tcl_Alloc(sizeof(CallChain)); + callPtr = (CallChain *) Tcl_Alloc(sizeof(CallChain)); memset(callPtr, 0, sizeof(CallChain)); callPtr->flags = flags & (PUBLIC_METHOD|PRIVATE_METHOD|FILTER_HANDLING); callPtr->epoch = fPtr->epoch; @@ -1557,7 +1556,8 @@ TclOOGetStereotypeCallChain( if (hPtr == NULL) { int isNew; if (clsPtr->classChainCache == NULL) { - clsPtr->classChainCache = (Tcl_HashTable *)Tcl_Alloc(sizeof(Tcl_HashTable)); + clsPtr->classChainCache = (Tcl_HashTable *) + Tcl_Alloc(sizeof(Tcl_HashTable)); Tcl_InitObjHashTable(clsPtr->classChainCache); } hPtr = Tcl_CreateHashEntry(clsPtr->classChainCache, @@ -1585,8 +1585,7 @@ static void AddClassFiltersToCallContext( Object *const oPtr, /* Object that the filters operate on. */ Class *clsPtr, /* Class to get the filters from. */ - struct ChainBuilder *const cbPtr, - /* Context to fill with call chain entries. */ + ChainBuilder *const cbPtr, /* Context to fill with call chain entries. */ Tcl_HashTable *const doneFilters, /* Where to record what filters have been * processed. Keys are objects, values are @@ -1673,8 +1672,7 @@ AddPrivatesFromClassChainToCallContext( * also be added. */ Tcl_Obj *const methodName, /* Name of method to add the call chain * entries for. */ - struct ChainBuilder *const cbPtr, - /* Where to add the call chain entries. */ + ChainBuilder *const cbPtr, /* Where to add the call chain entries. */ Tcl_HashTable *const doneFilters, /* Where to record what call chain entries * have been processed. */ @@ -1715,7 +1713,7 @@ AddPrivatesFromClassChainToCallContext( methodName); if (hPtr != NULL) { - Method *mPtr = (Method *)Tcl_GetHashValue(hPtr); + Method *mPtr = (Method *) Tcl_GetHashValue(hPtr); if (IS_PRIVATE(mPtr)) { AddMethodToCallChain(mPtr, cbPtr, doneFilters, filterDecl, @@ -1758,8 +1756,7 @@ AddSimpleClassChainToCallContext( Tcl_Obj *const methodNameObj, /* Name of method to add the call chain * entries for. */ - struct ChainBuilder *const cbPtr, - /* Where to add the call chain entries. */ + ChainBuilder *const cbPtr, /* Where to add the call chain entries. */ Tcl_HashTable *const doneFilters, /* Where to record what call chain entries * have been processed. */ @@ -1804,7 +1801,7 @@ AddSimpleClassChainToCallContext( privateDanger |= 1; } if (hPtr != NULL) { - Method *mPtr = (Method *)Tcl_GetHashValue(hPtr); + Method *mPtr = (Method *) Tcl_GetHashValue(hPtr); if (!IS_PRIVATE(mPtr)) { if (!(flags & KNOWN_STATE)) { @@ -1864,13 +1861,9 @@ TclOORenderCallChain( */ TclNewLiteralStringObj(filterLiteral, "filter"); - Tcl_IncrRefCount(filterLiteral); TclNewLiteralStringObj(methodLiteral, "method"); - Tcl_IncrRefCount(methodLiteral); TclNewLiteralStringObj(objectLiteral, "object"); - Tcl_IncrRefCount(objectLiteral); TclNewLiteralStringObj(privateLiteral, "private"); - Tcl_IncrRefCount(privateLiteral); /* * Do the actual construction of the descriptions. They consist of a list @@ -1884,9 +1877,10 @@ TclOORenderCallChain( * method (or "object" if it is declared on the instance). */ - objv = (Tcl_Obj **)TclStackAlloc(interp, callPtr->numChain * sizeof(Tcl_Obj *)); + objv = (Tcl_Obj **) + TclStackAlloc(interp, callPtr->numChain * sizeof(Tcl_Obj *)); for (i = 0 ; i < callPtr->numChain ; i++) { - struct MInvoke *miPtr = &callPtr->chain[i]; + MInvoke *miPtr = &callPtr->chain[i]; descObjs[0] = miPtr->isFilter ? filterLiteral : @@ -1911,10 +1905,10 @@ TclOORenderCallChain( * they'll live on the description itself. */ - Tcl_DecrRefCount(filterLiteral); - Tcl_DecrRefCount(methodLiteral); - Tcl_DecrRefCount(objectLiteral); - Tcl_DecrRefCount(privateLiteral); + Tcl_BounceRefCount(filterLiteral); + Tcl_BounceRefCount(methodLiteral); + Tcl_BounceRefCount(objectLiteral); + Tcl_BounceRefCount(privateLiteral); /* * Finish building the description and return it. @@ -2152,12 +2146,12 @@ AddDefinitionNamespaceToChain( if (definePtr->num == DEFINE_CHAIN_STATIC_SIZE) { DefineEntry *staticList = definePtr->list; - definePtr->list = - (DefineEntry *)Tcl_Alloc(sizeof(DefineEntry) * definePtr->size); + definePtr->list = (DefineEntry *) + Tcl_Alloc(sizeof(DefineEntry) * definePtr->size); memcpy(definePtr->list, staticList, sizeof(DefineEntry) * definePtr->num); } else { - definePtr->list = (DefineEntry *)Tcl_Realloc(definePtr->list, + definePtr->list = (DefineEntry *) Tcl_Realloc(definePtr->list, sizeof(DefineEntry) * definePtr->size); } } diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index d3ec410..882ca52 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -32,13 +32,12 @@ /* * Some things that make it easier to declare a slot. */ - -struct DeclaredSlot { +typedef struct DeclaredSlot { const char *name; const Tcl_MethodType getterType; const Tcl_MethodType setterType; const Tcl_MethodType resolverType; -}; +} DeclaredSlot; #define SLOT(name,getter,setter,resolver) \ {"::oo::" name, \ @@ -156,7 +155,7 @@ static int ResolveClass(void *clientData, * Now define the slots used in declarations. */ -static const struct DeclaredSlot slots[] = { +static const DeclaredSlot slots[] = { SLOT("define::filter", ClassFilter_Get, ClassFilter_Set, NULL), SLOT("define::mixin", ClassMixin_Get, ClassMixin_Set, ResolveClass), SLOT("define::superclass", ClassSuper_Get, ClassSuper_Set, ResolveClass), @@ -360,9 +359,9 @@ TclOOObjectSetFilters( size_t size = sizeof(Tcl_Obj *) * numFilters; if (oPtr->filters.num == 0) { - filtersList = (Tcl_Obj **)Tcl_Alloc(size); + filtersList = (Tcl_Obj **) Tcl_Alloc(size); } else { - filtersList = (Tcl_Obj **)Tcl_Realloc(oPtr->filters.list, size); + filtersList = (Tcl_Obj **) Tcl_Realloc(oPtr->filters.list, size); } for (i = 0 ; i < numFilters ; i++) { filtersList[i] = filters[i]; @@ -419,9 +418,10 @@ TclOOClassSetFilters( size_t size = sizeof(Tcl_Obj *) * numFilters; if (classPtr->filters.num == 0) { - filtersList = (Tcl_Obj **)Tcl_Alloc(size); + filtersList = (Tcl_Obj **) Tcl_Alloc(size); } else { - filtersList = (Tcl_Obj **)Tcl_Realloc(classPtr->filters.list, size); + filtersList = (Tcl_Obj **) + Tcl_Realloc(classPtr->filters.list, size); } for (i = 0 ; i < numFilters ; i++) { filtersList[i] = filters[i]; @@ -475,10 +475,11 @@ TclOOObjectSetMixins( } TclOODecrRefCount(mixinPtr->thisPtr); } - oPtr->mixins.list = (Class **)Tcl_Realloc(oPtr->mixins.list, + oPtr->mixins.list = (Class **) Tcl_Realloc(oPtr->mixins.list, sizeof(Class *) * numMixins); } else { - oPtr->mixins.list = (Class **)Tcl_Alloc(sizeof(Class *) * numMixins); + oPtr->mixins.list = (Class **) + Tcl_Alloc(sizeof(Class *) * numMixins); oPtr->flags &= ~USE_CLASS_CACHE; } oPtr->mixins.num = numMixins; @@ -533,10 +534,12 @@ TclOOClassSetMixins( TclOORemoveFromMixinSubs(classPtr, mixinPtr); TclOODecrRefCount(mixinPtr->thisPtr); } - classPtr->mixins.list = (Class **)Tcl_Realloc(classPtr->mixins.list, - sizeof(Class *) * numMixins); + classPtr->mixins.list = (Class **) + Tcl_Realloc(classPtr->mixins.list, + sizeof(Class *) * numMixins); } else { - classPtr->mixins.list = (Class **)Tcl_Alloc(sizeof(Class *) * numMixins); + classPtr->mixins.list = (Class **) + Tcl_Alloc(sizeof(Class *) * numMixins); } classPtr->mixins.num = numMixins; memcpy(classPtr->mixins.list, mixins, sizeof(Class *) * numMixins); @@ -584,9 +587,10 @@ InstallStandardVariableMapping( if (varc == 0) { Tcl_Free(vnlPtr->list); } else if (i) { - vnlPtr->list = (Tcl_Obj **)Tcl_Realloc(vnlPtr->list, sizeof(Tcl_Obj *) * varc); + vnlPtr->list = (Tcl_Obj **) + Tcl_Realloc(vnlPtr->list, sizeof(Tcl_Obj *) * varc); } else { - vnlPtr->list = (Tcl_Obj **)Tcl_Alloc(sizeof(Tcl_Obj *) * varc); + vnlPtr->list = (Tcl_Obj **) Tcl_Alloc(sizeof(Tcl_Obj *) * varc); } } vnlPtr->num = 0; @@ -607,7 +611,8 @@ InstallStandardVariableMapping( */ if (n != varc) { - vnlPtr->list = (Tcl_Obj **)Tcl_Realloc(vnlPtr->list, sizeof(Tcl_Obj *) * n); + vnlPtr->list = (Tcl_Obj **) + Tcl_Realloc(vnlPtr->list, sizeof(Tcl_Obj *) * n); } Tcl_DeleteHashTable(&uniqueTable); } @@ -668,7 +673,7 @@ InstallPrivateVariableMapping( */ if (n != varc) { - pvlPtr->list = (PrivateVariableMapping *)Tcl_Realloc(pvlPtr->list, + pvlPtr->list = (PrivateVariableMapping *) Tcl_Realloc(pvlPtr->list, sizeof(PrivateVariableMapping) * n); } Tcl_DeleteHashTable(&uniqueTable); @@ -748,7 +753,7 @@ RenameDeleteMethod( * Complete the splicing by changing the method's name. */ - mPtr = (Method *)Tcl_GetHashValue(hPtr); + mPtr = (Method *) Tcl_GetHashValue(hPtr); if (toPtr) { Tcl_IncrRefCount(toPtr); Tcl_DecrRefCount(mPtr->namePtr); @@ -975,7 +980,7 @@ TclOOGetDefineCmdContext( Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); return NULL; } - object = (Tcl_Object)iPtr->varFramePtr->clientData; + object = (Tcl_Object) iPtr->varFramePtr->clientData; if (Tcl_ObjectDeleted(object)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "this command cannot be called when the object has been" @@ -1107,7 +1112,7 @@ GenerateErrorInfo( Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (in definition script for %s \"%.*s%s\" line %d)", - typeOfSubject, (overflow ? limit : (int)length), objName, + typeOfSubject, (overflow ? limit : (int) length), objName, (overflow ? "..." : ""), Tcl_GetErrorLine(interp))); } @@ -1237,7 +1242,7 @@ TclOODefineObjCmd( Tcl_IncrRefCount(objNameObj); result = TclEvalObjEx(interp, objv[2], 0, - ((Interp *)interp)->cmdFramePtr, 2); + ((Interp *) interp)->cmdFramePtr, 2); if (result == TCL_ERROR) { GenerateErrorInfo(interp, oPtr, objNameObj, "class"); } @@ -1306,7 +1311,7 @@ TclOOObjDefObjCmd( Tcl_IncrRefCount(objNameObj); result = TclEvalObjEx(interp, objv[2], 0, - ((Interp *)interp)->cmdFramePtr, 2); + ((Interp *) interp)->cmdFramePtr, 2); if (result == TCL_ERROR) { GenerateErrorInfo(interp, oPtr, objNameObj, "object"); } @@ -1380,7 +1385,7 @@ TclOODefineSelfObjCmd( Tcl_IncrRefCount(objNameObj); result = TclEvalObjEx(interp, objv[1], 0, - ((Interp *)interp)->cmdFramePtr, 1); + ((Interp *) interp)->cmdFramePtr, 1); if (result == TCL_ERROR) { GenerateErrorInfo(interp, oPtr, objNameObj, "class object"); } @@ -1643,7 +1648,7 @@ TclOODefineConstructorObjCmd( return TCL_ERROR; } - (void)TclGetStringFromObj(objv[2], &bodyLength); + (void) TclGetStringFromObj(objv[2], &bodyLength); if (bodyLength > 0) { /* * Create the method structure. @@ -1837,7 +1842,7 @@ TclOODefineDestructorObjCmd( } - (void)TclGetStringFromObj(objv[1], &bodyLength); + (void) TclGetStringFromObj(objv[1], &bodyLength); if (bodyLength > 0) { /* * Create the method structure. @@ -1922,7 +1927,8 @@ TclOODefineExportObjCmd( if (isInstanceExport) { if (!oPtr->methodsPtr) { - oPtr->methodsPtr = (Tcl_HashTable *)Tcl_Alloc(sizeof(Tcl_HashTable)); + oPtr->methodsPtr = (Tcl_HashTable *) + Tcl_Alloc(sizeof(Tcl_HashTable)); Tcl_InitObjHashTable(oPtr->methodsPtr); oPtr->flags &= ~USE_CLASS_CACHE; } @@ -1934,14 +1940,14 @@ TclOODefineExportObjCmd( } if (isNew) { - mPtr = (Method *)Tcl_Alloc(sizeof(Method)); + mPtr = (Method *) Tcl_Alloc(sizeof(Method)); memset(mPtr, 0, sizeof(Method)); mPtr->refCount = 1; mPtr->namePtr = objv[i]; Tcl_IncrRefCount(objv[i]); Tcl_SetHashValue(hPtr, mPtr); } else { - mPtr = (Method *)Tcl_GetHashValue(hPtr); + mPtr = (Method *) Tcl_GetHashValue(hPtr); } if (isNew || !(mPtr->flags & (PUBLIC_METHOD | PRIVATE_METHOD))) { mPtr->flags |= PUBLIC_METHOD; @@ -2248,14 +2254,14 @@ TclOODefineUnexportObjCmd( } if (isNew) { - mPtr = (Method *)Tcl_Alloc(sizeof(Method)); + mPtr = (Method *) Tcl_Alloc(sizeof(Method)); memset(mPtr, 0, sizeof(Method)); mPtr->refCount = 1; mPtr->namePtr = objv[i]; Tcl_IncrRefCount(objv[i]); Tcl_SetHashValue(hPtr, mPtr); } else { - mPtr = (Method *)Tcl_GetHashValue(hPtr); + mPtr = (Method *) Tcl_GetHashValue(hPtr); } if (isNew || mPtr->flags & (PUBLIC_METHOD | TRUE_PRIVATE_METHOD)) { mPtr->flags &= ~(PUBLIC_METHOD | TRUE_PRIVATE_METHOD); @@ -2347,30 +2353,38 @@ int TclOODefineSlots( Foundation *fPtr) { - const struct DeclaredSlot *slotInfoPtr; - Tcl_Obj *getName = Tcl_NewStringObj("Get", -1); - Tcl_Obj *setName = Tcl_NewStringObj("Set", -1); - Tcl_Obj *resolveName = Tcl_NewStringObj("Resolve", -1); + const DeclaredSlot *slotInfoPtr; + Tcl_Interp *interp = fPtr->interp; + Tcl_Obj *getName, *setName, *resolveName; + Tcl_Object object = Tcl_NewObjectInstance(interp, (Tcl_Class) + fPtr->classCls, "::oo::Slot", NULL, TCL_INDEX_NONE, NULL, 0); Class *slotCls; - slotCls = ((Object *) Tcl_NewObjectInstance(fPtr->interp, (Tcl_Class) - fPtr->classCls, "::oo::Slot", NULL, TCL_INDEX_NONE, NULL, 0))->classPtr; + if (object == NULL) { + return TCL_ERROR; + } + slotCls = ((Object *) object)->classPtr; if (slotCls == NULL) { return TCL_ERROR; } + + TclNewLiteralStringObj(getName, "Get"); + TclNewLiteralStringObj(setName, "Set"); + TclNewLiteralStringObj(resolveName, "Resolve"); for (slotInfoPtr = slots ; slotInfoPtr->name ; slotInfoPtr++) { - Tcl_Object slotObject = Tcl_NewObjectInstance(fPtr->interp, - (Tcl_Class) slotCls, slotInfoPtr->name, NULL, TCL_INDEX_NONE, NULL, 0); + Tcl_Object slotObject = Tcl_NewObjectInstance(interp, + (Tcl_Class) slotCls, slotInfoPtr->name, NULL, TCL_INDEX_NONE, + NULL, 0); if (slotObject == NULL) { continue; } - TclNewInstanceMethod(fPtr->interp, slotObject, getName, 0, + TclNewInstanceMethod(interp, slotObject, getName, 0, &slotInfoPtr->getterType, NULL); - TclNewInstanceMethod(fPtr->interp, slotObject, setName, 0, + TclNewInstanceMethod(interp, slotObject, setName, 0, &slotInfoPtr->setterType, NULL); if (slotInfoPtr->resolverType.callProc) { - TclNewInstanceMethod(fPtr->interp, slotObject, resolveName, 0, + TclNewInstanceMethod(interp, slotObject, resolveName, 0, &slotInfoPtr->resolverType, NULL); } } @@ -2522,7 +2536,7 @@ ClassMixin_Set( return TCL_ERROR; } - mixins = (Class **)TclStackAlloc(interp, sizeof(Class *) * mixinc); + mixins = (Class **) TclStackAlloc(interp, sizeof(Class *) * mixinc); Tcl_InitHashTable(&uniqueCheck, TCL_ONE_WORD_KEYS); for (i = 0; i < mixinc; i++) { @@ -2647,7 +2661,7 @@ ClassSuper_Set( */ if (superc == 0) { - superclasses = (Class **)Tcl_Realloc(superclasses, sizeof(Class *)); + superclasses = (Class **) Tcl_Realloc(superclasses, sizeof(Class *)); if (TclOOIsReachable(fPtr->classCls, clsPtr)) { superclasses[0] = fPtr->classCls; } else { @@ -2959,7 +2973,7 @@ ObjMixin_Set( return TCL_ERROR; } - mixins = (Class **)TclStackAlloc(interp, sizeof(Class *) * mixinc); + mixins = (Class **) TclStackAlloc(interp, sizeof(Class *) * mixinc); Tcl_InitHashTable(&uniqueCheck, TCL_ONE_WORD_KEYS); for (i = 0; i < mixinc; i++) { @@ -3760,9 +3774,10 @@ TclOOPropertyDefinitionCmd( if (setterScript != NULL) { Tcl_Obj *setterName = Tcl_ObjPrintf("", TclGetString(propObj)); - Tcl_Obj *argsPtr = Tcl_NewStringObj("value", -1); + Tcl_Obj *argsPtr; Method *mPtr; + TclNewLiteralStringObj(argsPtr, "value"); Tcl_IncrRefCount(setterScript); if (useInstance) { mPtr = TclOONewProcInstanceMethod(interp, oPtr, 0, diff --git a/generic/tclOOInfo.c b/generic/tclOOInfo.c index 4555c39..feac2c0 100644 --- a/generic/tclOOInfo.c +++ b/generic/tclOOInfo.c @@ -95,6 +95,23 @@ static const EnsembleImplMap infoClassCmds[] = { /* * ---------------------------------------------------------------------- * + * LocalVarName -- + * + * Get the name of a local variable (especially a method argument) as a + * Tcl value. + * + * ---------------------------------------------------------------------- + */ +static inline Tcl_Obj * +LocalVarName( + CompiledLocal *localPtr) +{ + return Tcl_NewStringObj(localPtr->name, TCL_AUTO_LENGTH); +} + +/* + * ---------------------------------------------------------------------- + * * TclOOInitInfo -- * * Adjusts the Tcl core [info] command to contain subcommands ("object" @@ -256,22 +273,17 @@ InfoObjectDefnCmd( } hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, objv[2]); if (hPtr == NULL) { - unknownMethod: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "unknown method \"%s\"", TclGetString(objv[2]))); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", - TclGetString(objv[2]), (char *)NULL); - return TCL_ERROR; + goto unknownMethod; } - procPtr = TclOOGetProcFromMethod((Method *)Tcl_GetHashValue(hPtr)); + procPtr = TclOOGetProcFromMethod((Method *) Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "definition not available for this kind of method", -1)); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", - TclGetString(objv[2]), (char *)NULL); - return TCL_ERROR; + goto wrongType; } + /* + * We now have the method to describe the definition of. + */ + TclNewObj(resultObjs[0]); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { @@ -279,17 +291,34 @@ InfoObjectDefnCmd( Tcl_Obj *argObj; TclNewObj(argObj); - Tcl_ListObjAppendElement(NULL, argObj, - Tcl_NewStringObj(localPtr->name, -1)); + Tcl_ListObjAppendElement(NULL, argObj, LocalVarName(localPtr)); if (localPtr->defValuePtr != NULL) { Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr); } Tcl_ListObjAppendElement(NULL, resultObjs[0], argObj); } } - resultObjs[1] = TclOOGetMethodBody((Method *)Tcl_GetHashValue(hPtr)); + resultObjs[1] = TclOOGetMethodBody((Method *) Tcl_GetHashValue(hPtr)); Tcl_SetObjResult(interp, Tcl_NewListObj(2, resultObjs)); return TCL_OK; + + /* + * Errors... + */ + + unknownMethod: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown method \"%s\"", TclGetString(objv[2]))); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", + TclGetString(objv[2]), (char *)NULL); + return TCL_ERROR; + + wrongType: + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "definition not available for this kind of method", -1)); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", + TclGetString(objv[2]), (char *)NULL); + return TCL_ERROR; } /* @@ -367,25 +396,38 @@ InfoObjectForwardCmd( } hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, objv[2]); if (hPtr == NULL) { - unknownMethod: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "unknown method \"%s\"", TclGetString(objv[2]))); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", - TclGetString(objv[2]), (char *)NULL); - return TCL_ERROR; + goto unknownMethod; } - prefixObj = TclOOGetFwdFromMethod((Method *)Tcl_GetHashValue(hPtr)); + prefixObj = TclOOGetFwdFromMethod((Method *) Tcl_GetHashValue(hPtr)); if (prefixObj == NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "prefix argument list not available for this kind of method", - -1)); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", - TclGetString(objv[2]), (char *)NULL); - return TCL_ERROR; + goto wrongType; } + /* + * Describe the valid forward method. + */ + Tcl_SetObjResult(interp, prefixObj); return TCL_OK; + + /* + * Errors... + */ + + unknownMethod: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown method \"%s\"", TclGetString(objv[2]))); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", + TclGetString(objv[2]), (char *)NULL); + return TCL_ERROR; + + wrongType: + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "prefix argument list not available for this kind of method", + -1)); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", + TclGetString(objv[2]), (char *)NULL); + return TCL_ERROR; } /* @@ -544,6 +586,10 @@ InfoObjectMethodsCmd( SCOPE_LOCALPRIVATE }; + /* + * Parse arguments. + */ + if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "objName ?-option value ...?"); return TCL_ERROR; @@ -604,6 +650,10 @@ InfoObjectMethodsCmd( } } + /* + * List matching methods. + */ + TclNewObj(resultObj); if (recurse) { const char **names; @@ -615,7 +665,7 @@ InfoObjectMethodsCmd( Tcl_NewStringObj(names[i], -1)); } if (numNames > 0) { - Tcl_Free((void *)names); + Tcl_Free((void *) names); } } else if (oPtr->methodsPtr) { if (scope == -1) { @@ -684,7 +734,7 @@ InfoObjectMethodTypeCmd( TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } - mPtr = (Method *)Tcl_GetHashValue(hPtr); + mPtr = (Method *) Tcl_GetHashValue(hPtr); if (mPtr->typePtr == NULL) { /* * Special entry for visibility control: pretend the method doesnt @@ -970,8 +1020,7 @@ InfoClassConstrCmd( Tcl_Obj *argObj; TclNewObj(argObj); - Tcl_ListObjAppendElement(NULL, argObj, - Tcl_NewStringObj(localPtr->name, -1)); + Tcl_ListObjAppendElement(NULL, argObj, LocalVarName(localPtr)); if (localPtr->defValuePtr != NULL) { Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr); } @@ -1022,7 +1071,7 @@ InfoClassDefnCmd( TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } - procPtr = TclOOGetProcFromMethod((Method *)Tcl_GetHashValue(hPtr)); + procPtr = TclOOGetProcFromMethod((Method *) Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "definition not available for this kind of method", -1)); @@ -1038,15 +1087,14 @@ InfoClassDefnCmd( Tcl_Obj *argObj; TclNewObj(argObj); - Tcl_ListObjAppendElement(NULL, argObj, - Tcl_NewStringObj(localPtr->name, -1)); + Tcl_ListObjAppendElement(NULL, argObj, LocalVarName(localPtr)); if (localPtr->defValuePtr != NULL) { Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr); } Tcl_ListObjAppendElement(NULL, resultObjs[0], argObj); } } - resultObjs[1] = TclOOGetMethodBody((Method *)Tcl_GetHashValue(hPtr)); + resultObjs[1] = TclOOGetMethodBody((Method *) Tcl_GetHashValue(hPtr)); Tcl_SetObjResult(interp, Tcl_NewListObj(2, resultObjs)); return TCL_OK; } @@ -1220,7 +1268,7 @@ InfoClassForwardCmd( TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } - prefixObj = TclOOGetFwdFromMethod((Method *)Tcl_GetHashValue(hPtr)); + prefixObj = TclOOGetFwdFromMethod((Method *) Tcl_GetHashValue(hPtr)); if (prefixObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "prefix argument list not available for this kind of method", @@ -1383,7 +1431,7 @@ InfoClassMethodsCmd( Tcl_NewStringObj(names[i], -1)); } if (numNames > 0) { - Tcl_Free((void *)names); + Tcl_Free((void *) names); } } else { FOREACH_HASH_DECLS; @@ -1450,7 +1498,7 @@ InfoClassMethodTypeCmd( TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } - mPtr = (Method *)Tcl_GetHashValue(hPtr); + mPtr = (Method *) Tcl_GetHashValue(hPtr); if (mPtr->typePtr == NULL) { /* * Special entry for visibility control: pretend the method doesnt diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index 124953d..182d982 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -30,35 +30,45 @@ * Forward declarations. */ -struct CallChain; -struct Class; -struct Foundation; -struct Object; +typedef struct CallChain CallChain; +typedef struct CallContext CallContext; +typedef struct Class Class; +typedef struct DeclaredClassMethod DeclaredClassMethod; +typedef struct ForwardMethod ForwardMethod; +typedef struct Foundation Foundation; +typedef struct Method Method; +typedef struct MInvoke MInvoke; +typedef struct Object Object; +typedef struct PrivateVariableMapping PrivateVariableMapping; +typedef struct ProcedureMethod ProcedureMethod; +typedef struct PropertyStorage PropertyStorage; /* * The data that needs to be stored per method. This record is used to collect * information about all sorts of methods, including forwards, constructors * and destructors. */ - -typedef struct Method { - const Tcl_MethodType *typePtr; - /* The type of method. If NULL, this is a +struct Method { + union { + const Tcl_MethodType *typePtr; + const Tcl_MethodType2 *type2Ptr; + }; /* The type of method. If NULL, this is a * special flag record which is just used for - * the setting of the flags field. */ + * the setting of the flags field. Note that + * this is a union of two pointer types that + * have the same layout at least as far as the + * internal version field. */ Tcl_Size refCount; void *clientData; /* Type-specific data. */ Tcl_Obj *namePtr; /* Name of the method. */ - struct Object *declaringObjectPtr; - /* The object that declares this method, or + Object *declaringObjectPtr; /* The object that declares this method, or * NULL if it was declared by a class. */ - struct Class *declaringClassPtr; - /* The class that declares this method, or + Class *declaringClassPtr; /* The class that declares this method, or * NULL if it was declared directly on an * object. */ int flags; /* Assorted flags. Includes whether this * method is public/exported or not. */ -} Method; +}; /* * Pre- and post-call callbacks, to allow procedure-like methods to be fine @@ -75,10 +85,9 @@ typedef void *(TclOO_PmCDCloneProc)(void *clientData); /* * Procedure-like methods have the following extra information. */ - -typedef struct ProcedureMethod { +struct ProcedureMethod { int version; /* Version of this structure. Currently must - * be 0. */ + * be TCLOO_PROCEDURE_METHOD_VERSION_1. */ Proc *procPtr; /* Core of the implementation of the method; * includes the argument definition and the * body bytecodes. */ @@ -107,44 +116,47 @@ typedef struct ProcedureMethod { * destructor, which we can't know until then * for messy reasons. Other flags are variable * but not used. */ -} ProcedureMethod; +}; -#define TCLOO_PROCEDURE_METHOD_VERSION 0 +enum ProcedureMethodVersion { + TCLOO_PROCEDURE_METHOD_VERSION_1 = 0 +}; +#define TCLOO_PROCEDURE_METHOD_VERSION TCLOO_PROCEDURE_METHOD_VERSION_1 /* * Flags for use in a ProcedureMethod. * - * When the USE_DECLARER_NS flag is set, the method will use the namespace of - * the object or class that declared it (or the clone of it, if it was from - * such that the implementation of the method came to the particular use) - * instead of the namespace of the object on which the method was invoked. - * This flag must be distinct from all others that are associated with - * methods. */ - -#define USE_DECLARER_NS 0x80 +enum ProceudreMethodFlags { + USE_DECLARER_NS = 0x80 /* When set, the method will use the namespace + * of the object or class that declared it (or + * the clone of it, if it was from such that + * the implementation of the method came to the + * particular use) instead of the namespace of + * the object on which the method was invoked. + * This flag must be distinct from all others + * that are associated with methods. */ +}; /* * Forwarded methods have the following extra information. */ - -typedef struct ForwardMethod { +struct ForwardMethod { Tcl_Obj *prefixObj; /* The list of values to use to replace the * object and method name with. Will be a * non-empty list. */ -} ForwardMethod; +}; /* * Structure used in private variable mappings. Describes the mapping of a * single variable from the user's local name to the system's storage name. * [TIP #500] */ - -typedef struct { +struct PrivateVariableMapping { Tcl_Obj *variableObj; /* Name used within methods. This is the part * that is properly under user control. */ Tcl_Obj *fullNameObj; /* Name used at the instance namespace level. */ -} PrivateVariableMapping; +}; /* * Helper definitions that declare a "list" array. The two varieties are @@ -167,15 +179,19 @@ typedef struct { * These types are needed in function arguments. */ +typedef LIST_STATIC(Class *) ClassList; +typedef LIST_DYNAMIC(Class *) VarClassList; +typedef LIST_STATIC(Tcl_Obj *) FilterList; +typedef LIST_DYNAMIC(Object *) ObjectList; typedef LIST_STATIC(Tcl_Obj *) VariableNameList; typedef LIST_STATIC(PrivateVariableMapping) PrivateVariableList; typedef LIST_STATIC(Tcl_Obj *) PropertyList; /* - * This type is used in various places. + * This type is used in various places. It holds the parts of an object or + * class relating to property information. */ - -typedef struct { +struct PropertyStorage { PropertyList readable; /* The readable properties slot. */ PropertyList writable; /* The writable properties slot. */ Tcl_Obj *allReadableCache; /* The cache of all readable properties @@ -187,37 +203,33 @@ typedef struct { * stereotypical instances). Contains a sorted * unique list if not NULL. */ int epoch; /* The epoch that the caches are valid for. */ -} PropertyStorage; +}; /* * Now, the definition of what an object actually is. */ -typedef struct Object { - struct Foundation *fPtr; /* The basis for the object system. Putting - * this here allows the avoidance of quite a - * lot of hash lookups on the critical path - * for object invocation and creation. */ +struct Object { + Foundation *fPtr; /* The basis for the object system, which is + * conceptually part of the interpreter. */ Tcl_Namespace *namespacePtr;/* This object's namespace. */ Tcl_Command command; /* Reference to this object's public * command. */ Tcl_Command myCommand; /* Reference to this object's internal * command. */ - struct Class *selfCls; /* This object's class. */ + Class *selfCls; /* This object's class. */ Tcl_HashTable *methodsPtr; /* Object-local Tcl_Obj (method name) to * Method* mapping. */ - LIST_STATIC(struct Class *) mixins; - /* Classes mixed into this object. */ - LIST_STATIC(Tcl_Obj *) filters; - /* List of filter names. */ - struct Class *classPtr; /* This is non-NULL for all classes, and NULL + ClassList mixins; /* Classes mixed into this object. */ + FilterList filters; /* List of filter names. */ + Class *classPtr; /* This is non-NULL for all classes, and NULL * for everything else. It points to the class * structure. */ Tcl_Size refCount; /* Number of strong references to this object. * Note that there may be many more weak * references; this mechanism exists to * avoid Tcl_Preserve. */ - int flags; + int flags; /* See ObjectFlags. */ Tcl_Size creationEpoch; /* Unique value to make comparisons of objects * easier. */ Tcl_Size epoch; /* Per-object epoch, incremented when the way @@ -243,67 +255,62 @@ typedef struct Object { PropertyStorage properties; /* Information relating to the lists of * properties that this object *claims* to * support. */ -} Object; +}; -#define OBJECT_DESTRUCTING 1 /* Indicates that an object is being or has +enum ObjectFlags { + OBJECT_DESTRUCTING = 1, /* Indicates that an object is being or has * been destroyed */ -#define DESTRUCTOR_CALLED 2 /* Indicates that evaluation of destructor + DESTRUCTOR_CALLED = 2, /* Indicates that evaluation of destructor * script for the object has began */ -#define OO_UNUSED_4 4 /* No longer used. */ -#define ROOT_OBJECT 0x1000 /* Flag to say that this object is the root of + ROOT_OBJECT = 0x1000, /* Flag to say that this object is the root of * the class hierarchy and should be treated * specially during teardown. */ -#define FILTER_HANDLING 0x2000 /* Flag set when the object is processing a + FILTER_HANDLING = 0x2000, /* Flag set when the object is processing a * filter; when set, filters are *not* * processed on the object, preventing nasty * recursive filtering problems. */ -#define USE_CLASS_CACHE 0x4000 /* Flag set to say that the object is a pure + USE_CLASS_CACHE = 0x4000, /* Flag set to say that the object is a pure * instance of the class, and has had nothing * added that changes the dispatch chain (i.e. * no methods, mixins, or filters. */ -#define ROOT_CLASS 0x8000 /* Flag to say that this object is the root + ROOT_CLASS = 0x8000, /* Flag to say that this object is the root * class of classes, and should be treated * specially during teardown (and in a few * other spots). */ -#define FORCE_UNKNOWN 0x10000 /* States that we are *really* looking up the + FORCE_UNKNOWN = 0x10000, /* States that we are *really* looking up the * unknown method handler at that point. */ -#define DONT_DELETE 0x20000 /* Inhibit deletion of this object. Used + DONT_DELETE = 0x20000, /* Inhibit deletion of this object. Used * during fundamental object type mutation to * make sure that the object actually survives * to the end of the operation. */ -#define HAS_PRIVATE_METHODS 0x40000 + HAS_PRIVATE_METHODS = 0x40000 /* Object/class has (or had) private methods, * and so shouldn't be cached so * aggressively. */ +}; /* * And the definition of a class. Note that every class also has an associated * object, through which it is manipulated. */ -typedef struct Class { +struct Class { Object *thisPtr; /* Reference to the object associated with * this class. */ int flags; /* Assorted flags. */ - LIST_STATIC(struct Class *) superclasses; - /* List of superclasses, used for generation + ClassList superclasses; /* List of superclasses, used for generation * of method call chains. */ - LIST_DYNAMIC(struct Class *) subclasses; - /* List of subclasses, used to ensure deletion + VarClassList subclasses; /* List of subclasses, used to ensure deletion * of dependent entities happens properly when * the class itself is deleted. */ - LIST_DYNAMIC(Object *) instances; - /* List of instances, used to ensure deletion + ObjectList instances; /* List of instances, used to ensure deletion * of dependent entities happens properly when * the class itself is deleted. */ - LIST_STATIC(Tcl_Obj *) filters; - /* List of filter names, used for generation + FilterList filters; /* List of filter names, used for generation * of method call chains. */ - LIST_STATIC(struct Class *) mixins; - /* List of mixin classes, used for generation + ClassList mixins; /* List of mixin classes, used for generation * of method call chains. */ - LIST_DYNAMIC(struct Class *) mixinSubs; - /* List of classes that this class is mixed + VarClassList mixinSubs; /* List of classes that this class is mixed * into, used to ensure deletion of dependent * entities happens properly when the class * itself is deleted. */ @@ -319,8 +326,8 @@ typedef struct Class { * of each piece of attached metadata. This * field starts out as NULL and is only * allocated if metadata is attached. */ - struct CallChain *constructorChainPtr; - struct CallChain *destructorChainPtr; + CallChain *constructorChainPtr; + CallChain *destructorChainPtr; Tcl_HashTable *classChainCache; /* Places where call chains are stored. For * constructors, the class chain is always @@ -354,15 +361,12 @@ typedef struct Class { PropertyStorage properties; /* Information relating to the lists of * properties that this class *claims* to * support. */ -} Class; +}; /* - * The foundation of the object system within an interpreter contains - * references to the key classes and namespaces, together with a few other - * useful bits and pieces. Probably ought to eventually go in the Interp - * structure itself. + * Master epoch counter for making unique IDs for objects that can be compared + * cheaply. */ - typedef struct ThreadLocalData { Tcl_Size nsCount; /* Epoch counter is used for keeping * the values used in Tcl_Obj internal @@ -372,19 +376,17 @@ typedef struct ThreadLocalData { * generally cross threads). */ } ThreadLocalData; -typedef struct Foundation { - Tcl_Interp *interp; +/* + * The foundation of the object system within an interpreter contains + * references to the key classes and namespaces, together with a few other + * useful bits and pieces. Probably ought to eventually go in the Interp + * structure itself. + */ +struct Foundation { + Tcl_Interp *interp; /* The interpreter this is attached to. */ Class *objectCls; /* The root of the object system. */ Class *classCls; /* The class of all classes. */ Tcl_Namespace *ooNs; /* ::oo namespace. */ - Tcl_Namespace *defineNs; /* Namespace containing special commands for - * manipulating objects and classes. The - * "oo::define" command acts as a special kind - * of ensemble for this namespace. */ - Tcl_Namespace *objdefNs; /* Namespace containing special commands for - * manipulating objects and classes. The - * "oo::objdefine" command acts as a special - * kind of ensemble for this namespace. */ Tcl_Namespace *helpersNs; /* Namespace containing the commands that are * only valid when executing inside a * procedural method. */ @@ -403,17 +405,18 @@ typedef struct Foundation { * "" pseudo-constructor. */ Tcl_Obj *defineName; /* Fully qualified name of oo::define. */ Tcl_Obj *myName; /* The "my" shared object. */ -} Foundation; +}; /* - * A call context structure is built when a method is called. It contains the - * chain of method implementations that are to be invoked by a particular - * call, and the process of calling walks the chain, with the [next] command - * proceeding to the next entry in the chain. + * The number of MInvoke records in the CallChain before we allocate + * separately. */ - #define CALL_CHAIN_STATIC_SIZE 4 +/* + * Information relating to the invocation of a particular method implementation + * in a call chain. + */ struct MInvoke { Method *mPtr; /* Reference to the method implementation * record. */ @@ -422,7 +425,10 @@ struct MInvoke { * NULL, it was added by the object. */ }; -typedef struct CallChain { +/* + * The cacheable part of a call context. + */ +struct CallChain { Tcl_Size objectCreationEpoch;/* The object's creation epoch. Note that the * object reference is not stored in the call * chain; it is in the call context. */ @@ -433,13 +439,19 @@ typedef struct CallChain { int flags; /* Assorted flags, see below. */ Tcl_Size refCount; /* Reference count. */ Tcl_Size numChain; /* Size of the call chain. */ - struct MInvoke *chain; /* Array of call chain entries. May point to + MInvoke *chain; /* Array of call chain entries. May point to * staticChain if the number of entries is * small. */ - struct MInvoke staticChain[CALL_CHAIN_STATIC_SIZE]; -} CallChain; + MInvoke staticChain[CALL_CHAIN_STATIC_SIZE]; +}; -typedef struct CallContext { +/* + * A call context structure is built when a method is called. It contains the + * chain of method implementations that are to be invoked by a particular + * call, and the process of calling walks the chain, with the [next] command + * proceeding to the next entry in the chain. + */ +struct CallContext { Object *oPtr; /* The object associated with this call. */ Tcl_Size index; /* Index into the call chain of the currently * executing method implementation. */ @@ -448,33 +460,32 @@ typedef struct CallContext { * method call or a continuation via the * [next] command. */ CallChain *callPtr; /* The actual call chain. */ -} CallContext; +}; /* * Bits for the 'flags' field of the call chain. */ - -#define PUBLIC_METHOD 0x01 /* This is a public (exported) method. */ -#define PRIVATE_METHOD 0x02 /* This is a private (class's direct instances +enum TclOOCallChainFlags { + PUBLIC_METHOD = 0x01, /* This is a public (exported) method. */ + PRIVATE_METHOD = 0x02, /* This is a private (class's direct instances * only) method. Supports itcl. */ -#define OO_UNKNOWN_METHOD 0x04 /* This is an unknown method. */ -#define CONSTRUCTOR 0x08 /* This is a constructor. */ -#define DESTRUCTOR 0x10 /* This is a destructor. */ -#define TRUE_PRIVATE_METHOD 0x20 - /* This is a private method only accessible + OO_UNKNOWN_METHOD = 0x04, /* This is an unknown method. */ + CONSTRUCTOR = 0x08, /* This is a constructor. */ + DESTRUCTOR = 0x10, /* This is a destructor. */ + TRUE_PRIVATE_METHOD = 0x20 /* This is a private method only accessible * from other methods defined on this class * or instance. [TIP #500] */ +}; #define SCOPE_FLAGS (PUBLIC_METHOD | PRIVATE_METHOD | TRUE_PRIVATE_METHOD) /* * Structure containing definition information about basic class methods. */ - -typedef struct { +struct DeclaredClassMethod { const char *name; /* Name of the method in question. */ int isPublic; /* Whether the method is public by default. */ Tcl_MethodType definition; /* How to call the method. */ -} DeclaredClassMethod; +}; /* *---------------------------------------------------------------- @@ -538,7 +549,7 @@ MODULE_SCOPE Tcl_Method TclNewInstanceMethod(Tcl_Interp *interp, Tcl_Object object, Tcl_Obj *nameObj, int flags, const Tcl_MethodType *typePtr, void *clientData); -MODULE_SCOPE Tcl_Method TclNewMethod(Tcl_Interp *interp, Tcl_Class cls, +MODULE_SCOPE Tcl_Method TclNewMethod(Tcl_Class cls, Tcl_Obj *nameObj, int flags, const Tcl_MethodType *typePtr, void *clientData); @@ -595,7 +606,7 @@ MODULE_SCOPE int TclOOInvokeContext(void *clientData, MODULE_SCOPE int TclNRObjectContextInvokeNext(Tcl_Interp *interp, Tcl_ObjectContext context, Tcl_Size objc, Tcl_Obj *const *objv, Tcl_Size skip); -MODULE_SCOPE void TclOONewBasicMethod(Tcl_Interp *interp, Class *clsPtr, +MODULE_SCOPE void TclOONewBasicMethod(Class *clsPtr, const DeclaredClassMethod *dcm); MODULE_SCOPE Tcl_Obj * TclOOObjectName(Tcl_Interp *interp, Object *oPtr); MODULE_SCOPE void TclOOReleaseClassContents(Tcl_Interp *interp, diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c index f60b1c2..89e4d4e 100644 --- a/generic/tclOOMethod.c +++ b/generic/tclOOMethod.c @@ -21,7 +21,7 @@ * used in a procedure-like method. */ -typedef struct { +typedef struct PMFrameData { CallFrame *framePtr; /* Reference to the call frame itself (it's * actually allocated on the Tcl stack). */ ProcErrorProc *errProc; /* The error handler for the body. */ @@ -34,7 +34,7 @@ typedef struct { * on-the-ground resolvers used when working with resolved compiled variables. */ -typedef struct { +typedef struct OOResVarInfo { Tcl_ResolvedVarInfo info; /* "Type" information so that the compiled * variable can be linked to the namespace * variable at the right time. */ @@ -146,25 +146,25 @@ TclNewInstanceMethod( int isNew; if (nameObj == NULL) { - mPtr = (Method *)Tcl_Alloc(sizeof(Method)); + mPtr = (Method *) Tcl_Alloc(sizeof(Method)); mPtr->namePtr = NULL; mPtr->refCount = 1; goto populate; } if (!oPtr->methodsPtr) { - oPtr->methodsPtr = (Tcl_HashTable *)Tcl_Alloc(sizeof(Tcl_HashTable)); + oPtr->methodsPtr = (Tcl_HashTable *) Tcl_Alloc(sizeof(Tcl_HashTable)); Tcl_InitObjHashTable(oPtr->methodsPtr); oPtr->flags &= ~USE_CLASS_CACHE; } hPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, nameObj, &isNew); if (isNew) { - mPtr = (Method *)Tcl_Alloc(sizeof(Method)); + mPtr = (Method *) Tcl_Alloc(sizeof(Method)); mPtr->namePtr = nameObj; mPtr->refCount = 1; Tcl_IncrRefCount(nameObj); Tcl_SetHashValue(hPtr, mPtr); } else { - mPtr = (Method *)Tcl_GetHashValue(hPtr); + mPtr = (Method *) Tcl_GetHashValue(hPtr); if (mPtr->typePtr != NULL && mPtr->typePtr->deleteProc != NULL) { mPtr->typePtr->deleteProc(mPtr->clientData); } @@ -203,10 +203,11 @@ Tcl_NewInstanceMethod( * method to be created. */ { if (typePtr->version > TCL_OO_METHOD_VERSION_1) { - Tcl_Panic("%s: Wrong version in typePtr->version, should be TCL_OO_METHOD_VERSION_1", "Tcl_NewInstanceMethod"); + Tcl_Panic("%s: Wrong version in typePtr->version, should be %s", + "Tcl_NewInstanceMethod", "TCL_OO_METHOD_VERSION_1"); } - return TclNewInstanceMethod(NULL, object, nameObj, flags, - (const Tcl_MethodType *)typePtr, clientData); + return TclNewInstanceMethod(NULL, object, nameObj, flags, typePtr, + clientData); } Tcl_Method Tcl_NewInstanceMethod2( @@ -225,10 +226,11 @@ Tcl_NewInstanceMethod2( * method to be created. */ { if (typePtr->version < TCL_OO_METHOD_VERSION_2) { - Tcl_Panic("%s: Wrong version in typePtr->version, should be TCL_OO_METHOD_VERSION_2", "Tcl_NewInstanceMethod2"); + Tcl_Panic("%s: Wrong version in typePtr->version, should be %s", + "Tcl_NewInstanceMethod2", "TCL_OO_METHOD_VERSION_2"); } return TclNewInstanceMethod(NULL, object, nameObj, flags, - (const Tcl_MethodType *)typePtr, clientData); + (const Tcl_MethodType *) typePtr, clientData); } /* @@ -243,7 +245,6 @@ Tcl_NewInstanceMethod2( Tcl_Method TclNewMethod( - TCL_UNUSED(Tcl_Interp *), Tcl_Class cls, /* The class to attach the method to. */ Tcl_Obj *nameObj, /* The name of the object. May be NULL (e.g., * for constructors or destructors); if so, up @@ -262,20 +263,20 @@ TclNewMethod( int isNew; if (nameObj == NULL) { - mPtr = (Method *)Tcl_Alloc(sizeof(Method)); + mPtr = (Method *) Tcl_Alloc(sizeof(Method)); mPtr->namePtr = NULL; mPtr->refCount = 1; goto populate; } - hPtr = Tcl_CreateHashEntry(&clsPtr->classMethods, nameObj,&isNew); + hPtr = Tcl_CreateHashEntry(&clsPtr->classMethods, nameObj, &isNew); if (isNew) { - mPtr = (Method *)Tcl_Alloc(sizeof(Method)); + mPtr = (Method *) Tcl_Alloc(sizeof(Method)); mPtr->refCount = 1; mPtr->namePtr = nameObj; Tcl_IncrRefCount(nameObj); Tcl_SetHashValue(hPtr, mPtr); } else { - mPtr = (Method *)Tcl_GetHashValue(hPtr); + mPtr = (Method *) Tcl_GetHashValue(hPtr); if (mPtr->typePtr != NULL && mPtr->typePtr->deleteProc != NULL) { mPtr->typePtr->deleteProc(mPtr->clientData); } @@ -315,9 +316,10 @@ Tcl_NewMethod( * method to be created. */ { if (typePtr->version > TCL_OO_METHOD_VERSION_1) { - Tcl_Panic("%s: Wrong version in typePtr->version, should be TCL_OO_METHOD_VERSION_1", "Tcl_NewMethod"); + Tcl_Panic("%s: Wrong version in typePtr->version, should be %s", + "Tcl_NewMethod", "TCL_OO_METHOD_VERSION_1"); } - return TclNewMethod(NULL, cls, nameObj, flags, typePtr, clientData); + return TclNewMethod(cls, nameObj, flags, typePtr, clientData); } Tcl_Method @@ -336,9 +338,11 @@ Tcl_NewMethod2( * method to be created. */ { if (typePtr->version < TCL_OO_METHOD_VERSION_2) { - Tcl_Panic("%s: Wrong version in typePtr->version, should be TCL_OO_METHOD_VERSION_2", "Tcl_NewMethod2"); + Tcl_Panic("%s: Wrong version in typePtr->version, should be %s", + "Tcl_NewMethod2", "TCL_OO_METHOD_VERSION_2"); } - return TclNewMethod(NULL, cls, nameObj, flags, (const Tcl_MethodType *)typePtr, clientData); + return TclNewMethod(cls, nameObj, flags, + (const Tcl_MethodType *) typePtr, clientData); } /* @@ -380,7 +384,6 @@ TclOODelMethodRef( void TclOONewBasicMethod( - Tcl_Interp *interp, Class *clsPtr, /* Class to attach the method to. */ const DeclaredClassMethod *dcm) /* Name of the method, whether it is public, @@ -388,10 +391,9 @@ TclOONewBasicMethod( { Tcl_Obj *namePtr = Tcl_NewStringObj(dcm->name, -1); - Tcl_IncrRefCount(namePtr); - TclNewMethod(interp, (Tcl_Class) clsPtr, namePtr, + TclNewMethod((Tcl_Class) clsPtr, namePtr, (dcm->isPublic ? PUBLIC_METHOD : 0), &dcm->definition, NULL); - Tcl_DecrRefCount(namePtr); + Tcl_BounceRefCount(namePtr); } /* @@ -550,7 +552,7 @@ InitCmdFrame( if (context.line && context.nline > 1 && (context.line[context.nline - 1] >= 0)) { int isNew; - CmdFrame *cfPtr = (CmdFrame *)Tcl_Alloc(sizeof(CmdFrame)); + CmdFrame *cfPtr = (CmdFrame *) Tcl_Alloc(sizeof(CmdFrame)); Tcl_HashEntry *hPtr; cfPtr->level = -1; @@ -678,8 +680,8 @@ TclOOMakeProcMethod( InitCmdFrame(iPtr, procPtr); - return TclNewMethod(interp, (Tcl_Class) clsPtr, nameObj, flags, typePtr, - clientData); + return TclNewMethod( + (Tcl_Class) clsPtr, nameObj, flags, typePtr, clientData); } /* @@ -700,7 +702,7 @@ InvokeProcedureMethod( int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Arguments as actually seen. */ { - ProcedureMethod *pmPtr = (ProcedureMethod *)clientData; + ProcedureMethod *pmPtr = (ProcedureMethod *) clientData; int result; PMFrameData *fdPtr; /* Important data that has to have a lifetime * matched by this function (or rather, by the @@ -711,7 +713,7 @@ InvokeProcedureMethod( * the next thing in the chain. */ - if (TclOOObjectDestroyed(((CallContext *)context)->oPtr) + if (TclOOObjectDestroyed(((CallContext *) context)->oPtr) || Tcl_InterpDeleted(interp)) { return TclNRObjectContextInvokeNext(interp, context, objc, objv, Tcl_ObjectContextSkippedArgs(context)); @@ -752,7 +754,7 @@ InvokeProcedureMethod( * Allocate the special frame data. */ - fdPtr = (PMFrameData *)TclStackAlloc(interp, sizeof(PMFrameData)); + fdPtr = (PMFrameData *) TclStackAlloc(interp, sizeof(PMFrameData)); /* * Create a call frame for this method. @@ -802,9 +804,9 @@ FinalizePMCall( Tcl_Interp *interp, int result) { - ProcedureMethod *pmPtr = (ProcedureMethod *)data[0]; - Tcl_ObjectContext context = (Tcl_ObjectContext)data[1]; - PMFrameData *fdPtr = (PMFrameData *)data[2]; + ProcedureMethod *pmPtr = (ProcedureMethod *) data[0]; + Tcl_ObjectContext context = (Tcl_ObjectContext) data[1]; + PMFrameData *fdPtr = (PMFrameData *) data[2]; /* * Give the post-call callback a chance to do some cleanup. Note that at @@ -998,7 +1000,7 @@ ProcedureMethodCompiledVarConnect( if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) { return NULL; } - contextPtr = (CallContext *)framePtr->clientData; + contextPtr = (CallContext *) framePtr->clientData; /* * If we've done the work before (in a comparable context) then reuse that @@ -1118,7 +1120,7 @@ ProcedureMethodCompiledVarResolver( return TCL_CONTINUE; } - infoPtr = (OOResVarInfo *)Tcl_Alloc(sizeof(OOResVarInfo)); + infoPtr = (OOResVarInfo *) Tcl_Alloc(sizeof(OOResVarInfo)); infoPtr->info.fetchProc = ProcedureMethodCompiledVarConnect; infoPtr->info.deleteProc = ProcedureMethodCompiledVarDelete; infoPtr->cachedObjectVar = NULL; @@ -1208,7 +1210,8 @@ MethodErrorHandler( // We pull the method name out of context instead of from argument { Tcl_Size nameLen, objectNameLen; - CallContext *contextPtr = (CallContext *)((Interp *) interp)->varFramePtr->clientData; + CallContext *contextPtr = (CallContext *) + ((Interp *) interp)->varFramePtr->clientData; Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; const char *objectName, *kindName, *methodName = Tcl_GetStringFromObj(mPtr->namePtr, &nameLen); @@ -1239,7 +1242,8 @@ ConstructorErrorHandler( TCL_UNUSED(Tcl_Obj *) /*methodNameObj*/) // Ignore. We know it is the constructor. { - CallContext *contextPtr = (CallContext *)((Interp *) interp)->varFramePtr->clientData; + CallContext *contextPtr = (CallContext *) + ((Interp *) interp)->varFramePtr->clientData; Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; Object *declarerPtr; const char *objectName, *kindName; @@ -1269,7 +1273,8 @@ DestructorErrorHandler( TCL_UNUSED(Tcl_Obj *) /*methodNameObj*/) // Ignore. We know it is the destructor. { - CallContext *contextPtr = (CallContext *)((Interp *) interp)->varFramePtr->clientData; + CallContext *contextPtr = (CallContext *) + ((Interp *) interp)->varFramePtr->clientData; Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; Object *declarerPtr; const char *objectName, *kindName; @@ -1318,7 +1323,7 @@ static void DeleteProcedureMethod( void *clientData) { - ProcedureMethod *pmPtr = (ProcedureMethod *)clientData; + ProcedureMethod *pmPtr = (ProcedureMethod *) clientData; if (pmPtr->refCount-- <= 1) { DeleteProcedureMethodRecord(pmPtr); @@ -1331,7 +1336,7 @@ CloneProcedureMethod( void *clientData, void **newClientData) { - ProcedureMethod *pmPtr = (ProcedureMethod *)clientData; + ProcedureMethod *pmPtr = (ProcedureMethod *) clientData; ProcedureMethod *pm2Ptr; Tcl_Obj *bodyObj, *argsObj; CompiledLocal *localPtr; @@ -1370,7 +1375,7 @@ CloneProcedureMethod( * record. */ - pm2Ptr = (ProcedureMethod *)Tcl_Alloc(sizeof(ProcedureMethod)); + pm2Ptr = (ProcedureMethod *) Tcl_Alloc(sizeof(ProcedureMethod)); memcpy(pm2Ptr, pmPtr, sizeof(ProcedureMethod)); pm2Ptr->refCount = 1; pm2Ptr->cmd.clientData = &pm2Ptr->efi; @@ -1426,7 +1431,7 @@ TclOONewForwardInstanceMethod( return NULL; } - fmPtr = (ForwardMethod *)Tcl_Alloc(sizeof(ForwardMethod)); + fmPtr = (ForwardMethod *) Tcl_Alloc(sizeof(ForwardMethod)); fmPtr->prefixObj = prefixObj; Tcl_IncrRefCount(prefixObj); return (Method *) TclNewInstanceMethod(interp, (Tcl_Object) oPtr, @@ -1465,10 +1470,10 @@ TclOONewForwardMethod( return NULL; } - fmPtr = (ForwardMethod *)Tcl_Alloc(sizeof(ForwardMethod)); + fmPtr = (ForwardMethod *) Tcl_Alloc(sizeof(ForwardMethod)); fmPtr->prefixObj = prefixObj; Tcl_IncrRefCount(prefixObj); - return (Method *) TclNewMethod(interp, (Tcl_Class) clsPtr, nameObj, + return (Method *) TclNewMethod((Tcl_Class) clsPtr, nameObj, flags, &fwdMethodType, fmPtr); } @@ -1492,7 +1497,7 @@ InvokeForwardMethod( Tcl_Obj *const *objv) /* Arguments as actually seen. */ { CallContext *contextPtr = (CallContext *) context; - ForwardMethod *fmPtr = (ForwardMethod *)clientData; + ForwardMethod *fmPtr = (ForwardMethod *) clientData; Tcl_Obj **argObjs, **prefixObjs; Tcl_Size numPrefixes, skip = contextPtr->skip; int len; @@ -1513,8 +1518,8 @@ InvokeForwardMethod( * of the TCL_EVAL_NOERR flag results in an evaluation configuration * very much like TCL_EVAL_INVOKE. */ - ((Interp *)interp)->lookupNsPtr - = (Namespace *) contextPtr->oPtr->namespacePtr; + ((Interp *) interp)->lookupNsPtr = (Namespace *) + contextPtr->oPtr->namespacePtr; return TclNREvalObjv(interp, len, argObjs, TCL_EVAL_NOERR, NULL); } @@ -1524,7 +1529,7 @@ FinalizeForwardCall( Tcl_Interp *interp, int result) { - Tcl_Obj **argObjs = (Tcl_Obj **)data[0]; + Tcl_Obj **argObjs = (Tcl_Obj **) data[0]; TclStackFree(interp, argObjs); return result; @@ -1544,7 +1549,7 @@ static void DeleteForwardMethod( void *clientData) { - ForwardMethod *fmPtr = (ForwardMethod *)clientData; + ForwardMethod *fmPtr = (ForwardMethod *) clientData; Tcl_DecrRefCount(fmPtr->prefixObj); Tcl_Free(fmPtr); @@ -1556,8 +1561,8 @@ CloneForwardMethod( void *clientData, void **newClientData) { - ForwardMethod *fmPtr = (ForwardMethod *)clientData; - ForwardMethod *fm2Ptr = (ForwardMethod *)Tcl_Alloc(sizeof(ForwardMethod)); + ForwardMethod *fmPtr = (ForwardMethod *) clientData; + ForwardMethod *fm2Ptr = (ForwardMethod *) Tcl_Alloc(sizeof(ForwardMethod)); fm2Ptr->prefixObj = fmPtr->prefixObj; Tcl_IncrRefCount(fm2Ptr->prefixObj); @@ -1581,7 +1586,7 @@ TclOOGetProcFromMethod( Method *mPtr) { if (mPtr->typePtr == &procMethodType) { - ProcedureMethod *pmPtr = (ProcedureMethod *)mPtr->clientData; + ProcedureMethod *pmPtr = (ProcedureMethod *) mPtr->clientData; return pmPtr->procPtr; } @@ -1593,7 +1598,7 @@ TclOOGetMethodBody( Method *mPtr) { if (mPtr->typePtr == &procMethodType) { - ProcedureMethod *pmPtr = (ProcedureMethod *)mPtr->clientData; + ProcedureMethod *pmPtr = (ProcedureMethod *) mPtr->clientData; (void) TclGetString(pmPtr->procPtr->bodyPtr); return pmPtr->procPtr->bodyPtr; @@ -1606,7 +1611,7 @@ TclOOGetFwdFromMethod( Method *mPtr) { if (mPtr->typePtr == &fwdMethodType) { - ForwardMethod *fwPtr = (ForwardMethod *)mPtr->clientData; + ForwardMethod *fwPtr = (ForwardMethod *) mPtr->clientData; return fwPtr->prefixObj; } @@ -1648,7 +1653,8 @@ InitEnsembleRewrite( * array of rewritten arguments. */ { size_t len = rewriteLength + objc - toRewrite; - Tcl_Obj **argObjs = (Tcl_Obj **)TclStackAlloc(interp, sizeof(Tcl_Obj *) * len); + Tcl_Obj **argObjs = (Tcl_Obj **) + TclStackAlloc(interp, sizeof(Tcl_Obj *) * len); memcpy(argObjs, rewriteObjs, rewriteLength * sizeof(Tcl_Obj *)); memcpy(argObjs + rewriteLength, objv + toRewrite, @@ -1725,7 +1731,8 @@ Tcl_MethodIsType( Method *mPtr = (Method *) method; if (typePtr->version > TCL_OO_METHOD_VERSION_1) { - Tcl_Panic("%s: Wrong version in typePtr->version, should be TCL_OO_METHOD_VERSION_1", "Tcl_MethodIsType"); + Tcl_Panic("%s: Wrong version in typePtr->version, should be %s", + "Tcl_MethodIsType", "TCL_OO_METHOD_VERSION_1"); } if (mPtr->typePtr == typePtr) { if (clientDataPtr != NULL) { @@ -1745,9 +1752,10 @@ Tcl_MethodIsType2( Method *mPtr = (Method *) method; if (typePtr->version < TCL_OO_METHOD_VERSION_2) { - Tcl_Panic("%s: Wrong version in typePtr->version, should be TCL_OO_METHOD_VERSION_2", "Tcl_MethodIsType2"); + Tcl_Panic("%s: Wrong version in typePtr->version, should be %s", + "Tcl_MethodIsType2", "TCL_OO_METHOD_VERSION_2"); } - if (mPtr->typePtr == (const Tcl_MethodType *)typePtr) { + if (mPtr->typePtr == (const Tcl_MethodType *) typePtr) { if (clientDataPtr != NULL) { *clientDataPtr = mPtr->clientData; } @@ -1760,14 +1768,14 @@ int Tcl_MethodIsPublic( Tcl_Method method) { - return (((Method *)method)->flags & PUBLIC_METHOD) ? 1 : 0; + return (((Method *) method)->flags & PUBLIC_METHOD) ? 1 : 0; } int Tcl_MethodIsPrivate( Tcl_Method method) { - return (((Method *)method)->flags & TRUE_PRIVATE_METHOD) ? 1 : 0; + return (((Method *) method)->flags & TRUE_PRIVATE_METHOD) ? 1 : 0; } /* -- cgit v0.12 From f1f89714f1316b959c3fa005c1b005fb48aacafc Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 1 Aug 2024 19:40:04 +0000 Subject: Remove redundant code. --- generic/tclOO.c | 10 +++------- generic/tclOODefineCmds.c | 42 +----------------------------------------- generic/tclOOInt.h | 1 - 3 files changed, 4 insertions(+), 49 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 288b7f2..2ffc0d4 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -17,7 +17,7 @@ #include "tclOOInt.h" /* - * Commands in oo::define. + * Commands in oo::define and oo::objdefine. */ static const struct { @@ -337,7 +337,7 @@ InitFoundation( ThreadLocalData *tsdPtr = (ThreadLocalData *) Tcl_GetThreadData(&tsdKey, sizeof(ThreadLocalData)); Foundation *fPtr = (Foundation *) Tcl_Alloc(sizeof(Foundation)); - Tcl_Namespace *define, *objdef, *cfg; + Tcl_Namespace *define, *objdef; Tcl_Obj *namePtr; size_t i; @@ -356,7 +356,7 @@ InitFoundation( objdef = Tcl_CreateNamespace(interp, "::oo::objdefine", fPtr, NULL); fPtr->helpersNs = Tcl_CreateNamespace(interp, "::oo::Helpers", fPtr, DeletedHelpersNamespace); - cfg = Tcl_CreateNamespace(interp, "::oo::configuresupport", NULL, NULL); + Tcl_CreateNamespace(interp, "::oo::configuresupport", NULL, NULL); fPtr->epoch = 1; fPtr->tsdPtr = tsdPtr; @@ -461,10 +461,6 @@ InitFoundation( for (i = 0 ; cfgMethods[i].name ; i++) { TclOONewBasicMethod(((Object *) cfgCls)->classPtr, &cfgMethods[i]); } - TclCreateObjCommandInNs(interp, "StdObjectProperties", cfg, - TclOOInstallStdPropertyImplsCmd, (void *) 1, NULL); - TclCreateObjCommandInNs(interp, "StdClassProperties", cfg, - TclOOInstallStdPropertyImplsCmd, (void *) 0, NULL); /* * Don't have handles to these namespaces, so use Tcl_CreateObjCommand. diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 882ca52..0e81cc8 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -3800,11 +3800,7 @@ TclOOPropertyDefinitionCmd( /* * ---------------------------------------------------------------------- * - * InstallStdPropertyImpls, TclOOInstallStdPropertyImplsCmd -- - * - * Implementations of the "StdClassProperties" hidden definition for - * classes and the "StdObjectProperties" hidden definition for - * instances. Both are located in the ::oo::configuresupport namespace. + * InstallStdPropertyImpls -- * * Validates a (dashless) property name, and installs implementation * methods if asked to do so (readable and writable flags). @@ -3875,42 +3871,6 @@ InstallStdPropertyImpls( Tcl_SetErrorCode(interp, "TCL", "OO", "PROPERTY_FORMAT", NULL); return TCL_ERROR; } - -int -TclOOInstallStdPropertyImplsCmd( - void *useInstance, - Tcl_Interp *interp, - int objc, - Tcl_Obj *const *objv) -{ - int readable, writable; - Tcl_Obj *propName; - - /* - * Parse the arguments. - */ - - if (objc != 4) { - Tcl_WrongNumArgs(interp, 1, objv, "propName readable writable"); - return TCL_ERROR; - } - propName = objv[1]; - if (Tcl_GetBooleanFromObj(interp, objv[2], &readable) != TCL_OK) { - return TCL_ERROR; - } - if (Tcl_GetBooleanFromObj(interp, objv[3], &writable) != TCL_OK) { - return TCL_ERROR; - } - - - /* - * Validate the property name and install the implementations... if asked - * to do so. - */ - - return InstallStdPropertyImpls(useInstance, interp, propName, readable, - writable); -} /* * Local Variables: diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index 182d982..5377ca3 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -509,7 +509,6 @@ MODULE_SCOPE Tcl_ObjCmdProc TclOODefineClassObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineSelfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineObjSelfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefinePrivateObjCmd; -MODULE_SCOPE Tcl_ObjCmdProc TclOOInstallStdPropertyImplsCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOPropertyDefinitionCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOUnknownDefinition; MODULE_SCOPE Tcl_ObjCmdProc TclOOCopyObjectCmd; -- cgit v0.12 From 815598b87133a1634e4adc9913778780aae94f23 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 2 Aug 2024 12:03:24 +0000 Subject: Factor out most property-related C code into its own file. --- generic/tclOO.c | 42 +- generic/tclOOBasic.c | 471 +----------------- generic/tclOOCall.c | 247 ---------- generic/tclOODefineCmds.c | 276 ++--------- generic/tclOOInfo.c | 218 +-------- generic/tclOOInt.h | 20 +- generic/tclOOProp.c | 1174 +++++++++++++++++++++++++++++++++++++++++++++ unix/Makefile.in | 6 +- win/Makefile.in | 1 + win/makefile.vc | 1 + 10 files changed, 1258 insertions(+), 1198 deletions(-) create mode 100644 generic/tclOOProp.c diff --git a/generic/tclOO.c b/generic/tclOO.c index 2ffc0d4..7384232 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -1004,7 +1004,7 @@ TclOOReleaseClassContents( Class *clsPtr = oPtr->classPtr, *tmpClsPtr; Method *mPtr; Foundation *fPtr = oPtr->fPtr; - Tcl_Obj *variableObj, *propertyObj; + Tcl_Obj *variableObj; PrivateVariableMapping *privateVariable; /* @@ -1061,24 +1061,7 @@ TclOOReleaseClassContents( * Squelch the property lists. */ - if (clsPtr->properties.allReadableCache) { - Tcl_DecrRefCount(clsPtr->properties.allReadableCache); - } - if (clsPtr->properties.allWritableCache) { - Tcl_DecrRefCount(clsPtr->properties.allWritableCache); - } - if (clsPtr->properties.readable.num) { - FOREACH(propertyObj, clsPtr->properties.readable) { - Tcl_DecrRefCount(propertyObj); - } - Tcl_Free(clsPtr->properties.readable.list); - } - if (clsPtr->properties.writable.num) { - FOREACH(propertyObj, clsPtr->properties.writable) { - Tcl_DecrRefCount(propertyObj); - } - Tcl_Free(clsPtr->properties.writable.list); - } + TclOOReleasePropertyStorage(&clsPtr->properties); /* * Squelch our filter list. @@ -1181,7 +1164,7 @@ ObjectNamespaceDeleted( FOREACH_HASH_DECLS; Class *mixinPtr; Method *mPtr; - Tcl_Obj *filterObj, *variableObj, *propertyObj; + Tcl_Obj *filterObj, *variableObj; PrivateVariableMapping *privateVariable; Tcl_Interp *interp = oPtr->fPtr->interp; Tcl_Size i; @@ -1338,24 +1321,7 @@ ObjectNamespaceDeleted( * Squelch the property lists. */ - if (oPtr->properties.allReadableCache) { - Tcl_DecrRefCount(oPtr->properties.allReadableCache); - } - if (oPtr->properties.allWritableCache) { - Tcl_DecrRefCount(oPtr->properties.allWritableCache); - } - if (oPtr->properties.readable.num) { - FOREACH(propertyObj, oPtr->properties.readable) { - Tcl_DecrRefCount(propertyObj); - } - Tcl_Free(oPtr->properties.readable.list); - } - if (oPtr->properties.writable.num) { - FOREACH(propertyObj, oPtr->properties.writable) { - Tcl_DecrRefCount(propertyObj); - } - Tcl_Free(oPtr->properties.writable.list); - } + TclOOReleasePropertyStorage(&oPtr->properties); /* * Because an object can be a class that is an instance of itself, the diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index cfb7cb5..c9a5c7a 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -23,18 +23,6 @@ static Tcl_NRPostProc DecrRefsPostClassConstructor; static Tcl_NRPostProc FinalizeConstruction; static Tcl_NRPostProc FinalizeEval; static Tcl_NRPostProc NextRestoreFrame; - -/* Short-term cache for GetPropertyName(). */ -typedef struct GPNCache { - Tcl_Obj *listPtr; /* Holds references to names. */ - char *names[TCLFLEXARRAY]; /* NULL-terminated table of names. */ -} GPNCache; - -enum GPNFlags { - GPN_WRITABLE = 1, /* Are we looking for a writable property? */ - GPN_FALLING_BACK = 2 /* Are we doing a recursive call to determine - * if the property is of the other type? */ -}; /* * ---------------------------------------------------------------------- @@ -733,15 +721,14 @@ TclOO_Object_LinkVar( /* * ---------------------------------------------------------------------- * - * LookupObjectVar -- + * TclOOLookupObjectVar -- * * Look up a variable in an object. Tricky because of private variables. * * ---------------------------------------------------------------------- */ - -static Tcl_Var -LookupObjectVar( +Tcl_Var +TclOOLookupObjectVar( Tcl_Interp *interp, Tcl_Object object, Tcl_Obj *varName, @@ -860,7 +847,7 @@ TclOO_Object_VarName( return TCL_ERROR; } - varPtr = LookupObjectVar(interp, Tcl_ObjectContextObject(context), + varPtr = TclOOLookupObjectVar(interp, Tcl_ObjectContextObject(context), objv[objc - 1], &aryVar); if (varPtr == NULL) { return TCL_ERROR; @@ -1383,456 +1370,6 @@ TclOOCopyObjectCmd( } /* - * ---------------------------------------------------------------------- - * - * TclOO_Configurable_Configure -- - * - * Implementation of the oo::configurable->configure method. - * - * ---------------------------------------------------------------------- - */ - -/* - * Ugly thunks to read and write a property by calling the right method in - * the right way. Note that we MUST be correct in holding references to Tcl_Obj - * values, as this is potentially a call into user code. - */ -static inline int -ReadProperty( - Tcl_Interp *interp, - Object *oPtr, - Tcl_Obj *propObj) -{ - Tcl_Obj *args[] = { - oPtr->fPtr->myName, - Tcl_ObjPrintf("", TclGetString(propObj)) - }; - int code; - - Tcl_IncrRefCount(args[0]); - Tcl_IncrRefCount(args[1]); - code = TclOOPrivateObjectCmd(oPtr, interp, 2, args); - Tcl_DecrRefCount(args[0]); - Tcl_DecrRefCount(args[1]); - switch (code) { - case TCL_BREAK: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "property getter for %s did a break", TclGetString(propObj))); - return TCL_ERROR; - case TCL_CONTINUE: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "property getter for %s did a continue", TclGetString(propObj))); - return TCL_ERROR; - default: - return code; - } -} - -static inline int -WriteProperty( - Tcl_Interp *interp, - Object *oPtr, - Tcl_Obj *propObj, - Tcl_Obj *valueObj) -{ - Tcl_Obj *args[] = { - oPtr->fPtr->myName, - Tcl_ObjPrintf("", TclGetString(propObj)), - valueObj - }; - int code; - - Tcl_IncrRefCount(args[0]); - Tcl_IncrRefCount(args[1]); - Tcl_IncrRefCount(args[2]); - code = TclOOPrivateObjectCmd(oPtr, interp, 3, args); - Tcl_DecrRefCount(args[0]); - Tcl_DecrRefCount(args[1]); - Tcl_DecrRefCount(args[2]); - switch (code) { - case TCL_BREAK: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "property setter for %s did a break", TclGetString(propObj))); - return TCL_ERROR; - case TCL_CONTINUE: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "property setter for %s did a continue", TclGetString(propObj))); - return TCL_ERROR; - default: - return code; - } -} - -/* Look up a property full name. */ -static Tcl_Obj * -GetPropertyName( - Tcl_Interp *interp, /* Context and error reporting. */ - Object *oPtr, /* Object to get property name from. */ - int flags, /* Are we looking for a writable property? - * Can we do a fallback message? - * See GPNFlags for possible values */ - Tcl_Obj *namePtr, /* The name supplied by the user. */ - GPNCache **cachePtr) /* Where to cache the table, if the caller - * wants that. The contents are to be freed - * with Tcl_Free if the cache is used. */ -{ - Tcl_Size objc, index, i; - Tcl_Obj *listPtr = TclOOGetAllObjectProperties( - oPtr, flags & GPN_WRITABLE); - Tcl_Obj **objv; - GPNCache *tablePtr; - - (void) Tcl_ListObjGetElements(NULL, listPtr, &objc, &objv); - if (cachePtr && *cachePtr) { - tablePtr = *cachePtr; - } else { - tablePtr = (GPNCache *) TclStackAlloc(interp, - offsetof(GPNCache, names) + sizeof(char *) * (objc + 1)); - - for (i = 0; i < objc; i++) { - tablePtr->names[i] = TclGetString(objv[i]); - } - tablePtr->names[objc] = NULL; - if (cachePtr) { - /* - * Have a cache, but nothing in it so far. - * - * We cache the list here so it doesn't vanish from under our - * feet if a property implementation does something crazy like - * changing the set of properties. The type of copy this does - * means that the copy holds the references to the names in the - * table. - */ - tablePtr->listPtr = TclListObjCopy(NULL, listPtr); - Tcl_IncrRefCount(tablePtr->listPtr); - *cachePtr = tablePtr; - } else { - tablePtr->listPtr = NULL; - } - } - int result = Tcl_GetIndexFromObjStruct(interp, namePtr, tablePtr->names, - sizeof(char *), "property", TCL_INDEX_TEMP_TABLE, &index); - if (result == TCL_ERROR && !(flags & GPN_FALLING_BACK)) { - /* - * If property can be accessed the other way, use a special message. - * We use a recursive call to look this up. - */ - - Tcl_InterpState foo = Tcl_SaveInterpState(interp, result); - Tcl_Obj *otherName = GetPropertyName(interp, oPtr, - flags ^ (GPN_WRITABLE | GPN_FALLING_BACK), namePtr, NULL); - result = Tcl_RestoreInterpState(interp, foo); - if (otherName != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "property \"%s\" is %s only", - TclGetString(otherName), - (flags & GPN_WRITABLE) ? "read" : "write")); - } - } - if (!cachePtr) { - TclStackFree(interp, tablePtr); - } - if (result != TCL_OK) { - return NULL; - } - return objv[index]; -} - -/* Release the cache made by GetPropertyName(). */ -static inline void -ReleasePropertyNameCache( - Tcl_Interp *interp, - GPNCache **cachePtr) -{ - if (*cachePtr) { - GPNCache *tablePtr = *cachePtr; - if (tablePtr->listPtr) { - Tcl_DecrRefCount(tablePtr->listPtr); - } - TclStackFree(interp, tablePtr); - *cachePtr = NULL; - } -} - -int -TclOO_Configurable_Configure( - TCL_UNUSED(void *), - Tcl_Interp *interp, /* Interpreter used for the result, error - * reporting, etc. */ - Tcl_ObjectContext context, /* The object/call context. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const *objv) /* The actual arguments. */ -{ - Object *oPtr = (Object *) Tcl_ObjectContextObject(context); - Tcl_Size skip = Tcl_ObjectContextSkippedArgs(context); - Tcl_Obj *namePtr; - Tcl_Size i, namec; - int code = TCL_OK; - - objc -= skip; - if ((objc & 1) && (objc != 1)) { - /* - * Bad (odd > 1) number of arguments. - */ - - Tcl_WrongNumArgs(interp, skip, objv, "?-option value ...?"); - return TCL_ERROR; - } - - objv += skip; - if (objc == 0) { - /* - * Read all properties. - */ - - Tcl_Obj *listPtr = TclOOGetAllObjectProperties(oPtr, 0); - Tcl_Obj *resultPtr = Tcl_NewObj(), **namev; - - Tcl_IncrRefCount(listPtr); - ListObjGetElements(listPtr, namec, namev); - - for (i = 0; i < namec; ) { - code = ReadProperty(interp, oPtr, namev[i]); - if (code != TCL_OK) { - Tcl_DecrRefCount(resultPtr); - break; - } - Tcl_DictObjPut(NULL, resultPtr, namev[i], - Tcl_GetObjResult(interp)); - if (++i >= namec) { - Tcl_SetObjResult(interp, resultPtr); - break; - } - Tcl_SetObjResult(interp, Tcl_NewObj()); - } - Tcl_DecrRefCount(listPtr); - return code; - } else if (objc == 1) { - /* - * Read a single named property. - */ - - namePtr = GetPropertyName(interp, oPtr, 0, objv[0], NULL); - if (namePtr == NULL) { - return TCL_ERROR; - } - return ReadProperty(interp, oPtr, namePtr); - } else if (objc == 2) { - /* - * Special case for writing to one property. Saves fiddling with the - * cache in this common case. - */ - - namePtr = GetPropertyName(interp, oPtr, GPN_WRITABLE, objv[0], NULL); - if (namePtr == NULL) { - return TCL_ERROR; - } - code = WriteProperty(interp, oPtr, namePtr, objv[1]); - if (code == TCL_OK) { - Tcl_ResetResult(interp); - } - return code; - } else { - /* - * Write properties. Slightly tricky because we want to cache the - * table of property names. - */ - GPNCache *cache = NULL; - - code = TCL_OK; - for (i = 0; i < objc; i += 2) { - namePtr = GetPropertyName(interp, oPtr, GPN_WRITABLE, objv[i], - &cache); - if (namePtr == NULL) { - code = TCL_ERROR; - break; - } - code = WriteProperty(interp, oPtr, namePtr, objv[i + 1]); - if (code != TCL_OK) { - break; - } - } - if (code == TCL_OK) { - Tcl_ResetResult(interp); - } - ReleasePropertyNameCache(interp, &cache); - return code; - } -} - -/* - * ---------------------------------------------------------------------- - * - * Configurable_Getter, Configurable_Setter -- - * - * Standard property implementation. The clientData is a simple Tcl_Obj* - * that contains the name of the property. - * - * TclOOImplementObjectProperty, TclOOImplementClassProperty -- - * - * Installs a basic property implementation for a property, either on - * an instance or on a class. It's up to the code that calls these - * to ensure that the property name is syntactically valid. - * - * ---------------------------------------------------------------------- - */ - -static int -Configurable_Getter( - void *clientData, /* Which property to read. Actually a Tcl_Obj* - * reference that is the name of the variable - * in the cpntext object. */ - Tcl_Interp *interp, /* Interpreter used for the result, error - * reporting, etc. */ - Tcl_ObjectContext context, /* The object/call context. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const *objv) /* The actual arguments. */ -{ - Tcl_Obj *propNamePtr = (Tcl_Obj *) clientData; - Tcl_Var varPtr, aryVar; - Tcl_Obj *valuePtr; - - if ((int) Tcl_ObjectContextSkippedArgs(context) != objc) { - Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), - objv, NULL); - return TCL_ERROR; - } - - varPtr = LookupObjectVar(interp, Tcl_ObjectContextObject(context), - propNamePtr, &aryVar); - if (varPtr == NULL) { - return TCL_ERROR; - } - - valuePtr = TclPtrGetVar(interp, varPtr, aryVar, propNamePtr, NULL, - TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG); - if (valuePtr == NULL) { - return TCL_ERROR; - } - Tcl_SetObjResult(interp, valuePtr); - return TCL_OK; -} - -static int -Configurable_Setter( - void *clientData, /* Which property to write. Actually a Tcl_Obj* - * reference that is the name of the variable - * in the cpntext object. */ - Tcl_Interp *interp, /* Interpreter used for the result, error - * reporting, etc. */ - Tcl_ObjectContext context, /* The object/call context. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const *objv) /* The actual arguments. */ -{ - Tcl_Obj *propNamePtr = (Tcl_Obj *) clientData; - Tcl_Var varPtr, aryVar; - - if ((int) Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { - Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), - objv, "value"); - return TCL_ERROR; - } - - varPtr = LookupObjectVar(interp, Tcl_ObjectContextObject(context), - propNamePtr, &aryVar); - if (varPtr == NULL) { - return TCL_ERROR; - } - - if (TclPtrSetVar(interp, varPtr, aryVar, propNamePtr, NULL, - objv[objc - 1], TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { - return TCL_ERROR; - } - return TCL_OK; -} - -// Simple support functions -void DetailsDeleter( - void *clientData) -{ - // Just drop the reference count - Tcl_Obj *propNamePtr = (Tcl_Obj *) clientData; - Tcl_DecrRefCount(propNamePtr); -} - -int DetailsCloner( - TCL_UNUSED(Tcl_Interp *), - void *oldClientData, - void **newClientData) -{ - // Just add another reference to this name; easy! - Tcl_Obj *propNamePtr = (Tcl_Obj *) oldClientData; - Tcl_IncrRefCount(propNamePtr); - *newClientData = propNamePtr; - return TCL_OK; -} - -// Method descriptors -static Tcl_MethodType GetterType = { - TCL_OO_METHOD_VERSION_1, - "PropertyGetter", - Configurable_Getter, - DetailsDeleter, - DetailsCloner -}; - -static Tcl_MethodType SetterType = { - TCL_OO_METHOD_VERSION_1, - "PropertySetter", - Configurable_Setter, - DetailsDeleter, - DetailsCloner -}; - -void -TclOOImplementObjectProperty( - Tcl_Object targetObject, /* What to install into. */ - Tcl_Obj *propNamePtr, /* Property name, without leading - */ - int installGetter, /* Whether to install a standard getter. */ - int installSetter) /* Whether to install a standard setter. */ -{ - if (installGetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf( - "", TclGetString(propNamePtr)); - Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter - TclNewInstanceMethod( - NULL, targetObject, methodName, 0, &GetterType, propNamePtr); - Tcl_BounceRefCount(methodName); - } - if (installSetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf( - "", TclGetString(propNamePtr)); - Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter - TclNewInstanceMethod( - NULL, targetObject, methodName, 0, &SetterType, propNamePtr); - Tcl_BounceRefCount(methodName); - } -} - -void -TclOOImplementClassProperty( - Tcl_Class targetClass, /* What to install into. */ - Tcl_Obj *propNamePtr, /* Property name, without leading - */ - int installGetter, /* Whether to install a standard getter. */ - int installSetter) /* Whether to install a standard setter. */ -{ - if (installGetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf( - "", TclGetString(propNamePtr)); - Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter - TclNewMethod(targetClass, methodName, 0, &GetterType, propNamePtr); - Tcl_BounceRefCount(methodName); - } - if (installSetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf( - "", TclGetString(propNamePtr)); - Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter - TclNewMethod(targetClass, methodName, 0, &SetterType, propNamePtr); - Tcl_BounceRefCount(methodName); - } -} - -/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c index 27d8233..6ce1ef3 100644 --- a/generic/tclOOCall.c +++ b/generic/tclOOCall.c @@ -2161,253 +2161,6 @@ AddDefinitionNamespaceToChain( } /* - * ---------------------------------------------------------------------- - * - * FindClassProps -- - * - * Discover the properties known to a class and its superclasses. - * The property names become the keys in the accumulator hash table - * (which is used as a set). - * - * ---------------------------------------------------------------------- - */ - -static void -FindClassProps( - Class *clsPtr, /* The object to inspect. Must exist. */ - int writable, /* Whether we're after the readable or writable - * property set. */ - Tcl_HashTable *accumulator) /* Where to gather the names. */ -{ - int i, dummy; - Tcl_Obj *propName; - Class *mixin, *sup; - - tailRecurse: - if (writable) { - FOREACH(propName, clsPtr->properties.writable) { - Tcl_CreateHashEntry(accumulator, (void *) propName, &dummy); - } - } else { - FOREACH(propName, clsPtr->properties.readable) { - Tcl_CreateHashEntry(accumulator, (void *) propName, &dummy); - } - } - if (clsPtr->thisPtr->flags & ROOT_OBJECT) { - /* - * We do *not* traverse upwards from the root! - */ - return; - } - FOREACH(mixin, clsPtr->mixins) { - FindClassProps(mixin, writable, accumulator); - } - if (clsPtr->superclasses.num == 1) { - clsPtr = clsPtr->superclasses.list[0]; - goto tailRecurse; - } - FOREACH(sup, clsPtr->superclasses) { - FindClassProps(sup, writable, accumulator); - } -} - -/* - * ---------------------------------------------------------------------- - * - * FindObjectProps -- - * - * Discover the properties known to an object and all its classes. - * The property names become the keys in the accumulator hash table - * (which is used as a set). - * - * ---------------------------------------------------------------------- - */ - -static void -FindObjectProps( - Object *oPtr, /* The object to inspect. Must exist. */ - int writable, /* Whether we're after the readable or writable - * property set. */ - Tcl_HashTable *accumulator) /* Where to gather the names. */ -{ - int i, dummy; - Tcl_Obj *propName; - Class *mixin; - - if (writable) { - FOREACH(propName, oPtr->properties.writable) { - Tcl_CreateHashEntry(accumulator, (void *) propName, &dummy); - } - } else { - FOREACH(propName, oPtr->properties.readable) { - Tcl_CreateHashEntry(accumulator, (void *) propName, &dummy); - } - } - FOREACH(mixin, oPtr->mixins) { - FindClassProps(mixin, writable, accumulator); - } - FindClassProps(oPtr->selfCls, writable, accumulator); -} - -/* - * ---------------------------------------------------------------------- - * - * TclOOGetAllClassProperties -- - * - * Get the list of all properties known to a class, including to its - * superclasses. Manages a cache so this operation is usually cheap. - * The order of properties in the resulting list is undefined. - * - * ---------------------------------------------------------------------- - */ - -Tcl_Obj * -TclOOGetAllClassProperties( - Class *clsPtr, /* The class to inspect. Must exist. */ - int writable, /* Whether to get writable properties. If - * false, readable properties will be returned - * instead. */ - int *allocated) /* Address of variable to set to true if a - * Tcl_Obj was allocated and may be safely - * modified by the caller. */ -{ - Tcl_HashTable hashTable; - FOREACH_HASH_DECLS; - Tcl_Obj *propName, *result; - void *dummy; - - /* - * Look in the cache. - */ - - if (clsPtr->properties.epoch == clsPtr->thisPtr->fPtr->epoch) { - if (writable) { - if (clsPtr->properties.allWritableCache) { - *allocated = 0; - return clsPtr->properties.allWritableCache; - } - } else { - if (clsPtr->properties.allReadableCache) { - *allocated = 0; - return clsPtr->properties.allReadableCache; - } - } - } - - /* - * Gather the information. Unsorted! (Caller will sort.) - */ - - *allocated = 1; - Tcl_InitObjHashTable(&hashTable); - FindClassProps(clsPtr, writable, &hashTable); - TclNewObj(result); - FOREACH_HASH(propName, dummy, &hashTable) { - Tcl_ListObjAppendElement(NULL, result, propName); - } - Tcl_DeleteHashTable(&hashTable); - - /* - * Cache the information. Also purges the cache. - */ - - if (clsPtr->properties.epoch != clsPtr->thisPtr->fPtr->epoch) { - if (clsPtr->properties.allWritableCache) { - Tcl_DecrRefCount(clsPtr->properties.allWritableCache); - clsPtr->properties.allWritableCache = NULL; - } - if (clsPtr->properties.allReadableCache) { - Tcl_DecrRefCount(clsPtr->properties.allReadableCache); - clsPtr->properties.allReadableCache = NULL; - } - } - clsPtr->properties.epoch = clsPtr->thisPtr->fPtr->epoch; - if (writable) { - clsPtr->properties.allWritableCache = result; - } else { - clsPtr->properties.allReadableCache = result; - } - Tcl_IncrRefCount(result); - return result; -} - -/* - * ---------------------------------------------------------------------- - * - * TclOOGetAllObjectProperties -- - * - * Get the sorted list of all properties known to a object, including to its - * its classes. Manages a cache so this operation is usually cheap. - * - * ---------------------------------------------------------------------- - */ - -Tcl_Obj * -TclOOGetAllObjectProperties( - Object *oPtr, /* The object to inspect. Must exist. */ - int writable) /* Whether to get writable properties. If - * false, readable properties will be returned - * instead. */ -{ - Tcl_HashTable hashTable; - FOREACH_HASH_DECLS; - Tcl_Obj *propName, *result; - void *dummy; - - /* - * Look in the cache. - */ - - if (oPtr->properties.epoch == oPtr->fPtr->epoch) { - if (writable) { - if (oPtr->properties.allWritableCache) { - return oPtr->properties.allWritableCache; - } - } else { - if (oPtr->properties.allReadableCache) { - return oPtr->properties.allReadableCache; - } - } - } - - /* - * Gather the information. Unsorted! (Caller will sort.) - */ - - Tcl_InitObjHashTable(&hashTable); - FindObjectProps(oPtr, writable, &hashTable); - TclNewObj(result); - FOREACH_HASH(propName, dummy, &hashTable) { - Tcl_ListObjAppendElement(NULL, result, propName); - } - Tcl_DeleteHashTable(&hashTable); - TclOOSortPropList(result); - - /* - * Cache the information. - */ - - if (oPtr->properties.epoch != oPtr->fPtr->epoch) { - if (oPtr->properties.allWritableCache) { - Tcl_DecrRefCount(oPtr->properties.allWritableCache); - oPtr->properties.allWritableCache = NULL; - } - if (oPtr->properties.allReadableCache) { - Tcl_DecrRefCount(oPtr->properties.allReadableCache); - oPtr->properties.allReadableCache = NULL; - } - } - oPtr->properties.epoch = oPtr->fPtr->epoch; - if (writable) { - oPtr->properties.allWritableCache = result; - } else { - oPtr->properties.allReadableCache = result; - } - Tcl_IncrRefCount(result); - return result; -} - -/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 0e81cc8..ceb65ef 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -74,9 +74,6 @@ static inline Tcl_Namespace *GetNamespaceInOuterContext(Tcl_Interp *interp, static inline int InitDefineContext(Tcl_Interp *interp, Tcl_Namespace *namespacePtr, Object *oPtr, int objc, Tcl_Obj *const objv[]); -static int InstallStdPropertyImpls(void *useInstance, - Tcl_Interp *interp, Tcl_Obj *propName, - int readable, int writable); static inline void RecomputeClassCacheFlag(Object *oPtr); static int RenameDeleteMethod(Tcl_Interp *interp, Object *oPtr, int useClass, Tcl_Obj *const fromPtr, @@ -956,7 +953,7 @@ InitDefineContext( /* * ---------------------------------------------------------------------- * - * TclOOGetDefineCmdContext -- + * TclOOGetDefineCmdContext, TclOOGetClassDefineCmdContext -- * * Extracts the magic token from the current stack frame, or returns NULL * (and leaves an error message) otherwise. @@ -991,8 +988,8 @@ TclOOGetDefineCmdContext( return object; } -static Class * -GetClassDefineCmdContext( +Class * +TclOOGetClassDefineCmdContext( Tcl_Interp *interp) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); @@ -1637,7 +1634,7 @@ TclOODefineConstructorObjCmd( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Method method; Tcl_Size bodyLength; @@ -1702,7 +1699,7 @@ TclOODefineDefnNsObjCmd( NULL }; int kind = 0; - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Namespace *nsPtr; Tcl_Obj *nsNamePtr, **storagePtr; @@ -1832,7 +1829,7 @@ TclOODefineDestructorObjCmd( { Tcl_Method method; Tcl_Size bodyLength; - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); if (clsPtr == NULL) { return TCL_ERROR; @@ -2413,7 +2410,7 @@ ClassFilter_Get( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Obj *resultObj, *filterObj; Tcl_Size i; @@ -2441,7 +2438,7 @@ ClassFilter_Set( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Size filterc; Tcl_Obj **filterv; @@ -2482,7 +2479,7 @@ ClassMixin_Get( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Obj *resultObj; Class *mixinPtr; Tcl_Size i; @@ -2513,7 +2510,7 @@ ClassMixin_Set( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Size mixinc, i; Tcl_Obj **mixinv; Class **mixins; /* The references to the classes to actually @@ -2591,7 +2588,7 @@ ClassSuper_Get( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Obj *resultObj; Class *superPtr; Tcl_Size i; @@ -2621,7 +2618,7 @@ ClassSuper_Set( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Size superc, j; Tcl_Size i; Tcl_Obj **superv; @@ -2749,7 +2746,7 @@ ClassVars_Get( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Obj *resultObj; Tcl_Size i; @@ -2787,7 +2784,7 @@ ClassVars_Set( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Size i; Tcl_Size varc; Tcl_Obj **varv; @@ -3159,140 +3156,6 @@ ResolveClass( /* * ---------------------------------------------------------------------- * - * SetPropertyList -- - * - * Helper for writing a property list (which is actually a set). - * - * ---------------------------------------------------------------------- - */ -static inline void -SetPropertyList( - PropertyList *propList, /* The property list to write. Replaces the - * property list's contents. */ - Tcl_Size objc, /* Number of property names. */ - Tcl_Obj *const objv[]) /* Property names. */ -{ - Tcl_Size i, n; - Tcl_Obj *propObj; - int created; - Tcl_HashTable uniqueTable; - - for (i=0 ; ilist); - } else if (i) { - propList->list = (Tcl_Obj **) - Tcl_Realloc(propList->list, sizeof(Tcl_Obj *) * objc); - } else { - propList->list = (Tcl_Obj **) - Tcl_Alloc(sizeof(Tcl_Obj *) * objc); - } - } - propList->num = 0; - if (objc > 0) { - Tcl_InitObjHashTable(&uniqueTable); - for (i=n=0 ; ilist[n++] = objv[i]; - } else { - Tcl_DecrRefCount(objv[i]); - } - } - propList->num = n; - - /* - * Shouldn't be necessary, but maintain num/list invariant. - */ - - if (n != objc) { - propList->list = (Tcl_Obj **) - Tcl_Realloc(propList->list, sizeof(Tcl_Obj *) * n); - } - Tcl_DeleteHashTable(&uniqueTable); - } -} - -/* - * ---------------------------------------------------------------------- - * - * InstallReadableProps -- - * - * Helper for writing the readable property list (which is actually a set) - * that includes flushing the name cache. - * - * ---------------------------------------------------------------------- - */ -static inline void -InstallReadableProps( - PropertyStorage *props, /* Which property list to install into. */ - Tcl_Size objc, /* Number of property names. */ - Tcl_Obj *const objv[]) /* Property names. */ -{ - if (props->allReadableCache) { - Tcl_DecrRefCount(props->allReadableCache); - props->allReadableCache = NULL; - } - - SetPropertyList(&props->readable, objc, objv); -} - -/* - * ---------------------------------------------------------------------- - * - * InstallWritableProps -- - * - * Helper for writing the writable property list (which is actually a set) - * that includes flushing the name cache. - * - * ---------------------------------------------------------------------- - */ -static inline void -InstallWritableProps( - PropertyStorage *props, /* Which property list to install into. */ - Tcl_Size objc, /* Number of property names. */ - Tcl_Obj *const objv[]) /* Property names. */ -{ - if (props->allWritableCache) { - Tcl_DecrRefCount(props->allWritableCache); - props->allWritableCache = NULL; - } - - SetPropertyList(&props->writable, objc, objv); -} - -/* - * ---------------------------------------------------------------------- - * - * GetPropertyList -- - * - * Helper for reading a property list. - * - * ---------------------------------------------------------------------- - */ -static inline Tcl_Obj * -GetPropertyList( - PropertyList *propList) /* The property list to read. */ -{ - Tcl_Obj *resultObj, *propNameObj; - Tcl_Size i; - - TclNewObj(resultObj); - FOREACH(propNameObj, *propList) { - Tcl_ListObjAppendElement(NULL, resultObj, propNameObj); - } - return resultObj; -} - -/* - * ---------------------------------------------------------------------- - * * Configurable_ClassReadableProps_Get, Configurable_ClassReadableProps_Set, * Configurable_ObjectReadableProps_Get, Configurable_ObjectReadableProps_Set -- * @@ -3310,7 +3173,7 @@ Configurable_ClassReadableProps_Get( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); if (clsPtr == NULL) { return TCL_ERROR; @@ -3320,7 +3183,7 @@ Configurable_ClassReadableProps_Get( return TCL_ERROR; } - Tcl_SetObjResult(interp, GetPropertyList(&clsPtr->properties.readable)); + Tcl_SetObjResult(interp, TclOOGetPropertyList(&clsPtr->properties.readable)); return TCL_OK; } @@ -3332,7 +3195,7 @@ Configurable_ClassReadableProps_Set( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Size varc; Tcl_Obj **varv; @@ -3349,7 +3212,7 @@ Configurable_ClassReadableProps_Set( return TCL_ERROR; } - InstallReadableProps(&clsPtr->properties, varc, varv); + TclOOInstallReadableProps(&clsPtr->properties, varc, varv); BumpGlobalEpoch(interp, clsPtr); return TCL_OK; } @@ -3372,7 +3235,7 @@ Configurable_ObjectReadableProps_Get( return TCL_ERROR; } - Tcl_SetObjResult(interp, GetPropertyList(&oPtr->properties.readable)); + Tcl_SetObjResult(interp, TclOOGetPropertyList(&oPtr->properties.readable)); return TCL_OK; } @@ -3402,7 +3265,7 @@ Configurable_ObjectReadableProps_Set( return TCL_ERROR; } - InstallReadableProps(&oPtr->properties, varc, varv); + TclOOInstallReadableProps(&oPtr->properties, varc, varv); return TCL_OK; } @@ -3426,7 +3289,7 @@ Configurable_ClassWritableProps_Get( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); if (clsPtr == NULL) { return TCL_ERROR; @@ -3436,7 +3299,7 @@ Configurable_ClassWritableProps_Get( return TCL_ERROR; } - Tcl_SetObjResult(interp, GetPropertyList(&clsPtr->properties.writable)); + Tcl_SetObjResult(interp, TclOOGetPropertyList(&clsPtr->properties.writable)); return TCL_OK; } @@ -3448,7 +3311,7 @@ Configurable_ClassWritableProps_Set( int objc, Tcl_Obj *const *objv) { - Class *clsPtr = GetClassDefineCmdContext(interp); + Class *clsPtr = TclOOGetClassDefineCmdContext(interp); Tcl_Size varc; Tcl_Obj **varv; @@ -3465,7 +3328,7 @@ Configurable_ClassWritableProps_Set( return TCL_ERROR; } - InstallWritableProps(&clsPtr->properties, varc, varv); + TclOOInstallWritableProps(&clsPtr->properties, varc, varv); BumpGlobalEpoch(interp, clsPtr); return TCL_OK; } @@ -3488,7 +3351,7 @@ Configurable_ObjectWritableProps_Get( return TCL_ERROR; } - Tcl_SetObjResult(interp, GetPropertyList(&oPtr->properties.writable)); + Tcl_SetObjResult(interp, TclOOGetPropertyList(&oPtr->properties.writable)); return TCL_OK; } @@ -3518,7 +3381,7 @@ Configurable_ObjectWritableProps_Set( return TCL_ERROR; } - InstallWritableProps(&oPtr->properties, varc, varv); + TclOOInstallWritableProps(&oPtr->properties, varc, varv); return TCL_OK; } @@ -3586,13 +3449,13 @@ TclOORegisterInstanceProperty( if (BuildPropertyList(&oPtr->properties.readable, propName, registerReader, listObj)) { TclListObjGetElements(NULL, listObj, &count, &objv); - InstallReadableProps(&oPtr->properties, count, objv); + TclOOInstallReadableProps(&oPtr->properties, count, objv); } if (BuildPropertyList(&oPtr->properties.writable, propName, registerWriter, listObj)) { TclListObjGetElements(NULL, listObj, &count, &objv); - InstallWritableProps(&oPtr->properties, count, objv); + TclOOInstallWritableProps(&oPtr->properties, count, objv); } Tcl_BounceRefCount(listObj); } @@ -3618,14 +3481,14 @@ TclOORegisterProperty( if (BuildPropertyList(&clsPtr->properties.readable, propName, registerReader, listObj)) { TclListObjGetElements(NULL, listObj, &count, &objv); - InstallReadableProps(&clsPtr->properties, count, objv); + TclOOInstallReadableProps(&clsPtr->properties, count, objv); changed = 1; } if (BuildPropertyList(&clsPtr->properties.writable, propName, registerWriter, listObj)) { TclListObjGetElements(NULL, listObj, &count, &objv); - InstallWritableProps(&clsPtr->properties, count, objv); + TclOOInstallWritableProps(&clsPtr->properties, count, objv); changed = 1; } Tcl_BounceRefCount(listObj); @@ -3724,11 +3587,11 @@ TclOOPropertyDefinitionCmd( } /* - * Install the property. Note that InstallStdPropertyImpls + * Install the property. Note that TclOOInstallStdPropertyImpls * validates the property name as well. */ - if (InstallStdPropertyImpls(useInstance, interp, propObj, + if (TclOOInstallStdPropertyImpls(useInstance, interp, propObj, kind != KIND_WO && getterScript == NULL, kind != KIND_RO && setterScript == NULL) != TCL_OK) { return TCL_ERROR; @@ -3798,81 +3661,6 @@ TclOOPropertyDefinitionCmd( } /* - * ---------------------------------------------------------------------- - * - * InstallStdPropertyImpls -- - * - * Validates a (dashless) property name, and installs implementation - * methods if asked to do so (readable and writable flags). - * - * ---------------------------------------------------------------------- - */ - -static int -InstallStdPropertyImpls( - void *useInstance, - Tcl_Interp *interp, - Tcl_Obj *propName, - int readable, - int writable) -{ - const char *name, *reason; - Tcl_Size len; - char flag = TCL_DONT_QUOTE_HASH; - - /* - * Validate the property name. Note that just calling TclScanElement() is - * cheaper than actually formatting a list and comparing the string - * version of that with the original, as TclScanElement() is one of the - * core parts of doing that; this skips a whole load of irrelevant memory - * allocations! - */ - - name = Tcl_GetStringFromObj(propName, &len); - if (Tcl_StringMatch(name, "-*")) { - reason = "must not begin with -"; - goto badProp; - } - if (TclScanElement(name, len, &flag) != len) { - reason = "must be a simple word"; - goto badProp; - } - if (Tcl_StringMatch(name, "*::*")) { - reason = "must not contain namespace separators"; - goto badProp; - } - if (Tcl_StringMatch(name, "*[()]*")) { - reason = "must not contain parentheses"; - goto badProp; - } - - /* - * Install the implementations... if asked to do so. - */ - - if (useInstance) { - Tcl_Object object = TclOOGetDefineCmdContext(interp); - if (!object) { - return TCL_ERROR; - } - TclOOImplementObjectProperty(object, propName, readable, writable); - } else { - Tcl_Class cls = (Tcl_Class) GetClassDefineCmdContext(interp); - if (!cls) { - return TCL_ERROR; - } - TclOOImplementClassProperty(cls, propName, readable, writable); - } - return TCL_OK; - - badProp: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad property name \"%s\": %s", name, reason)); - Tcl_SetErrorCode(interp, "TCL", "OO", "PROPERTY_FORMAT", NULL); - return TCL_ERROR; -} - -/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tclOOInfo.c b/generic/tclOOInfo.c index feac2c0..26241b2 100644 --- a/generic/tclOOInfo.c +++ b/generic/tclOOInfo.c @@ -16,7 +16,6 @@ #include "tclInt.h" #include "tclOOInt.h" -static inline Class * GetClassFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr); static Tcl_ObjCmdProc InfoObjectCallCmd; static Tcl_ObjCmdProc InfoObjectClassCmd; static Tcl_ObjCmdProc InfoObjectDefnCmd; @@ -28,7 +27,6 @@ static Tcl_ObjCmdProc InfoObjectMethodsCmd; static Tcl_ObjCmdProc InfoObjectMethodTypeCmd; static Tcl_ObjCmdProc InfoObjectMixinsCmd; static Tcl_ObjCmdProc InfoObjectNsCmd; -static Tcl_ObjCmdProc InfoObjectPropCmd; static Tcl_ObjCmdProc InfoObjectVarsCmd; static Tcl_ObjCmdProc InfoObjectVariablesCmd; static Tcl_ObjCmdProc InfoClassCallCmd; @@ -42,7 +40,6 @@ static Tcl_ObjCmdProc InfoClassInstancesCmd; static Tcl_ObjCmdProc InfoClassMethodsCmd; static Tcl_ObjCmdProc InfoClassMethodTypeCmd; static Tcl_ObjCmdProc InfoClassMixinsCmd; -static Tcl_ObjCmdProc InfoClassPropCmd; static Tcl_ObjCmdProc InfoClassSubsCmd; static Tcl_ObjCmdProc InfoClassSupersCmd; static Tcl_ObjCmdProc InfoClassVariablesCmd; @@ -63,7 +60,7 @@ static const EnsembleImplMap infoObjectCmds[] = { {"methodtype", InfoObjectMethodTypeCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, {"mixins", InfoObjectMixinsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"namespace", InfoObjectNsCmd, TclCompileInfoObjectNamespaceCmd, NULL, NULL, 0}, - {"properties", InfoObjectPropCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, + {"properties", TclOOInfoObjectPropCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, {"variables", InfoObjectVariablesCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, {"vars", InfoObjectVarsCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, {NULL, NULL, NULL, NULL, NULL, 0} @@ -85,7 +82,7 @@ static const EnsembleImplMap infoClassCmds[] = { {"methods", InfoClassMethodsCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, {"methodtype", InfoClassMethodTypeCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, {"mixins", InfoClassMixinsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"properties", InfoClassPropCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, + {"properties", TclOOInfoClassPropCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, {"subclasses", InfoClassSubsCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, {"superclasses", InfoClassSupersCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"variables", InfoClassVariablesCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, @@ -150,7 +147,7 @@ TclOOInitInfo( /* * ---------------------------------------------------------------------- * - * GetClassFromObj -- + * TclOOGetClassFromObj -- * * How to correctly get a class from a Tcl_Obj. Just a wrapper round * Tcl_GetObjectFromObj, but this is an idiom that was used heavily. @@ -158,8 +155,8 @@ TclOOInitInfo( * ---------------------------------------------------------------------- */ -static inline Class * -GetClassFromObj( +Class * +TclOOGetClassFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr) { @@ -215,7 +212,7 @@ InfoObjectClassCmd( Class *mixinPtr, *o2clsPtr; Tcl_Size i; - o2clsPtr = GetClassFromObj(interp, objv[2]); + o2clsPtr = TclOOGetClassFromObj(interp, objv[2]); if (o2clsPtr == NULL) { return TCL_ERROR; } @@ -998,7 +995,7 @@ InfoClassConstrCmd( Tcl_WrongNumArgs(interp, 1, objv, "className"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1059,7 +1056,7 @@ InfoClassDefnCmd( Tcl_WrongNumArgs(interp, 1, objv, "className methodName"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1129,7 +1126,7 @@ InfoClassDefnNsCmd( Tcl_WrongNumArgs(interp, 1, objv, "className ?kind?"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1173,7 +1170,7 @@ InfoClassDestrCmd( Tcl_WrongNumArgs(interp, 1, objv, "className"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1218,7 +1215,7 @@ InfoClassFiltersCmd( Tcl_WrongNumArgs(interp, 1, objv, "className"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1256,7 +1253,7 @@ InfoClassForwardCmd( Tcl_WrongNumArgs(interp, 1, objv, "className methodName"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1309,7 +1306,7 @@ InfoClassInstancesCmd( Tcl_WrongNumArgs(interp, 1, objv, "className ?pattern?"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1368,7 +1365,7 @@ InfoClassMethodsCmd( Tcl_WrongNumArgs(interp, 1, objv, "className ?-option value ...?"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1484,7 +1481,7 @@ InfoClassMethodTypeCmd( Tcl_WrongNumArgs(interp, 1, objv, "className methodName"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1536,7 +1533,7 @@ InfoClassMixinsCmd( Tcl_WrongNumArgs(interp, 1, objv, "className"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1579,7 +1576,7 @@ InfoClassSubsCmd( Tcl_WrongNumArgs(interp, 1, objv, "className ?pattern?"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1633,7 +1630,7 @@ InfoClassSupersCmd( Tcl_WrongNumArgs(interp, 1, objv, "className"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1679,7 +1676,7 @@ InfoClassVariablesCmd( } isPrivate = 1; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1772,7 +1769,7 @@ InfoClassCallCmd( Tcl_WrongNumArgs(interp, 1, objv, "className methodName"); return TCL_ERROR; } - clsPtr = GetClassFromObj(interp, objv[1]); + clsPtr = TclOOGetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } @@ -1793,181 +1790,6 @@ InfoClassCallCmd( } /* - * ---------------------------------------------------------------------- - * - * InfoClassPropCmd, InfoObjectPropCmd -- - * - * Implements [info class properties $clsName ?$option...?] and - * [info object properties $objName ?$option...?] - * - * ---------------------------------------------------------------------- - */ - -enum PropOpt { - PROP_ALL, PROP_READABLE, PROP_WRITABLE -}; -static const char *const propOptNames[] = { - "-all", "-readable", "-writable", - NULL -}; - -static int -InfoClassPropCmd( - TCL_UNUSED(void *), - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - Class *clsPtr; - int i, idx, all = 0, writable = 0, allocated = 0; - Tcl_Obj *result, *propObj; - - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "className ?options...?"); - return TCL_ERROR; - } - clsPtr = GetClassFromObj(interp, objv[1]); - if (clsPtr == NULL) { - return TCL_ERROR; - } - for (i = 2; i < objc; i++) { - if (Tcl_GetIndexFromObj(interp, objv[i], propOptNames, "option", 0, - &idx) != TCL_OK) { - return TCL_ERROR; - } - switch (idx) { - case PROP_ALL: - all = 1; - break; - case PROP_READABLE: - writable = 0; - break; - case PROP_WRITABLE: - writable = 1; - break; - } - } - - /* - * Get the properties. - */ - - if (all) { - result = TclOOGetAllClassProperties(clsPtr, writable, &allocated); - if (allocated) { - TclOOSortPropList(result); - } - } else { - TclNewObj(result); - if (writable) { - FOREACH(propObj, clsPtr->properties.writable) { - Tcl_ListObjAppendElement(NULL, result, propObj); - } - } else { - FOREACH(propObj, clsPtr->properties.readable) { - Tcl_ListObjAppendElement(NULL, result, propObj); - } - } - TclOOSortPropList(result); - } - Tcl_SetObjResult(interp, result); - return TCL_OK; -} - -static int -InfoObjectPropCmd( - TCL_UNUSED(void *), - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - Object *oPtr; - int i, idx, all = 0, writable = 0; - Tcl_Obj *result, *propObj; - - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "objName ?options...?"); - return TCL_ERROR; - } - oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]); - if (oPtr == NULL) { - return TCL_ERROR; - } - for (i = 2; i < objc; i++) { - if (Tcl_GetIndexFromObj(interp, objv[i], propOptNames, "option", 0, - &idx) != TCL_OK) { - return TCL_ERROR; - } - switch (idx) { - case PROP_ALL: - all = 1; - break; - case PROP_READABLE: - writable = 0; - break; - case PROP_WRITABLE: - writable = 1; - break; - } - } - - /* - * Get the properties. - */ - - if (all) { - result = TclOOGetAllObjectProperties(oPtr, writable); - } else { - TclNewObj(result); - if (writable) { - FOREACH(propObj, oPtr->properties.writable) { - Tcl_ListObjAppendElement(NULL, result, propObj); - } - } else { - FOREACH(propObj, oPtr->properties.readable) { - Tcl_ListObjAppendElement(NULL, result, propObj); - } - } - TclOOSortPropList(result); - } - Tcl_SetObjResult(interp, result); - return TCL_OK; -} - -/* - * ---------------------------------------------------------------------- - * - * SortPropList -- - * Sort a list of names of properties. Simple support function. Assumes - * that the list Tcl_Obj is unshared and doesn't have a string - * representation. - * - * ---------------------------------------------------------------------- - */ - -static int -PropNameCompare( - const void *a, - const void *b) -{ - Tcl_Obj *first = *(Tcl_Obj **) a; - Tcl_Obj *second = *(Tcl_Obj **) b; - - return strcmp(TclGetString(first), TclGetString(second)); -} - -void -TclOOSortPropList( - Tcl_Obj *list) -{ - Tcl_Size ec; - Tcl_Obj **ev; - - Tcl_ListObjGetElements(NULL, list, &ec, &ev); - qsort(ev, ec, sizeof(Tcl_Obj *), PropNameCompare); -} - -/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index 5377ca3..88ce0e7 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -515,6 +515,8 @@ MODULE_SCOPE Tcl_ObjCmdProc TclOOCopyObjectCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOONextObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOONextToObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOSelfObjCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclOOInfoObjectPropCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclOOInfoClassPropCmd; /* * Method implementations (in tclOOBasic.c). @@ -570,14 +572,15 @@ MODULE_SCOPE void TclOODeleteContext(CallContext *contextPtr); MODULE_SCOPE void TclOODeleteDescendants(Tcl_Interp *interp, Object *oPtr); MODULE_SCOPE void TclOODelMethodRef(Method *method); -MODULE_SCOPE Tcl_Obj * TclOOGetAllClassProperties(Class *clsPtr, - int writable, int *allocated); MODULE_SCOPE Tcl_Obj * TclOOGetAllObjectProperties(Object *oPtr, int writable); MODULE_SCOPE CallContext *TclOOGetCallContext(Object *oPtr, Tcl_Obj *methodNameObj, int flags, Object *contextObjPtr, Class *contextClsPtr, Tcl_Obj *cacheInThisObj); +MODULE_SCOPE Class * TclOOGetClassDefineCmdContext(Tcl_Interp *interp); +MODULE_SCOPE Class * TclOOGetClassFromObj(Tcl_Interp *interp, + Tcl_Obj *objPtr); MODULE_SCOPE Tcl_Namespace *TclOOGetDefineContextNamespace( Tcl_Interp *interp, Object *oPtr, int forClass); MODULE_SCOPE CallChain *TclOOGetStereotypeCallChain(Class *clsPtr, @@ -602,6 +605,9 @@ MODULE_SCOPE void TclOOInitInfo(Tcl_Interp *interp); MODULE_SCOPE int TclOOInvokeContext(void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +MODULE_SCOPE Tcl_Var TclOOLookupObjectVar(Tcl_Interp *interp, + Tcl_Object object, Tcl_Obj *varName, + Tcl_Var *aryPtr); MODULE_SCOPE int TclNRObjectContextInvokeNext(Tcl_Interp *interp, Tcl_ObjectContext context, Tcl_Size objc, Tcl_Obj *const *objv, Tcl_Size skip); @@ -618,7 +624,15 @@ MODULE_SCOPE int TclOORemoveFromSubclasses(Class *subPtr, Class *superPtr); MODULE_SCOPE Tcl_Obj * TclOORenderCallChain(Tcl_Interp *interp, CallChain *callPtr); -MODULE_SCOPE void TclOOSortPropList(Tcl_Obj *listPtr); +MODULE_SCOPE Tcl_Obj * TclOOGetPropertyList(PropertyList *propList); +MODULE_SCOPE void TclOOReleasePropertyStorage(PropertyStorage *propsPtr); +MODULE_SCOPE void TclOOInstallReadableProps(PropertyStorage *props, + Tcl_Size objc, Tcl_Obj *const objv[]); +MODULE_SCOPE void TclOOInstallWritableProps(PropertyStorage *props, + Tcl_Size objc, Tcl_Obj *const objv[]); +MODULE_SCOPE int TclOOInstallStdPropertyImpls(void *useInstance, + Tcl_Interp *interp, Tcl_Obj *propName, + int readable, int writable); MODULE_SCOPE void TclOOStashContext(Tcl_Obj *objPtr, CallContext *contextPtr); MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr); diff --git a/generic/tclOOProp.c b/generic/tclOOProp.c new file mode 100644 index 0000000..ef66f4e --- /dev/null +++ b/generic/tclOOProp.c @@ -0,0 +1,1174 @@ +/* + * tclOOProp.c -- + * + * This file contains implementations of the configurable property + * mecnanisms. + * + * Copyright © 2023-2024 Donal K. Fellows + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#include "tclOOInt.h" + +/* Short-term cache for GetPropertyName(). */ +typedef struct GPNCache { + Tcl_Obj *listPtr; /* Holds references to names. */ + char *names[TCLFLEXARRAY]; /* NULL-terminated table of names. */ +} GPNCache; + +enum GPNFlags { + GPN_WRITABLE = 1, /* Are we looking for a writable property? */ + GPN_FALLING_BACK = 2 /* Are we doing a recursive call to determine + * if the property is of the other type? */ +}; + +/* + * Shared bits for [property] declarations. + */ +enum PropOpt { + PROP_ALL, PROP_READABLE, PROP_WRITABLE +}; +static const char *const propOptNames[] = { + "-all", "-readable", "-writable", + NULL +}; + +/* + * Forward declarations. + */ + +static int Configurable_Getter(void *clientData, + Tcl_Interp *interp, Tcl_ObjectContext context, + int objc, Tcl_Obj *const *objv); +static int Configurable_Setter(void *clientData, + Tcl_Interp *interp, Tcl_ObjectContext context, + int objc, Tcl_Obj *const *objv); +static void DetailsDeleter(void *clientData); +static int DetailsCloner(Tcl_Interp *, void *oldClientData, + void **newClientData); + +/* + * Method descriptors + */ + +static const Tcl_MethodType GetterType = { + TCL_OO_METHOD_VERSION_1, + "PropertyGetter", + Configurable_Getter, + DetailsDeleter, + DetailsCloner +}; + +static const Tcl_MethodType SetterType = { + TCL_OO_METHOD_VERSION_1, + "PropertySetter", + Configurable_Setter, + DetailsDeleter, + DetailsCloner +}; + +/* + * ---------------------------------------------------------------------- + * + * TclOO_Configurable_Configure -- + * + * Implementation of the oo::configurable->configure method. + * + * ---------------------------------------------------------------------- + */ + +/* + * Ugly thunks to read and write a property by calling the right method in + * the right way. Note that we MUST be correct in holding references to Tcl_Obj + * values, as this is potentially a call into user code. + */ +static inline int +ReadProperty( + Tcl_Interp *interp, + Object *oPtr, + Tcl_Obj *propObj) +{ + Tcl_Obj *args[] = { + oPtr->fPtr->myName, + Tcl_ObjPrintf("", TclGetString(propObj)) + }; + int code; + + Tcl_IncrRefCount(args[0]); + Tcl_IncrRefCount(args[1]); + code = TclOOPrivateObjectCmd(oPtr, interp, 2, args); + Tcl_DecrRefCount(args[0]); + Tcl_DecrRefCount(args[1]); + switch (code) { + case TCL_BREAK: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "property getter for %s did a break", TclGetString(propObj))); + return TCL_ERROR; + case TCL_CONTINUE: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "property getter for %s did a continue", TclGetString(propObj))); + return TCL_ERROR; + default: + return code; + } +} + +static inline int +WriteProperty( + Tcl_Interp *interp, + Object *oPtr, + Tcl_Obj *propObj, + Tcl_Obj *valueObj) +{ + Tcl_Obj *args[] = { + oPtr->fPtr->myName, + Tcl_ObjPrintf("", TclGetString(propObj)), + valueObj + }; + int code; + + Tcl_IncrRefCount(args[0]); + Tcl_IncrRefCount(args[1]); + Tcl_IncrRefCount(args[2]); + code = TclOOPrivateObjectCmd(oPtr, interp, 3, args); + Tcl_DecrRefCount(args[0]); + Tcl_DecrRefCount(args[1]); + Tcl_DecrRefCount(args[2]); + switch (code) { + case TCL_BREAK: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "property setter for %s did a break", TclGetString(propObj))); + return TCL_ERROR; + case TCL_CONTINUE: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "property setter for %s did a continue", TclGetString(propObj))); + return TCL_ERROR; + default: + return code; + } +} + +/* Look up a property full name. */ +static Tcl_Obj * +GetPropertyName( + Tcl_Interp *interp, /* Context and error reporting. */ + Object *oPtr, /* Object to get property name from. */ + int flags, /* Are we looking for a writable property? + * Can we do a fallback message? + * See GPNFlags for possible values */ + Tcl_Obj *namePtr, /* The name supplied by the user. */ + GPNCache **cachePtr) /* Where to cache the table, if the caller + * wants that. The contents are to be freed + * with Tcl_Free if the cache is used. */ +{ + Tcl_Size objc, index, i; + Tcl_Obj *listPtr = TclOOGetAllObjectProperties( + oPtr, flags & GPN_WRITABLE); + Tcl_Obj **objv; + GPNCache *tablePtr; + + (void) Tcl_ListObjGetElements(NULL, listPtr, &objc, &objv); + if (cachePtr && *cachePtr) { + tablePtr = *cachePtr; + } else { + tablePtr = (GPNCache *) TclStackAlloc(interp, + offsetof(GPNCache, names) + sizeof(char *) * (objc + 1)); + + for (i = 0; i < objc; i++) { + tablePtr->names[i] = TclGetString(objv[i]); + } + tablePtr->names[objc] = NULL; + if (cachePtr) { + /* + * Have a cache, but nothing in it so far. + * + * We cache the list here so it doesn't vanish from under our + * feet if a property implementation does something crazy like + * changing the set of properties. The type of copy this does + * means that the copy holds the references to the names in the + * table. + */ + tablePtr->listPtr = TclListObjCopy(NULL, listPtr); + Tcl_IncrRefCount(tablePtr->listPtr); + *cachePtr = tablePtr; + } else { + tablePtr->listPtr = NULL; + } + } + int result = Tcl_GetIndexFromObjStruct(interp, namePtr, tablePtr->names, + sizeof(char *), "property", TCL_INDEX_TEMP_TABLE, &index); + if (result == TCL_ERROR && !(flags & GPN_FALLING_BACK)) { + /* + * If property can be accessed the other way, use a special message. + * We use a recursive call to look this up. + */ + + Tcl_InterpState foo = Tcl_SaveInterpState(interp, result); + Tcl_Obj *otherName = GetPropertyName(interp, oPtr, + flags ^ (GPN_WRITABLE | GPN_FALLING_BACK), namePtr, NULL); + result = Tcl_RestoreInterpState(interp, foo); + if (otherName != NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "property \"%s\" is %s only", + TclGetString(otherName), + (flags & GPN_WRITABLE) ? "read" : "write")); + } + } + if (!cachePtr) { + TclStackFree(interp, tablePtr); + } + if (result != TCL_OK) { + return NULL; + } + return objv[index]; +} + +/* Release the cache made by GetPropertyName(). */ +static inline void +ReleasePropertyNameCache( + Tcl_Interp *interp, + GPNCache **cachePtr) +{ + if (*cachePtr) { + GPNCache *tablePtr = *cachePtr; + if (tablePtr->listPtr) { + Tcl_DecrRefCount(tablePtr->listPtr); + } + TclStackFree(interp, tablePtr); + *cachePtr = NULL; + } +} + +int +TclOO_Configurable_Configure( + TCL_UNUSED(void *), + Tcl_Interp *interp, /* Interpreter used for the result, error + * reporting, etc. */ + Tcl_ObjectContext context, /* The object/call context. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* The actual arguments. */ +{ + Object *oPtr = (Object *) Tcl_ObjectContextObject(context); + Tcl_Size skip = Tcl_ObjectContextSkippedArgs(context); + Tcl_Obj *namePtr; + Tcl_Size i, namec; + int code = TCL_OK; + + objc -= skip; + if ((objc & 1) && (objc != 1)) { + /* + * Bad (odd > 1) number of arguments. + */ + + Tcl_WrongNumArgs(interp, skip, objv, "?-option value ...?"); + return TCL_ERROR; + } + + objv += skip; + if (objc == 0) { + /* + * Read all properties. + */ + + Tcl_Obj *listPtr = TclOOGetAllObjectProperties(oPtr, 0); + Tcl_Obj *resultPtr = Tcl_NewObj(), **namev; + + Tcl_IncrRefCount(listPtr); + ListObjGetElements(listPtr, namec, namev); + + for (i = 0; i < namec; ) { + code = ReadProperty(interp, oPtr, namev[i]); + if (code != TCL_OK) { + Tcl_DecrRefCount(resultPtr); + break; + } + Tcl_DictObjPut(NULL, resultPtr, namev[i], + Tcl_GetObjResult(interp)); + if (++i >= namec) { + Tcl_SetObjResult(interp, resultPtr); + break; + } + Tcl_SetObjResult(interp, Tcl_NewObj()); + } + Tcl_DecrRefCount(listPtr); + return code; + } else if (objc == 1) { + /* + * Read a single named property. + */ + + namePtr = GetPropertyName(interp, oPtr, 0, objv[0], NULL); + if (namePtr == NULL) { + return TCL_ERROR; + } + return ReadProperty(interp, oPtr, namePtr); + } else if (objc == 2) { + /* + * Special case for writing to one property. Saves fiddling with the + * cache in this common case. + */ + + namePtr = GetPropertyName(interp, oPtr, GPN_WRITABLE, objv[0], NULL); + if (namePtr == NULL) { + return TCL_ERROR; + } + code = WriteProperty(interp, oPtr, namePtr, objv[1]); + if (code == TCL_OK) { + Tcl_ResetResult(interp); + } + return code; + } else { + /* + * Write properties. Slightly tricky because we want to cache the + * table of property names. + */ + GPNCache *cache = NULL; + + code = TCL_OK; + for (i = 0; i < objc; i += 2) { + namePtr = GetPropertyName(interp, oPtr, GPN_WRITABLE, objv[i], + &cache); + if (namePtr == NULL) { + code = TCL_ERROR; + break; + } + code = WriteProperty(interp, oPtr, namePtr, objv[i + 1]); + if (code != TCL_OK) { + break; + } + } + if (code == TCL_OK) { + Tcl_ResetResult(interp); + } + ReleasePropertyNameCache(interp, &cache); + return code; + } +} + +/* + * ---------------------------------------------------------------------- + * + * Configurable_Getter, Configurable_Setter -- + * + * Standard property implementation. The clientData is a simple Tcl_Obj* + * that contains the name of the property. + * + * ---------------------------------------------------------------------- + */ + +static int +Configurable_Getter( + void *clientData, /* Which property to read. Actually a Tcl_Obj* + * reference that is the name of the variable + * in the cpntext object. */ + Tcl_Interp *interp, /* Interpreter used for the result, error + * reporting, etc. */ + Tcl_ObjectContext context, /* The object/call context. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* The actual arguments. */ +{ + Tcl_Obj *propNamePtr = (Tcl_Obj *) clientData; + Tcl_Var varPtr, aryVar; + Tcl_Obj *valuePtr; + + if ((int) Tcl_ObjectContextSkippedArgs(context) != objc) { + Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), + objv, NULL); + return TCL_ERROR; + } + + varPtr = TclOOLookupObjectVar(interp, Tcl_ObjectContextObject(context), + propNamePtr, &aryVar); + if (varPtr == NULL) { + return TCL_ERROR; + } + + valuePtr = TclPtrGetVar(interp, varPtr, aryVar, propNamePtr, NULL, + TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG); + if (valuePtr == NULL) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, valuePtr); + return TCL_OK; +} + +static int +Configurable_Setter( + void *clientData, /* Which property to write. Actually a Tcl_Obj* + * reference that is the name of the variable + * in the cpntext object. */ + Tcl_Interp *interp, /* Interpreter used for the result, error + * reporting, etc. */ + Tcl_ObjectContext context, /* The object/call context. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* The actual arguments. */ +{ + Tcl_Obj *propNamePtr = (Tcl_Obj *) clientData; + Tcl_Var varPtr, aryVar; + + if ((int) Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { + Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), + objv, "value"); + return TCL_ERROR; + } + + varPtr = TclOOLookupObjectVar(interp, Tcl_ObjectContextObject(context), + propNamePtr, &aryVar); + if (varPtr == NULL) { + return TCL_ERROR; + } + + if (TclPtrSetVar(interp, varPtr, aryVar, propNamePtr, NULL, + objv[objc - 1], TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG) == NULL) { + return TCL_ERROR; + } + return TCL_OK; +} + +// Simple support functions +static void +DetailsDeleter( + void *clientData) +{ + // Just drop the reference count + Tcl_Obj *propNamePtr = (Tcl_Obj *) clientData; + Tcl_DecrRefCount(propNamePtr); +} + +static int +DetailsCloner( + TCL_UNUSED(Tcl_Interp *), + void *oldClientData, + void **newClientData) +{ + // Just add another reference to this name; easy! + Tcl_Obj *propNamePtr = (Tcl_Obj *) oldClientData; + Tcl_IncrRefCount(propNamePtr); + *newClientData = propNamePtr; + return TCL_OK; +} + +/* + * ---------------------------------------------------------------------- + * + * TclOOImplementObjectProperty, TclOOImplementClassProperty -- + * + * Installs a basic property implementation for a property, either on + * an instance or on a class. It's up to the code that calls these + * to ensure that the property name is syntactically valid. + * + * ---------------------------------------------------------------------- + */ + +void +TclOOImplementObjectProperty( + Tcl_Object targetObject, /* What to install into. */ + Tcl_Obj *propNamePtr, /* Property name, without leading - */ + int installGetter, /* Whether to install a standard getter. */ + int installSetter) /* Whether to install a standard setter. */ +{ + if (installGetter) { + Tcl_Obj *methodName = Tcl_ObjPrintf( + "", TclGetString(propNamePtr)); + Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter + TclNewInstanceMethod( + NULL, targetObject, methodName, 0, &GetterType, propNamePtr); + Tcl_BounceRefCount(methodName); + } + if (installSetter) { + Tcl_Obj *methodName = Tcl_ObjPrintf( + "", TclGetString(propNamePtr)); + Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter + TclNewInstanceMethod( + NULL, targetObject, methodName, 0, &SetterType, propNamePtr); + Tcl_BounceRefCount(methodName); + } +} + +void +TclOOImplementClassProperty( + Tcl_Class targetClass, /* What to install into. */ + Tcl_Obj *propNamePtr, /* Property name, without leading - */ + int installGetter, /* Whether to install a standard getter. */ + int installSetter) /* Whether to install a standard setter. */ +{ + if (installGetter) { + Tcl_Obj *methodName = Tcl_ObjPrintf( + "", TclGetString(propNamePtr)); + Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter + TclNewMethod(targetClass, methodName, 0, &GetterType, propNamePtr); + Tcl_BounceRefCount(methodName); + } + if (installSetter) { + Tcl_Obj *methodName = Tcl_ObjPrintf( + "", TclGetString(propNamePtr)); + Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter + TclNewMethod(targetClass, methodName, 0, &SetterType, propNamePtr); + Tcl_BounceRefCount(methodName); + } +} + +/* + * ---------------------------------------------------------------------- + * + * FindClassProps -- + * + * Discover the properties known to a class and its superclasses. + * The property names become the keys in the accumulator hash table + * (which is used as a set). + * + * ---------------------------------------------------------------------- + */ + +static void +FindClassProps( + Class *clsPtr, /* The object to inspect. Must exist. */ + int writable, /* Whether we're after the readable or writable + * property set. */ + Tcl_HashTable *accumulator) /* Where to gather the names. */ +{ + int i, dummy; + Tcl_Obj *propName; + Class *mixin, *sup; + + tailRecurse: + if (writable) { + FOREACH(propName, clsPtr->properties.writable) { + Tcl_CreateHashEntry(accumulator, (void *) propName, &dummy); + } + } else { + FOREACH(propName, clsPtr->properties.readable) { + Tcl_CreateHashEntry(accumulator, (void *) propName, &dummy); + } + } + if (clsPtr->thisPtr->flags & ROOT_OBJECT) { + /* + * We do *not* traverse upwards from the root! + */ + return; + } + FOREACH(mixin, clsPtr->mixins) { + FindClassProps(mixin, writable, accumulator); + } + if (clsPtr->superclasses.num == 1) { + clsPtr = clsPtr->superclasses.list[0]; + goto tailRecurse; + } + FOREACH(sup, clsPtr->superclasses) { + FindClassProps(sup, writable, accumulator); + } +} + +/* + * ---------------------------------------------------------------------- + * + * FindObjectProps -- + * + * Discover the properties known to an object and all its classes. + * The property names become the keys in the accumulator hash table + * (which is used as a set). + * + * ---------------------------------------------------------------------- + */ + +static void +FindObjectProps( + Object *oPtr, /* The object to inspect. Must exist. */ + int writable, /* Whether we're after the readable or writable + * property set. */ + Tcl_HashTable *accumulator) /* Where to gather the names. */ +{ + int i, dummy; + Tcl_Obj *propName; + Class *mixin; + + if (writable) { + FOREACH(propName, oPtr->properties.writable) { + Tcl_CreateHashEntry(accumulator, (void *) propName, &dummy); + } + } else { + FOREACH(propName, oPtr->properties.readable) { + Tcl_CreateHashEntry(accumulator, (void *) propName, &dummy); + } + } + FOREACH(mixin, oPtr->mixins) { + FindClassProps(mixin, writable, accumulator); + } + FindClassProps(oPtr->selfCls, writable, accumulator); +} + +/* + * ---------------------------------------------------------------------- + * + * GetAllClassProperties -- + * + * Get the list of all properties known to a class, including to its + * superclasses. Manages a cache so this operation is usually cheap. + * The order of properties in the resulting list is undefined. + * + * ---------------------------------------------------------------------- + */ + +static Tcl_Obj * +GetAllClassProperties( + Class *clsPtr, /* The class to inspect. Must exist. */ + int writable, /* Whether to get writable properties. If + * false, readable properties will be returned + * instead. */ + int *allocated) /* Address of variable to set to true if a + * Tcl_Obj was allocated and may be safely + * modified by the caller. */ +{ + Tcl_HashTable hashTable; + FOREACH_HASH_DECLS; + Tcl_Obj *propName, *result; + void *dummy; + + /* + * Look in the cache. + */ + + if (clsPtr->properties.epoch == clsPtr->thisPtr->fPtr->epoch) { + if (writable) { + if (clsPtr->properties.allWritableCache) { + *allocated = 0; + return clsPtr->properties.allWritableCache; + } + } else { + if (clsPtr->properties.allReadableCache) { + *allocated = 0; + return clsPtr->properties.allReadableCache; + } + } + } + + /* + * Gather the information. Unsorted! (Caller will sort.) + */ + + *allocated = 1; + Tcl_InitObjHashTable(&hashTable); + FindClassProps(clsPtr, writable, &hashTable); + TclNewObj(result); + FOREACH_HASH(propName, dummy, &hashTable) { + Tcl_ListObjAppendElement(NULL, result, propName); + } + Tcl_DeleteHashTable(&hashTable); + + /* + * Cache the information. Also purges the cache. + */ + + if (clsPtr->properties.epoch != clsPtr->thisPtr->fPtr->epoch) { + if (clsPtr->properties.allWritableCache) { + Tcl_DecrRefCount(clsPtr->properties.allWritableCache); + clsPtr->properties.allWritableCache = NULL; + } + if (clsPtr->properties.allReadableCache) { + Tcl_DecrRefCount(clsPtr->properties.allReadableCache); + clsPtr->properties.allReadableCache = NULL; + } + } + clsPtr->properties.epoch = clsPtr->thisPtr->fPtr->epoch; + if (writable) { + clsPtr->properties.allWritableCache = result; + } else { + clsPtr->properties.allReadableCache = result; + } + Tcl_IncrRefCount(result); + return result; +} + +/* + * ---------------------------------------------------------------------- + * + * SortPropList -- + * Sort a list of names of properties. Simple support function. Assumes + * that the list Tcl_Obj is unshared and doesn't have a string + * representation. + * + * ---------------------------------------------------------------------- + */ + +static int +PropNameCompare( + const void *a, + const void *b) +{ + Tcl_Obj *first = *(Tcl_Obj **) a; + Tcl_Obj *second = *(Tcl_Obj **) b; + + return strcmp(TclGetString(first), TclGetString(second)); +} + +static inline void +SortPropList( + Tcl_Obj *list) +{ + Tcl_Size ec; + Tcl_Obj **ev; + + Tcl_ListObjGetElements(NULL, list, &ec, &ev); + qsort(ev, ec, sizeof(Tcl_Obj *), PropNameCompare); +} + +/* + * ---------------------------------------------------------------------- + * + * TclOOGetAllObjectProperties -- + * + * Get the sorted list of all properties known to a object, including to its + * its classes. Manages a cache so this operation is usually cheap. + * + * ---------------------------------------------------------------------- + */ + +Tcl_Obj * +TclOOGetAllObjectProperties( + Object *oPtr, /* The object to inspect. Must exist. */ + int writable) /* Whether to get writable properties. If + * false, readable properties will be returned + * instead. */ +{ + Tcl_HashTable hashTable; + FOREACH_HASH_DECLS; + Tcl_Obj *propName, *result; + void *dummy; + + /* + * Look in the cache. + */ + + if (oPtr->properties.epoch == oPtr->fPtr->epoch) { + if (writable) { + if (oPtr->properties.allWritableCache) { + return oPtr->properties.allWritableCache; + } + } else { + if (oPtr->properties.allReadableCache) { + return oPtr->properties.allReadableCache; + } + } + } + + /* + * Gather the information. Unsorted! (Caller will sort.) + */ + + Tcl_InitObjHashTable(&hashTable); + FindObjectProps(oPtr, writable, &hashTable); + TclNewObj(result); + FOREACH_HASH(propName, dummy, &hashTable) { + Tcl_ListObjAppendElement(NULL, result, propName); + } + Tcl_DeleteHashTable(&hashTable); + SortPropList(result); + + /* + * Cache the information. + */ + + if (oPtr->properties.epoch != oPtr->fPtr->epoch) { + if (oPtr->properties.allWritableCache) { + Tcl_DecrRefCount(oPtr->properties.allWritableCache); + oPtr->properties.allWritableCache = NULL; + } + if (oPtr->properties.allReadableCache) { + Tcl_DecrRefCount(oPtr->properties.allReadableCache); + oPtr->properties.allReadableCache = NULL; + } + } + oPtr->properties.epoch = oPtr->fPtr->epoch; + if (writable) { + oPtr->properties.allWritableCache = result; + } else { + oPtr->properties.allReadableCache = result; + } + Tcl_IncrRefCount(result); + return result; +} + +/* + * ---------------------------------------------------------------------- + * + * SetPropertyList -- + * + * Helper for writing a property list (which is actually a set). + * + * ---------------------------------------------------------------------- + */ +static inline void +SetPropertyList( + PropertyList *propList, /* The property list to write. Replaces the + * property list's contents. */ + Tcl_Size objc, /* Number of property names. */ + Tcl_Obj *const objv[]) /* Property names. */ +{ + Tcl_Size i, n; + Tcl_Obj *propObj; + int created; + Tcl_HashTable uniqueTable; + + for (i=0 ; ilist); + } else if (i) { + propList->list = (Tcl_Obj **) + Tcl_Realloc(propList->list, sizeof(Tcl_Obj *) * objc); + } else { + propList->list = (Tcl_Obj **) + Tcl_Alloc(sizeof(Tcl_Obj *) * objc); + } + } + propList->num = 0; + if (objc > 0) { + Tcl_InitObjHashTable(&uniqueTable); + for (i=n=0 ; ilist[n++] = objv[i]; + } else { + Tcl_DecrRefCount(objv[i]); + } + } + propList->num = n; + + /* + * Shouldn't be necessary, but maintain num/list invariant. + */ + + if (n != objc) { + propList->list = (Tcl_Obj **) + Tcl_Realloc(propList->list, sizeof(Tcl_Obj *) * n); + } + Tcl_DeleteHashTable(&uniqueTable); + } +} + +/* + * ---------------------------------------------------------------------- + * + * TclOOInstallReadableProps -- + * + * Helper for writing the readable property list (which is actually a set) + * that includes flushing the name cache. + * + * ---------------------------------------------------------------------- + */ +void +TclOOInstallReadableProps( + PropertyStorage *props, /* Which property list to install into. */ + Tcl_Size objc, /* Number of property names. */ + Tcl_Obj *const objv[]) /* Property names. */ +{ + if (props->allReadableCache) { + Tcl_DecrRefCount(props->allReadableCache); + props->allReadableCache = NULL; + } + + SetPropertyList(&props->readable, objc, objv); +} + +/* + * ---------------------------------------------------------------------- + * + * TclOOInstallWritableProps -- + * + * Helper for writing the writable property list (which is actually a set) + * that includes flushing the name cache. + * + * ---------------------------------------------------------------------- + */ +void +TclOOInstallWritableProps( + PropertyStorage *props, /* Which property list to install into. */ + Tcl_Size objc, /* Number of property names. */ + Tcl_Obj *const objv[]) /* Property names. */ +{ + if (props->allWritableCache) { + Tcl_DecrRefCount(props->allWritableCache); + props->allWritableCache = NULL; + } + + SetPropertyList(&props->writable, objc, objv); +} + +/* + * ---------------------------------------------------------------------- + * + * TclOOGetPropertyList -- + * + * Helper for reading a property list. + * + * ---------------------------------------------------------------------- + */ +Tcl_Obj * +TclOOGetPropertyList( + PropertyList *propList) /* The property list to read. */ +{ + Tcl_Obj *resultObj, *propNameObj; + Tcl_Size i; + + TclNewObj(resultObj); + FOREACH(propNameObj, *propList) { + Tcl_ListObjAppendElement(NULL, resultObj, propNameObj); + } + return resultObj; +} + +/* + * ---------------------------------------------------------------------- + * + * TclOOInstallStdPropertyImpls -- + * + * Validates a (dashless) property name, and installs implementation + * methods if asked to do so (readable and writable flags). + * + * ---------------------------------------------------------------------- + */ +int +TclOOInstallStdPropertyImpls( + void *useInstance, + Tcl_Interp *interp, + Tcl_Obj *propName, + int readable, + int writable) +{ + const char *name, *reason; + Tcl_Size len; + char flag = TCL_DONT_QUOTE_HASH; + + /* + * Validate the property name. Note that just calling TclScanElement() is + * cheaper than actually formatting a list and comparing the string + * version of that with the original, as TclScanElement() is one of the + * core parts of doing that; this skips a whole load of irrelevant memory + * allocations! + */ + + name = Tcl_GetStringFromObj(propName, &len); + if (Tcl_StringMatch(name, "-*")) { + reason = "must not begin with -"; + goto badProp; + } + if (TclScanElement(name, len, &flag) != len) { + reason = "must be a simple word"; + goto badProp; + } + if (Tcl_StringMatch(name, "*::*")) { + reason = "must not contain namespace separators"; + goto badProp; + } + if (Tcl_StringMatch(name, "*[()]*")) { + reason = "must not contain parentheses"; + goto badProp; + } + + /* + * Install the implementations... if asked to do so. + */ + + if (useInstance) { + Tcl_Object object = TclOOGetDefineCmdContext(interp); + if (!object) { + return TCL_ERROR; + } + TclOOImplementObjectProperty(object, propName, readable, writable); + } else { + Tcl_Class cls = (Tcl_Class) TclOOGetClassDefineCmdContext(interp); + if (!cls) { + return TCL_ERROR; + } + TclOOImplementClassProperty(cls, propName, readable, writable); + } + return TCL_OK; + + badProp: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad property name \"%s\": %s", name, reason)); + Tcl_SetErrorCode(interp, "TCL", "OO", "PROPERTY_FORMAT", NULL); + return TCL_ERROR; +} + +/* + * ---------------------------------------------------------------------- + * + * TclOOInfoClassPropCmd, TclOOInfoObjectPropCmd -- + * + * Implements [info class properties $clsName ?$option...?] and + * [info object properties $objName ?$option...?] + * + * ---------------------------------------------------------------------- + */ + +int +TclOOInfoClassPropCmd( + TCL_UNUSED(void *), + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + Class *clsPtr; + int i, idx, all = 0, writable = 0, allocated = 0; + Tcl_Obj *result; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "className ?options...?"); + return TCL_ERROR; + } + clsPtr = TclOOGetClassFromObj(interp, objv[1]); + if (clsPtr == NULL) { + return TCL_ERROR; + } + for (i = 2; i < objc; i++) { + if (Tcl_GetIndexFromObj(interp, objv[i], propOptNames, "option", 0, + &idx) != TCL_OK) { + return TCL_ERROR; + } + switch (idx) { + case PROP_ALL: + all = 1; + break; + case PROP_READABLE: + writable = 0; + break; + case PROP_WRITABLE: + writable = 1; + break; + } + } + + /* + * Get the properties. + */ + + if (all) { + result = GetAllClassProperties(clsPtr, writable, &allocated); + if (allocated) { + SortPropList(result); + } + } else { + if (writable) { + result = TclOOGetPropertyList(&clsPtr->properties.writable); + } else { + result = TclOOGetPropertyList(&clsPtr->properties.readable); + } + SortPropList(result); + } + Tcl_SetObjResult(interp, result); + return TCL_OK; +} + +int +TclOOInfoObjectPropCmd( + TCL_UNUSED(void *), + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + Object *oPtr; + int i, idx, all = 0, writable = 0; + Tcl_Obj *result; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "objName ?options...?"); + return TCL_ERROR; + } + oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]); + if (oPtr == NULL) { + return TCL_ERROR; + } + for (i = 2; i < objc; i++) { + if (Tcl_GetIndexFromObj(interp, objv[i], propOptNames, "option", 0, + &idx) != TCL_OK) { + return TCL_ERROR; + } + switch (idx) { + case PROP_ALL: + all = 1; + break; + case PROP_READABLE: + writable = 0; + break; + case PROP_WRITABLE: + writable = 1; + break; + } + } + + /* + * Get the properties. + */ + + if (all) { + result = TclOOGetAllObjectProperties(oPtr, writable); + } else { + if (writable) { + result = TclOOGetPropertyList(&oPtr->properties.writable); + } else { + result = TclOOGetPropertyList(&oPtr->properties.readable); + } + SortPropList(result); + } + Tcl_SetObjResult(interp, result); + return TCL_OK; +} + +/* + * ---------------------------------------------------------------------- + * + * TclOOReleasePropertyStorage -- + * + * Delete the memory associated with a class or object's properties. + * + * ---------------------------------------------------------------------- + */ + +static inline void +ReleasePropertyList( + PropertyList *propList) +{ + Tcl_Obj *propertyObj; + Tcl_Size i; + + FOREACH(propertyObj, *propList) { + Tcl_DecrRefCount(propertyObj); + } + Tcl_Free(propList->list); + propList->list = NULL; + propList->num = 0; +} + +void +TclOOReleasePropertyStorage( + PropertyStorage *propsPtr) +{ + if (propsPtr->allReadableCache) { + Tcl_DecrRefCount(propsPtr->allReadableCache); + } + if (propsPtr->allWritableCache) { + Tcl_DecrRefCount(propsPtr->allWritableCache); + } + if (propsPtr->readable.num) { + ReleasePropertyList(&propsPtr->readable); + } + if (propsPtr->writable.num) { + ReleasePropertyList(&propsPtr->writable); + } +} + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/unix/Makefile.in b/unix/Makefile.in index 6e20947..0c5462e 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -321,7 +321,7 @@ GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \ tclTomMathInterface.o tclZipfs.o OO_OBJS = tclOO.o tclOOBasic.o tclOOCall.o tclOODefineCmds.o tclOOInfo.o \ - tclOOMethod.o tclOOStubInit.o + tclOOMethod.o tclOOProp.o tclOOStubInit.o TOMMATH_OBJS = bn_s_mp_reverse.o bn_s_mp_mul_digs_fast.o \ bn_s_mp_sqr_fast.o bn_mp_add.o bn_mp_and.o \ @@ -494,6 +494,7 @@ OO_SRCS = \ $(GENERIC_DIR)/tclOODefineCmds.c \ $(GENERIC_DIR)/tclOOInfo.c \ $(GENERIC_DIR)/tclOOMethod.c \ + $(GENERIC_DIR)/tclOOProp.c \ $(GENERIC_DIR)/tclOOStubInit.c STUB_SRCS = \ @@ -1478,6 +1479,9 @@ tclOOInfo.o: $(GENERIC_DIR)/tclOOInfo.c tclOOMethod.o: $(GENERIC_DIR)/tclOOMethod.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclOOMethod.c +tclOOProp.o: $(GENERIC_DIR)/tclOOProp.c + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclOOProp.c + tclOOStubInit.o: $(GENERIC_DIR)/tclOOStubInit.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclOOStubInit.c diff --git a/win/Makefile.in b/win/Makefile.in index 9df1a95..b3e5ace 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -342,6 +342,7 @@ GENERIC_OBJS = \ tclOODefineCmds.$(OBJEXT) \ tclOOInfo.$(OBJEXT) \ tclOOMethod.$(OBJEXT) \ + tclOOProp.$(OBJEXT) \ tclOOStubInit.$(OBJEXT) \ tclObj.$(OBJEXT) \ tclOptimize.$(OBJEXT) \ diff --git a/win/makefile.vc b/win/makefile.vc index 82fcc74..cba51ee 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -301,6 +301,7 @@ COREOBJS = \ $(TMP_DIR)\tclOODefineCmds.obj \ $(TMP_DIR)\tclOOInfo.obj \ $(TMP_DIR)\tclOOMethod.obj \ + $(TMP_DIR)\tclOOProp.obj \ $(TMP_DIR)\tclOOStubInit.obj \ $(TMP_DIR)\tclObj.obj \ $(TMP_DIR)\tclOptimize.obj \ -- cgit v0.12 From 21e666117b5dda60cbbd1d080272937f4d610dfe Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Sat, 3 Aug 2024 12:30:05 +0000 Subject: Bug [fccb9f322f] - incorrect system encoding with zipfs builds --- generic/tclZipfs.c | 2 ++ tests/unixInit.test | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index b72abfc..0c964e8 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4240,6 +4240,8 @@ ScriptLibrarySetup( Tcl_IncrRefCount(searchPathObj); Tcl_SetEncodingSearchPath(searchPathObj); Tcl_DecrRefCount(searchPathObj); + /* Bug [fccb9f322f]. Reinit system encoding after setting search path */ + TclpSetInitialEncodings(); return libDirObj; } diff --git a/tests/unixInit.test b/tests/unixInit.test index 3bbe1e9..099dccb 100644 --- a/tests/unixInit.test +++ b/tests/unixInit.test @@ -100,7 +100,7 @@ test unixInit-3.2 {TclpSetInitialEncodings} -setup { catch {set oldlc_all $env(LC_ALL)} catch {set oldtcl_library $env(TCL_LIBRARY)} unset -nocomplain env(TCL_LIBRARY) -} -constraints {unix stdio knownBug} -body { +} -constraints {unix stdio} -body { set env(LANG) japanese set env(LC_ALL) japanese set f [open "|[list [interpreter]]" w+] -- cgit v0.12 From 9bf8cbc6796704b68d292afb1ba03295c453831b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 4 Aug 2024 21:54:43 +0000 Subject: TCL_ZIP_FILE/TK_ZIP_FILE definition to nmake makefile, to be consistent with autoconf build --- win/rules.vc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/win/rules.vc b/win/rules.vc index 143ea9e..32742ba 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -1135,8 +1135,8 @@ STUBPREFIX = $(PROJECT)stub # # TIP 430. Unused for 8.6 but no harm defining it to allow a common rules.vc -TCLSCRIPTZIPNAME = libtcl$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip -TKSCRIPTZIPNAME = libtk$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip +TCL_ZIP_FILE = libtcl$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip +TK_ZIP_FILE = libtk$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip !if $(DOING_TCL) TCLSHNAME = $(PROJECT)sh$(VERSION)$(SUFX).exe @@ -1144,7 +1144,7 @@ TCLSH = $(OUT_DIR)\$(TCLSHNAME) TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT) TCLLIB = $(OUT_DIR)\$(TCLLIBNAME) -TCLSCRIPTZIP = $(OUT_DIR)\$(TCLSCRIPTZIPNAME) +TCLSCRIPTZIP = $(OUT_DIR)\$(TCL_ZIP_FILE) !if $(TCL_MAJOR_VERSION) == 8 TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib @@ -1180,7 +1180,7 @@ TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)t$(SUFX:t=).lib TCL_LIBRARY = $(_TCLDIR)\lib TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib -TCLSCRIPTZIP = $(_TCLDIR)\lib\$(TCLSCRIPTZIPNAME) +TCLSCRIPTZIP = $(_TCLDIR)\lib\$(TCL_ZIP_FILE) TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target TCL_INCLUDES = -I"$(_TCLDIR)\include" @@ -1204,7 +1204,7 @@ TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)t$(SUFX:t=).lib TCL_LIBRARY = $(_TCLDIR)\library TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib -TCLSCRIPTZIP = $(_TCLDIR)\win\$(BUILDDIRTOP)\$(TCLSCRIPTZIPNAME) +TCLSCRIPTZIP = $(_TCLDIR)\win\$(BUILDDIRTOP)\$(TCL_ZIP_FILE) TCLTOOLSDIR = $(_TCLDIR)\tools TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win" @@ -1248,12 +1248,12 @@ TKSTUBLIBNAME = tkstub.lib !endif !if $(DOING_TK) -WISH = $(OUT_DIR)\$(WISHNAME) +WISH = $(OUT_DIR)\$(WISHNAME) TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME) TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME) TKLIB = $(OUT_DIR)\$(TKLIBNAME) TK_INCLUDES = -I"$(WIN_DIR)" -I"$(GENERICDIR)" -TKSCRIPTZIP = $(OUT_DIR)\$(TKSCRIPTZIPNAME) +TKSCRIPTZIP = $(OUT_DIR)\$(TK_ZIP_FILE) !else # effectively NEED_TK @@ -1268,7 +1268,7 @@ TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME) !endif TK_INCLUDES = -I"$(_TKDIR)\include" -TKSCRIPTZIP = $(_TKDIR)\lib\$(TKSCRIPTZIPNAME) +TKSCRIPTZIP = $(_TKDIR)\lib\$(TK_ZIP_FILE) !else # Building against Tk sources @@ -1282,7 +1282,7 @@ TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME) !endif TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib" -TKSCRIPTZIP = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSCRIPTZIPNAME) +TKSCRIPTZIP = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TK_ZIP_FILE) !endif # TKINSTALL -- cgit v0.12 From 9fe40ed86bbc13f65effaac7d6791d47ffd2f139 Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Mon, 5 Aug 2024 08:10:42 +0000 Subject: Fix ICU function names for FreeBSD --- generic/tclIcu.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/generic/tclIcu.c b/generic/tclIcu.c index b6355ee..5b88eac 100644 --- a/generic/tclIcu.c +++ b/generic/tclIcu.c @@ -578,10 +578,16 @@ TclIcuInit( #endif #define ICUUC_SYM(name) \ + do { \ strcpy(symbol, #name ); \ - strcat(symbol, icuversion); \ icu_fns._##name = (fn_ ## name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol) + Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ + if (icu_fns._##name == NULL) { \ + strcat(symbol, icuversion); \ + icu_fns._##name = (fn_ ## name) \ + Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ + } \ + } while (0) if (icu_fns.libs[0] != NULL) { ICUUC_SYM(u_cleanup); ICUUC_SYM(u_errorName); @@ -607,10 +613,17 @@ TclIcuInit( } #define ICUIN_SYM(name) \ + do { \ strcpy(symbol, #name ); \ - strcat(symbol, icuversion); \ icu_fns._##name = (fn_ ## name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol) + Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ + if (icu_fns._##name == NULL) { \ + strcat(symbol, icuversion); \ + icu_fns._##name = (fn_ ## name) \ + Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ + } \ + } while (0) + if (icu_fns.libs[1] != NULL) { ICUIN_SYM(ucsdet_close); ICUIN_SYM(ucsdet_detect); -- cgit v0.12 From dedd36ee8fb5079808f42483f4d9d552ac9455e3 Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Mon, 5 Aug 2024 08:18:08 +0000 Subject: Fix indentation --- generic/tclIcu.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/generic/tclIcu.c b/generic/tclIcu.c index 5b88eac..dd7e82f 100644 --- a/generic/tclIcu.c +++ b/generic/tclIcu.c @@ -577,17 +577,19 @@ TclIcuInit( } #endif -#define ICUUC_SYM(name) \ - do { \ - strcpy(symbol, #name ); \ - icu_fns._##name = (fn_ ## name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ - if (icu_fns._##name == NULL) { \ - strcat(symbol, icuversion); \ - icu_fns._##name = (fn_ ## name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ - } \ + /* Try for symbol without version (Windows, FreeBSD), then with version */ +#define ICUUC_SYM(name) \ + do { \ + strcpy(symbol, #name); \ + icu_fns._##name = \ + (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ + if (icu_fns._##name == NULL) { \ + strcat(symbol, icuversion); \ + icu_fns._##name = \ + (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ + } \ } while (0) + if (icu_fns.libs[0] != NULL) { ICUUC_SYM(u_cleanup); ICUUC_SYM(u_errorName); @@ -612,16 +614,16 @@ TclIcuInit( #undef ICUUC_SYM } -#define ICUIN_SYM(name) \ - do { \ - strcpy(symbol, #name ); \ - icu_fns._##name = (fn_ ## name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ - if (icu_fns._##name == NULL) { \ - strcat(symbol, icuversion); \ - icu_fns._##name = (fn_ ## name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ - } \ +#define ICUIN_SYM(name) \ + do { \ + strcpy(symbol, #name); \ + icu_fns._##name = \ + (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ + if (icu_fns._##name == NULL) { \ + strcat(symbol, icuversion); \ + icu_fns._##name = \ + (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ + } \ } while (0) if (icu_fns.libs[1] != NULL) { -- cgit v0.12 From ed06290315ca52c2086fae19b818fe82a9e9a2cf Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 5 Aug 2024 08:30:18 +0000 Subject: Add format/scan modifier changes to release notes --- changes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changes.md b/changes.md index aec26b7..6702db3 100644 --- a/changes.md +++ b/changes.md @@ -37,6 +37,9 @@ writing Tcl scripts. - Removed subcommands [trace variable|vdelete|vinfo] - No -eofchar option for channels anymore for writing. - On Windows 10+ (Version 1903 or higher), system encoding is always utf-8. + - %b/%d/%o/%x format modifiers (without size modifier) for "format" + and "scan" always truncate to 32-bits on all platforms. + - %L size modifier for "scan" no longer truncates to 64-bit. - Removed command ::tcl::unsupported::inject. ## Incompatibilities in C public interface -- cgit v0.12 From 5bbf48932cac794c42cdb4a19128d66f7aa473f5 Mon Sep 17 00:00:00 2001 From: Torsten Date: Mon, 5 Aug 2024 12:49:33 +0000 Subject: add/document the zlib command to the set of commands in a safe interpreter --- doc/interp.n | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/interp.n b/doc/interp.n index 74745be..e2f3a44 100644 --- a/doc/interp.n +++ b/doc/interp.n @@ -644,6 +644,7 @@ built-in commands: \fBsubst\fR \fBswitch\fR \fBtell\fR \fBtime\fR \fBtrace\fR \fBunset\fR \fBupdate\fR \fBuplevel\fR \fBupvar\fR \fBvariable\fR \fBvwait\fR \fBwhile\fR +\fBzlib\fR .DE The following commands are hidden by \fBinterp create\fR when it creates a safe interpreter: -- cgit v0.12 From f8f2aa2a1361c63e3e4425fec6f4f894a3a9a047 Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 5 Aug 2024 14:09:59 +0000 Subject: More cleaning up. --- generic/tclOO.c | 4 +- generic/tclOOBasic.c | 8 +- generic/tclOODefineCmds.c | 181 ++-------------------------------- generic/tclOOInfo.c | 38 +++++--- generic/tclOOInt.h | 22 ++--- generic/tclOOProp.c | 244 ++++++++++++++++++++++++++++++++++++++++------ tests/compile.test | 17 ++-- 7 files changed, 270 insertions(+), 244 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 7384232..b314df7 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -468,10 +468,10 @@ InitFoundation( Tcl_CreateObjCommand(interp, "::oo::configuresupport::configurableobject::property", - TclOOPropertyDefinitionCmd, (void *) 1, NULL); + TclOODefinePropertyCmd, (void *) 1, NULL); Tcl_CreateObjCommand(interp, "::oo::configuresupport::configurableclass::property", - TclOOPropertyDefinitionCmd, (void *) 0, NULL); + TclOODefinePropertyCmd, (void *) 0, NULL); /* * Evaluate the remaining definitions, which are a compiled-in Tcl script. diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index c9a5c7a..1506a34 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -772,8 +772,8 @@ TclOOLookupObjectVar( if (mPtr->declaringObjectPtr == oPtr) { FOREACH_STRUCT(pvPtr, oPtr->privateVariables) { - if (!strcmp(TclGetString(pvPtr->variableObj), - TclGetString(varName))) { + if (!TclStringCmp(pvPtr->variableObj, varName, 1, 0, + TCL_INDEX_NONE)) { varName = pvPtr->fullNameObj; break; } @@ -794,8 +794,8 @@ TclOOLookupObjectVar( } if (isInstance) { FOREACH_STRUCT(pvPtr, clsPtr->privateVariables) { - if (!strcmp(TclGetString(pvPtr->variableObj), - TclGetString(varName))) { + if (!TclStringCmp(pvPtr->variableObj, varName, 1, 0, + TCL_INDEX_NONE)) { varName = pvPtr->fullNameObj; break; } diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index ceb65ef..70f0381 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -3212,7 +3212,7 @@ Configurable_ClassReadableProps_Set( return TCL_ERROR; } - TclOOInstallReadableProps(&clsPtr->properties, varc, varv); + TclOOInstallReadableProperties(&clsPtr->properties, varc, varv); BumpGlobalEpoch(interp, clsPtr); return TCL_OK; } @@ -3265,7 +3265,7 @@ Configurable_ObjectReadableProps_Set( return TCL_ERROR; } - TclOOInstallReadableProps(&oPtr->properties, varc, varv); + TclOOInstallReadableProperties(&oPtr->properties, varc, varv); return TCL_OK; } @@ -3328,7 +3328,7 @@ Configurable_ClassWritableProps_Set( return TCL_ERROR; } - TclOOInstallWritableProps(&clsPtr->properties, varc, varv); + TclOOInstallWritableProperties(&clsPtr->properties, varc, varv); BumpGlobalEpoch(interp, clsPtr); return TCL_OK; } @@ -3381,7 +3381,7 @@ Configurable_ObjectWritableProps_Set( return TCL_ERROR; } - TclOOInstallWritableProps(&oPtr->properties, varc, varv); + TclOOInstallWritableProperties(&oPtr->properties, varc, varv); return TCL_OK; } @@ -3413,7 +3413,7 @@ BuildPropertyList( Tcl_SetListObj(listObj, 0, NULL); FOREACH(other, *propsList) { - if (strcmp(TclGetString(propName), TclGetString(other)) == 0) { + if (!TclStringCmp(propName, other, 1, 0, TCL_INDEX_NONE)) { present = 1; if (!addingProp) { changed = 1; @@ -3449,13 +3449,13 @@ TclOORegisterInstanceProperty( if (BuildPropertyList(&oPtr->properties.readable, propName, registerReader, listObj)) { TclListObjGetElements(NULL, listObj, &count, &objv); - TclOOInstallReadableProps(&oPtr->properties, count, objv); + TclOOInstallReadableProperties(&oPtr->properties, count, objv); } if (BuildPropertyList(&oPtr->properties.writable, propName, registerWriter, listObj)) { TclListObjGetElements(NULL, listObj, &count, &objv); - TclOOInstallWritableProps(&oPtr->properties, count, objv); + TclOOInstallWritableProperties(&oPtr->properties, count, objv); } Tcl_BounceRefCount(listObj); } @@ -3481,14 +3481,14 @@ TclOORegisterProperty( if (BuildPropertyList(&clsPtr->properties.readable, propName, registerReader, listObj)) { TclListObjGetElements(NULL, listObj, &count, &objv); - TclOOInstallReadableProps(&clsPtr->properties, count, objv); + TclOOInstallReadableProperties(&clsPtr->properties, count, objv); changed = 1; } if (BuildPropertyList(&clsPtr->properties.writable, propName, registerWriter, listObj)) { TclListObjGetElements(NULL, listObj, &count, &objv); - TclOOInstallWritableProps(&clsPtr->properties, count, objv); + TclOOInstallWritableProperties(&clsPtr->properties, count, objv); changed = 1; } Tcl_BounceRefCount(listObj); @@ -3498,169 +3498,6 @@ TclOORegisterProperty( } /* - * ---------------------------------------------------------------------- - * - * TclOOPropertyDefinitionCmd -- - * - * Implementation of the "property" definition for classes and instances - * governed by the [oo::configurable] metaclass. - * - * ---------------------------------------------------------------------- - */ - -int -TclOOPropertyDefinitionCmd( - void *useInstance, /* NULL for class, non-NULL for object. */ - Tcl_Interp *interp, /* For error reporting and lookup. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const *objv) /* Arguments. */ -{ - int i; - const char *const options[] = { - "-get", "-kind", "-set", NULL - }; - enum Options { - OPT_GET, OPT_KIND, OPT_SET - }; - const char *const kinds[] = { - "readable", "readwrite", "writable", NULL - }; - enum Kinds { - KIND_RO, KIND_RW, KIND_WO - }; - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); - - if (oPtr == NULL) { - return TCL_ERROR; - } - if (!useInstance && !oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); - return TCL_ERROR; - } - - for (i = 1; i < objc; i++) { - Tcl_Obj *propObj = objv[i], *nextObj, *argObj, *hyphenated; - Tcl_Obj *getterScript = NULL, *setterScript = NULL; - - /* - * Parse the extra options for the property. - */ - - int kind = KIND_RW; - while (i + 1 < objc) { - int option; - - nextObj = objv[i + 1]; - if (TclGetString(nextObj)[0] != '-') { - break; - } - if (Tcl_GetIndexFromObj(interp, nextObj, options, "option", 0, - &option) != TCL_OK) { - return TCL_ERROR; - } - if (i + 2 >= objc) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "missing %s to go with %s option", - (option == OPT_KIND ? "kind value" : "body"), - options[option])); - Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); - return TCL_ERROR; - } - argObj = objv[i + 2]; - i += 2; - switch (option) { - case OPT_GET: - getterScript = argObj; - break; - case OPT_SET: - setterScript = argObj; - break; - case OPT_KIND: - if (Tcl_GetIndexFromObj(interp, argObj, kinds, "kind", 0, - &kind) != TCL_OK) { - return TCL_ERROR; - } - break; - } - } - - /* - * Install the property. Note that TclOOInstallStdPropertyImpls - * validates the property name as well. - */ - - if (TclOOInstallStdPropertyImpls(useInstance, interp, propObj, - kind != KIND_WO && getterScript == NULL, - kind != KIND_RO && setterScript == NULL) != TCL_OK) { - return TCL_ERROR; - } - - hyphenated = Tcl_ObjPrintf("-%s", TclGetString(propObj)); - if (useInstance) { - TclOORegisterInstanceProperty(oPtr, hyphenated, - kind != KIND_WO, kind != KIND_RO); - } else { - TclOORegisterProperty(oPtr->classPtr, hyphenated, - kind != KIND_WO, kind != KIND_RO); - } - Tcl_BounceRefCount(hyphenated); - - /* - * Create property implementation methods by using the right - * back-end API, but only if the user has given us the bodies of the - * methods we'll make. - */ - - if (getterScript != NULL) { - Tcl_Obj *getterName = Tcl_ObjPrintf("", - TclGetString(propObj)); - Tcl_Obj *argsPtr = Tcl_NewObj(); - Method *mPtr; - - Tcl_IncrRefCount(getterScript); - if (useInstance) { - mPtr = TclOONewProcInstanceMethod(interp, oPtr, 0, - getterName, argsPtr, getterScript, NULL); - } else { - mPtr = TclOONewProcMethod(interp, oPtr->classPtr, 0, - getterName, argsPtr, getterScript, NULL); - } - Tcl_BounceRefCount(getterName); - Tcl_BounceRefCount(argsPtr); - Tcl_DecrRefCount(getterScript); - if (mPtr == NULL) { - return TCL_ERROR; - } - } - if (setterScript != NULL) { - Tcl_Obj *setterName = Tcl_ObjPrintf("", - TclGetString(propObj)); - Tcl_Obj *argsPtr; - Method *mPtr; - - TclNewLiteralStringObj(argsPtr, "value"); - Tcl_IncrRefCount(setterScript); - if (useInstance) { - mPtr = TclOONewProcInstanceMethod(interp, oPtr, 0, - setterName, argsPtr, setterScript, NULL); - } else { - mPtr = TclOONewProcMethod(interp, oPtr->classPtr, 0, - setterName, argsPtr, setterScript, NULL); - } - Tcl_BounceRefCount(setterName); - Tcl_BounceRefCount(argsPtr); - Tcl_DecrRefCount(setterScript); - if (mPtr == NULL) { - return TCL_ERROR; - } - } - } - return TCL_OK; -} - -/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tclOOInfo.c b/generic/tclOOInfo.c index 26241b2..914ed38 100644 --- a/generic/tclOOInfo.c +++ b/generic/tclOOInfo.c @@ -724,12 +724,7 @@ InfoObjectMethodTypeCmd( } hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, objv[2]); if (hPtr == NULL) { - unknownMethod: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "unknown method \"%s\"", TclGetString(objv[2]))); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", - TclGetString(objv[2]), (char *)NULL); - return TCL_ERROR; + goto unknownMethod; } mPtr = (Method *) Tcl_GetHashValue(hPtr); if (mPtr->typePtr == NULL) { @@ -743,6 +738,13 @@ InfoObjectMethodTypeCmd( Tcl_SetObjResult(interp, Tcl_NewStringObj(mPtr->typePtr->name, -1)); return TCL_OK; + + unknownMethod: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown method \"%s\"", TclGetString(objv[2]))); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", + TclGetString(objv[2]), (char *)NULL); + return TCL_ERROR; } /* @@ -881,6 +883,10 @@ InfoObjectVariablesCmd( } if (objc == 3) { if (strcmp("-private", TclGetString(objv[2])) != 0) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "option \"%s\" is not exactly \"-private\"", + TclGetString(objv[2]))); + Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_ARG"); return TCL_ERROR; } isPrivate = 1; @@ -1488,12 +1494,7 @@ InfoClassMethodTypeCmd( hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, objv[2]); if (hPtr == NULL) { - unknownMethod: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "unknown method \"%s\"", TclGetString(objv[2]))); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", - TclGetString(objv[2]), (char *)NULL); - return TCL_ERROR; + goto unknownMethod; } mPtr = (Method *) Tcl_GetHashValue(hPtr); if (mPtr->typePtr == NULL) { @@ -1506,6 +1507,13 @@ InfoClassMethodTypeCmd( } Tcl_SetObjResult(interp, Tcl_NewStringObj(mPtr->typePtr->name, -1)); return TCL_OK; + + unknownMethod: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown method \"%s\"", TclGetString(objv[2]))); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", + TclGetString(objv[2]), (char *)NULL); + return TCL_ERROR; } /* @@ -1672,6 +1680,10 @@ InfoClassVariablesCmd( } if (objc == 3) { if (strcmp("-private", TclGetString(objv[2])) != 0) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "option \"%s\" is not exactly \"-private\"", + TclGetString(objv[2]))); + Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_ARG"); return TCL_ERROR; } isPrivate = 1; @@ -1737,6 +1749,7 @@ InfoObjectCallCmd( if (contextPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot construct any call chain", -1)); + Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_CALL_CHAIN"); return TCL_ERROR; } Tcl_SetObjResult(interp, @@ -1782,6 +1795,7 @@ InfoClassCallCmd( if (callPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot construct any call chain", -1)); + Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_CALL_CHAIN"); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOORenderCallChain(interp, callPtr)); diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index 88ce0e7..3ef395c 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -509,7 +509,7 @@ MODULE_SCOPE Tcl_ObjCmdProc TclOODefineClassObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineSelfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineObjSelfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefinePrivateObjCmd; -MODULE_SCOPE Tcl_ObjCmdProc TclOOPropertyDefinitionCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclOODefinePropertyCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOUnknownDefinition; MODULE_SCOPE Tcl_ObjCmdProc TclOOCopyObjectCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOONextObjCmd; @@ -572,8 +572,6 @@ MODULE_SCOPE void TclOODeleteContext(CallContext *contextPtr); MODULE_SCOPE void TclOODeleteDescendants(Tcl_Interp *interp, Object *oPtr); MODULE_SCOPE void TclOODelMethodRef(Method *method); -MODULE_SCOPE Tcl_Obj * TclOOGetAllObjectProperties(Object *oPtr, - int writable); MODULE_SCOPE CallContext *TclOOGetCallContext(Object *oPtr, Tcl_Obj *methodNameObj, int flags, Object *contextObjPtr, Class *contextClsPtr, @@ -594,12 +592,6 @@ MODULE_SCOPE size_t TclOOGetSortedClassMethodList(Class *clsPtr, MODULE_SCOPE int TclOOGetSortedMethodList(Object *oPtr, Object *contextObj, Class *contextCls, int flags, const char ***stringsPtr); -MODULE_SCOPE void TclOOImplementObjectProperty(Tcl_Object targetObject, - Tcl_Obj *propNamePtr, int installGetter, - int installSetter); -MODULE_SCOPE void TclOOImplementClassProperty(Tcl_Class targetObject, - Tcl_Obj *propNamePtr, int installGetter, - int installSetter); MODULE_SCOPE int TclOOInit(Tcl_Interp *interp); MODULE_SCOPE void TclOOInitInfo(Tcl_Interp *interp); MODULE_SCOPE int TclOOInvokeContext(void *clientData, @@ -624,18 +616,20 @@ MODULE_SCOPE int TclOORemoveFromSubclasses(Class *subPtr, Class *superPtr); MODULE_SCOPE Tcl_Obj * TclOORenderCallChain(Tcl_Interp *interp, CallChain *callPtr); +MODULE_SCOPE void TclOOStashContext(Tcl_Obj *objPtr, + CallContext *contextPtr); +MODULE_SCOPE Tcl_Obj * TclOOGetAllObjectProperties(Object *oPtr, + int writable); +MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr); MODULE_SCOPE Tcl_Obj * TclOOGetPropertyList(PropertyList *propList); MODULE_SCOPE void TclOOReleasePropertyStorage(PropertyStorage *propsPtr); -MODULE_SCOPE void TclOOInstallReadableProps(PropertyStorage *props, +MODULE_SCOPE void TclOOInstallReadableProperties(PropertyStorage *props, Tcl_Size objc, Tcl_Obj *const objv[]); -MODULE_SCOPE void TclOOInstallWritableProps(PropertyStorage *props, +MODULE_SCOPE void TclOOInstallWritableProperties(PropertyStorage *props, Tcl_Size objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TclOOInstallStdPropertyImpls(void *useInstance, Tcl_Interp *interp, Tcl_Obj *propName, int readable, int writable); -MODULE_SCOPE void TclOOStashContext(Tcl_Obj *objPtr, - CallContext *contextPtr); -MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr); MODULE_SCOPE void TclOORegisterProperty(Class *clsPtr, Tcl_Obj *propName, int mayRead, int mayWrite); MODULE_SCOPE void TclOORegisterInstanceProperty(Object *oPtr, diff --git a/generic/tclOOProp.c b/generic/tclOOProp.c index ef66f4e..4cff300 100644 --- a/generic/tclOOProp.c +++ b/generic/tclOOProp.c @@ -48,6 +48,12 @@ static int Configurable_Setter(void *clientData, static void DetailsDeleter(void *clientData); static int DetailsCloner(Tcl_Interp *, void *oldClientData, void **newClientData); +static void ImplementObjectProperty(Tcl_Object targetObject, + Tcl_Obj *propNamePtr, int installGetter, + int installSetter); +static void ImplementClassProperty(Tcl_Class targetObject, + Tcl_Obj *propNamePtr, int installGetter, + int installSetter); /* * Method descriptors @@ -88,11 +94,11 @@ static inline int ReadProperty( Tcl_Interp *interp, Object *oPtr, - Tcl_Obj *propObj) + const char *propName) { Tcl_Obj *args[] = { oPtr->fPtr->myName, - Tcl_ObjPrintf("", TclGetString(propObj)) + Tcl_ObjPrintf("", propName) }; int code; @@ -104,11 +110,11 @@ ReadProperty( switch (code) { case TCL_BREAK: Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "property getter for %s did a break", TclGetString(propObj))); + "property getter for %s did a break", propName)); return TCL_ERROR; case TCL_CONTINUE: Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "property getter for %s did a continue", TclGetString(propObj))); + "property getter for %s did a continue", propName)); return TCL_ERROR; default: return code; @@ -119,12 +125,12 @@ static inline int WriteProperty( Tcl_Interp *interp, Object *oPtr, - Tcl_Obj *propObj, + const char *propName, Tcl_Obj *valueObj) { Tcl_Obj *args[] = { oPtr->fPtr->myName, - Tcl_ObjPrintf("", TclGetString(propObj)), + Tcl_ObjPrintf("", propName), valueObj }; int code; @@ -139,11 +145,11 @@ WriteProperty( switch (code) { case TCL_BREAK: Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "property setter for %s did a break", TclGetString(propObj))); + "property setter for %s did a break", propName)); return TCL_ERROR; case TCL_CONTINUE: Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "property setter for %s did a continue", TclGetString(propObj))); + "property setter for %s did a continue", propName)); return TCL_ERROR; default: return code; @@ -279,7 +285,7 @@ TclOO_Configurable_Configure( ListObjGetElements(listPtr, namec, namev); for (i = 0; i < namec; ) { - code = ReadProperty(interp, oPtr, namev[i]); + code = ReadProperty(interp, oPtr, TclGetString(namev[i])); if (code != TCL_OK) { Tcl_DecrRefCount(resultPtr); break; @@ -303,7 +309,7 @@ TclOO_Configurable_Configure( if (namePtr == NULL) { return TCL_ERROR; } - return ReadProperty(interp, oPtr, namePtr); + return ReadProperty(interp, oPtr, TclGetString(namePtr)); } else if (objc == 2) { /* * Special case for writing to one property. Saves fiddling with the @@ -314,7 +320,7 @@ TclOO_Configurable_Configure( if (namePtr == NULL) { return TCL_ERROR; } - code = WriteProperty(interp, oPtr, namePtr, objv[1]); + code = WriteProperty(interp, oPtr, TclGetString(namePtr), objv[1]); if (code == TCL_OK) { Tcl_ResetResult(interp); } @@ -334,7 +340,8 @@ TclOO_Configurable_Configure( code = TCL_ERROR; break; } - code = WriteProperty(interp, oPtr, namePtr, objv[i + 1]); + code = WriteProperty(interp, oPtr, TclGetString(namePtr), + objv[i + 1]); if (code != TCL_OK) { break; } @@ -453,7 +460,7 @@ DetailsCloner( /* * ---------------------------------------------------------------------- * - * TclOOImplementObjectProperty, TclOOImplementClassProperty -- + * ImplementObjectProperty, ImplementClassProperty -- * * Installs a basic property implementation for a property, either on * an instance or on a class. It's up to the code that calls these @@ -463,23 +470,26 @@ DetailsCloner( */ void -TclOOImplementObjectProperty( +ImplementObjectProperty( Tcl_Object targetObject, /* What to install into. */ - Tcl_Obj *propNamePtr, /* Property name, without leading - */ + Tcl_Obj *propNamePtr, /* Property name. */ int installGetter, /* Whether to install a standard getter. */ int installSetter) /* Whether to install a standard setter. */ { + const char *propName = TclGetString(propNamePtr); + + while (propName[0] == '-') { + propName++; + } if (installGetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf( - "", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf("", propName); Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter TclNewInstanceMethod( NULL, targetObject, methodName, 0, &GetterType, propNamePtr); Tcl_BounceRefCount(methodName); } if (installSetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf( - "", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf("", propName); Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter TclNewInstanceMethod( NULL, targetObject, methodName, 0, &SetterType, propNamePtr); @@ -488,22 +498,25 @@ TclOOImplementObjectProperty( } void -TclOOImplementClassProperty( +ImplementClassProperty( Tcl_Class targetClass, /* What to install into. */ - Tcl_Obj *propNamePtr, /* Property name, without leading - */ + Tcl_Obj *propNamePtr, /* Property name. */ int installGetter, /* Whether to install a standard getter. */ int installSetter) /* Whether to install a standard setter. */ { + const char *propName = TclGetString(propNamePtr); + + while (propName[0] == '-') { + propName++; + } if (installGetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf( - "", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf("", propName); Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter TclNewMethod(targetClass, methodName, 0, &GetterType, propNamePtr); Tcl_BounceRefCount(methodName); } if (installSetter) { - Tcl_Obj *methodName = Tcl_ObjPrintf( - "", TclGetString(propNamePtr)); + Tcl_Obj *methodName = Tcl_ObjPrintf("", propName); Tcl_IncrRefCount(propNamePtr); // Paired with DetailsDeleter TclNewMethod(targetClass, methodName, 0, &SetterType, propNamePtr); Tcl_BounceRefCount(methodName); @@ -700,7 +713,7 @@ PropNameCompare( Tcl_Obj *first = *(Tcl_Obj **) a; Tcl_Obj *second = *(Tcl_Obj **) b; - return strcmp(TclGetString(first), TclGetString(second)); + return TclStringCmp(first, second, 0, 0, TCL_INDEX_NONE); } static inline void @@ -710,7 +723,11 @@ SortPropList( Tcl_Size ec; Tcl_Obj **ev; + if (Tcl_IsShared(list)) { + Tcl_Panic("shared property list cannot be sorted"); + } Tcl_ListObjGetElements(NULL, list, &ec, &ev); + TclInvalidateStringRep(list); qsort(ev, ec, sizeof(Tcl_Obj *), PropNameCompare); } @@ -856,7 +873,7 @@ SetPropertyList( /* * ---------------------------------------------------------------------- * - * TclOOInstallReadableProps -- + * TclOOInstallReadableProperties -- * * Helper for writing the readable property list (which is actually a set) * that includes flushing the name cache. @@ -864,7 +881,7 @@ SetPropertyList( * ---------------------------------------------------------------------- */ void -TclOOInstallReadableProps( +TclOOInstallReadableProperties( PropertyStorage *props, /* Which property list to install into. */ Tcl_Size objc, /* Number of property names. */ Tcl_Obj *const objv[]) /* Property names. */ @@ -880,7 +897,7 @@ TclOOInstallReadableProps( /* * ---------------------------------------------------------------------- * - * TclOOInstallWritableProps -- + * TclOOInstallWritableProperties -- * * Helper for writing the writable property list (which is actually a set) * that includes flushing the name cache. @@ -888,7 +905,7 @@ TclOOInstallReadableProps( * ---------------------------------------------------------------------- */ void -TclOOInstallWritableProps( +TclOOInstallWritableProperties( PropertyStorage *props, /* Which property list to install into. */ Tcl_Size objc, /* Number of property names. */ Tcl_Obj *const objv[]) /* Property names. */ @@ -981,13 +998,13 @@ TclOOInstallStdPropertyImpls( if (!object) { return TCL_ERROR; } - TclOOImplementObjectProperty(object, propName, readable, writable); + ImplementObjectProperty(object, propName, readable, writable); } else { Tcl_Class cls = (Tcl_Class) TclOOGetClassDefineCmdContext(interp); if (!cls) { return TCL_ERROR; } - TclOOImplementClassProperty(cls, propName, readable, writable); + ImplementClassProperty(cls, propName, readable, writable); } return TCL_OK; @@ -1001,6 +1018,169 @@ TclOOInstallStdPropertyImpls( /* * ---------------------------------------------------------------------- * + * TclOODefinePropertyCmd -- + * + * Implementation of the "property" definition for classes and instances + * governed by the [oo::configurable] metaclass. + * + * ---------------------------------------------------------------------- + */ + +int +TclOODefinePropertyCmd( + void *useInstance, /* NULL for class, non-NULL for object. */ + Tcl_Interp *interp, /* For error reporting and lookup. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* Arguments. */ +{ + int i; + const char *const options[] = { + "-get", "-kind", "-set", NULL + }; + enum Options { + OPT_GET, OPT_KIND, OPT_SET + }; + const char *const kinds[] = { + "readable", "readwrite", "writable", NULL + }; + enum Kinds { + KIND_RO, KIND_RW, KIND_WO + }; + Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + + if (oPtr == NULL) { + return TCL_ERROR; + } + if (!useInstance && !oPtr->classPtr) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "attempt to misuse API", -1)); + Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); + return TCL_ERROR; + } + + for (i = 1; i < objc; i++) { + Tcl_Obj *propObj = objv[i], *nextObj, *argObj, *hyphenated; + Tcl_Obj *getterScript = NULL, *setterScript = NULL; + + /* + * Parse the extra options for the property. + */ + + int kind = KIND_RW; + while (i + 1 < objc) { + int option; + + nextObj = objv[i + 1]; + if (TclGetString(nextObj)[0] != '-') { + break; + } + if (Tcl_GetIndexFromObj(interp, nextObj, options, "option", 0, + &option) != TCL_OK) { + return TCL_ERROR; + } + if (i + 2 >= objc) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "missing %s to go with %s option", + (option == OPT_KIND ? "kind value" : "body"), + options[option])); + Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); + return TCL_ERROR; + } + argObj = objv[i + 2]; + i += 2; + switch (option) { + case OPT_GET: + getterScript = argObj; + break; + case OPT_SET: + setterScript = argObj; + break; + case OPT_KIND: + if (Tcl_GetIndexFromObj(interp, argObj, kinds, "kind", 0, + &kind) != TCL_OK) { + return TCL_ERROR; + } + break; + } + } + + /* + * Install the property. Note that TclOOInstallStdPropertyImpls + * validates the property name as well. + */ + + if (TclOOInstallStdPropertyImpls(useInstance, interp, propObj, + kind != KIND_WO && getterScript == NULL, + kind != KIND_RO && setterScript == NULL) != TCL_OK) { + return TCL_ERROR; + } + + hyphenated = Tcl_ObjPrintf("-%s", TclGetString(propObj)); + if (useInstance) { + TclOORegisterInstanceProperty(oPtr, hyphenated, + kind != KIND_WO, kind != KIND_RO); + } else { + TclOORegisterProperty(oPtr->classPtr, hyphenated, + kind != KIND_WO, kind != KIND_RO); + } + Tcl_BounceRefCount(hyphenated); + + /* + * Create property implementation methods by using the right + * back-end API, but only if the user has given us the bodies of the + * methods we'll make. + */ + + if (getterScript != NULL) { + Tcl_Obj *getterName = Tcl_ObjPrintf("", + TclGetString(propObj)); + Tcl_Obj *argsPtr = Tcl_NewObj(); + Method *mPtr; + + Tcl_IncrRefCount(getterScript); + if (useInstance) { + mPtr = TclOONewProcInstanceMethod(interp, oPtr, 0, + getterName, argsPtr, getterScript, NULL); + } else { + mPtr = TclOONewProcMethod(interp, oPtr->classPtr, 0, + getterName, argsPtr, getterScript, NULL); + } + Tcl_BounceRefCount(getterName); + Tcl_BounceRefCount(argsPtr); + Tcl_DecrRefCount(getterScript); + if (mPtr == NULL) { + return TCL_ERROR; + } + } + if (setterScript != NULL) { + Tcl_Obj *setterName = Tcl_ObjPrintf("", + TclGetString(propObj)); + Tcl_Obj *argsPtr; + Method *mPtr; + + TclNewLiteralStringObj(argsPtr, "value"); + Tcl_IncrRefCount(setterScript); + if (useInstance) { + mPtr = TclOONewProcInstanceMethod(interp, oPtr, 0, + setterName, argsPtr, setterScript, NULL); + } else { + mPtr = TclOONewProcMethod(interp, oPtr->classPtr, 0, + setterName, argsPtr, setterScript, NULL); + } + Tcl_BounceRefCount(setterName); + Tcl_BounceRefCount(argsPtr); + Tcl_DecrRefCount(setterScript); + if (mPtr == NULL) { + return TCL_ERROR; + } + } + } + return TCL_OK; +} + +/* + * ---------------------------------------------------------------------- + * * TclOOInfoClassPropCmd, TclOOInfoObjectPropCmd -- * * Implements [info class properties $clsName ?$option...?] and diff --git a/tests/compile.test b/tests/compile.test index cf552e2..72eef5e 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -827,6 +827,7 @@ test compile-18.19 {disassembler - basics} -setup { # There never was a compile-18.20. # The keys of the dictionary produced by [getbytecode] are defined. set bytecodekeys {literals variables exception instructions auxiliary commands script namespace stackdepth exceptdepth} +set allbytecodekeys [list {*}$bytecodekeys initiallinenumber sourcefile] test compile-18.21 {disassembler - basics} -returnCodes error -body { tcl::unsupported::getbytecode } -match glob -result {wrong # args: should be "*"} @@ -841,7 +842,7 @@ test compile-18.24 {disassembler - basics} -returnCodes error -body { } -result "can't interpret \"\{\" as a lambda expression" test compile-18.25 {disassembler - basics} -body { dict keys [tcl::unsupported::getbytecode lambda {{} {}}] -} -result "$bytecodekeys initiallinenumber sourcefile" +} -result $allbytecodekeys test compile-18.26 {disassembler - basics} -returnCodes error -body { tcl::unsupported::getbytecode proc } -match glob -result {wrong # args: should be "* proc procName"} @@ -854,7 +855,7 @@ test compile-18.28 {disassembler - basics} -setup { dict keys [tcl::unsupported::getbytecode proc chewonthis] } -cleanup { rename chewonthis {} -} -result "$bytecodekeys initiallinenumber sourcefile" +} -result $allbytecodekeys test compile-18.28.1 {disassembler - tricky bit} -setup { eval [list proc chewonthis {} {}] } -body { @@ -868,7 +869,7 @@ test compile-18.28.2 {disassembler - tricky bit} -setup { dict keys [tcl::unsupported::getbytecode proc chewonthis] } -cleanup { rename chewonthis {} -} -result "$bytecodekeys initiallinenumber sourcefile" +} -result $allbytecodekeys test compile-18.28.3 {disassembler - tricky bit} -setup { proc Proc {n a b} { proc $n $a $b @@ -890,7 +891,7 @@ test compile-18.28.4 {disassembler - tricky bit} -setup { } -cleanup { rename Proc {} rename chewonthis {} -} -result "$bytecodekeys initiallinenumber sourcefile" +} -result $allbytecodekeys test compile-18.29 {disassembler - basics} -returnCodes error -body { tcl::unsupported::getbytecode script } -match glob -result {wrong # args: should be "* script script"} @@ -919,7 +920,7 @@ test compile-18.35 {disassembler - basics} -setup { dict keys [tcl::unsupported::getbytecode method foo bar] } -cleanup { foo destroy -} -result "$bytecodekeys initiallinenumber sourcefile" +} -result $allbytecodekeys test compile-18.36 {disassembler - basics} -returnCodes error -body { tcl::unsupported::getbytecode objmethod } -match glob -result {wrong # args: should be "* objmethod objectName methodName"} @@ -936,7 +937,7 @@ test compile-18.39 {disassembler - basics} -setup { dict keys [tcl::unsupported::getbytecode objmethod foo bar] } -cleanup { foo destroy -} -result "$bytecodekeys initiallinenumber sourcefile" +} -result $allbytecodekeys test compile-18.40 {disassembler - basics} -returnCodes error -body { tcl::unsupported::disassemble constructor } -match glob -result {wrong # args: should be "* constructor className"} @@ -984,7 +985,7 @@ test compile-18.48 {disassembler - basics} -setup { dict keys [tcl::unsupported::getbytecode constructor foo] } -cleanup { foo destroy -} -result "$bytecodekeys" +} -result $allbytecodekeys # There is no compile-18.49 test compile-18.50 {disassembler - basics} -returnCodes error -body { tcl::unsupported::disassemble destructor @@ -1033,7 +1034,7 @@ test compile-18.58 {disassembler - basics} -setup { dict keys [tcl::unsupported::getbytecode destructor foo] } -cleanup { foo destroy -} -result "$bytecodekeys" +} -result $allbytecodekeys test compile-19.0 {Bug 3614102: reset stack housekeeping} -body { # This will panic in a --enable-symbols=compile build, unless bug is fixed. -- cgit v0.12 From 1c8d9701af466f1977b1b782465b507087d420c2 Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 5 Aug 2024 14:12:05 +0000 Subject: Use TclStringCmp() instead of strcmp() to compare Tcl_Obj values --- generic/tclCmdMZ.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index a36e349..30d9b1d 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -4961,8 +4961,8 @@ TryPostBody( continue; } for (j=0 ; j Date: Mon, 5 Aug 2024 15:12:49 +0000 Subject: Clean up ICU code --- generic/tclIcu.c | 370 +++++++++++++++++++++++++++++++------------------------ tests/icu.test | 18 +-- 2 files changed, 222 insertions(+), 166 deletions(-) diff --git a/generic/tclIcu.c b/generic/tclIcu.c index dd7e82f..c72acda 100644 --- a/generic/tclIcu.c +++ b/generic/tclIcu.c @@ -18,13 +18,13 @@ * Runtime linking of libicu. */ typedef enum UBreakIteratorTypex { - UBRK_CHARACTERX = 0, - UBRK_WORDX = 1 + UBRK_CHARACTERX = 0, + UBRK_WORDX = 1 } UBreakIteratorTypex; typedef enum UErrorCodex { U_AMBIGUOUS_ALIAS_WARNING = -122, - U_ZERO_ERRORZ = 0, /**< No error, no warning. */ + U_ZERO_ERRORZ = 0, /**< No error, no warning. */ } UErrorCodex; #define U_SUCCESS(x) ((x)<=U_ZERO_ERRORZ) @@ -36,6 +36,7 @@ struct UCharsetDetector; typedef struct UCharsetDetector UCharsetDetector; struct UCharsetMatch; typedef struct UCharsetMatch UCharsetMatch; +typedef struct UBreakIterator UBreakIterator; /* * Prototypes for ICU functions sorted by category. @@ -44,34 +45,42 @@ typedef void (*fn_u_cleanup)(void); typedef const char *(*fn_u_errorName)(UErrorCodex); typedef uint16_t (*fn_ucnv_countAliases)(const char *, UErrorCodex *); -typedef int32_t (*fn_ucnv_countAvailable)(); +typedef int32_t (*fn_ucnv_countAvailable)(void); typedef const char *(*fn_ucnv_getAlias)(const char *, uint16_t, UErrorCodex *); typedef const char *(*fn_ucnv_getAvailableName)(int32_t); -typedef void *(*fn_ubrk_open)(UBreakIteratorTypex, const char *, - const uint16_t *, int32_t, UErrorCodex *); -typedef void (*fn_ubrk_close)(void *); -typedef int32_t (*fn_ubrk_preceding)(void *, int32_t); -typedef int32_t (*fn_ubrk_following)(void *, int32_t); -typedef int32_t (*fn_ubrk_previous)(void *); -typedef int32_t (*fn_ubrk_next)(void *); -typedef void (*fn_ubrk_setText)(void *, const void *, int32_t, UErrorCodex *); - -typedef UCharsetDetector * (*fn_ucsdet_open)(UErrorCodex *status); +typedef UBreakIterator *(*fn_ubrk_open)( + UBreakIteratorTypex, const char *, const uint16_t *, int32_t, + UErrorCodex *); +typedef void (*fn_ubrk_close)(UBreakIterator *); +typedef int32_t (*fn_ubrk_preceding)(UBreakIterator *, int32_t); +typedef int32_t (*fn_ubrk_following)(UBreakIterator *, int32_t); +typedef int32_t (*fn_ubrk_previous)(UBreakIterator *); +typedef int32_t (*fn_ubrk_next)(UBreakIterator *); +typedef void (*fn_ubrk_setText)( + UBreakIterator *, const void *, int32_t, UErrorCodex *); + +typedef UCharsetDetector * (*fn_ucsdet_open)(UErrorCodex *status); typedef void (*fn_ucsdet_close)(UCharsetDetector *ucsd); -typedef void (*fn_ucsdet_setText)(UCharsetDetector *ucsd, const char *textIn, int32_t len, UErrorCodex *status); -typedef const char * (*fn_ucsdet_getName)(const UCharsetMatch *ucsm, UErrorCodex *status); -typedef UEnumeration * (*fn_ucsdet_getAllDetectableCharsets)(UCharsetDetector *ucsd, UErrorCodex *status); -typedef const UCharsetMatch * (*fn_ucsdet_detect)(UCharsetDetector *ucsd, UErrorCodex *status); -typedef const UCharsetMatch ** (*fn_ucsdet_detectAll)(UCharsetDetector *ucsd, int32_t *matchesFound, UErrorCodex *status); +typedef void (*fn_ucsdet_setText)(UCharsetDetector *ucsd, + const char *textIn, int32_t len, UErrorCodex *status); +typedef const char * (*fn_ucsdet_getName)( + const UCharsetMatch *ucsm, UErrorCodex *status); +typedef UEnumeration * (*fn_ucsdet_getAllDetectableCharsets)( + UCharsetDetector *ucsd, UErrorCodex *status); +typedef const UCharsetMatch * (*fn_ucsdet_detect)( + UCharsetDetector *ucsd, UErrorCodex *status); +typedef const UCharsetMatch ** (*fn_ucsdet_detectAll)( + UCharsetDetector *ucsd, int32_t *matchesFound, UErrorCodex *status); typedef void (*fn_uenum_close)(UEnumeration *); typedef int32_t (*fn_uenum_count)(UEnumeration *, UErrorCodex *); typedef const char *(*fn_uenum_next)(UEnumeration *, int32_t *, UErrorCodex *); #define FIELD(name) fn_ ## name _ ## name + static struct { - size_t nopen; /* Total number of references to ALL libraries */ + size_t nopen; /* Total number of references to ALL libraries */ /* * Depending on platform, ICU symbols may be distributed amongst * multiple libraries. For current functionality at most 2 needed. @@ -106,7 +115,6 @@ static struct { FIELD(uenum_close); FIELD(uenum_count); FIELD(uenum_next); - } icu_fns = { 0, {NULL, NULL}, /* Reference count, library handles */ NULL, NULL, /* u_* */ @@ -146,32 +154,48 @@ static struct { TCL_DECLARE_MUTEX(icu_mutex); + +/* Error handlers. */ -static int FunctionNotAvailableError(Tcl_Interp *interp) { +static int +FunctionNotAvailableError( + Tcl_Interp *interp) +{ if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("ICU function not available", TCL_INDEX_NONE)); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "ICU function not available", TCL_AUTO_LENGTH)); + Tcl_SetErrorCode(interp, "TCL", "ICU", "UNSUPPORTED_OP", NULL); } return TCL_ERROR; } -static int IcuError(Tcl_Interp *interp, const char *message, UErrorCodex code) +static int +IcuError( + Tcl_Interp *interp, + const char *message, + UErrorCodex code) { if (interp) { const char *codeMessage = NULL; if (u_errorName) { codeMessage = u_errorName(code); } - Tcl_SetObjResult(interp, - Tcl_ObjPrintf("%s. ICU error (%d): %s", - message, - code, - codeMessage ? codeMessage : "")); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s. ICU error (%d): %s", + message, code, codeMessage ? codeMessage : "")); + Tcl_SetErrorCode(interp, "TCL", "ICU", codeMessage, NULL); } return TCL_ERROR; } - -static int DetectEncoding(Tcl_Interp *interp, Tcl_Obj *objPtr, int all) + +/* + * Detect the likely encoding of the string encoded in the given byte array. + */ +static int +DetectEncoding( + Tcl_Interp *interp, + Tcl_Obj *objPtr, + int all) { Tcl_Size len; const char *bytes; @@ -180,9 +204,13 @@ static int DetectEncoding(Tcl_Interp *interp, Tcl_Obj *objPtr, int all) int nmatches; int ret; - if (ucsdet_open == NULL || ucsdet_setText == NULL || - ucsdet_detect == NULL || ucsdet_detectAll == NULL || - ucsdet_getName == NULL || ucsdet_close == NULL) { + // Confirm we have the profile of functions we need. + if (ucsdet_open == NULL || + ucsdet_setText == NULL || + ucsdet_detect == NULL || + ucsdet_detectAll == NULL || + ucsdet_getName == NULL || + ucsdet_close == NULL) { return FunctionNotAvailableError(interp); } @@ -194,31 +222,30 @@ static int DetectEncoding(Tcl_Interp *interp, Tcl_Obj *objPtr, int all) UCharsetDetector* csd = ucsdet_open(&status); if (U_FAILURE(status)) { - return IcuError(interp, "Could not open charset detector.", status); + return IcuError(interp, "Could not open charset detector", status); } ucsdet_setText(csd, bytes, len, &status); if (U_FAILURE(status)) { - IcuError(interp, "Could not set detection text.", status); + IcuError(interp, "Could not set detection text", status); ucsdet_close(csd); return TCL_ERROR; } if (all) { matches = ucsdet_detectAll(csd, &nmatches, &status); - } - else { + } else { match = ucsdet_detect(csd, &status); matches = &match; nmatches = match ? 1 : 0; } if (U_FAILURE(status) || nmatches == 0) { - ret = IcuError(interp, "Could not detect character set.", status); - } - else { + ret = IcuError(interp, "Could not detect character set", status); + } else { int i; Tcl_Obj *resultObj = Tcl_NewListObj(nmatches, NULL); + for (i = 0; i < nmatches; ++i) { const char *name = ucsdet_getName(matches[i], &status); if (U_FAILURE(status) || name == NULL) { @@ -226,7 +253,7 @@ static int DetectEncoding(Tcl_Interp *interp, Tcl_Obj *objPtr, int all) status = U_ZERO_ERRORZ; /* Reset on failure */ } Tcl_ListObjAppendElement( - NULL, resultObj, Tcl_NewStringObj(name, -1)); + NULL, resultObj, Tcl_NewStringObj(name, TCL_AUTO_LENGTH)); } Tcl_SetObjResult(interp, resultObj); ret = TCL_OK; @@ -236,37 +263,45 @@ static int DetectEncoding(Tcl_Interp *interp, Tcl_Obj *objPtr, int all) return ret; } -static int DetectableEncodings(Tcl_Interp *interp) +static int +DetectableEncodings( + Tcl_Interp *interp) { - if (ucsdet_open == NULL || ucsdet_getAllDetectableCharsets == NULL || - ucsdet_close == NULL || uenum_next == NULL || uenum_count == NULL || - uenum_close == NULL) { + // Confirm we have the profile of functions we need. + if (ucsdet_open == NULL || + ucsdet_getAllDetectableCharsets == NULL || + ucsdet_close == NULL || + uenum_next == NULL || + uenum_count == NULL || + uenum_close == NULL) { return FunctionNotAvailableError(interp); } UErrorCodex status = U_ZERO_ERRORZ; + UCharsetDetector *csd = ucsdet_open(&status); - UCharsetDetector* csd = ucsdet_open(&status); if (U_FAILURE(status)) { - return IcuError(interp, "Could not open charset detector.", status); + return IcuError(interp, "Could not open charset detector", status); } int ret; UEnumeration *enumerator = ucsdet_getAllDetectableCharsets(csd, &status); if (U_FAILURE(status) || enumerator == NULL) { - IcuError(interp, "Could not get list of detectable encodings.", status); + IcuError(interp, "Could not get list of detectable encodings", status); ret = TCL_ERROR; } else { - int32_t count; - count = uenum_count(enumerator, &status); + int32_t count = uenum_count(enumerator, &status); + if (U_FAILURE(status)) { - IcuError(interp, "Could not get charset enumerator count.", status); + IcuError(interp, "Could not get charset enumerator count", status); ret = TCL_ERROR; } else { int i; Tcl_Obj *resultObj = Tcl_NewListObj(0, NULL); + for (i = 0; i < count; ++i) { const char *name; int32_t len; + name = uenum_next(enumerator, &len, &status); if (name == NULL || U_FAILURE(status)) { name = "unknown"; @@ -274,7 +309,7 @@ static int DetectableEncodings(Tcl_Interp *interp) status = U_ZERO_ERRORZ; /* Reset on error */ } Tcl_ListObjAppendElement( - interp, resultObj, Tcl_NewStringObj(name, len)); + NULL, resultObj, Tcl_NewStringObj(name, len)); } Tcl_SetObjResult(interp, resultObj); ret = TCL_OK; @@ -285,22 +320,22 @@ static int DetectableEncodings(Tcl_Interp *interp) ucsdet_close(csd); return ret; } - + /* *------------------------------------------------------------------------ * * EncodingDetectObjCmd -- * - * Implements the Tcl command EncodingDetect. - * encdetect - returns names of all detectable encodings - * encdetect BYTES ?-all? - return detected encoding(s) + * Implements the Tcl command EncodingDetect. + * encdetect - returns names of all detectable encodings + * encdetect BYTES ?-all? - return detected encoding(s) * * Results: - * TCL_OK - Success. - * TCL_ERROR - Error. + * TCL_OK - Success. + * TCL_ERROR - Error. * * Side effects: - * Interpreter result holds result or error message. + * Interpreter result holds result or error message. * *------------------------------------------------------------------------ */ @@ -323,10 +358,9 @@ IcuDetectObjCmd( int all = 0; if (objc == 3) { if (strcmp("-all", Tcl_GetString(objv[2]))) { - Tcl_SetObjResult( - interp, - Tcl_ObjPrintf("Invalid option %s, must be \"-all\"", - Tcl_GetString(objv[2]))); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Invalid option %s, must be \"-all\"", + Tcl_GetString(objv[2]))); return TCL_ERROR; } all = 1; @@ -334,29 +368,29 @@ IcuDetectObjCmd( return DetectEncoding(interp, objv[1], all); } - + /* *------------------------------------------------------------------------ * * IcuConverterNamesObjCmd -- * - * Sets interp result to list of available ICU converters. + * Sets interp result to list of available ICU converters. * * Results: - * TCL_OK - Success. - * TCL_ERROR - Error. + * TCL_OK - Success. + * TCL_ERROR - Error. * * Side effects: - * Interpreter result holds list of converter names. + * Interpreter result holds list of converter names. * *------------------------------------------------------------------------ */ static int -IcuConverterNamesObjCmd ( +IcuConverterNamesObjCmd( TCL_UNUSED(void *), - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc != 1) { @@ -373,39 +407,40 @@ IcuConverterNamesObjCmd ( } Tcl_Obj *resultObj = Tcl_NewListObj(count, NULL); int32_t i; + for (i = 0; i < count; ++i) { const char *name = ucnv_getAvailableName(i); if (name) { - Tcl_ListObjAppendElement( - NULL, resultObj, Tcl_NewStringObj(name, -1)); + Tcl_ListObjAppendElement(NULL, resultObj, + Tcl_NewStringObj(name, TCL_AUTO_LENGTH)); } } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } - + /* *------------------------------------------------------------------------ * * IcuConverterAliasesObjCmd -- * - * Sets interp result to list of available ICU converters. + * Sets interp result to list of available ICU converters. * * Results: - * TCL_OK - Success. - * TCL_ERROR - Error. + * TCL_OK - Success. + * TCL_ERROR - Error. * * Side effects: - * Interpreter result holds list of converter names. + * Interpreter result holds list of converter names. * *------------------------------------------------------------------------ */ static int -IcuConverterAliasesObjCmd ( +IcuConverterAliasesObjCmd( TCL_UNUSED(void *), - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc != 2) { Tcl_WrongNumArgs(interp, 1 , objv, "convertername"); @@ -419,29 +454,43 @@ IcuConverterAliasesObjCmd ( UErrorCodex status = U_ZERO_ERRORZ; uint16_t count = ucnv_countAliases(name, &status); if (status != U_AMBIGUOUS_ALIAS_WARNING && U_FAILURE(status)) { - return IcuError(interp, "Could not get aliases.", status); + return IcuError(interp, "Could not get aliases", status); } if (count <= 0) { return TCL_OK; } + Tcl_Obj *resultObj = Tcl_NewListObj(count, NULL); uint16_t i; + for (i = 0; i < count; ++i) { status = U_ZERO_ERRORZ; /* Reset in case U_AMBIGUOUS_ALIAS_WARNING */ const char *aliasName = ucnv_getAlias(name, i, &status); + if (status != U_AMBIGUOUS_ALIAS_WARNING && U_FAILURE(status)) { status = U_ZERO_ERRORZ; /* Reset error for next iteration */ continue; } if (aliasName) { - Tcl_ListObjAppendElement( - NULL, resultObj, Tcl_NewStringObj(aliasName, -1)); + Tcl_ListObjAppendElement(NULL, resultObj, + Tcl_NewStringObj(aliasName, TCL_AUTO_LENGTH)); } } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } - + +/* + *------------------------------------------------------------------------ + * + * TclIcuCleanup -- + * + * Called whenever a command referencing the ICU function table is + * deleted. When the reference count drops to zero, the table is released + * and the ICU shared libraries are unloaded. + * + *------------------------------------------------------------------------ + */ static void TclIcuCleanup( TCL_UNUSED(void *)) @@ -453,7 +502,7 @@ TclIcuCleanup( u_cleanup(); } for (i = 0; i < (int)(sizeof(icu_fns.libs) / sizeof(icu_fns.libs[0])); - ++i) { + ++i) { if (icu_fns.libs[i] != NULL) { Tcl_FSUnloadFile(NULL, icu_fns.libs[i]); } @@ -462,7 +511,18 @@ TclIcuCleanup( } Tcl_MutexUnlock(&icu_mutex); } - + +/* + *------------------------------------------------------------------------ + * + * TclIcuInit -- + * + * Load the ICU commands into the given interpreter. If the ICU + * commands have never previously been loaded, the ICU libraries are + * loaded first. + * + *------------------------------------------------------------------------ + */ static void TclIcuInit( Tcl_Interp *interp) @@ -512,15 +572,16 @@ TclIcuInit( #endif while (iculibs[i] != NULL) { Tcl_ResetResult(interp); - nameobj = Tcl_NewStringObj(iculibs[i], TCL_INDEX_NONE); + nameobj = Tcl_NewStringObj(iculibs[i], TCL_AUTO_LENGTH); char *nameStr = Tcl_GetString(nameobj); char *p = strchr(nameStr, '?'); + if (p != NULL) { memcpy(p, icuversion+1, 2); } Tcl_IncrRefCount(nameobj); - if (Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, &icu_fns.libs[0]) - == TCL_OK) { + if (Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, + &icu_fns.libs[0]) == TCL_OK) { if (p == NULL) { icuversion[0] = '\0'; } @@ -539,7 +600,7 @@ TclIcuInit( (void) Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, &icu_fns.libs[1]); Tcl_DecrRefCount(nameobj); } -#if defined(_WIN32) +#ifdef _WIN32 /* * On Windows, if no ICU install found, look for the system's * (Win10 1703 or later). There are two cases. Newer systems @@ -548,46 +609,48 @@ TclIcuInit( */ if (icu_fns.libs[0] == NULL) { Tcl_ResetResult(interp); - nameobj = Tcl_NewStringObj("icu.dll", TCL_INDEX_NONE); - Tcl_IncrRefCount(nameobj); - if (Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, &icu_fns.libs[0]) - == TCL_OK) { - /* Reload same for second set of functions. */ - (void) Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, &icu_fns.libs[1]); - /* Functions do NOT have version suffixes */ - icuversion[0] = '\0'; - } - Tcl_DecrRefCount(nameobj); + nameobj = Tcl_NewStringObj("icu.dll", TCL_AUTO_LENGTH); + Tcl_IncrRefCount(nameobj); + if (Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, &icu_fns.libs[0]) + == TCL_OK) { + /* Reload same for second set of functions. */ + (void) Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, + &icu_fns.libs[1]); + /* Functions do NOT have version suffixes */ + icuversion[0] = '\0'; + } + Tcl_DecrRefCount(nameobj); } if (icu_fns.libs[0] == NULL) { /* No icu.dll. Try last fallback */ Tcl_ResetResult(interp); - nameobj = Tcl_NewStringObj("icuuc.dll", TCL_INDEX_NONE); + nameobj = Tcl_NewStringObj("icuuc.dll", TCL_AUTO_LENGTH); Tcl_IncrRefCount(nameobj); if (Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, &icu_fns.libs[0]) - == TCL_OK) { + == TCL_OK) { Tcl_DecrRefCount(nameobj); - nameobj = Tcl_NewStringObj("icuin.dll", TCL_INDEX_NONE); + nameobj = Tcl_NewStringObj("icuin.dll", TCL_AUTO_LENGTH); Tcl_IncrRefCount(nameobj); - (void) Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, &icu_fns.libs[1]); + (void) Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, + &icu_fns.libs[1]); /* Functions do NOT have version suffixes */ icuversion[0] = '\0'; } Tcl_DecrRefCount(nameobj); } -#endif +#endif // _WIN32 /* Try for symbol without version (Windows, FreeBSD), then with version */ -#define ICUUC_SYM(name) \ - do { \ - strcpy(symbol, #name); \ - icu_fns._##name = \ - (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ - if (icu_fns._##name == NULL) { \ - strcat(symbol, icuversion); \ - icu_fns._##name = \ - (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ - } \ +#define ICUUC_SYM(name) \ + do { \ + strcpy(symbol, #name); \ + icu_fns._##name = (fn_##name) \ + Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ + if (icu_fns._##name == NULL) { \ + strcat(symbol, icuversion); \ + icu_fns._##name = (fn_##name) \ + Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ + } \ } while (0) if (icu_fns.libs[0] != NULL) { @@ -614,16 +677,16 @@ TclIcuInit( #undef ICUUC_SYM } -#define ICUIN_SYM(name) \ - do { \ - strcpy(symbol, #name); \ - icu_fns._##name = \ - (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ - if (icu_fns._##name == NULL) { \ - strcat(symbol, icuversion); \ - icu_fns._##name = \ - (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ - } \ +#define ICUIN_SYM(name) \ + do { \ + strcpy(symbol, #name); \ + icu_fns._##name = (fn_##name) \ + Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ + if (icu_fns._##name == NULL) { \ + strcat(symbol, icuversion); \ + icu_fns._##name = (fn_##name) \ + Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ + } \ } while (0) if (icu_fns.libs[1] != NULL) { @@ -636,11 +699,7 @@ TclIcuInit( ICUIN_SYM(ucsdet_setText); #undef ICUIN_SYM } - } -#undef ICU_SYM - - Tcl_MutexUnlock(&icu_mutex); if (icu_fns.libs[0] != NULL) { /* @@ -652,51 +711,44 @@ TclIcuInit( /* Ref count number of commands */ icu_fns.nopen += 1; - Tcl_CreateObjCommand(interp, - "::tcl::unsupported::icu::detect", - IcuDetectObjCmd, - 0, - TclIcuCleanup); + Tcl_CreateObjCommand(interp, "::tcl::unsupported::icu::detect", + IcuDetectObjCmd, 0, TclIcuCleanup); } /* Commands needing only libs[0] (icuuc) */ /* Ref count number of commands */ icu_fns.nopen += 2; - Tcl_CreateObjCommand(interp, - "::tcl::unsupported::icu::converters", - IcuConverterNamesObjCmd, - 0, - TclIcuCleanup); - Tcl_CreateObjCommand(interp, - "::tcl::unsupported::icu::aliases", - IcuConverterAliasesObjCmd, - 0, - TclIcuCleanup); + Tcl_CreateObjCommand(interp, "::tcl::unsupported::icu::converters", + IcuConverterNamesObjCmd, 0, TclIcuCleanup); + Tcl_CreateObjCommand(interp, "::tcl::unsupported::icu::aliases", + IcuConverterAliasesObjCmd, 0, TclIcuCleanup); } -} + Tcl_MutexUnlock(&icu_mutex); +} + /* *------------------------------------------------------------------------ * * TclLoadIcuObjCmd -- * - * Loads and initializes ICU + * Loads and initializes ICU * * Results: - * TCL_OK - Success. - * TCL_ERROR - Error. + * TCL_OK - Success. + * TCL_ERROR - Error. * * Side effects: - * Interpreter result holds result or error message. + * Interpreter result holds result or error message. * *------------------------------------------------------------------------ */ int -TclLoadIcuObjCmd ( +TclLoadIcuObjCmd( TCL_UNUSED(void *), - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc != 1) { Tcl_WrongNumArgs(interp, 1 , objv, ""); @@ -705,7 +757,7 @@ TclLoadIcuObjCmd ( TclIcuInit(interp); return TCL_OK; } - + /* * Local Variables: * mode: c diff --git a/tests/icu.test b/tests/icu.test index bc29312..3c07995 100644 --- a/tests/icu.test +++ b/tests/icu.test @@ -7,12 +7,13 @@ if {"::tcltest" ni [namespace children]} { # Force late loading of ICU if present catch {::tcl::unsupported::icu} -testConstraint icu [expr {[info commands ::tcl::unsupported::icu::detect] ne ""}] +testConstraint icu [llength [info commands ::tcl::unsupported::icu::detect]] namespace eval icu { test icu-detect-0 {Return list of ICU encodings} -constraints icu -body { set encoders [::tcl::unsupported::icu detect] - list [::tcl::mathop::in UTF-8 $encoders] [::tcl::mathop::in ISO-8859-1 $encoders] + list [::tcl::mathop::in UTF-8 $encoders] \ + [::tcl::mathop::in ISO-8859-1 $encoders] } -result {1 1} test icu-detect-1 {Guess encoding} -constraints icu -body { @@ -21,13 +22,16 @@ namespace eval icu { test icu-detect-2 {Get all possible encodings} -constraints icu -body { set encodings [::tcl::unsupported::icu detect [readFile [info script]] -all] - list [::tcl::mathop::in UTF-8 $encodings] [::tcl::mathop::in ISO-8859-1 $encodings] + list [::tcl::mathop::in UTF-8 $encodings] \ + [::tcl::mathop::in ISO-8859-1 $encodings] } -result {1 1} test icu-tclToIcu-0 {Map Tcl encoding} -constraints icu -body { # tis-620 because it is ambiguous in ICU on some platforms # but should return the preferred encoding - list [::tcl::unsupported::icu tclToIcu utf-8] [::tcl::unsupported::icu tclToIcu tis-620] [::tcl::unsupported::icu tclToIcu shiftjis] + list [::tcl::unsupported::icu tclToIcu utf-8] \ + [::tcl::unsupported::icu tclToIcu tis-620] \ + [::tcl::unsupported::icu tclToIcu shiftjis] } -result {UTF-8 TIS-620 ibm-943_P15A-2003} test icu-tclToIcu-1 {Map Tcl encoding - no map} -constraints icu -body { @@ -36,16 +40,16 @@ namespace eval icu { } -result {} test icu-icuToTcl-0 {Map ICU encoding} -constraints icu -body { - list [::tcl::unsupported::icu icuToTcl UTF-8] [::tcl::unsupported::icu icuToTcl TIS-620] [::tcl::unsupported::icu icuToTcl ibm-943_P15A-2003] + list [::tcl::unsupported::icu icuToTcl UTF-8] \ + [::tcl::unsupported::icu icuToTcl TIS-620] \ + [::tcl::unsupported::icu icuToTcl ibm-943_P15A-2003] } -result {utf-8 tis-620 cp932} test icu-icuToTcl-1 {Map ICU encoding - no map} -constraints icu -body { # Should not raise an error ::tcl::unsupported::icu icuToTcl dummy } -result {} - } - namespace delete icu ::tcltest::cleanupTests -- cgit v0.12 From 1029c41df99f1466e7c3089966fa06f70f2cdcd7 Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Mon, 5 Aug 2024 16:18:42 +0000 Subject: VC++ build tool. Builds/tests/installs all configs. Type vctool help. --- win/vctool.bat | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 win/vctool.bat diff --git a/win/vctool.bat b/win/vctool.bat new file mode 100644 index 0000000..262ae1c --- /dev/null +++ b/win/vctool.bat @@ -0,0 +1,173 @@ +@echo off +REM Pass /? as argument for usage. + +IF DEFINED VCINSTALLDIR goto setup + +echo "Not in a Visual Studio command prompt." +exit /B 1 + + +:setup +setlocal + +REM Get the current directory +set "currentDir=%CD%" + +REM Use FOR command to get the parent directory +for %%I in ("%currentDir%") do set "parentDir=%%~dpI" + +REM Remove the trailing backslash +set "parentDir=%parentDir:~0,-1%" + +REM Use FOR command again to get the parent of the parent directory +for %%J in ("%parentDir%") do set "grandParentDir=%%~dpJ" + +REM Remove the trailing backslash +set "grandParentDir=%grandParentDir:~0,-1%" + +REM Use FOR command to extract the last component +for %%I in ("%grandParentDir%") do set "grandParentTail=%%~nxI" + +REM Extract the drive letter +for %%I in ("%currentDir%") do set "driveLetter=%%~dI" + +set ARCH=%VSCMD_ARG_TGT_ARCH% +if "%TCLINSTALLROOT%" == "" ( + set INSTROOT=%driveLetter%\Tcl\%grandParentTail%\%ARCH% +) else ( + set INSTROOT=%TCLINSTALLROOT%\%grandParentTail%\%ARCH% +) + +REM Parse options +:options +if "%1" == "" goto dobuilds +if "%1" == "/?" goto help +if "%1" == "-?" goto help +if /i "%1" == "/help" goto help +if "%1" == "all" goto all +if "%1" == "shared" goto shared +if "%1" == "static" goto static +if "%1" == "shared_noembed" goto shared_noembed +if "%1" == "static_noembed" goto static_noembed +if "%1" == "compile" goto compile +if "%1" == "test" goto targets +if "%1" == "install" goto targets +if "%1" == "runshell" goto targets +if "%1" == "pdbs" goto pdbs +goto help + +:pdbs +set pdbs=1 +shift +goto options + +:shared +set shared=1 +shift +goto options + +:static +set static=1 +shift +goto options + +:shared_noembed +set shared_noembed=1 +shift +goto options + +:static_noembed +set static_noembed=1 +shift +goto options + +:all +set shared=1 +set static=1 +set shared_noembed=1 +set static_noembed=1 +shift +goto options + +:targets +set TARGETS=%TARGETS% %1 +shift +goto options + +REM The makefile.vc compilation target is called "release" +:compile +set TARGETS=%TARGETS% release +shift +goto options + +:dobuilds +if "%shared%%static%%shared_noembed%%static_noembed%" == "" ( + echo At least one of shared, static, shared_noembed, static_noembed, all must be specified. + echo For more help, type "%0 help" + goto error +) + +if DEFINED shared ( + call :runmake shared +) +if DEFINED shared_noembed ( +call :runmake shared-noembed noembed +) +if DEFINED static ( +call :runmake static static +) +if DEFINED static_noembed ( +call :runmake static-noembed "static,noembed" +) + +:done +endlocal +exit /b 0 + +:error +endlocal +exit /b 1 + +:: call :runmake dir opts +:runmake +if "%pdbs%" == "" ( + nmake /s /f makefile.vc OUT_DIR=%currentDir%\vc-%ARCH%-%1 TMP_DIR=%currentDir%\vc-%ARCH%-%1\objs OPTS=pdbs,%2 INSTALLDIR=%INSTROOT%-%1 %TARGETS% && goto error +) else ( + nmake /s /f makefile.vc OUT_DIR=%currentDir%\vc-%ARCH%-%1-debug TMP_DIR=%currentDir%\vc-%ARCH%-%1-debug\objs OPTS=pdbs,%2 cdebug="-Zi -Od" INSTALLDIR=%INSTROOT%-%1-debug %TARGETS% && goto error +) +goto eof + +:help +echo. +echo Usage: %0 arg ... +echo. +echo where each arg may be either a build config or a target or "debug". +echo. +echo Configs: shared, static, shared_noembed, static_noembed, all +echo Targets: compile (default), test, install +echo. +echo Multiple configs and targets may be specified and intermixed. +echo At least one config must be specified. If no targets specified, +echo default is compile. If multiple targets are present, they +echo are built in specified order. +echo. +echo If "debug" is supplied as an argument, the build has optimizations +echo disabled and full debug information. +echo. +echo If environment variable TCLINSTALLROOT is defined, install target +echo will be subdirectory under it named after the grandparent of the +echo current directory. TCLINSTALLROOT defaults to the X:\Tcl where +echo X is the current drive. +echo. +echo For example, if the current directory C:\src\core-8-branch\tcl\win, +echo install directories will be echo under c:\Tcl\core-8-branch\ as +echo x64-shared, x64-static etc. or x64-shared-debug etc. if "pdbs" passed. +echo. +echo Examples: +echo %0 shared (Builds default "shared" config) +echo %0 shared test (Tests shared build) +echo %0 static compile test (Builds and tests static build) +echo %0 all debug (Build debug versions of all configs) +echo %0 all compile install debug (Builds and installs all configs) +echo %0 shared static shared_noembed (Builds three configs) +goto done -- cgit v0.12 From 76718af2027a541a834a6979b532a1daf4c900cf Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 5 Aug 2024 22:44:50 +0000 Subject: Missed some backports from 9.0. Some indenting --- changes.md | 3 +- doc/clock.n | 15 ++++++- doc/library.n | 2 +- doc/msgcat.n | 11 +++-- doc/object.n | 1 + generic/tclCkalloc.c | 14 +++--- generic/tclClock.c | 2 +- generic/tclCmdAH.c | 10 ++--- generic/tclCmdMZ.c | 33 +++++++------- generic/tclCompCmds.c | 2 +- generic/tclDictObj.c | 14 +++--- generic/tclEncoding.c | 4 +- generic/tclIORTrans.c | 30 ++++++------- generic/tclIOSock.c | 2 +- generic/tclLink.c | 30 ++++++------- generic/tclListObj.c | 24 +++++------ generic/tclOO.c | 2 +- generic/tclPathObj.c | 72 +++++++++++++++---------------- generic/tclResult.c | 110 +++++++++++++++++++++++------------------------ generic/tclStringObj.c | 6 +++ generic/tclThreadAlloc.c | 2 +- generic/tclTimer.c | 36 ++++++++-------- generic/tclTrace.c | 2 +- generic/tclUtil.c | 44 +++++++++---------- generic/tclVar.c | 8 ++-- generic/tclZipfs.c | 6 +-- tests/clock.test | 2 +- tests/info.test | 9 ++++ tests/zipfs.test | 3 +- unix/tclUnixPipe.c | 4 +- 30 files changed, 266 insertions(+), 237 deletions(-) diff --git a/changes.md b/changes.md index 51adf8a..2adbd1e 100644 --- a/changes.md +++ b/changes.md @@ -31,7 +31,7 @@ writing Tcl scripts. - `chan isbinary` - `coroinject`, `coroprobe` - `clock add weekdays` - - `dict getdefault` + - `dict getwithdefault` - `file tempdir`, `file home`, `file tildeexpand` - `info commandtype` - `ledit` @@ -42,6 +42,7 @@ writing Tcl scripts. - `string insert`, `string is dict` - `tcl::process` - `*::build-info` + - `readFile`, `writeFile`, `foreachLine` ## New command options - `regsub ... -command ...` diff --git a/doc/clock.n b/doc/clock.n index 8a54e07..12897b2 100644 --- a/doc/clock.n +++ b/doc/clock.n @@ -113,7 +113,7 @@ Specifies the desired output format for \fBclock format\fR or the expected input format for \fBclock scan\fR. The \fIformat\fR string consists of any number of characters other than the per-cent sign .PQ \fB%\fR -interspersed with any number of \fIformat groups\fR, which are two-character +interspersed with any number of \fIformat groups\fR, which are two- or three-character sequences beginning with the per-cent sign. The permissible format groups, and their interpretation, are described under \fBFORMAT GROUPS\fR. .RS @@ -169,6 +169,15 @@ the environment variable \fBTZ\fR. .IP [3] on Windows systems, the time zone settings from the Control Panel. .RE +.\" OPTION: -validate +.TP +\fB\-validate\fR boolean +. +If \fIboolean\fR is true, \fBclock scan\fR will raise an error if the +input contains invalid values, e.g. day of month greater than number +of days in the month. If specified as false (default), the command +makes an adjustment to bring values within acceptable range. See +\fBSCANNING TIMES\fR for details. .PP If none of these is present, the C \fBlocaltime\fR and \fBmktime\fR functions are used to attempt to convert times between local and @@ -467,7 +476,9 @@ time zone when converting local times. This caveat does not apply to UTC times.) .PP If the interpretation of the groups yields an impossible time because -a field is out of range, enough of that field's unit will be added to +a field is out of range, an exception is raised if the \fB-validate\fR +option is passed as true. If passed as false or not present, +enough of that field's unit will be added to or subtracted from the time to bring it in range. Thus, if attempting to scan or format day 0 of the month, one day will be subtracted from day 1 of the month, yielding the last day of the previous month. diff --git a/doc/library.n b/doc/library.n index 0342cbe..5c364bb 100644 --- a/doc/library.n +++ b/doc/library.n @@ -9,7 +9,7 @@ .so man.macros .BS .SH NAME -auto_execok, auto_import, auto_load, auto_mkindex, auto_qualify, auto_reset, tcl_findLibrary, parray, tcl_endOfWord, tcl_startOfNextWord, tcl_startOfPreviousWord, tcl_wordBreakAfter, tcl_wordBreakBefore \- standard library of Tcl procedures +auto_execok, auto_import, auto_load, auto_mkindex, auto_qualify, auto_reset, foreachLine, parray, readFile, tcl_findLibrary, tcl_endOfWord, tcl_startOfNextWord, tcl_startOfPreviousWord, tcl_wordBreakAfter, tcl_wordBreakBefore, writeFile \- standard library of Tcl procedures .SH SYNOPSIS .nf \fBauto_execok \fIcmd\fR diff --git a/doc/msgcat.n b/doc/msgcat.n index 9d82688..f486326 100644 --- a/doc/msgcat.n +++ b/doc/msgcat.n @@ -35,7 +35,7 @@ msgcat \- Tcl message catalog .VE "TIP 499" .sp .VS "TIP 412" -\fB::msgcat::mcloadedlocales subcommand\fR ?\fIlocale\fR? +\fB::msgcat::mcloadedlocales subcommand\fR .VE "TIP 412" .sp \fB::msgcat::mcload \fIdirname\fR @@ -239,7 +239,7 @@ configured by: .PP .\" COMMAND: mcloadedlocales .TP -\fB::msgcat::mcloadedlocales subcommand\fR ?\fIlocale\fR? +\fB::msgcat::mcloadedlocales subcommand\fR .VS "TIP 499" This group of commands manage the list of loaded locales for packages not setting a package locale. @@ -399,10 +399,9 @@ language[_country][_modifier] .PP On Windows and Cygwin, if none of those environment variables is set, msgcat will attempt to extract locale information from the registry. -From Windows Vista on, the RFC4747 locale name "lang-script-country-options" +The RFC4747 locale name "lang-script-country-options" is transformed to the locale as "lang_country_script" (Example: -sr-Latn-CS -> sr_cs_latin). For Windows XP, the language id is -transformed analogously (Example: 0c1a -> sr_yu_cyrillic). +sr-Latn-CS -> sr_cs_latin). If all these attempts to discover an initial locale from the user's environment fail, msgcat defaults to an initial locale of .QW C . @@ -615,7 +614,7 @@ If a set of locale preferences is given, it is set as package locale preference list. The package locale is set to the first element of the preference list. A package locale is activated, if it was not set so far. .PP -Locale preferences are loaded now for the package, if not jet loaded. +Locale preferences are loaded now for the package, if not yet loaded. .VE "TIP 499" .RE .PP diff --git a/doc/object.n b/doc/object.n index 7bdbbe2..96f5d39 100644 --- a/doc/object.n +++ b/doc/object.n @@ -69,6 +69,7 @@ associated with \fIobj\fR, returning the result of the evaluation. Note that object-internal commands such as \fBmy\fR and \fBself\fR can be invoked in this context. .RE +.\" METHOD: unknown .TP \fIobj \fBunknown ?\fImethodName\fR? ?\fIarg ...\fR? . diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c index f0c625f..e0a1224 100644 --- a/generic/tclCkalloc.c +++ b/generic/tclCkalloc.c @@ -170,7 +170,7 @@ TclDumpMemoryInfo( char buf[1024]; if (clientData == NULL) { - return 0; + return 0; } snprintf(buf, sizeof(buf), "total mallocs %10" TCL_Z_MODIFIER "u\n" @@ -826,7 +826,7 @@ MemoryCmd( Tcl_DStringFree(&buffer); if (result != TCL_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("error accessing %s: %s", - TclGetString(objv[2]), Tcl_PosixError(interp))); + TclGetString(objv[2]), Tcl_PosixError(interp))); return TCL_ERROR; } return TCL_OK; @@ -871,8 +871,8 @@ MemoryCmd( fileP = fopen(fileName, "w"); if (fileP == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "cannot open output file: %s", - Tcl_PosixError(interp))); + "cannot open output file: %s", + Tcl_PosixError(interp))); return TCL_ERROR; } TclDbDumpActiveObjects(fileP); @@ -936,9 +936,9 @@ MemoryCmd( } Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad option \"%s\": should be active, break_on_malloc, info, " - "init, objs, onexit, tag, trace, trace_on_at_malloc, or validate", - TclGetString(objv[1]))); + "bad option \"%s\": should be active, break_on_malloc, info, " + "init, objs, onexit, tag, trace, trace_on_at_malloc, or validate", + TclGetString(objv[1]))); return TCL_ERROR; argError: diff --git a/generic/tclClock.c b/generic/tclClock.c index 0b72bf4..3942632 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -3420,7 +3420,7 @@ ClockParseFmtScnArgs( Tcl_Obj *baseObj = opts->baseObj; /* bypass integer recognition if looks like "now" or "-now" */ - if ((baseObj->bytes && + if ((baseObj->bytes && ((baseObj->length == 3 && baseObj->bytes[0] == 'n') || (baseObj->length == 4 && baseObj->bytes[1] == 'n'))) || TclGetWideIntFromObj(NULL, baseObj, &baseVal) != TCL_OK) { diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index 3a740e5..7a01a58 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -685,7 +685,7 @@ EncodingConvertfromObjCmd( return TCL_ERROR; } result = Tcl_ExternalToUtfDStringEx(interp, encoding, bytesPtr, length, flags, - &ds, failVarObj ? &errorLocation : NULL); + &ds, failVarObj ? &errorLocation : NULL); /* NOTE: ds must be freed beyond this point even on error */ switch (result) { case TCL_OK: @@ -782,7 +782,7 @@ EncodingConverttoObjCmd( stringPtr = TclGetStringFromObj(data, &length); result = Tcl_UtfToExternalDStringEx(interp, encoding, stringPtr, length, flags, - &ds, failVarObj ? &errorLocation : NULL); + &ds, failVarObj ? &errorLocation : NULL); /* NOTE: ds must be freed beyond this point even on error */ switch (result) { @@ -2480,9 +2480,9 @@ StoreStatData( TclNewObj(result); Tcl_IncrRefCount(result); #define DOBJPUT(key, objValue) \ - Tcl_DictObjPut(NULL, result, \ - Tcl_NewStringObj((key), -1), \ - (objValue)); + Tcl_DictObjPut(NULL, result, \ + Tcl_NewStringObj((key), -1), \ + (objValue)); DOBJPUT("dev", Tcl_NewWideIntObj((long)statPtr->st_dev)); DOBJPUT("ino", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_ino)); DOBJPUT("nlink", Tcl_NewWideIntObj((long)statPtr->st_nlink)); diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 29e3395..20197aa 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -29,7 +29,7 @@ static Tcl_NRPostProc TryPostFinal; static Tcl_NRPostProc TryPostHandler; static int UniCharIsAscii(int character); static int UniCharIsHexDigit(int character); -static int StringCmpOpts(Tcl_Interp *interp, int objc, +static int StringCmpOpts(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int *nocase, Tcl_Size *reqlength); @@ -1529,7 +1529,8 @@ StringIsCmd( { const char *string1, *end, *stop; int (*chcomp)(int) = NULL; /* The UniChar comparison function. */ - int i, failat = 0, result = 1, strict = 0, index, length1, length2; + int i, result = 1, strict = 0; + Tcl_Size failat = 0, length1, length2, index; Tcl_Obj *objPtr, *failVarObj = NULL; Tcl_WideInt w; @@ -1994,7 +1995,8 @@ StringMapCmd( if (!TclHasStringRep(objv[objc-2]) && TclHasInternalRep(objv[objc-2], &tclDictType)) { - int i, done; + Tcl_Size i; + int done; Tcl_DictSearch search; /* @@ -2245,8 +2247,7 @@ StringMatchCmd( Tcl_Size length; const char *string = TclGetStringFromObj(objv[1], &length); - if ((length > 1) && - strncmp(string, "-nocase", length) == 0) { + if ((length > 1) && strncmp(string, "-nocase", length) == 0) { nocase = TCL_MATCH_NOCASE; } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -2412,7 +2413,7 @@ StringRplcCmd( * result is the original string. */ - if ((last < 0) || /* Range ends before start of string */ + if ((last < 0) || /* Range ends before start of string */ (first > end) || /* Range begins after end of string */ (last < first)) { /* Range begins after it starts */ /* @@ -2663,7 +2664,7 @@ StringEqualCmd( goto str_cmp_args; } i++; - if (Tcl_GetWideIntFromObj(interp, objv[i], &reqlength) != TCL_OK) { + if (TclGetWideIntFromObj(interp, objv[i], &reqlength) != TCL_OK) { return TCL_ERROR; } if ((Tcl_WideUInt)reqlength > TCL_SIZE_MAX) { @@ -2766,13 +2767,13 @@ StringCmpOpts( goto str_cmp_args; } i++; - if (Tcl_GetWideIntFromObj(interp, objv[i], &wreqlength) != TCL_OK) { + if (TclGetWideIntFromObj(interp, objv[i], &wreqlength) != TCL_OK) { return TCL_ERROR; } if ((Tcl_WideUInt)wreqlength > TCL_SIZE_MAX) { - *reqlength = -1; + *reqlength = -1; } else { - *reqlength = wreqlength; + *reqlength = wreqlength; } } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -3184,7 +3185,7 @@ StringTrimCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { const char *string1, *string2; - int triml, trimr, length1, length2; + Tcl_Size triml, trimr, length1, length2; if (objc == 3) { string2 = TclGetStringFromObj(objv[2], &length2); @@ -4243,14 +4244,14 @@ Tcl_TimeRateObjCmd( } objPtr = objv[i++]; if (i < objc) { /* max-time */ - result = Tcl_GetWideIntFromObj(interp, objv[i++], &maxms); + result = TclGetWideIntFromObj(interp, objv[i], &maxms); if (result != TCL_OK) { return result; } - if (i < objc) { /* max-count*/ + if (++i < objc) { /* max-count*/ Tcl_WideInt v; - result = Tcl_GetWideIntFromObj(interp, objv[i], &v); + result = TclGetWideIntFromObj(interp, objv[i], &v); if (result != TCL_OK) { return result; } @@ -5005,8 +5006,8 @@ TryPostBody( continue; } for (j=0 ; jtwoPtrValue.ptr1 : NULL; \ + const Tcl_ObjInternalRep *irPtr; \ + irPtr = TclFetchInternalRep((objPtr), &tclDictType); \ + (dictRepPtr) = irPtr ? (Dict *)irPtr->twoPtrValue.ptr1 : NULL; \ } while (0) /* diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index d1096d2..380f3ed 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -1272,7 +1272,7 @@ Tcl_ExternalToUtfDStringEx( Tcl_DString *dstPtr, /* Uninitialized or free DString in which the * converted string is stored. */ Tcl_Size *errorLocPtr) /* Where to store the error location - (or TCL_INDEX_NONE if no error). May + (or TCL_INDEX_NONE if no error). May be NULL. */ { char *dst; @@ -1562,7 +1562,7 @@ Tcl_UtfToExternalDStringEx( Tcl_DString *dstPtr, /* Uninitialized or free DString in which the * converted string is stored. */ Tcl_Size *errorLocPtr) /* Where to store the error location - (or TCL_INDEX_NONE if no error). May + (or TCL_INDEX_NONE if no error). May be NULL. */ { char *dst; diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index 81345dc..0bc6a50 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -608,9 +608,9 @@ TclChanPushObjCmd( */ if (TclListObjGetElements(NULL, resObj, &listc, &listv) != TCL_OK) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "chan handler \"%s initialize\" returned non-list: %s", - TclGetString(cmdObj), TclGetString(resObj))); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "chan handler \"%s initialize\" returned non-list: %s", + TclGetString(cmdObj), TclGetString(resObj))); Tcl_DecrRefCount(resObj); goto error; } @@ -633,9 +633,9 @@ TclChanPushObjCmd( Tcl_DecrRefCount(resObj); if ((REQUIRED_METHODS & methods) != REQUIRED_METHODS) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "chan handler \"%s\" does not support all required methods", - TclGetString(cmdObj))); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "chan handler \"%s\" does not support all required methods", + TclGetString(cmdObj))); goto error; } @@ -655,9 +655,9 @@ TclChanPushObjCmd( } if (!mode) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "chan handler \"%s\" makes the channel inaccessible", - TclGetString(cmdObj))); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "chan handler \"%s\" makes the channel inaccessible", + TclGetString(cmdObj))); goto error; } @@ -666,16 +666,16 @@ TclChanPushObjCmd( */ if (!IMPLIES(HAS(methods, METH_DRAIN), HAS(methods, METH_READ))) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "chan handler \"%s\" supports \"drain\" but not \"read\"", - TclGetString(cmdObj))); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "chan handler \"%s\" supports \"drain\" but not \"read\"", + TclGetString(cmdObj))); goto error; } if (!IMPLIES(HAS(methods, METH_FLUSH), HAS(methods, METH_WRITE))) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "chan handler \"%s\" supports \"flush\" but not \"write\"", - TclGetString(cmdObj))); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "chan handler \"%s\" supports \"flush\" but not \"write\"", + TclGetString(cmdObj))); goto error; } diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c index eaa9cc8..01ec325 100644 --- a/generic/tclIOSock.c +++ b/generic/tclIOSock.c @@ -249,7 +249,7 @@ TclCreateSocketAddress( (result == EAI_SYSTEM) ? Tcl_PosixError(interp) : #endif /* EAI_SYSTEM */ gai_strerror(result); - return 0; + return 0; } /* diff --git a/generic/tclLink.c b/generic/tclLink.c index fc4741b..fd7dd2d 100644 --- a/generic/tclLink.c +++ b/generic/tclLink.c @@ -323,7 +323,7 @@ Tcl_LinkArray( /* * If no address is given create one and use as address the - * not needed linkPtr->lastValue + * not needed linkPtr->lastValue */ if (addr == NULL) { @@ -920,7 +920,7 @@ LinkTraceProc( if (GetInt(objv[i], varPtr)) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) "variable array must have integer values"; + return (char *) "variable array must have integer values"; } } } else { @@ -988,7 +988,7 @@ LinkTraceProc( if (Tcl_GetBooleanFromObj(NULL, objv[i], varPtr) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) "variable array must have boolean value"; + return (char *) "variable array must have boolean value"; } } } else { @@ -1007,10 +1007,10 @@ LinkTraceProc( if (linkPtr->flags & LINK_ALLOC_LAST) { for (i=0; i < objc; i++) { if (GetInt(objv[i], &valueInt) - || !InRange(SCHAR_MIN, valueInt, SCHAR_MAX)) { + || !InRange(SCHAR_MIN, valueInt, SCHAR_MAX)) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) "variable array must have char value"; + return (char *) "variable array must have char value"; } linkPtr->lastValue.cPtr[i] = (char) valueInt; } @@ -1029,7 +1029,7 @@ LinkTraceProc( if (linkPtr->flags & LINK_ALLOC_LAST) { for (i=0; i < objc; i++) { if (GetInt(objv[i], &valueInt) - || !InRange(0, valueInt, (int)UCHAR_MAX)) { + || !InRange(0, valueInt, (int)UCHAR_MAX)) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) @@ -1056,7 +1056,7 @@ LinkTraceProc( || !InRange(SHRT_MIN, valueInt, SHRT_MAX)) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) "variable array must have short value"; + return (char *) "variable array must have short value"; } linkPtr->lastValue.sPtr[i] = (short) valueInt; } @@ -1075,10 +1075,10 @@ LinkTraceProc( if (linkPtr->flags & LINK_ALLOC_LAST) { for (i=0; i < objc; i++) { if (GetInt(objv[i], &valueInt) - || !InRange(0, valueInt, (int)USHRT_MAX)) { + || !InRange(0, valueInt, (int)USHRT_MAX)) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) + return (char *) "variable array must have unsigned short value"; } linkPtr->lastValue.usPtr[i] = (unsigned short) valueInt; @@ -1102,7 +1102,7 @@ LinkTraceProc( || !InRange(0, valueWide, (Tcl_WideInt)UINT_MAX)) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) + return (char *) "variable array must have unsigned int value"; } linkPtr->lastValue.uiPtr[i] = (unsigned int) valueWide; @@ -1127,7 +1127,7 @@ LinkTraceProc( || !InRange(LONG_MIN, valueWide, LONG_MAX)) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) "variable array must have long value"; + return (char *) "variable array must have long value"; } linkPtr->lastValue.lPtr[i] = (long) valueWide; } @@ -1149,7 +1149,7 @@ LinkTraceProc( || (valueUWide > ULONG_MAX)) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) + return (char *) "variable array must have unsigned long value"; } linkPtr->lastValue.ulPtr[i] = (unsigned long) valueUWide; @@ -1173,7 +1173,7 @@ LinkTraceProc( if (GetUWide(objv[i], &valueUWide)) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) + return (char *) "variable array must have unsigned wide int value"; } linkPtr->lastValue.uwPtr[i] = valueUWide; @@ -1193,10 +1193,10 @@ LinkTraceProc( for (i=0; i < objc; i++) { if (GetDouble(objv[i], &valueDouble) && !InRange(FLT_MIN, fabs(valueDouble), FLT_MAX) - && !IsSpecial(valueDouble)) { + && !IsSpecial(valueDouble)) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) "variable array must have float value"; + return (char *) "variable array must have float value"; } linkPtr->lastValue.fPtr[i] = (float) valueDouble; } diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 228a18a..89e72b6 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -2933,11 +2933,11 @@ TclLsetFlat( } indexArray++; - /* - * Special case 0-length lists. The Tcl indexing function treat - * will return any value beyond length as TCL_SIZE_MAX for this - * case. - */ + /* + * Special case 0-length lists. The Tcl indexing function treat + * will return any value beyond length as TCL_SIZE_MAX for this + * case. + */ if ((index == TCL_SIZE_MAX) && (elemCount == 0)) { index = 0; } @@ -2946,14 +2946,14 @@ TclLsetFlat( /* ...the index points outside the sublist. */ if (interp != NULL) { Tcl_SetObjResult(interp, - Tcl_ObjPrintf("index \"%s\" out of range", - TclGetString(indexArray[-1]))); + Tcl_ObjPrintf("index \"%s\" out of range", + TclGetString(indexArray[-1]))); Tcl_SetErrorCode(interp, - "TCL", - "VALUE", - "INDEX" - "OUTOFRANGE", - (char *)NULL); + "TCL", + "VALUE", + "INDEX" + "OUTOFRANGE", + (char *)NULL); } result = TCL_ERROR; break; diff --git a/generic/tclOO.c b/generic/tclOO.c index 9df5338..46d81c9 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -751,7 +751,7 @@ AllocObject( TclOOPrivateObjectCmd, PrivateNRObjectCmd, oPtr, MyDeleted); oPtr->myclassCommand = TclNRCreateCommandInNs(interp, "myclass", oPtr->namespacePtr, TclOOMyClassObjCmd, MyClassNRObjCmd, oPtr, - MyClassDeleted); + MyClassDeleted); return oPtr; } diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index ec70add..258c288 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -2377,10 +2377,10 @@ SetFsPathFromAny( if (transPtr == pathPtr) { (void)TclGetString(pathPtr); TclFreeInternalRep(pathPtr); - transPtr = Tcl_DuplicateObj(pathPtr); - fsPathPtr->filesystemEpoch = 0; + transPtr = Tcl_DuplicateObj(pathPtr); + fsPathPtr->filesystemEpoch = 0; } else { - fsPathPtr->filesystemEpoch = TclFSEpoch(); + fsPathPtr->filesystemEpoch = TclFSEpoch(); } Tcl_IncrRefCount(transPtr); fsPathPtr->translatedPathPtr = transPtr; @@ -2612,7 +2612,7 @@ MakeTildeRelativePath( const char *user, /* User name. NULL -> current user */ const char *subPath, /* Rest of path. May be NULL */ Tcl_DString *dsPtr) /* Output. Is initialized by the function. Must be - freed on success */ + freed on success */ { const char *dir; Tcl_DString dirString; @@ -2621,30 +2621,30 @@ MakeTildeRelativePath( Tcl_DStringInit(&dirString); if (user == NULL || user[0] == 0) { - /* No user name specified -> current user */ + /* No user name specified -> current user */ dir = TclGetEnv("HOME", &dirString); if (dir == NULL) { - if (interp) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "couldn't find HOME environment variable to" - " expand path", -1)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", - "HOMELESS", (char *)NULL); - } - return TCL_ERROR; - } + if (interp) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "couldn't find HOME environment variable to" + " expand path", -1)); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", + "HOMELESS", (char *)NULL); + } + return TCL_ERROR; + } } else { - /* User name specified - ~user */ + /* User name specified - ~user */ dir = TclpGetUserHome(user, &dirString); if (dir == NULL) { if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "user \"%s\" doesn't exist", user)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "NOUSER", - (char *)NULL); - } - return TCL_ERROR; + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "user \"%s\" doesn't exist", user)); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "NOUSER", + (char *)NULL); + } + return TCL_ERROR; } } if (subPath) { @@ -2730,20 +2730,20 @@ TclResolveTildePath( split = FindSplitPos(path, '/'); if (split == 1) { - /* No user name specified -> current user */ + /* No user name specified -> current user */ if (MakeTildeRelativePath( interp, NULL, path[1] ? 2 + path : NULL, &resolvedPath) != TCL_OK) { return NULL; } } else { - /* User name specified - ~user */ - const char *expandedUser; - Tcl_DString userName; + /* User name specified - ~user */ + const char *expandedUser; + Tcl_DString userName; - Tcl_DStringInit(&userName); - Tcl_DStringAppend(&userName, path+1, split-1); - expandedUser = Tcl_DStringValue(&userName); + Tcl_DStringInit(&userName); + Tcl_DStringAppend(&userName, path+1, split-1); + expandedUser = Tcl_DStringValue(&userName); /* path[split] is / or \0 */ if (MakeTildeRelativePath(interp, @@ -2795,29 +2795,29 @@ TclResolveTildePathList( const char *path; if (pathsObj == NULL) { - return NULL; + return NULL; } if (Tcl_ListObjGetElements(NULL, pathsObj, &objc, &objv) != TCL_OK) { - return NULL; /* Not a list */ + return NULL; /* Not a list */ } /* * Figure out if any paths need resolving to avoid unnecessary allocations. */ for (i = 0; i < objc; ++i) { - path = TclGetString(objv[i]); - if (path[0] == '~') { - break; /* At least one path needs resolution */ - } + path = TclGetString(objv[i]); + if (path[0] == '~') { + break; /* At least one path needs resolution */ + } } if (i == objc) { - return pathsObj; /* No paths needed to be resolved */ + return pathsObj; /* No paths needed to be resolved */ } resolvedPaths = Tcl_NewListObj(objc, NULL); for (i = 0; i < objc; ++i) { Tcl_Obj *resolvedPath; - path = TclGetString(objv[i]); + path = TclGetString(objv[i]); if (path[0] == 0) { continue; /* Skip empty strings */ } diff --git a/generic/tclResult.c b/generic/tclResult.c index 5497622..ece2634 100644 --- a/generic/tclResult.c +++ b/generic/tclResult.c @@ -387,9 +387,9 @@ Tcl_DiscardResult( if (statePtr->result == statePtr->appendResult) { ckfree(statePtr->appendResult); } else if (statePtr->freeProc == TCL_DYNAMIC) { - ckfree(statePtr->result); + ckfree(statePtr->result); } else if (statePtr->freeProc) { - statePtr->freeProc(statePtr->result); + statePtr->freeProc(statePtr->result); } } @@ -1299,7 +1299,7 @@ TclProcessReturn( iPtr->errorInfo = NULL; } Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORINFO], - &valuePtr); + &valuePtr); if (valuePtr != NULL) { (void) TclGetString(valuePtr); if (valuePtr->length) { @@ -1309,41 +1309,41 @@ TclProcessReturn( } } Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORSTACK], - &valuePtr); + &valuePtr); if (valuePtr != NULL) { - int len, valueObjc; - Tcl_Obj **valueObjv; - - if (Tcl_IsShared(iPtr->errorStack)) { - Tcl_Obj *newObj; - - newObj = Tcl_DuplicateObj(iPtr->errorStack); - Tcl_DecrRefCount(iPtr->errorStack); - Tcl_IncrRefCount(newObj); - iPtr->errorStack = newObj; - } - - /* - * List extraction done after duplication to avoid moving the rug - * if someone does [return -errorstack [info errorstack]] - */ - - if (TclListObjGetElements(interp, valuePtr, &valueObjc, - &valueObjv) == TCL_ERROR) { - return TCL_ERROR; - } - iPtr->resetErrorStack = 0; - TclListObjLength(interp, iPtr->errorStack, &len); - - /* - * Reset while keeping the list internalrep as much as possible. - */ - - Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, valueObjc, - valueObjv); + int len, valueObjc; + Tcl_Obj **valueObjv; + + if (Tcl_IsShared(iPtr->errorStack)) { + Tcl_Obj *newObj; + + newObj = Tcl_DuplicateObj(iPtr->errorStack); + Tcl_DecrRefCount(iPtr->errorStack); + Tcl_IncrRefCount(newObj); + iPtr->errorStack = newObj; + } + + /* + * List extraction done after duplication to avoid moving the rug + * if someone does [return -errorstack [info errorstack]] + */ + + if (TclListObjGetElements(interp, valuePtr, &valueObjc, + &valueObjv) == TCL_ERROR) { + return TCL_ERROR; + } + iPtr->resetErrorStack = 0; + TclListObjLength(interp, iPtr->errorStack, &len); + + /* + * Reset while keeping the list internalrep as much as possible. + */ + + Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, valueObjc, + valueObjv); } Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORCODE], - &valuePtr); + &valuePtr); if (valuePtr != NULL) { Tcl_SetObjErrorCode(interp, valuePtr); } else { @@ -1351,7 +1351,7 @@ TclProcessReturn( } Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORLINE], - &valuePtr); + &valuePtr); if (valuePtr != NULL) { TclGetIntFromObj(NULL, valuePtr, &iPtr->errorLine); } @@ -1424,8 +1424,8 @@ TclMergeReturnOptions( */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad %s value: expected dictionary but got \"%s\"", - compare, TclGetString(objv[1]))); + "bad %s value: expected dictionary but got \"%s\"", + compare, TclGetString(objv[1]))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_OPTIONS", (char *)NULL); goto error; @@ -1455,7 +1455,7 @@ TclMergeReturnOptions( Tcl_DictObjGet(NULL, returnOpts, keys[KEY_CODE], &valuePtr); if (valuePtr != NULL) { if (TclGetCompletionCodeFromObj(interp, valuePtr, - &code) == TCL_ERROR) { + &code) == TCL_ERROR) { goto error; } Tcl_DictObjRemove(NULL, returnOpts, keys[KEY_CODE]); @@ -1474,8 +1474,8 @@ TclMergeReturnOptions( */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad -level value: expected non-negative integer but got" - " \"%s\"", TclGetString(valuePtr))); + "bad -level value: expected non-negative integer but got" + " \"%s\"", TclGetString(valuePtr))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_LEVEL", (char *)NULL); goto error; } @@ -1496,8 +1496,8 @@ TclMergeReturnOptions( */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad -errorcode value: expected a list but got \"%s\"", - TclGetString(valuePtr))); + "bad -errorcode value: expected a list but got \"%s\"", + TclGetString(valuePtr))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_ERRORCODE", (char *)NULL); goto error; @@ -1518,24 +1518,24 @@ TclMergeReturnOptions( */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad -errorstack value: expected a list but got \"%s\"", - TclGetString(valuePtr))); + "bad -errorstack value: expected a list but got \"%s\"", + TclGetString(valuePtr))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "NONLIST_ERRORSTACK", - (char *)NULL); + (char *)NULL); goto error; } - if (length % 2) { - /* - * Errorstack must always be an even-sized list - */ + if (length % 2) { + /* + * Errorstack must always be an even-sized list + */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "forbidden odd-sized list for -errorstack: \"%s\"", + "forbidden odd-sized list for -errorstack: \"%s\"", TclGetString(valuePtr))); Tcl_SetErrorCode(interp, "TCL", "RESULT", - "ODDSIZEDLIST_ERRORSTACK", (char *)NULL); + "ODDSIZEDLIST_ERRORSTACK", (char *)NULL); goto error; - } + } } /* @@ -1615,7 +1615,7 @@ Tcl_GetReturnOptions( if (result == TCL_ERROR) { Tcl_AddErrorInfo(interp, ""); - Tcl_DictObjPut(NULL, options, keys[KEY_ERRORSTACK], iPtr->errorStack); + Tcl_DictObjPut(NULL, options, keys[KEY_ERRORSTACK], iPtr->errorStack); } if (iPtr->errorCode) { Tcl_DictObjPut(NULL, options, keys[KEY_ERRORCODE], iPtr->errorCode); @@ -1685,7 +1685,7 @@ Tcl_SetReturnOptions( if (TCL_ERROR == TclListObjGetElements(interp, options, &objc, &objv) || (objc % 2)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "expected dict but got \"%s\"", TclGetString(options))); + "expected dict but got \"%s\"", TclGetString(options))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_OPTIONS", (char *)NULL); code = TCL_ERROR; } else if (TCL_ERROR == TclMergeReturnOptions(interp, objc, objv, diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index b4da1a9..ebdae0e 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2896,12 +2896,18 @@ Tcl_AppendFormatToObj( TclNewObj(segment); allocSegment = 1; if (!Tcl_AttemptSetObjLength(segment, length)) { + if (allocSegment) { + Tcl_DecrRefCount(segment); + } msg = overflow; errCode = "OVERFLOW"; goto errorMsg; } bytes = TclGetString(segment); if (!Tcl_AttemptSetObjLength(segment, snprintf(bytes, segment->length, spec, d))) { + if (allocSegment) { + Tcl_DecrRefCount(segment); + } msg = overflow; errCode = "OVERFLOW"; goto errorMsg; diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index df4d2e3..26680d4 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -214,7 +214,7 @@ GetCache(void) if (cachePtr == NULL) { Tcl_Panic("alloc: could not allocate new cache"); } - memset(cachePtr, 0, sizeof(Cache)); + memset(cachePtr, 0, sizeof(Cache)); Tcl_MutexLock(listLockPtr); cachePtr->nextPtr = firstCachePtr; firstCachePtr = cachePtr; diff --git a/generic/tclTimer.c b/generic/tclTimer.c index d921854..3609d95 100644 --- a/generic/tclTimer.c +++ b/generic/tclTimer.c @@ -820,13 +820,13 @@ Tcl_AfterObjCmd( if (Tcl_GetWideIntFromObj(NULL, objv[1], &ms) != TCL_OK) { if (Tcl_GetIndexFromObj(NULL, objv[1], afterSubCmds, "", 0, &index) != TCL_OK) { - const char *arg = TclGetString(objv[1]); + const char *arg = TclGetString(objv[1]); Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad argument \"%s\": must be" - " cancel, idle, info, or an integer", arg)); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "argument", - arg, (char *)NULL); + "bad argument \"%s\": must be" + " cancel, idle, info, or an integer", arg)); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "argument", + arg, (char *)NULL); return TCL_ERROR; } } @@ -952,7 +952,7 @@ Tcl_AfterObjCmd( "after#%d", afterPtr->id)); } } - Tcl_SetObjResult(interp, resultObj); + Tcl_SetObjResult(interp, resultObj); return TCL_OK; } if (objc != 3) { @@ -961,11 +961,11 @@ Tcl_AfterObjCmd( } afterPtr = GetAfterEvent(assocPtr, objv[2]); if (afterPtr == NULL) { - const char *eventStr = TclGetString(objv[2]); + const char *eventStr = TclGetString(objv[2]); Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "event \"%s\" doesn't exist", eventStr)); - Tcl_SetErrorCode(interp, "TCL","LOOKUP","EVENT", eventStr, (char *)NULL); + "event \"%s\" doesn't exist", eventStr)); + Tcl_SetErrorCode(interp, "TCL","LOOKUP","EVENT", eventStr, (char *)NULL); return TCL_ERROR; } else { Tcl_Obj *resultListPtr; @@ -975,7 +975,7 @@ Tcl_AfterObjCmd( afterPtr->commandPtr); Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj( (afterPtr->token == NULL) ? "idle" : "timer", -1)); - Tcl_SetObjResult(interp, resultListPtr); + Tcl_SetObjResult(interp, resultListPtr); } break; default: @@ -1043,17 +1043,17 @@ AfterDelay( if (diff > TCL_TIME_MAXIMUM_SLICE) { diff = TCL_TIME_MAXIMUM_SLICE; } - if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) { - diff = 1; - } + if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) { + diff = 1; + } if (diff > 0) { Tcl_Sleep((long) diff); - if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) { - break; - } + if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) { + break; + } } else { - break; - } + break; + } } else { diff = TCL_TIME_DIFF_MS(iPtr->limit.time, now); if (diff > TCL_TIME_MAXIMUM_SLICE) { diff --git a/generic/tclTrace.c b/generic/tclTrace.c index 733685a..f169de6 100644 --- a/generic/tclTrace.c +++ b/generic/tclTrace.c @@ -1276,7 +1276,7 @@ Tcl_UntraceCommand( cmdPtr->flags &= ~CMD_HAS_EXEC_TRACES; - /* + /* * Bug 3484621: up the interp's epoch if this is a BC'ed command */ diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 0119243..4571baf 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3510,10 +3510,10 @@ TclNeedSpace( end = Tcl_UtfPrev(end, start); while (*end == '{') { - if (end == start) { - return 0; - } - end = Tcl_UtfPrev(end, start); + if (end == start) { + return 0; + } + end = Tcl_UtfPrev(end, start); } * @@ -3522,7 +3522,7 @@ TclNeedSpace( while ((--end >= start) && (*end == '{')) { } if (end < start) { - return 0; + return 0; } /* @@ -3644,9 +3644,9 @@ GetWideForIndex( Tcl_Obj *objPtr, /* Points to the value to be parsed */ Tcl_WideInt endValue, /* The value to be stored at *widePtr if * objPtr holds "end". - * NOTE: this value may be TCL_INDEX_NONE. */ + * NOTE: this value may be TCL_INDEX_NONE. */ Tcl_WideInt *widePtr) /* Location filled in with a wide integer - * representing an index. */ + * representing an index. */ { int numType; void *cd; @@ -3771,9 +3771,9 @@ GetEndOffsetFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, /* Pointer to the object to parse */ Tcl_WideInt endValue, /* The value to be stored at "widePtr" if - * "objPtr" holds "end". */ + * "objPtr" holds "end". */ Tcl_WideInt *widePtr) /* Location filled in with an integer - * representing an index. */ + * representing an index. */ { Tcl_ObjInternalRep *irPtr; Tcl_WideInt offset = -1; /* Offset in the "end-offset" expression - 1 */ @@ -3807,14 +3807,14 @@ GetEndOffsetFromObj( if ((TclMaxListLength(bytes, TCL_INDEX_NONE, NULL) > 1) /* If it's possible, do the full list parse. */ - && (TCL_OK == TclListObjLength(NULL, objPtr, &length)) - && (length > 1)) { - goto parseError; + && (TCL_OK == TclListObjLength(NULL, objPtr, &length)) + && (length > 1)) { + goto parseError; } /* Passed the list screen, so parse for index arithmetic expression */ if (TCL_OK == TclParseNumber(NULL, objPtr, NULL, NULL, TCL_INDEX_NONE, &opPtr, - TCL_PARSE_INTEGER_ONLY)) { + TCL_PARSE_INTEGER_ONLY)) { Tcl_WideInt w1=0, w2=0; /* value starts with valid integer... */ @@ -3987,15 +3987,15 @@ GetEndOffsetFromObj( /* Report a parse error. */ parseError: if (interp != NULL) { - char * bytes = TclGetString(objPtr); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad index \"%s\": must be integer?[+-]integer? or" - " end?[+-]integer?", bytes)); - if (!strncmp(bytes, "end-", 4)) { - bytes += 4; - } - TclCheckBadOctal(interp, bytes); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", (char *)NULL); + char * bytes = TclGetString(objPtr); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad index \"%s\": must be integer?[+-]integer? or" + " end?[+-]integer?", bytes)); + if (!strncmp(bytes, "end-", 4)) { + bytes += 4; + } + TclCheckBadOctal(interp, bytes); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", (char *)NULL); } return TCL_ERROR; diff --git a/generic/tclVar.c b/generic/tclVar.c index 8deb2b7..d2922ec 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -6869,13 +6869,13 @@ SetArrayDefault( */ if (tablePtr->defaultObj) { - Tcl_DecrRefCount(tablePtr->defaultObj); - Tcl_DecrRefCount(tablePtr->defaultObj); + Tcl_DecrRefCount(tablePtr->defaultObj); + Tcl_DecrRefCount(tablePtr->defaultObj); } tablePtr->defaultObj = defaultObj; if (tablePtr->defaultObj) { - Tcl_IncrRefCount(tablePtr->defaultObj); - Tcl_IncrRefCount(tablePtr->defaultObj); + Tcl_IncrRefCount(tablePtr->defaultObj); + Tcl_IncrRefCount(tablePtr->defaultObj); } } diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 2eb90a5..c288b3f 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -1675,7 +1675,7 @@ ZipFSOpenArchive( ZIPFS_POSIX_ERROR(interp, "seek error"); goto error; } - /* What's the magic about 64 * 1024 * 1024 ? */ + /* What's the magic about 64 * 1024 * 1024 ? */ if ((zf->length <= ZIP_CENTRAL_END_LEN) || (zf->length - ZIP_CENTRAL_END_LEN) > (64 * 1024 * 1024 - ZIP_CENTRAL_END_LEN)) { @@ -6238,8 +6238,8 @@ TclZipfs_Init( "proc ::tcl::zipfs::Find dir {\n" " set result {}\n" " if {[catch {\n" - " concat [glob -directory $dir -nocomplain *] [glob -directory $dir -types hidden -nocomplain *]\n" - " } list]} {\n" + " concat [glob -directory $dir -nocomplain *] [glob -directory $dir -types hidden -nocomplain *]\n" + " } list]} {\n" " return $result\n" " }\n" " foreach file $list {\n" diff --git a/tests/clock.test b/tests/clock.test index 1b70c04..76155b5 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -37265,7 +37265,7 @@ test clock-46.16-pos-fmt2 {scan with format: validation rules: valid day of week 0 946728000 0 946814400 0 946900800 0 946987200 0 947073600 0 947160000 0 947246400 \ 0 946641600 0 946728000 0 946814400 0 946900800 0 946987200 0 947073600 0 947160000 \ ] -test clock-46.16-pos-fmt2 {scan with format: validation rules: valid day of week (must work for all weekdays)} \ +test clock-46.16-pos-fmt3 {scan with format: validation rules: valid day of week (must work for all weekdays)} \ -body { _invalid_test {:GMT -12:00 +12:00} {-format "%w, %d %b %Y %H:%M:%S"} {6, 01 Jan 2000 00:00:00} {0, 02 Jan 2000 00:00:00} {1, 03 Jan 2000 00:00:00} {2, 04 Jan 2000 00:00:00} {3, 05 Jan 2000 00:00:00} {4, 06 Jan 2000 00:00:00} {5, 07 Jan 2000 00:00:00} } -result [list \ diff --git a/tests/info.test b/tests/info.test index e08d6d9..19978b0 100644 --- a/tests/info.test +++ b/tests/info.test @@ -2619,6 +2619,15 @@ test info-41.0 {Bug 0de6c1d79c crash} -setup { unset -nocomplain msg } -result {1 {type precompiled} {type precompiled} 1 {bad level "-1"} 1 {bad level "2"}} +test info-41.1 {Bug 0de6c1d79c crash} -setup { + interp create child + child hide info +} -cleanup { + interp delete child +} -body { + child invokehidden info frame +} -result 1 + # cleanup catch {namespace delete test_ns_info1 test_ns_info2} ::tcltest::cleanupTests diff --git a/tests/zipfs.test b/tests/zipfs.test index 9571d36..b988898 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -1945,11 +1945,12 @@ namespace eval test_ns_zipfs { set basename bug-7d5f1c1308 set mt //zipfs:/$basename-mt set zipfile $basename.zip - set dir [tcltest::makeDirectory $basename] + set dir [makeDirectory $basename] close [open [file join $dir .ext] w] } -cleanup { zipfs unmount $mt file delete $zipfile + removeDirectory $basename } -body { zipfs mkzip $zipfile $dir [file dirname $dir] zipfs mount $zipfile $mt diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c index be1d422..e3311a3 100644 --- a/unix/tclUnixPipe.c +++ b/unix/tclUnixPipe.c @@ -419,8 +419,8 @@ TclpCreateProcess( TclFile errPipeIn, errPipeOut; int count, status, fd; char errSpace[200 + TCL_INTEGER_SPACE]; - Tcl_DString *dsArray; - char **newArgv; + Tcl_DString *volatile dsArray; + char **volatile newArgv; int pid; int i; #if defined(HAVE_POSIX_SPAWNP) -- cgit v0.12 From e92ac699c1a4fc8683a61f855f5250c72d12b1c1 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 5 Aug 2024 22:48:31 +0000 Subject: add/document the zlib command to the set of commands in a safe interpreter --- doc/interp.n | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/interp.n b/doc/interp.n index 1127632..42b1e08 100644 --- a/doc/interp.n +++ b/doc/interp.n @@ -605,6 +605,7 @@ built-in commands: \fBtell\fR \fBtime\fR \fBtrace\fR \fBunset\fR \fBupdate\fR \fBuplevel\fR \fBupvar\fR \fBvariable\fR \fBvwait\fR \fBwhile\fR +\fBzlib\fR .DE The following commands are hidden by \fBinterp create\fR when it creates a safe interpreter: -- cgit v0.12 From 207f5c59fd19d2c2b3b0a1e8c8283136087e6779 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 6 Aug 2024 08:17:01 +0000 Subject: Tidy up the icu tests and (very basic) error case checks --- tests/icu.test | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/tests/icu.test b/tests/icu.test index 3c07995..eabe3df 100644 --- a/tests/icu.test +++ b/tests/icu.test @@ -10,45 +10,50 @@ catch {::tcl::unsupported::icu} testConstraint icu [llength [info commands ::tcl::unsupported::icu::detect]] namespace eval icu { + namespace path {::tcl::unsupported ::tcl::mathop} + test icu-detect-0 {Return list of ICU encodings} -constraints icu -body { - set encoders [::tcl::unsupported::icu detect] - list [::tcl::mathop::in UTF-8 $encoders] \ - [::tcl::mathop::in ISO-8859-1 $encoders] + set encoders [icu detect] + list [in UTF-8 $encoders] [in ISO-8859-1 $encoders] } -result {1 1} - test icu-detect-1 {Guess encoding} -constraints icu -body { - ::tcl::unsupported::icu detect [readFile [info script]] + icu detect [readFile [info script]] } -result ISO-8859-1 - test icu-detect-2 {Get all possible encodings} -constraints icu -body { - set encodings [::tcl::unsupported::icu detect [readFile [info script]] -all] - list [::tcl::mathop::in UTF-8 $encodings] \ - [::tcl::mathop::in ISO-8859-1 $encodings] + set encodings [icu detect [readFile [info script]] -all] + list [in UTF-8 $encodings] [in ISO-8859-1 $encodings] } -result {1 1} + test icu-detect-3 {error case} -constraints icu -returnCodes error -body { + icu detect gorp gorp gorp + } -result {wrong # args: should be "icu detect ?bytes ?-all??"} test icu-tclToIcu-0 {Map Tcl encoding} -constraints icu -body { # tis-620 because it is ambiguous in ICU on some platforms # but should return the preferred encoding - list [::tcl::unsupported::icu tclToIcu utf-8] \ - [::tcl::unsupported::icu tclToIcu tis-620] \ - [::tcl::unsupported::icu tclToIcu shiftjis] + lmap enc {utf-8 tis-620 shiftjis} { + icu tclToIcu $enc + } } -result {UTF-8 TIS-620 ibm-943_P15A-2003} - test icu-tclToIcu-1 {Map Tcl encoding - no map} -constraints icu -body { # Should not raise an error - ::tcl::unsupported::icu tclToIcu dummy + icu tclToIcu dummy } -result {} + test icu-tclToIcu-2 {error case} -constraints icu -returnCodes error -body { + icu tclToIcu gorp gorp + } -result {wrong # args: should be "icu tclToIcu tclName"} test icu-icuToTcl-0 {Map ICU encoding} -constraints icu -body { - list [::tcl::unsupported::icu icuToTcl UTF-8] \ - [::tcl::unsupported::icu icuToTcl TIS-620] \ - [::tcl::unsupported::icu icuToTcl ibm-943_P15A-2003] + lmap enc {UTF-8 TIS-620 ibm-943_P15A-2003} { + icu icuToTcl $enc + } } -result {utf-8 tis-620 cp932} - test icu-icuToTcl-1 {Map ICU encoding - no map} -constraints icu -body { # Should not raise an error - ::tcl::unsupported::icu icuToTcl dummy + icu icuToTcl dummy } -result {} + test icu-icuToTcl-2 {error case} -constraints icu -returnCodes error -body { + icu icuToTcl gorp gorp + } -result {wrong # args: should be "icu icuToTcl icuName"} } namespace delete icu -- cgit v0.12 From 07cc6662489f0e09786858c43f6012e6a8b7ef6c Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 6 Aug 2024 09:11:41 +0000 Subject: Fix some indentation --- generic/tclInt.h | 19 +++++++------- generic/tclVar.c | 80 ++++++++++++++++++++++++++++---------------------------- 2 files changed, 50 insertions(+), 49 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 69e1166..d397879 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -1601,10 +1601,10 @@ typedef struct ExecStack { * restored into the interpreter to be used. */ typedef struct CorContext { - struct CallFrame *framePtr; /* See Interp.framePtr */ - struct CallFrame *varFramePtr; /* See Interp.varFramePtr */ - struct CmdFrame *cmdFramePtr; /* See Interp.cmdFramePtr */ - Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ + CallFrame *framePtr; /* See Interp.framePtr */ + CallFrame *varFramePtr; /* See Interp.varFramePtr */ + CmdFrame *cmdFramePtr; /* See Interp.cmdFramePtr */ + Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ } CorContext; /* @@ -2929,9 +2929,11 @@ typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, Tcl_Encoding *encodingPtr); #ifdef _WIN32 -# define TCLFSENCODING tclUtf8Encoding /* On Windows, all Unicode (except surrogates) are valid */ +/* On Windows, all Unicode (except surrogates) are valid. */ +# define TCLFSENCODING tclUtf8Encoding #else -# define TCLFSENCODING NULL /* On Non-Windows, use the system encoding for validation checks */ +/* On Non-Windows, use the system encoding for validation checks. */ +# define TCLFSENCODING NULL #endif /* @@ -3008,7 +3010,6 @@ typedef struct ProcessGlobalValue { * examples. Best to use those functions. Direct use of TclUpsizeAlloc / * TclResizeAlloc is needed in special cases such as when total size of * memory block is limited to less than TCL_SIZE_MAX. - * *---------------------------------------------------------------------- */ @@ -3324,7 +3325,7 @@ MODULE_SCOPE int TclCheckEmptyString(Tcl_Obj *objPtr); MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp, Tcl_Channel chan); MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd; -MODULE_SCOPE int TclChanIsBinary(Tcl_Channel chan); +MODULE_SCOPE int TclChanIsBinary(Tcl_Channel chan); MODULE_SCOPE Tcl_NRPostProc TclClearRootEnsemble; MODULE_SCOPE int TclCompareTwoNumbers(Tcl_Obj *valuePtr, Tcl_Obj *value2Ptr); @@ -4128,7 +4129,7 @@ MODULE_SCOPE void TclProcessCreated(Tcl_Pid pid); MODULE_SCOPE TclProcessWaitStatus TclProcessWait(Tcl_Pid pid, int options, int *codePtr, Tcl_Obj **msgObjPtr, Tcl_Obj **errorObjPtr); -MODULE_SCOPE int TclClose(Tcl_Interp *, Tcl_Channel chan); +MODULE_SCOPE int TclClose(Tcl_Interp *, Tcl_Channel chan); /* * TIP #508: [array default] diff --git a/generic/tclVar.c b/generic/tclVar.c index e939797..74647ee 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -212,7 +212,7 @@ static void UnsetVarStruct(Var *varPtr, Var *arrayPtr, * TIP #508: [array default] */ -static Tcl_ObjCmdProc ArrayDefaultCmd; +static Tcl_ObjCmdProc ArrayDefaultCmd; static void DeleteArrayVar(Var *arrayPtr); static void SetArrayDefault(Var *arrayPtr, Tcl_Obj *defaultObj); @@ -252,7 +252,7 @@ static const Tcl_ObjType localVarNameType = { TCL_OBJTYPE_V0 }; -#define LocalSetInternalRep(objPtr, index, namePtr) \ +#define LocalSetInternalRep(objPtr, index, namePtr) \ do { \ Tcl_ObjInternalRep ir; \ Tcl_Obj *ptr = (namePtr); \ @@ -262,12 +262,12 @@ static const Tcl_ObjType localVarNameType = { Tcl_StoreInternalRep((objPtr), &localVarNameType, &ir); \ } while (0) -#define LocalGetInternalRep(objPtr, index, name) \ +#define LocalGetInternalRep(objPtr, index, name) \ do { \ - const Tcl_ObjInternalRep *irPtr; \ - irPtr = TclFetchInternalRep((objPtr), &localVarNameType); \ - (name) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr1 : NULL; \ - (index) = irPtr ? PTR2INT(irPtr->twoPtrValue.ptr2) : TCL_INDEX_NONE; \ + const Tcl_ObjInternalRep *irPtr; \ + irPtr = TclFetchInternalRep((objPtr), &localVarNameType); \ + (name) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr1 : NULL; \ + (index) = irPtr ? PTR2INT(irPtr->twoPtrValue.ptr2) : TCL_INDEX_NONE; \ } while (0) static const Tcl_ObjType parsedVarNameType = { @@ -276,7 +276,7 @@ static const Tcl_ObjType parsedVarNameType = { TCL_OBJTYPE_V0 }; -#define ParsedSetInternalRep(objPtr, arrayPtr, elem) \ +#define ParsedSetInternalRep(objPtr, arrayPtr, elem) \ do { \ Tcl_ObjInternalRep ir; \ Tcl_Obj *ptr1 = (arrayPtr); \ @@ -285,16 +285,16 @@ static const Tcl_ObjType parsedVarNameType = { if (ptr2) {Tcl_IncrRefCount(ptr2);} \ ir.twoPtrValue.ptr1 = ptr1; \ ir.twoPtrValue.ptr2 = ptr2; \ - Tcl_StoreInternalRep((objPtr), &parsedVarNameType, &ir); \ + Tcl_StoreInternalRep((objPtr), &parsedVarNameType, &ir); \ } while (0) -#define ParsedGetInternalRep(objPtr, parsed, array, elem) \ +#define ParsedGetInternalRep(objPtr, parsed, array, elem) \ do { \ - const Tcl_ObjInternalRep *irPtr; \ - irPtr = TclFetchInternalRep((objPtr), &parsedVarNameType); \ + const Tcl_ObjInternalRep *irPtr; \ + irPtr = TclFetchInternalRep((objPtr), &parsedVarNameType); \ (parsed) = (irPtr != NULL); \ - (array) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr1 : NULL; \ - (elem) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr2 : NULL; \ + (array) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr1 : NULL; \ + (elem) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr2 : NULL; \ } while (0) Var * @@ -531,7 +531,7 @@ TclLookupVar( Var * TclObjLookupVar( Tcl_Interp *interp, /* Interpreter to use for lookup. */ - Tcl_Obj *part1Ptr, /* If part2 isn't NULL, this is the name of an + Tcl_Obj *part1Ptr, /* If part2 isn't NULL, this is the name of an * array. Otherwise, this is a full variable * name that could include a parenthesized * array element. */ @@ -541,10 +541,10 @@ TclObjLookupVar( const char *msg, /* Verb to use in error messages, e.g. "read" * or "set". Only needed if TCL_LEAVE_ERR_MSG * is set in flags. */ - int createPart1, /* If 1, create hash table entry for part 1 of + int createPart1, /* If 1, create hash table entry for part 1 of * name, if it doesn't already exist. If 0, * return error if it doesn't exist. */ - int createPart2, /* If 1, create hash table entry for part 2 of + int createPart2, /* If 1, create hash table entry for part 2 of * name, if it doesn't already exist. If 0, * return error if it doesn't exist. */ Var **arrayPtrPtr) /* If the name refers to an element of an @@ -591,10 +591,10 @@ TclObjLookupVarEx( const char *msg, /* Verb to use in error messages, e.g. "read" * or "set". Only needed if TCL_LEAVE_ERR_MSG * is set in flags. */ - int createPart1, /* If 1, create hash table entry for part 1 of + int createPart1, /* If 1, create hash table entry for part 1 of * name, if it doesn't already exist. If 0, * return error if it doesn't exist. */ - int createPart2, /* If 1, create hash table entry for part 2 of + int createPart2, /* If 1, create hash table entry for part 2 of * name, if it doesn't already exist. If 0, * return error if it doesn't exist. */ Var **arrayPtrPtr) /* If the name refers to an element of an @@ -827,7 +827,7 @@ TclLookupSimpleVar( int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_AVOID_RESOLVERS and TCL_LEAVE_ERR_MSG * bits matter. */ - int create, /* If 1, create hash table entry for varname, + int create, /* If 1, create hash table entry for varname, * if it doesn't already exist. If 0, return * error if it doesn't exist. */ const char **errMsgPtr, @@ -1060,15 +1060,15 @@ TclLookupArrayElement( Tcl_Obj *arrayNamePtr, /* This is the name of the array, or NULL if * index>= 0. */ Tcl_Obj *elNamePtr, /* Name of element within array. */ - int flags, /* Only TCL_LEAVE_ERR_MSG bit matters. */ + int flags, /* Only TCL_LEAVE_ERR_MSG bit matters. */ const char *msg, /* Verb to use in error messages, e.g. "read" * or "set". Only needed if TCL_LEAVE_ERR_MSG * is set in flags. */ - int createArray, /* If 1, transform arrayName to be an array if + int createArray, /* If 1, transform arrayName to be an array if * it isn't one yet and the transformation is * possible. If 0, return error if it isn't * already an array. */ - int createElem, /* If 1, create hash table entry for the + int createElem, /* If 1, create hash table entry for the * element, if it doesn't already exist. If 0, * return error if it doesn't exist. */ Var *arrayPtr, /* Pointer to the array's Var structure. */ @@ -1277,10 +1277,10 @@ Tcl_Obj * Tcl_ObjGetVar2( Tcl_Interp *interp, /* Command interpreter in which variable is to * be looked up. */ - Tcl_Obj *part1Ptr, /* Points to an object holding the name of an + Tcl_Obj *part1Ptr, /* Points to an object holding the name of an * array (if part2 is non-NULL) or the name of * a variable. */ - Tcl_Obj *part2Ptr, /* If non-null, points to an object holding + Tcl_Obj *part2Ptr, /* If non-null, points to an object holding * the name of an element in the array * part1Ptr. */ int flags) /* OR-ed combination of TCL_GLOBAL_ONLY and @@ -1336,7 +1336,7 @@ TclPtrGetVar( * the name of a variable. */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ - int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and + int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ { if (varPtr == NULL) { @@ -1375,14 +1375,14 @@ Tcl_Obj * TclPtrGetVarIdx( Tcl_Interp *interp, /* Command interpreter in which variable is to * be looked up. */ - Var *varPtr, /* The variable to be read.*/ + Var *varPtr, /* The variable to be read.*/ Var *arrayPtr, /* NULL for scalar variables, pointer to the * containing array otherwise. */ Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or * the name of a variable. */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ - int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and + int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ int index) /* Index into the local variable table of the * variable, or -1. Only used when part1Ptr is @@ -1483,7 +1483,7 @@ TclPtrGetVarIdx( int Tcl_SetObjCmd( TCL_UNUSED(void *), - Tcl_Interp *interp,/* Current interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { @@ -1660,10 +1660,10 @@ Tcl_Obj * Tcl_ObjSetVar2( Tcl_Interp *interp, /* Command interpreter in which variable is to * be found. */ - Tcl_Obj *part1Ptr, /* Points to an object holding the name of an + Tcl_Obj *part1Ptr, /* Points to an object holding the name of an * array (if part2 is non-NULL) or the name of * a variable. */ - Tcl_Obj *part2Ptr, /* If non-NULL, points to an object holding + Tcl_Obj *part2Ptr, /* If non-NULL, points to an object holding * the name of an element in the array * part1Ptr. */ Tcl_Obj *newValuePtr, /* New value for variable. */ @@ -1731,7 +1731,7 @@ TclPtrSetVar( Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ Tcl_Obj *newValuePtr, /* New value for variable. */ - int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and + int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ { if (varPtr == NULL) { @@ -1900,7 +1900,7 @@ Tcl_Obj * TclPtrSetVarIdx( Tcl_Interp *interp, /* Command interpreter in which variable is to * be looked up. */ - Var *varPtr, /* Reference to the variable to set. */ + Var *varPtr, /* Reference to the variable to set. */ Var *arrayPtr, /* Reference to the array containing the * variable, or NULL if the variable is a * scalar. */ @@ -1910,7 +1910,7 @@ TclPtrSetVarIdx( Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ Tcl_Obj *newValuePtr, /* New value for variable. */ - int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and + int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ int index) /* Index of local var where part1 is to be * found. */ @@ -2169,7 +2169,7 @@ TclPtrIncrObjVar( * part1Ptr. */ Tcl_Obj *incrPtr, /* Increment value. */ /* TODO: Which of these flag values really make sense? */ - int flags) /* Various flags that tell how to incr value: + int flags) /* Various flags that tell how to incr value: * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_APPEND_VALUE, TCL_LIST_ELEMENT, * TCL_LEAVE_ERR_MSG. */ @@ -2225,7 +2225,7 @@ TclPtrIncrObjVarIdx( * part1Ptr. */ Tcl_Obj *incrPtr, /* Increment value. */ /* TODO: Which of these flag values really make sense? */ - int flags, /* Various flags that tell how to incr value: + int flags, /* Various flags that tell how to incr value: * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_APPEND_VALUE, TCL_LIST_ELEMENT, * TCL_LEAVE_ERR_MSG. */ @@ -2414,7 +2414,7 @@ TclPtrUnsetVar( * the name of a variable. */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ - int flags) /* OR-ed combination of any of + int flags) /* OR-ed combination of any of * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_LEAVE_ERR_MSG. */ { @@ -4480,7 +4480,7 @@ ObjMakeUpvar( * NULL means use global :: context. */ Tcl_Obj *otherP1Ptr, const char *otherP2, /* Two-part name of variable in framePtr. */ - int otherFlags, /* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY: + int otherFlags, /* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY: * indicates scope of "other" variable. */ Tcl_Obj *myNamePtr, /* Name of variable which will refer to * otherP1/otherP2. Must be a scalar. */ @@ -5337,7 +5337,7 @@ ParseSearchId( static void DeleteSearches( Interp *iPtr, - Var *arrayVarPtr) /* Variable whose searches are to be + Var *arrayVarPtr) /* Variable whose searches are to be * deleted. */ { ArraySearch *searchPtr, *nextPtr; @@ -6766,7 +6766,7 @@ FreeVarEntry( static int CompareVarKeys( - void *keyPtr, /* New key to compare. */ + void *keyPtr, /* New key to compare. */ Tcl_HashEntry *hPtr) /* Existing key to compare. */ { Tcl_Obj *objPtr1 = (Tcl_Obj *)keyPtr; -- cgit v0.12 From f857387af95ad458000186bb3b796d5998e7de72 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 6 Aug 2024 09:14:24 +0000 Subject: Remove unwanted change --- generic/tclInt.h | 1 - 1 file changed, 1 deletion(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index e153aa8..d397879 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3004,7 +3004,6 @@ typedef struct ProcessGlobalValue { /* *---------------------------------------------------------------------- - * * Common functions for calculating overallocation. Trivial but allows for * experimenting with growth factors without having to change code in * multiple places. See TclAttemptAllocElemsEx and similar for usage -- cgit v0.12 From 47f0695e3b9b2a99a9516c80d0b4353af88318e8 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 6 Aug 2024 13:15:45 +0000 Subject: fix build --- generic/tclOO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index edee7af..461fc54 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -691,7 +691,7 @@ AllocObject( * Couldn't make the specific namespace. Report as an error. * [Bug 154f0982f2] */ - ckfree(oPtr); + Tcl_Free(oPtr); return NULL; } creationEpoch = ++fPtr->tsdPtr->nsCount; -- cgit v0.12 From 6d389fbb997d7a59de6e12193ddfdbc282557011 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 6 Aug 2024 19:47:04 +0000 Subject: Clean up of the ICU code and tests --- generic/tclIcu.c | 35 +++++++++++++++++++++++++---------- tests/icu.test | 49 +++++++++++++++++++++++++++++-------------------- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/generic/tclIcu.c b/generic/tclIcu.c index b6355ee..dd7e82f 100644 --- a/generic/tclIcu.c +++ b/generic/tclIcu.c @@ -577,11 +577,19 @@ TclIcuInit( } #endif -#define ICUUC_SYM(name) \ - strcpy(symbol, #name ); \ - strcat(symbol, icuversion); \ - icu_fns._##name = (fn_ ## name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol) + /* Try for symbol without version (Windows, FreeBSD), then with version */ +#define ICUUC_SYM(name) \ + do { \ + strcpy(symbol, #name); \ + icu_fns._##name = \ + (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ + if (icu_fns._##name == NULL) { \ + strcat(symbol, icuversion); \ + icu_fns._##name = \ + (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ + } \ + } while (0) + if (icu_fns.libs[0] != NULL) { ICUUC_SYM(u_cleanup); ICUUC_SYM(u_errorName); @@ -606,11 +614,18 @@ TclIcuInit( #undef ICUUC_SYM } -#define ICUIN_SYM(name) \ - strcpy(symbol, #name ); \ - strcat(symbol, icuversion); \ - icu_fns._##name = (fn_ ## name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol) +#define ICUIN_SYM(name) \ + do { \ + strcpy(symbol, #name); \ + icu_fns._##name = \ + (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ + if (icu_fns._##name == NULL) { \ + strcat(symbol, icuversion); \ + icu_fns._##name = \ + (fn_##name)Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ + } \ + } while (0) + if (icu_fns.libs[1] != NULL) { ICUIN_SYM(ucsdet_close); ICUIN_SYM(ucsdet_detect); diff --git a/tests/icu.test b/tests/icu.test index 522ed53..eabe3df 100644 --- a/tests/icu.test +++ b/tests/icu.test @@ -7,45 +7,54 @@ if {"::tcltest" ni [namespace children]} { # Force late loading of ICU if present catch {::tcl::unsupported::icu} -testConstraint icu [expr {[info commands ::tcl::unsupported::icu::detect] ne ""}] +testConstraint icu [llength [info commands ::tcl::unsupported::icu::detect]] namespace eval icu { + namespace path {::tcl::unsupported ::tcl::mathop} + test icu-detect-0 {Return list of ICU encodings} -constraints icu -body { - set encoders [::tcl::unsupported::icu detect] - list [::tcl::mathop::in UTF-8 $encoders] [::tcl::mathop::in ISO-8859-1 $encoders] + set encoders [icu detect] + list [in UTF-8 $encoders] [in ISO-8859-1 $encoders] } -result {1 1} - test icu-detect-1 {Guess encoding} -constraints icu -body { - ::tcl::unsupported::icu detect [readFile [info script]] + icu detect [readFile [info script]] } -result ISO-8859-1 - test icu-detect-2 {Get all possible encodings} -constraints icu -body { - set encodings [::tcl::unsupported::icu detect [readFile [info script]] -all] - list [::tcl::mathop::in UTF-8 $encodings] [::tcl::mathop::in ISO-8859-1 $encodings] + set encodings [icu detect [readFile [info script]] -all] + list [in UTF-8 $encodings] [in ISO-8859-1 $encodings] } -result {1 1} + test icu-detect-3 {error case} -constraints icu -returnCodes error -body { + icu detect gorp gorp gorp + } -result {wrong # args: should be "icu detect ?bytes ?-all??"} test icu-tclToIcu-0 {Map Tcl encoding} -constraints icu -body { - # tis-620 because it is ambiguous in ICU on some platforms - # but should return the preferred encoding - list [::tcl::unsupported::icu tclToIcu utf-8] [::tcl::unsupported::icu tclToIcu tis-620] [::tcl::unsupported::icu tclToIcu shiftjis] + # tis-620 because it is ambiguous in ICU on some platforms + # but should return the preferred encoding + lmap enc {utf-8 tis-620 shiftjis} { + icu tclToIcu $enc + } } -result {UTF-8 TIS-620 ibm-943_P15A-2003} - test icu-tclToIcu-1 {Map Tcl encoding - no map} -constraints icu -body { - # Should not raise an error - ::tcl::unsupported::icu tclToIcu dummy + # Should not raise an error + icu tclToIcu dummy } -result {} + test icu-tclToIcu-2 {error case} -constraints icu -returnCodes error -body { + icu tclToIcu gorp gorp + } -result {wrong # args: should be "icu tclToIcu tclName"} test icu-icuToTcl-0 {Map ICU encoding} -constraints icu -body { - list [::tcl::unsupported::icu icuToTcl UTF-8] [::tcl::unsupported::icu icuToTcl TIS-620] [::tcl::unsupported::icu icuToTcl ibm-943_P15A-2003] + lmap enc {UTF-8 TIS-620 ibm-943_P15A-2003} { + icu icuToTcl $enc + } } -result {utf-8 tis-620 cp932} - test icu-icuToTcl-1 {Map ICU encoding - no map} -constraints icu -body { - # Should not raise an error - ::tcl::unsupported::icu icuToTcl dummy + # Should not raise an error + icu icuToTcl dummy } -result {} - + test icu-icuToTcl-2 {error case} -constraints icu -returnCodes error -body { + icu icuToTcl gorp gorp + } -result {wrong # args: should be "icu icuToTcl icuName"} } - namespace delete icu ::tcltest::cleanupTests -- cgit v0.12 From 0125c7b6961b58037fea9d0e9502c4b66dc3b96e Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 6 Aug 2024 21:01:05 +0000 Subject: Make varname method handle array elements better. [2da1cb0c80] --- generic/tclOOBasic.c | 22 +++++++++++++++------- tests/oo.test | 11 +++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 1506a34..3d24636 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -856,7 +856,19 @@ TclOO_Object_VarName( /* * The variable reference must not disappear too soon. [Bug 74b6110204] */ - TclSetVarNamespaceVar((Var *) varPtr); + if (!TclIsVarArrayElement((Var *) varPtr)) { + TclSetVarNamespaceVar((Var *) varPtr); + } + + /* + * If the varPtr points to an element of an array but we don't already + * have the array, find it now. Note that this can't be easily backported; + * the arrayPtr field is new in Tcl 9.0. [Bug 2da1cb0c80] + */ + + if (aryVar == NULL && TclIsVarArrayElement((Var *) varPtr)) { + aryVar = (Tcl_Var) TclVarParentArray(varPtr); + } /* * Now that we've pinned down what variable we're really talking about @@ -864,15 +876,11 @@ TclOO_Object_VarName( */ TclNewObj(varNamePtr); + if (aryVar != NULL) { Tcl_GetVariableFullName(interp, aryVar, varNamePtr); - - /* - * WARNING! This code pokes inside the implementation of hash tables! - */ - Tcl_AppendPrintfToObj(varNamePtr, "(%s)", Tcl_GetString( - ((VarInHash *) varPtr)->entry.key.objPtr)); + VarHashGetKey(varPtr))); } else { Tcl_GetVariableFullName(interp, varPtr, varNamePtr); } diff --git a/tests/oo.test b/tests/oo.test index 55352c0..c5ad866 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -3116,6 +3116,17 @@ test oo-19.4 {OO: varname ghosts [Bug 74b6110204]} -setup { } -cleanup { testClass destroy } -result {::testoo19_4::foo 0 ::testoo19_4::foo} +test oo-19.5 {OO: varname array elements [Bug 2da1cb0c80]} -setup { + set obj [oo::object new] + oo::objdefine $obj export eval varname +} -body { + $obj eval { + namespace upvar :: tcl_platform(platform) foo + } + $obj varname foo +} -cleanup { + $obj destroy +} -result ::tcl_platform(platform) test oo-20.1 {OO: variable method} -body { oo::class create testClass { -- cgit v0.12 From 2e730cf19d436075290fcba3390f76b620d18cb4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 6 Aug 2024 21:57:56 +0000 Subject: Fix some indentation --- generic/tcl.h | 83 +++--- generic/tclInt.h | 769 ++++++++++++++++++++++++++++--------------------------- generic/tclVar.c | 100 ++++---- 3 files changed, 486 insertions(+), 466 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index 7afd119..5ce9026 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -110,7 +110,8 @@ extern "C" { * Special macro to define mutexes. */ -#define TCL_DECLARE_MUTEX(name) static Tcl_Mutex name; +#define TCL_DECLARE_MUTEX(name) \ + static Tcl_Mutex name; /* * Tcl's public routine Tcl_FSSeek() uses the values SEEK_SET, SEEK_CUR, and @@ -576,7 +577,7 @@ typedef void (Tcl_ThreadCreateProc) (void *clientData); * Flags values passed to Tcl_RegExpExecObj. */ -#define TCL_REG_NOTBOL 0001 /* Beginning of string does not match ^. */ +#define TCL_REG_NOTBOL 0001 /* Beginning of string does not match ^. */ #define TCL_REG_NOTEOL 0002 /* End of string does not match $. */ /* @@ -587,9 +588,9 @@ typedef void (Tcl_ThreadCreateProc) (void *clientData); typedef struct Tcl_RegExpIndices { #if TCL_MAJOR_VERSION > 8 - Tcl_Size start; /* Character offset of first character in + Tcl_Size start; /* Character offset of first character in * match. */ - Tcl_Size end; /* Character offset of first character after + Tcl_Size end; /* Character offset of first character after * the match. */ #else long start; @@ -598,11 +599,11 @@ typedef struct Tcl_RegExpIndices { } Tcl_RegExpIndices; typedef struct Tcl_RegExpInfo { - Tcl_Size nsubs; /* Number of subexpressions in the compiled + Tcl_Size nsubs; /* Number of subexpressions in the compiled * expression. */ Tcl_RegExpIndices *matches; /* Array of nsubs match offset pairs. */ #if TCL_MAJOR_VERSION > 8 - Tcl_Size extendStart; /* The offset at which a subsequent match + Tcl_Size extendStart; /* The offset at which a subsequent match * might begin. */ #else long extendStart; @@ -834,9 +835,9 @@ typedef struct Tcl_Obj { * corresponds to the type of the object's * internal rep. NULL indicates the object has * no internal rep (has no type). */ - Tcl_ObjInternalRep internalRep; /* The internal representation: */ + Tcl_ObjInternalRep internalRep; + /* The internal representation: */ } Tcl_Obj; - /* *---------------------------------------------------------------------------- @@ -871,7 +872,7 @@ typedef struct Tcl_Namespace { * is an synonym. */ char *fullName; /* The namespace's fully qualified name. This * starts with ::. */ - void *clientData; /* Arbitrary value associated with this + void *clientData; /* Arbitrary value associated with this * namespace. */ Tcl_NamespaceDeleteProc *deleteProc; /* Function invoked when deleting the @@ -906,7 +907,7 @@ typedef struct Tcl_Namespace { */ typedef struct Tcl_CallFrame { - Tcl_Namespace *nsPtr; + Tcl_Namespace *nsPtr; /* Current namespace for the call frame. */ int dummy1; Tcl_Size dummy2; void *dummy3; @@ -945,11 +946,11 @@ typedef struct Tcl_CmdInfo { Tcl_ObjCmdProc *objProc; /* Command's object-based function. */ void *objClientData; /* ClientData for object proc. */ Tcl_CmdProc *proc; /* Command's string-based function. */ - void *clientData; /* ClientData for string proc. */ + void *clientData; /* ClientData for string proc. */ Tcl_CmdDeleteProc *deleteProc; /* Function to call when command is * deleted. */ - void *deleteData; /* Value to pass to deleteProc (usually the + void *deleteData; /* Value to pass to deleteProc (usually the * same as clientData). */ Tcl_Namespace *namespacePtr;/* Points to the namespace that contains this * command. Note that Tcl_SetCmdInfo will not @@ -971,8 +972,8 @@ typedef struct Tcl_CmdInfo { typedef struct Tcl_DString { char *string; /* Points to beginning of string: either * staticSpace below or a malloced array. */ - Tcl_Size length; /* Number of non-NULL characters in the - * string. */ + Tcl_Size length; /* Number of bytes in string excluding + * terminating nul */ Tcl_Size spaceAvl; /* Total number of bytes available for the * string and its terminating NULL char. */ char staticSpace[TCL_DSTRING_STATIC_SIZE]; @@ -1071,7 +1072,7 @@ typedef struct Tcl_DString { * TCL_CANCEL_UNWIND: Magical Tcl_CancelEval mode that causes the * stack for the script in progress to be * completely unwound. - * TCL_EVAL_NOERR: Do no exception reporting at all, just return + * TCL_EVAL_NOERR: Do no exception reporting at all, just return * as the caller will report. */ @@ -1210,7 +1211,7 @@ struct Tcl_HashEntry { void *hash; /* Hash value, stored as pointer to ensure * that the offsets of the fields in this * structure are not changed. */ - void *clientData; /* Application stores something here with + void *clientData; /* Application stores something here with * Tcl_SetHashValue. */ union { /* Key has one of these forms: */ char *oneWordValue; /* One-word value for key. */ @@ -1237,7 +1238,7 @@ struct Tcl_HashEntry { * allocated for the hash table that is not for an * entry will use the system heap. * TCL_HASH_KEY_DIRECT_COMPARE - - * Allows fast comparison for hash keys directly + * Allows fast comparison for hash keys directly * by compare of their key.oneWordValue values, * before call of compareKeysProc (much slower * than a direct compare, so it is speed-up only @@ -1306,11 +1307,11 @@ struct Tcl_HashTable { Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; /* Bucket array used for small tables (to * avoid mallocs and frees). */ - Tcl_Size numBuckets; /* Total number of buckets allocated at + Tcl_Size numBuckets; /* Total number of buckets allocated at * **bucketPtr. */ - Tcl_Size numEntries; /* Total number of entries present in + Tcl_Size numEntries; /* Total number of entries present in * table. */ - Tcl_Size rebuildSize; /* Enlarge table when numEntries gets to be + Tcl_Size rebuildSize; /* Enlarge table when numEntries gets to be * this large. */ #if TCL_MAJOR_VERSION > 8 size_t mask; /* Mask value used in hashing function. */ @@ -1319,7 +1320,7 @@ struct Tcl_HashTable { * Designed to use high-order bits of * randomized keys. */ #if TCL_MAJOR_VERSION < 9 - int mask; /* Mask value used in hashing function. */ + int mask; /* Mask value used in hashing function. */ #endif int keyType; /* Type of keys used in this table. It's * either TCL_CUSTOM_KEYS, TCL_STRING_KEYS, @@ -1382,7 +1383,7 @@ typedef struct Tcl_HashSearch { typedef struct { void *next; /* Search position for underlying hash * table. */ - TCL_HASH_TYPE epoch; /* Epoch marker for dictionary being searched, + TCL_HASH_TYPE epoch; /* Epoch marker for dictionary being searched, * or 0 if search has terminated. */ Tcl_Dict dictionaryPtr; /* Reference to dictionary being searched. */ } Tcl_DictSearch; @@ -1420,7 +1421,7 @@ struct Tcl_Event { typedef enum { TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK, - TCL_QUEUE_ALERT_IF_EMPTY=4 + TCL_QUEUE_ALERT_IF_EMPTY=4 } Tcl_QueuePosition; /* @@ -1835,7 +1836,7 @@ typedef struct Tcl_Filesystem { * 'file attributes'. */ Tcl_FSFileAttrsSetProc *fileAttrsSetProc; /* Called by 'Tcl_FSFileAttrsSet()' and by - * 'file attributes'. */ + * 'file attributes'. */ Tcl_FSCreateDirectoryProc *createDirectoryProc; /* Called by 'Tcl_FSCreateDirectory()'. May be * NULL if the filesystem is read-only. */ @@ -1928,8 +1929,8 @@ typedef struct Tcl_Token { int type; /* Type of token, such as TCL_TOKEN_WORD; see * below for valid types. */ const char *start; /* First character in token. */ - Tcl_Size size; /* Number of bytes in token. */ - Tcl_Size numComponents; /* If this token is composed of other tokens, + Tcl_Size size; /* Number of bytes in token. */ + Tcl_Size numComponents; /* If this token is composed of other tokens, * this field tells how many of them there are * (including components of components, etc.). * The component tokens immediately follow @@ -2043,13 +2044,13 @@ typedef struct Tcl_Token { typedef struct Tcl_Parse { const char *commentStart; /* Pointer to # that begins the first of one * or more comments preceding the command. */ - Tcl_Size commentSize; /* Number of bytes in comments (up through + Tcl_Size commentSize; /* Number of bytes in comments (up through * newline character that terminates the last * comment). If there were no comments, this * field is 0. */ const char *commandStart; /* First character in first word of * command. */ - Tcl_Size commandSize; /* Number of bytes in command, including first + Tcl_Size commandSize; /* Number of bytes in command, including first * character of first word, up through the * terminating newline, close bracket, or * semicolon. */ @@ -2119,7 +2120,7 @@ typedef struct Tcl_EncodingType { Tcl_EncodingFreeProc *freeProc; /* If non-NULL, function to call when this * encoding is deleted. */ - void *clientData; /* Arbitrary value associated with encoding + void *clientData; /* Arbitrary value associated with encoding * type. Passed to conversion functions. */ Tcl_Size nullSize; /* Number of zero bytes that signify * end-of-string in this encoding. This number @@ -2326,7 +2327,7 @@ typedef struct { * depends on type.*/ const char *helpStr; /* Documentation message describing this * option. */ - void *clientData; /* Word to pass to function callbacks. */ + void *clientData; /* Word to pass to function callbacks. */ } Tcl_ArgvInfo; /* @@ -2446,9 +2447,9 @@ typedef int (Tcl_NRPostProc) (void *data[], Tcl_Interp *interp, */ #if TCL_MAJOR_VERSION > 8 -# define TCL_STUB_MAGIC ((int) 0xFCA3BACB + (int) sizeof(void *)) +# define TCL_STUB_MAGIC ((int) 0xFCA3BACB + (int) sizeof(void *)) #else -# define TCL_STUB_MAGIC ((int) 0xFCA3BACF) +# define TCL_STUB_MAGIC ((int) 0xFCA3BACF) #endif /* @@ -2597,11 +2598,11 @@ EXTERN const char *TclZipfs_AppHook(int *argc, char ***argv); */ # undef Tcl_DecrRefCount # define Tcl_DecrRefCount(objPtr) \ - do { \ - Tcl_Obj *_objPtr = (objPtr); \ - if (_objPtr->refCount-- <= 1) { \ - TclFreeObj(_objPtr); \ - } \ + do { \ + Tcl_Obj *_objPtr = (objPtr); \ + if (_objPtr->refCount-- <= 1) { \ + TclFreeObj(_objPtr); \ + } \ } while(0) # undef Tcl_IsShared # define Tcl_IsShared(objPtr) \ @@ -2649,10 +2650,10 @@ EXTERN const char *TclZipfs_AppHook(int *argc, char ***argv); #define Tcl_GetHashValue(h) ((h)->clientData) #define Tcl_SetHashValue(h, value) ((h)->clientData = (void *)(value)) #define Tcl_GetHashKey(tablePtr, h) \ - ((void *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS || \ - (tablePtr)->keyType == TCL_CUSTOM_PTR_KEYS) \ - ? (h)->key.oneWordValue \ - : (h)->key.string)) + ((void *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS || \ + (tablePtr)->keyType == TCL_CUSTOM_PTR_KEYS) \ + ? (h)->key.oneWordValue \ + : (h)->key.string)) /* * Macros to use for clients to use to invoke find and create functions for diff --git a/generic/tclInt.h b/generic/tclInt.h index c2f52b3..31e06df 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -236,8 +236,8 @@ typedef struct NamespacePathEntry NamespacePathEntry; */ typedef struct TclVarHashTable { - Tcl_HashTable table; - struct Namespace *nsPtr; + Tcl_HashTable table; /* "Inherit" from Tcl_HashTable. */ + struct Namespace *nsPtr; /* The namespace containing the variables. */ } TclVarHashTable; /* @@ -270,7 +270,7 @@ typedef struct Namespace { * synonym. */ char *fullName; /* The namespace's fully qualified name. This * starts with ::. */ - void *clientData; /* An arbitrary value associated with this + void *clientData; /* An arbitrary value associated with this * namespace. */ Tcl_NamespaceDeleteProc *deleteProc; /* Procedure invoked when deleting the @@ -321,12 +321,12 @@ typedef struct Namespace { * registered using "namespace export". */ Tcl_Size maxExportPatterns; /* Number of export patterns for which space * is currently allocated. */ - Tcl_Size cmdRefEpoch; /* Incremented if a newly added command + Tcl_Size cmdRefEpoch; /* Incremented if a newly added command * shadows a command for which this namespace * has already cached a Command* pointer; this * causes all its cached Command* pointers to * be invalidated. */ - Tcl_Size resolverEpoch; /* Incremented whenever (a) the name + Tcl_Size resolverEpoch; /* Incremented whenever (a) the name * resolution rules change for this namespace * or (b) a newly added command shadows a * command that is compiled to bytecodes. This @@ -433,8 +433,8 @@ struct NamespacePathEntry { * TCL_NAMESPACE_ONLY - (see tcl.h) Look only in the context ns. * TCL_CREATE_NS_IF_UNKNOWN - Create unknown namespaces. * TCL_FIND_ONLY_NS - The name sought is a namespace name. - * TCL_FIND_IF_NOT_SIMPLE - Retrieve last namespace even if the rest of - * name is not simple name (contains ::). + * TCL_FIND_IF_NOT_SIMPLE - Retrieve last namespace even if the rest of + * name is not simple name (contains ::). */ #define TCL_CREATE_NS_IF_UNKNOWN 0x800 @@ -456,7 +456,7 @@ typedef struct EnsembleConfig { * if the command has been deleted (or never * existed; the global namespace never has an * ensemble command.) */ - Tcl_Size epoch; /* The epoch at which this ensemble's table of + Tcl_Size epoch; /* The epoch at which this ensemble's table of * exported commands is valid. */ char **subcommandArrayPtr; /* Array of ensemble subcommand names. At all * consistent points, this will have the same @@ -513,7 +513,7 @@ typedef struct EnsembleConfig { * core, presumably because the ensemble * itself has been updated. */ Tcl_Obj *parameterList; /* List of ensemble parameter names. */ - Tcl_Size numParameters; /* Cached number of parameters. This is either + Tcl_Size numParameters; /* Cached number of parameters. This is either * 0 (if the parameterList field is NULL) or * the length of the list in the parameterList * field. */ @@ -543,7 +543,7 @@ typedef struct EnsembleConfig { typedef struct VarTrace { Tcl_VarTraceProc *traceProc;/* Procedure to call when operations given by * flags are performed on variable. */ - void *clientData; /* Argument to pass to proc. */ + void *clientData; /* Argument to pass to proc. */ int flags; /* What events the trace procedure is * interested in: OR-ed combination of * TCL_TRACE_READS, TCL_TRACE_WRITES, @@ -562,7 +562,7 @@ typedef struct CommandTrace { Tcl_CommandTraceProc *traceProc; /* Procedure to call when operations given by * flags are performed on command. */ - void *clientData; /* Argument to pass to proc. */ + void *clientData; /* Argument to pass to proc. */ int flags; /* What events the trace procedure is * interested in: OR-ed combination of * TCL_TRACE_RENAME, TCL_TRACE_DELETE. */ @@ -641,7 +641,7 @@ typedef struct Var { } Var; typedef struct VarInHash { - Var var; + Var var; /* "Inherit" from Var. */ Tcl_Size refCount; /* Counts number of active uses of this * variable: 1 for the entry in the hash * table, 1 for each additional variable whose @@ -871,8 +871,8 @@ typedef struct VarInHash { #define TclGetVarNsPtr(varPtr) \ (TclIsVarInHash(varPtr) \ - ? ((TclVarHashTable *) ((((VarInHash *) (varPtr))->entry.tablePtr)))->nsPtr \ - : NULL) + ? ((TclVarHashTable *) ((((VarInHash *) (varPtr))->entry.tablePtr)))->nsPtr \ + : NULL) #define VarHashRefCount(varPtr) \ ((VarInHash *) (varPtr))->refCount @@ -889,7 +889,7 @@ typedef struct VarInHash { #define TclIsVarDirectReadable(varPtr) \ ( (!TclIsVarTricky(varPtr,VAR_TRACED_READ)) \ - && (varPtr)->value.objPtr) + && (varPtr)->value.objPtr) #define TclIsVarDirectWritable(varPtr) \ (!TclIsVarTricky(varPtr,VAR_TRACED_WRITE|VAR_DEAD_HASH)) @@ -899,19 +899,19 @@ typedef struct VarInHash { #define TclIsVarDirectModifyable(varPtr) \ ( (!TclIsVarTricky(varPtr,VAR_TRACED_READ|VAR_TRACED_WRITE)) \ - && (varPtr)->value.objPtr) + && (varPtr)->value.objPtr) #define TclIsVarDirectReadable2(varPtr, arrayPtr) \ - (TclIsVarDirectReadable(varPtr) && \ - (!(arrayPtr) || !((arrayPtr)->flags & VAR_TRACED_READ))) + (TclIsVarDirectReadable(varPtr) &&\ + (!(arrayPtr) || !((arrayPtr)->flags & VAR_TRACED_READ))) #define TclIsVarDirectWritable2(varPtr, arrayPtr) \ - (TclIsVarDirectWritable(varPtr) && \ - (!(arrayPtr) || !((arrayPtr)->flags & VAR_TRACED_WRITE))) + (TclIsVarDirectWritable(varPtr) &&\ + (!(arrayPtr) || !((arrayPtr)->flags & VAR_TRACED_WRITE))) #define TclIsVarDirectModifyable2(varPtr, arrayPtr) \ - (TclIsVarDirectModifyable(varPtr) && \ - (!(arrayPtr) || !((arrayPtr)->flags & (VAR_TRACED_READ|VAR_TRACED_WRITE)))) + (TclIsVarDirectModifyable(varPtr) &&\ + (!(arrayPtr) || !((arrayPtr)->flags & (VAR_TRACED_READ|VAR_TRACED_WRITE)))) /* *---------------------------------------------------------------- @@ -953,9 +953,9 @@ typedef struct CompiledLocal { /* Next compiler-recognized local variable for * this procedure, or NULL if this is the last * local. */ - Tcl_Size nameLength; /* The number of bytes in local variable's name. + Tcl_Size nameLength; /* The number of bytes in local variable's name. * Among others used to speed up var lookups. */ - Tcl_Size frameIndex; /* Index in the array of compiler-assigned + Tcl_Size frameIndex; /* Index in the array of compiler-assigned * variables in the procedure call frame. */ int flags; /* Flag bits for the local variable. Same as * the flags for the Var structure above, @@ -971,7 +971,7 @@ typedef struct CompiledLocal { * is marked by a unique tag during * compilation, and that same tag is used to * find the variable at runtime. */ - char name[TCLFLEXARRAY]; /* Name of the local variable starts here. If + char name[TCLFLEXARRAY]; /* Name of the local variable starts here. If * the name is NULL, this will just be '\0'. * The actual size of this field will be large * enough to hold the name. MUST BE THE LAST @@ -1029,7 +1029,7 @@ typedef struct Trace { Tcl_Size level; /* Only trace commands at nesting level less * than or equal to this. */ Tcl_CmdObjTraceProc *proc; /* Procedure to call to trace command. */ - void *clientData; /* Arbitrary value to pass to proc. */ + void *clientData; /* Arbitrary value to pass to proc. */ struct Trace *nextPtr; /* Next in list of traces for this interp. */ int flags; /* Flags governing the trace - see * Tcl_CreateObjTrace for details. */ @@ -1062,10 +1062,10 @@ typedef struct ActiveInterpTrace { * related flag values. * * TCL_TRACE_ENTER_EXEC - triggers enter/enterstep traces. - * - passed to Tcl_CreateObjTrace to set up + * - passed to Tcl_CreateObjTrace to set up * "enterstep" traces. * TCL_TRACE_LEAVE_EXEC - triggers leave/leavestep traces. - * - passed to Tcl_CreateObjTrace to set up + * - passed to Tcl_CreateObjTrace to set up * "leavestep" traces. */ @@ -1094,7 +1094,7 @@ MODULE_SCOPE Tcl_Obj * TclNewArithSeriesObj(Tcl_Interp *interp, typedef struct AssocData { Tcl_InterpDeleteProc *proc; /* Proc to call when deleting. */ - void *clientData; /* Value to pass to proc. */ + void *clientData; /* Value to pass to proc. */ } AssocData; /* @@ -1117,9 +1117,9 @@ typedef struct AssocData { */ typedef struct LocalCache { - Tcl_Size refCount; - Tcl_Size numVars; - Tcl_Obj *varName0; + Tcl_Size refCount; /* Reference count. */ + Tcl_Size numVars; /* Number of variables. */ + Tcl_Obj *varName0; /* First variable name. */ } LocalCache; #define localName(framePtr, i) \ @@ -1138,11 +1138,10 @@ typedef struct CallFrame { * If FRAME_IS_PROC is set, the frame was * pushed to execute a Tcl procedure and may * have local vars. */ - Tcl_Size objc; /* This and objv below describe the arguments + Tcl_Size objc; /* This and objv below describe the arguments * for this procedure call. */ Tcl_Obj *const *objv; /* Array of argument objects. */ - struct CallFrame *callerPtr; - /* Value of interp->framePtr when this + struct CallFrame *callerPtr;/* Value of interp->framePtr when this * procedure was invoked (i.e. next higher in * stack of all active procedures). */ struct CallFrame *callerVarPtr; @@ -1152,7 +1151,7 @@ typedef struct CallFrame { * callerPtr unless an "uplevel" command or * something equivalent was active in the * caller). */ - Tcl_Size level; /* Level of this procedure, for "uplevel" + Tcl_Size level; /* Level of this procedure, for "uplevel" * purposes (i.e. corresponds to nesting of * callerVarPtr's, not callerPtr's). 1 for * outermost procedure, 0 for top-level. */ @@ -1172,7 +1171,7 @@ typedef struct CallFrame { * recognized by the compiler. The compiler * emits code that refers to these variables * using an index into this array. */ - void *clientData; /* Pointer to some context that is used by + void *clientData; /* Pointer to some context that is used by * object systems. The meaning of the contents * of this field is defined by the code that * sets it, and it should only ever be set by @@ -1181,13 +1180,14 @@ typedef struct CallFrame { * have some means of discovering what the * meaning of the value is, which we do not * specify. */ - LocalCache *localCachePtr; - Tcl_Obj *tailcallPtr; - /* NULL if no tailcall is scheduled */ + LocalCache *localCachePtr; /* Pointer to the start of the cached variable + * names and initialisation data for local + * variables. */ + Tcl_Obj *tailcallPtr; /* NULL if no tailcall is scheduled */ } CallFrame; -#define FRAME_IS_PROC 0x1 -#define FRAME_IS_LAMBDA 0x2 +#define FRAME_IS_PROC 0x1 /* Frame is a procedure body. */ +#define FRAME_IS_LAMBDA 0x2 /* Frame is a lambda term body. */ #define FRAME_IS_METHOD 0x4 /* The frame is a method body, and the frame's * clientData field contains a CallContext * reference. Part of TIP#257. */ @@ -1228,7 +1228,7 @@ typedef struct CmdFrame { int level; /* Number of frames in stack, prevent O(n) * scan of list. */ Tcl_Size *line; /* Lines the words of the command start on. */ - Tcl_Size nline; + Tcl_Size nline; /* Number of lines in CmdFrame.line. */ CallFrame *framePtr; /* Procedure activation record, may be * NULL. */ struct CmdFrame *nextPtr; /* Link to calling frame. */ @@ -1272,7 +1272,7 @@ typedef struct CmdFrame { } data; Tcl_Obj *cmdObj; const char *cmd; /* The executed command, if possible... */ - Tcl_Size len; /* ... and its length. */ + Tcl_Size len; /* ... and its length. */ const struct CFWordBC *litarg; /* Link to set of literal arguments which have * ben pushed on the lineLABCPtr stack by @@ -1282,16 +1282,16 @@ typedef struct CmdFrame { typedef struct CFWord { CmdFrame *framePtr; /* CmdFrame to access. */ - Tcl_Size word; /* Index of the word in the command. */ + Tcl_Size word; /* Index of the word in the command. */ Tcl_Size refCount; /* Number of times the word is on the * stack. */ } CFWord; typedef struct CFWordBC { CmdFrame *framePtr; /* CmdFrame to access. */ - Tcl_Size pc; /* Instruction pointer of a command in + Tcl_Size pc; /* Instruction pointer of a command in * ExtCmdLoc.loc[.] */ - Tcl_Size word; /* Index of word in + Tcl_Size word; /* Index of word in * ExtCmdLoc.loc[cmd]->line[.] */ struct CFWordBC *prevPtr; /* Previous entry in stack for same Tcl_Obj. */ struct CFWordBC *nextPtr; /* Next entry for same command call. See @@ -1320,7 +1320,7 @@ typedef struct CFWordBC { #define CLL_END (-1) typedef struct ContLineLoc { - Tcl_Size num; /* Number of entries in loc, not counting the + Tcl_Size num; /* Number of entries in loc, not counting the * final -1 marker entry. */ Tcl_Size loc[TCLFLEXARRAY];/* Table of locations, as character offsets. * The table is allocated as part of the @@ -1363,14 +1363,14 @@ typedef struct ContLineLoc { typedef Tcl_Obj * (GetFrameInfoValueProc)(void *clientData); typedef struct { const char *name; /* Name of this field. */ - GetFrameInfoValueProc *proc; /* Function to generate a Tcl_Obj* from the + GetFrameInfoValueProc *proc;/* Function to generate a Tcl_Obj* from the * clientData, or just use the clientData * directly (after casting) if NULL. */ - void *clientData; /* Context for above function, or Tcl_Obj* if + void *clientData; /* Context for above function, or Tcl_Obj* if * proc field is NULL. */ } ExtraFrameInfoField; typedef struct { - Tcl_Size length; /* Length of array. */ + Tcl_Size length; /* Length of array. */ ExtraFrameInfoField fields[2]; /* Really as long as necessary, but this is * long enough for nearly anything. */ @@ -1435,15 +1435,15 @@ struct CompileEnv; * be one of the following: * * TCL_OK Compilation completed normally. - * TCL_ERROR Compilation could not be completed. This can be just a - * judgment by the CompileProc that the command is too - * complex to compile effectively, or it can indicate - * that in the current state of the interp, the command - * would raise an error. The bytecode compiler will not - * do any error reporting at compiler time. Error - * reporting is deferred until the actual runtime, - * because by then changes in the interp state may allow - * the command to be successfully evaluated. + * TCL_ERROR Compilation could not be completed. This can be just a + * judgment by the CompileProc that the command is too + * complex to compile effectively, or it can indicate + * that in the current state of the interp, the command + * would raise an error. The bytecode compiler will not + * do any error reporting at compiler time. Error + * reporting is deferred until the actual runtime, + * because by then changes in the interp state may allow + * the command to be successfully evaluated. * TCL_OUT_LINE_COMPILE A source-compatible alias for TCL_ERROR, kept for the * sake of old code only. */ @@ -1464,19 +1464,35 @@ typedef int (CompileHookProc)(Tcl_Interp *interp, struct CompileEnv *compEnvPtr, void *clientData); /* - * The data structure for a (linked list of) execution stacks. + * The data structure for a (linked list of) execution stacks. Note that the + * first word on a particular execution stack is NULL, which is used as a + * marker to say "go to the previous stack in the list" when unwinding the + * stack. */ typedef struct ExecStack { - struct ExecStack *prevPtr; - struct ExecStack *nextPtr; - Tcl_Obj **markerPtr; - Tcl_Obj **endPtr; - Tcl_Obj **tosPtr; + struct ExecStack *prevPtr; /* Previous stack in list. */ + struct ExecStack *nextPtr; /* Next stack in list. */ + Tcl_Obj **markerPtr; /* The location of the NULL marker. */ + Tcl_Obj **endPtr; /* Where the stack end is. */ + Tcl_Obj **tosPtr; /* Where the stack top is. */ Tcl_Obj *stackWords[TCLFLEXARRAY]; + /* The actual stack space, following this + * structure in memory. */ } ExecStack; /* + * Saved copies of the stack frame references from the interpreter. Have to be + * restored into the interpreter to be used. + */ +typedef struct CorContext { + CallFrame *framePtr; /* See Interp.framePtr */ + CallFrame *varFramePtr; /* See Interp.varFramePtr */ + CmdFrame *cmdFramePtr; /* See Interp.cmdFramePtr */ + Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ +} CorContext; + +/* * The data structure defining the execution environment for ByteCode's. * There is one ExecEnv structure per Tcl interpreter. It holds the evaluation * stack that holds command operands and results. The stack grows towards @@ -1484,13 +1500,6 @@ typedef struct ExecStack { * currently active execution stack. */ -typedef struct CorContext { - struct CallFrame *framePtr; - struct CallFrame *varFramePtr; - struct CmdFrame *cmdFramePtr; /* See Interp.cmdFramePtr */ - Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ -} CorContext; - typedef struct CoroutineData { struct Command *cmdPtr; /* The command handle for the coroutine. */ struct ExecEnv *eePtr; /* The special execution environment (stacks, @@ -1499,33 +1508,37 @@ typedef struct CoroutineData { * the coroutine, which might be the * interpreter global environment or another * coroutine. */ - CorContext caller; - CorContext running; - Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ - void *stackLevel; - Tcl_Size auxNumLevels; /* While the coroutine is running the + CorContext caller; /* Caller's saved execution context. */ + CorContext running; /* This coroutine's saved execution context. */ + Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ + void *stackLevel; /* C stack frame reference. Used to try to + * ensure we don't overflow that stack. */ + Tcl_Size auxNumLevels; /* While the coroutine is running the * numLevels of the create/resume command is * stored here; for suspended coroutines it * holds the nesting numLevels at yield. */ - Tcl_Size nargs; /* Number of args required for resuming this - * coroutine; COROUTINE_ARGUMENTS_SINGLE_OPTIONAL means "0 or 1" - * (default), COROUTINE_ARGUMENTS_ARBITRARY means "any" */ + Tcl_Size nargs; /* Number of args required for resuming this + * coroutine; COROUTINE_ARGUMENTS_SINGLE_OPTIONAL + * means "0 or 1" (default), + * COROUTINE_ARGUMENTS_ARBITRARY means "any" */ Tcl_Obj *yieldPtr; /* The command to yield to. Stored here in * order to reset splice point in * TclNRCoroutineActivateCallback if the - * coroutine is busy. - */ + * coroutine is busy. */ } CoroutineData; typedef struct ExecEnv { ExecStack *execStackPtr; /* Points to the first item in the evaluation * stack on the heap. */ Tcl_Obj *constants[2]; /* Pointers to constant "0" and "1" objs. */ - struct Tcl_Interp *interp; + struct Tcl_Interp *interp; /* Owning interpreter. */ struct NRE_callback *callbackPtr; /* Top callback in NRE's stack. */ struct CoroutineData *corPtr; - int rewind; + /* Current coroutine. */ + int rewind; /* Set when exception trapping is disabled + * because a context is being deleted (e.g., + * the current coroutine has been deleted). */ } ExecEnv; #define COR_IS_SUSPENDED(corPtr) \ @@ -1571,11 +1584,11 @@ typedef struct LiteralTable { LiteralEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; /* Bucket array used for small tables to avoid * mallocs and frees. */ - TCL_HASH_TYPE numBuckets; /* Total number of buckets allocated at + TCL_HASH_TYPE numBuckets; /* Total number of buckets allocated at * **buckets. */ - TCL_HASH_TYPE numEntries; /* Total number of entries present in + TCL_HASH_TYPE numEntries; /* Total number of entries present in * table. */ - TCL_HASH_TYPE rebuildSize; /* Enlarge table when numEntries gets to be + TCL_HASH_TYPE rebuildSize; /* Enlarge table when numEntries gets to be * this large. */ TCL_HASH_TYPE mask; /* Mask value used in hashing function. */ } LiteralTable; @@ -1588,10 +1601,11 @@ typedef struct LiteralTable { #ifdef TCL_COMPILE_STATS typedef struct ByteCodeStats { - size_t numExecutions; /* Number of ByteCodes executed. */ + size_t numExecutions; /* Number of ByteCodes executed. */ size_t numCompilations; /* Number of ByteCodes created. */ size_t numByteCodesFreed; /* Number of ByteCodes destroyed. */ - size_t instructionCount[256]; /* Number of times each instruction was + size_t instructionCount[256]; + /* Number of times each instruction was * executed. */ double totalSrcBytes; /* Total source bytes ever compiled. */ @@ -1599,7 +1613,7 @@ typedef struct ByteCodeStats { double currentSrcBytes; /* Src bytes for all current ByteCodes. */ double currentByteCodeBytes;/* Code bytes in all current ByteCodes. */ - size_t srcCount[32]; /* Source size distribution: # of srcs of + size_t srcCount[32]; /* Source size distribution: # of srcs of * size [2**(n-1)..2**n), n in [0..32). */ size_t byteCodeCount[32]; /* ByteCode size distribution. */ size_t lifetimeCount[32]; /* ByteCode lifetime distribution (ms). */ @@ -1629,7 +1643,7 @@ typedef struct { Tcl_ObjCmdProc *proc; /* The implementation of the subcommand. */ CompileProc *compileProc; /* The compiler for the subcommand. */ Tcl_ObjCmdProc *nreProc; /* NRE implementation of this command. */ - void *clientData; /* Any clientData to give the command. */ + void *clientData; /* Any clientData to give the command. */ int unsafe; /* Whether this command is to be hidden by * default in a safe interpreter. */ } EnsembleImplMap; @@ -1708,11 +1722,11 @@ typedef struct Command { Tcl_ObjCmdProc *objProc; /* Object-based command procedure. */ void *objClientData; /* Arbitrary value passed to object proc. */ Tcl_CmdProc *proc; /* String-based command procedure. */ - void *clientData; /* Arbitrary value passed to string proc. */ + void *clientData; /* Arbitrary value passed to string proc. */ Tcl_CmdDeleteProc *deleteProc; /* Procedure invoked when deleting command to, * e.g., free all client data. */ - void *deleteData; /* Arbitrary value passed to deleteProc. */ + void *deleteData; /* Arbitrary value passed to deleteProc. */ int flags; /* Miscellaneous bits of information about * command. See below for definitions. */ ImportRef *importRefPtr; /* List of each imported Command created in @@ -1751,17 +1765,16 @@ typedef struct Command { * (these last two flags are defined in tcl.h) */ -#define CMD_DYING 0x01 +#define CMD_DYING 0x01 #ifndef TCL_NO_DEPRECATED # define CMD_IS_DELETED 0x01 /* Same as CMD_DYING */ #endif -#define CMD_TRACE_ACTIVE 0x02 -#define CMD_HAS_EXEC_TRACES 0x04 -#define CMD_COMPILES_EXPANDED 0x08 -#define CMD_REDEF_IN_PROGRESS 0x10 -#define CMD_VIA_RESOLVER 0x20 -#define CMD_DEAD 0x40 - +#define CMD_TRACE_ACTIVE 0x02 +#define CMD_HAS_EXEC_TRACES 0x04 +#define CMD_COMPILES_EXPANDED 0x08 +#define CMD_REDEF_IN_PROGRESS 0x10 +#define CMD_VIA_RESOLVER 0x20 +#define CMD_DEAD 0x40 /* *---------------------------------------------------------------- @@ -1867,12 +1880,14 @@ typedef struct Interp { * line number in the command where the error * occurred (1 means first line). */ const struct TclStubs *stubTable; - /* Pointer to the exported Tcl stub table. On - * previous versions of Tcl this is a pointer - * to the objResultPtr or a pointer to a - * buckets array in a hash table. We therefore - * have to do some careful checking before we - * can use this. */ + /* Pointer to the exported Tcl stub table. In + * ancient pre-8.1 versions of Tcl this was a + * pointer to the objResultPtr or a pointer to a + * buckets array in a hash table. Deployed stubs + * enabled extensions check for a NULL pointer value + * and for a TCL_STUBS_MAGIC value to verify they + * are not [load]ing into one of those pre-stubs + * interps. */ TclHandle handle; /* Handle used to keep track of when this * interp is deleted. */ @@ -1882,7 +1897,7 @@ typedef struct Interp { /* Hash table used by tclBasic.c to keep track * of hidden commands on a per-interp * basis. */ - void *interpInfo; /* Information used by tclInterp.c to keep + void *interpInfo; /* Information used by tclInterp.c to keep * track of parent/child interps on a * per-interp basis. */ union { @@ -2016,7 +2031,6 @@ typedef struct Interp { ActiveInterpTrace *activeInterpTracePtr; /* First in list of active traces for interp, * or NULL if no active traces. */ - Tcl_Size tracesForbiddingInline; /* Count of traces (in the list headed by * tracePtr) that forbid inline bytecode @@ -2126,7 +2140,7 @@ typedef struct Interp { * Proc structure for a procedure. The values * are "struct ExtCmdLoc*". (See * tclCompile.h) */ - Tcl_HashTable *lineLABCPtr; + Tcl_HashTable *lineLABCPtr; /* Tcl_Obj* (by exact pointer) -> CFWordBC* */ Tcl_HashTable *lineLAPtr; /* This table remembers for each argument of a * command on the execution stack the index of * the argument in the command, and the @@ -2176,7 +2190,7 @@ typedef struct Interp { * They are used by the macros defined below. */ - AllocCache *allocCache; + AllocCache *allocCache; /* Allocator cache for stack frames. */ void *pendingObjDataPtr; /* Pointer to the Cache and PendingObjData * structs for this interp's thread; see * tclObj.c and tclThreadAlloc.c */ @@ -2211,15 +2225,15 @@ typedef struct Interp { * over the default error messages returned by * a script cancellation operation. */ - /* - * TIP #348 IMPLEMENTATION - Substituted error stack - */ + /* + * TIP #348 IMPLEMENTATION - Substituted error stack + */ Tcl_Obj *errorStack; /* [info errorstack] value (as a Tcl_Obj). */ Tcl_Obj *upLiteral; /* "UP" literal for [info errorstack] */ Tcl_Obj *callLiteral; /* "CALL" literal for [info errorstack] */ Tcl_Obj *innerLiteral; /* "INNER" literal for [info errorstack] */ Tcl_Obj *innerContext; /* cached list for fast reallocation */ - int resetErrorStack; /* controls cleaning up of ::errorStack */ + int resetErrorStack; /* controls cleaning up of ::errorStack */ #ifdef TCL_COMPILE_STATS /* @@ -2246,10 +2260,10 @@ typedef struct Interp { #define TclCanceled(iPtr) \ (((iPtr)->flags & CANCELED) || ((iPtr)->flags & TCL_CANCEL_UNWIND)) -#define TclSetCancelFlags(iPtr, cancelFlags) \ - (iPtr)->flags |= CANCELED; \ - if ((cancelFlags) & TCL_CANCEL_UNWIND) { \ - (iPtr)->flags |= TCL_CANCEL_UNWIND; \ +#define TclSetCancelFlags(iPtr, cancelFlags) \ + (iPtr)->flags |= CANCELED; \ + if ((cancelFlags) & TCL_CANCEL_UNWIND) { \ + (iPtr)->flags |= TCL_CANCEL_UNWIND; \ } #define TclUnsetCancelFlags(iPtr) \ @@ -2415,7 +2429,8 @@ struct TclMaxAlignment { */ #define TclOOM(ptr, size) \ - ((size) && ((ptr)||(Tcl_Panic("unable to alloc %" TCL_Z_MODIFIER "u bytes", (size_t)(size)),1))) + ((size) && ((ptr) || (Tcl_Panic( \ + "unable to alloc %" TCL_Z_MODIFIER "u bytes", (size_t)(size)), 1))) /* * The following enum values are used to specify the runtime platform setting @@ -2485,36 +2500,38 @@ typedef enum TclEolTranslation { * */ typedef struct ListStore { - Tcl_Size firstUsed; /* Index of first slot in use within slots[] */ - Tcl_Size numUsed; /* Number of slots in use (starting firstUsed) */ - Tcl_Size numAllocated; /* Total number of slots[] array slots. */ - size_t refCount; /* Number of references to this instance */ - int flags; /* LISTSTORE_* flags */ - Tcl_Obj *slots[TCLFLEXARRAY]; /* Variable size array. Grown as needed */ + Tcl_Size firstUsed; /* Index of first slot in use within slots[] */ + Tcl_Size numUsed; /* Number of slots in use (starting firstUsed) */ + Tcl_Size numAllocated; /* Total number of slots[] array slots. */ + size_t refCount; /* Number of references to this instance. */ + int flags; /* LISTSTORE_* flags */ + Tcl_Obj *slots[TCLFLEXARRAY]; + /* Variable size array. Grown as needed */ } ListStore; #define LISTSTORE_CANONICAL 0x1 /* All Tcl_Obj's referencing this - store have their string representation - derived from the list representation */ + * store have their string representation + * derived from the list representation */ /* Max number of elements that can be contained in a list */ -#define LIST_MAX \ - ((Tcl_Size)(((size_t)TCL_SIZE_MAX - offsetof(ListStore, slots)) \ - / sizeof(Tcl_Obj *))) +#define LIST_MAX \ + ((Tcl_Size)(((size_t)TCL_SIZE_MAX - offsetof(ListStore, slots)) \ + / sizeof(Tcl_Obj *))) /* Memory size needed for a ListStore to hold numSlots_ elements */ #define LIST_SIZE(numSlots_) \ - ((Tcl_Size)(offsetof(ListStore, slots) + ((numSlots_) * sizeof(Tcl_Obj *)))) + ((Tcl_Size)(offsetof(ListStore, slots) \ + + ((numSlots_) * sizeof(Tcl_Obj *)))) /* * ListSpan -- * See comments above for ListStore */ typedef struct ListSpan { - Tcl_Size spanStart; /* Starting index of the span */ - Tcl_Size spanLength; /* Number of elements in the span */ - size_t refCount; /* Count of references to this span record */ + Tcl_Size spanStart; /* Starting index of the span. */ + Tcl_Size spanLength; /* Number of elements in the span. */ + size_t refCount; /* Count of references to this span record. */ } ListSpan; -#ifndef LIST_SPAN_THRESHOLD /* May be set on build line */ +#ifndef LIST_SPAN_THRESHOLD /* May be set on build line */ #define LIST_SPAN_THRESHOLD 101 #endif @@ -2523,9 +2540,11 @@ typedef struct ListSpan { * See comments above for ListStore */ typedef struct ListRep { - ListStore *storePtr;/* element array shared amongst different lists */ - ListSpan *spanPtr; /* If not NULL, the span holds the range of slots - within *storePtr that contain this list elements. */ + ListStore *storePtr; /* element array shared amongst different + * lists */ + ListSpan *spanPtr; /* If not NULL, the span holds the range of + * slots within *storePtr that contain this + * list elements. */ } ListRep; /* @@ -2541,14 +2560,16 @@ typedef struct ListRep { */ /* Returns the starting slot for this listRep in the contained ListStore */ -#define ListRepStart(listRepPtr_) \ - ((listRepPtr_)->spanPtr ? (listRepPtr_)->spanPtr->spanStart \ - : (listRepPtr_)->storePtr->firstUsed) +#define ListRepStart(listRepPtr_) \ + ((listRepPtr_)->spanPtr \ + ? (listRepPtr_)->spanPtr->spanStart \ + : (listRepPtr_)->storePtr->firstUsed) /* Returns the number of elements in this listRep */ -#define ListRepLength(listRepPtr_) \ - ((listRepPtr_)->spanPtr ? (listRepPtr_)->spanPtr->spanLength \ - : (listRepPtr_)->storePtr->numUsed) +#define ListRepLength(listRepPtr_) \ + ((listRepPtr_)->spanPtr \ + ? (listRepPtr_)->spanPtr->spanLength \ + : (listRepPtr_)->storePtr->numUsed) /* Returns a pointer to the first slot containing this ListRep elements */ #define ListRepElementsBase(listRepPtr_) \ @@ -2556,7 +2577,7 @@ typedef struct ListRep { /* Stores the number of elements and base address of the element array */ #define ListRepElements(listRepPtr_, objc_, objv_) \ - (((objv_) = ListRepElementsBase(listRepPtr_)), \ + (((objv_) = ListRepElementsBase(listRepPtr_)), \ ((objc_) = ListRepLength(listRepPtr_))) /* Returns 1/0 whether the ListRep's ListStore is shared. */ @@ -2571,34 +2592,36 @@ typedef struct ListRep { ((ListSpan *)((listObj_)->internalRep.twoPtrValue.ptr2)) /* Returns the ListRep internal representaton in a Tcl_Obj */ -#define ListObjGetRep(listObj_, listRepPtr_) \ - do { \ - (listRepPtr_)->storePtr = ListObjStorePtr(listObj_); \ - (listRepPtr_)->spanPtr = ListObjSpanPtr(listObj_); \ +#define ListObjGetRep(listObj_, listRepPtr_) \ + do { \ + (listRepPtr_)->storePtr = ListObjStorePtr(listObj_); \ + (listRepPtr_)->spanPtr = ListObjSpanPtr(listObj_); \ } while (0) /* Returns the length of the list */ -#define ListObjLength(listObj_, len_) \ - ((len_) = ListObjSpanPtr(listObj_) ? ListObjSpanPtr(listObj_)->spanLength \ - : ListObjStorePtr(listObj_)->numUsed) +#define ListObjLength(listObj_, len_) \ + ((len_) = ListObjSpanPtr(listObj_) \ + ? ListObjSpanPtr(listObj_)->spanLength \ + : ListObjStorePtr(listObj_)->numUsed) /* Returns the starting slot index of this list's elements in the ListStore */ -#define ListObjStart(listObj_) \ - (ListObjSpanPtr(listObj_) ? ListObjSpanPtr(listObj_)->spanStart \ - : ListObjStorePtr(listObj_)->firstUsed) +#define ListObjStart(listObj_) \ + (ListObjSpanPtr(listObj_) \ + ? ListObjSpanPtr(listObj_)->spanStart \ + : ListObjStorePtr(listObj_)->firstUsed) /* Stores the element count and base address of this list's elements */ #define ListObjGetElements(listObj_, objc_, objv_) \ (((objv_) = &ListObjStorePtr(listObj_)->slots[ListObjStart(listObj_)]), \ (ListObjLength(listObj_, (objc_)))) - /* * Returns 1/0 whether the internal representation (not the Tcl_Obj itself) * is shared. Note by intent this only checks for sharing of ListStore, * not spans. */ -#define ListObjRepIsShared(listObj_) (ListObjStorePtr(listObj_)->refCount > 1) +#define ListObjRepIsShared(listObj_) \ + (ListObjStorePtr(listObj_)->refCount > 1) /* * Certain commands like concat are optimized if an existing string @@ -2679,8 +2702,8 @@ typedef struct ListRep { (((objPtr)->typePtr == &tclIntType \ && (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(LONG_MIN) \ && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(LONG_MAX)) \ - ? ((*(longPtr) = (long)(objPtr)->internalRep.wideValue), TCL_OK) \ - : Tcl_GetLongFromObj((interp), (objPtr), (longPtr))) + ? ((*(longPtr) = (long)(objPtr)->internalRep.wideValue), TCL_OK) \ + : Tcl_GetLongFromObj((interp), (objPtr), (longPtr))) #endif #define TclGetIntFromObj(interp, objPtr, intPtr) \ @@ -2705,9 +2728,8 @@ typedef struct ListRep { #define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \ (((objPtr)->typePtr == &tclIntType) \ - ? (*(wideIntPtr) = \ - ((objPtr)->internalRep.wideValue), TCL_OK) : \ - Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr))) + ? (*(wideIntPtr) = ((objPtr)->internalRep.wideValue), TCL_OK) \ + : Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr))) /* * Flag values for TclTraceDictPath(). @@ -2752,7 +2774,8 @@ typedef struct ListRep { #define TCL_FILESYSTEM_VERSION_2 ((Tcl_FSVersion) 0x2) typedef void *(TclFSGetCwdProc2)(void *clientData); typedef int (Tcl_FSLoadFileProc2) (Tcl_Interp *interp, Tcl_Obj *pathPtr, - Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); + Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr, + int flags); /* * The following types are used for getting and storing platform-specific file @@ -2826,7 +2849,8 @@ typedef Tcl_ObjCmdProc *TclObjCmdProcType; *---------------------------------------------------------------- */ -typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, TCL_HASH_TYPE *lengthPtr, +typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, + TCL_HASH_TYPE *lengthPtr, Tcl_Encoding *encodingPtr); /* @@ -2838,14 +2862,14 @@ typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, TCL_HASH_TYPE *len */ typedef struct ProcessGlobalValue { - Tcl_Size epoch; /* Epoch counter to detect changes in the + Tcl_Size epoch; /* Epoch counter to detect changes in the * global value. */ TCL_HASH_TYPE numBytes; /* Length of the global string. */ char *value; /* The global string value. */ Tcl_Encoding encoding; /* system encoding when global string was * initialized. */ TclInitProcessGlobalValueProc *proc; - /* A procedure to initialize the global string + /* A procedure to initialize the global string * copy when a "get" request comes in before * any "set" request has been received. */ Tcl_Mutex mutex; /* Enforce orderly access from multiple @@ -2860,26 +2884,25 @@ typedef struct ProcessGlobalValue { *---------------------------------------------------------------------- */ -#define TCL_PARSE_DECIMAL_ONLY 1 +#define TCL_PARSE_DECIMAL_ONLY 1 /* Leading zero doesn't denote octal or * hex. */ -#define TCL_PARSE_OCTAL_ONLY 2 +#define TCL_PARSE_OCTAL_ONLY 2 /* Parse octal even without prefix. */ #define TCL_PARSE_HEXADECIMAL_ONLY 4 /* Parse hexadecimal even without prefix. */ -#define TCL_PARSE_INTEGER_ONLY 8 +#define TCL_PARSE_INTEGER_ONLY 8 /* Disable floating point parsing. */ -#define TCL_PARSE_SCAN_PREFIXES 16 +#define TCL_PARSE_SCAN_PREFIXES 16 /* Use [scan] rules dealing with 0? * prefixes. */ -#define TCL_PARSE_NO_WHITESPACE 32 +#define TCL_PARSE_NO_WHITESPACE 32 /* Reject leading/trailing whitespace. */ #define TCL_PARSE_BINARY_ONLY 64 /* Parse binary even without prefix. */ #define TCL_PARSE_NO_UNDERSCORE 128 /* Reject underscore digit separator */ - /* *---------------------------------------------------------------------- * Internal convenience macros for manipulating encoding flags. See @@ -2889,12 +2912,12 @@ typedef struct ProcessGlobalValue { #define ENCODING_PROFILE_MASK 0xFF000000 #define ENCODING_PROFILE_GET(flags_) (((flags_) & TCL_ENCODING_PROFILE_STRICT) ? \ - TCL_ENCODING_PROFILE_STRICT : (((flags_) & ENCODING_PROFILE_MASK) ? \ - ((flags_) & ENCODING_PROFILE_MASK) : TCL_ENCODING_PROFILE_TCL8)) -#define ENCODING_PROFILE_SET(flags_, profile_) \ - do { \ - (flags_) &= ~(ENCODING_PROFILE_MASK|TCL_ENCODING_PROFILE_STRICT); \ - (flags_) |= (profile_) & (ENCODING_PROFILE_MASK|TCL_ENCODING_PROFILE_STRICT); \ + TCL_ENCODING_PROFILE_STRICT : (((flags_) & ENCODING_PROFILE_MASK) ? \ + ((flags_) & ENCODING_PROFILE_MASK) : TCL_ENCODING_PROFILE_TCL8)) +#define ENCODING_PROFILE_SET(flags_, profile_) \ + do { \ + (flags_) &= ~(ENCODING_PROFILE_MASK|TCL_ENCODING_PROFILE_STRICT); \ + (flags_) |= ((profile_) & (ENCODING_PROFILE_MASK|TCL_ENCODING_PROFILE_STRICT)); \ } while (0) /* @@ -2914,13 +2937,12 @@ MODULE_SCOPE TclPlatformType tclPlatform; MODULE_SCOPE Tcl_Encoding tclIdentityEncoding; MODULE_SCOPE Tcl_Encoding tclUtf8Encoding; -MODULE_SCOPE int -TclEncodingProfileNameToId(Tcl_Interp *interp, - const char *profileName, - int *profilePtr); +MODULE_SCOPE int TclEncodingProfileNameToId(Tcl_Interp *interp, + const char *profileName, + int *profilePtr); MODULE_SCOPE const char *TclEncodingProfileIdToName(Tcl_Interp *interp, - int profileId); -MODULE_SCOPE void TclGetEncodingProfiles(Tcl_Interp *interp); + int profileId); +MODULE_SCOPE void TclGetEncodingProfiles(Tcl_Interp *interp); /* * TIP #233 (Virtualized Time) @@ -3022,12 +3044,13 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldToObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRInvoke; MODULE_SCOPE Tcl_NRPostProc TclNRReleaseValues; -MODULE_SCOPE void TclSetTailcall(Tcl_Interp *interp, Tcl_Obj *tailcallPtr); -MODULE_SCOPE void TclPushTailcallPoint(Tcl_Interp *interp); +MODULE_SCOPE void TclSetTailcall(Tcl_Interp *interp, + Tcl_Obj *tailcallPtr); +MODULE_SCOPE void TclPushTailcallPoint(Tcl_Interp *interp); /* These two can be considered for the public api */ -MODULE_SCOPE void TclMarkTailcall(Tcl_Interp *interp); -MODULE_SCOPE void TclSkipTailcall(Tcl_Interp *interp); +MODULE_SCOPE void TclMarkTailcall(Tcl_Interp *interp); +MODULE_SCOPE void TclSkipTailcall(Tcl_Interp *interp); /* * This structure holds the data for the various iteration callbacks used to @@ -3044,7 +3067,7 @@ typedef struct ForIterData { Tcl_Obj *body; /* Loop body. */ Tcl_Obj *next; /* Loop step script, NULL for 'while'. */ const char *msg; /* Error message part. */ - Tcl_Size word; /* Index of the body script in the command */ + Tcl_Size word; /* Index of the body script in the command */ } ForIterData; /* TIP #357 - Structure doing the bookkeeping of handles for Tcl_LoadFile @@ -3052,9 +3075,9 @@ typedef struct ForIterData { * typedef in tcl.h */ typedef void* TclFindSymbolProc(Tcl_Interp* interp, Tcl_LoadHandle loadHandle, - const char* symbol); + const char* symbol); struct Tcl_LoadHandle_ { - void *clientData; /* Client data is the load handle in the + void *clientData; /* Client data is the load handle in the * native filesystem if a module was loaded * there, or an opaque pointer to a structure * for further bookkeeping on load-from-VFS @@ -3068,16 +3091,12 @@ struct Tcl_LoadHandle_ { /* Flags for conversion of doubles to digit strings */ -#define TCL_DD_E_FORMAT 0x2 - /* Use a fixed-length string of digits, +#define TCL_DD_E_FORMAT 0x2 /* Use a fixed-length string of digits, * suitable for E format*/ -#define TCL_DD_F_FORMAT 0x3 - /* Use a fixed number of digits after the +#define TCL_DD_F_FORMAT 0x3 /* Use a fixed number of digits after the * decimal point, suitable for F format */ -#define TCL_DD_SHORTEST 0x4 - /* Use the shortest possible string */ -#define TCL_DD_NO_QUICK 0x8 - /* Debug flag: forbid quick FP conversion */ +#define TCL_DD_SHORTEST 0x4 /* Use the shortest possible string */ +#define TCL_DD_NO_QUICK 0x8 /* Debug flag: forbid quick FP conversion */ #define TCL_DD_CONVERSION_TYPE_MASK 0x3 /* Mask to isolate the conversion type */ @@ -3097,12 +3116,13 @@ MODULE_SCOPE void TclAppendBytesToByteArray(Tcl_Obj *objPtr, MODULE_SCOPE void TclAppendUtfToUtf(Tcl_Obj *objPtr, const char *bytes, Tcl_Size numBytes); MODULE_SCOPE void TclArgumentEnter(Tcl_Interp *interp, - Tcl_Obj *objv[], int objc, CmdFrame *cf); + Tcl_Obj *objv[], Tcl_Size objc, CmdFrame *cf); MODULE_SCOPE void TclArgumentRelease(Tcl_Interp *interp, - Tcl_Obj *objv[], int objc); + Tcl_Obj *objv[], Tcl_Size objc); MODULE_SCOPE void TclArgumentBCEnter(Tcl_Interp *interp, - Tcl_Obj *objv[], int objc, - void *codePtr, CmdFrame *cfPtr, Tcl_Size cmd, Tcl_Size pc); + Tcl_Obj *objv[], Tcl_Size objc, + void *codePtr, CmdFrame *cfPtr, Tcl_Size cmd, + Tcl_Size pc); MODULE_SCOPE void TclArgumentBCRelease(Tcl_Interp *interp, CmdFrame *cfPtr); MODULE_SCOPE void TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj, @@ -3126,7 +3146,7 @@ MODULE_SCOPE int TclCheckEmptyString(Tcl_Obj *objPtr); MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp, Tcl_Channel chan); MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd; -MODULE_SCOPE int TclChanIsBinary(Tcl_Channel chan); +MODULE_SCOPE int TclChanIsBinary(Tcl_Channel chan); MODULE_SCOPE Tcl_NRPostProc TclClearRootEnsemble; MODULE_SCOPE int TclCompareTwoNumbers(Tcl_Obj *valuePtr, Tcl_Obj *value2Ptr); @@ -3185,7 +3205,8 @@ MODULE_SCOPE char * TclDStringAppendObj(Tcl_DString *dsPtr, MODULE_SCOPE char * TclDStringAppendDString(Tcl_DString *dsPtr, Tcl_DString *toAppendPtr); MODULE_SCOPE Tcl_Obj *const *TclFetchEnsembleRoot(Tcl_Interp *interp, - Tcl_Obj *const *objv, Tcl_Size objc, Tcl_Size *objcPtr); + Tcl_Obj *const *objv, Tcl_Size objc, + Tcl_Size *objcPtr); MODULE_SCOPE Tcl_Obj *const *TclEnsembleGetRewriteValues(Tcl_Interp *interp); MODULE_SCOPE Tcl_Namespace *TclEnsureNamespace(Tcl_Interp *interp, Tcl_Namespace *namespacePtr); @@ -3232,7 +3253,7 @@ MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, MODULE_SCOPE Proc * TclGetLambdaFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj **nsObjPtrPtr); MODULE_SCOPE Tcl_Obj * TclGetProcessGlobalValue(ProcessGlobalValue *pgvPtr); -MODULE_SCOPE Tcl_Obj * TclGetSourceFromFrame(CmdFrame *cfPtr, int objc, +MODULE_SCOPE Tcl_Obj * TclGetSourceFromFrame(CmdFrame *cfPtr, Tcl_Size objc, Tcl_Obj *const objv[]); MODULE_SCOPE char * TclGetStringStorage(Tcl_Obj *objPtr, TCL_HASH_TYPE *sizePtr); @@ -3300,7 +3321,7 @@ MODULE_SCOPE Tcl_Size TclMaxListLength(const char *bytes, Tcl_Size numBytes, MODULE_SCOPE int TclMergeReturnOptions(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], Tcl_Obj **optionsPtrPtr, int *codePtr, int *levelPtr); -MODULE_SCOPE Tcl_Obj * TclNoErrorStack(Tcl_Interp *interp, Tcl_Obj *options); +MODULE_SCOPE Tcl_Obj * TclNoErrorStack(Tcl_Interp *interp, Tcl_Obj *options); MODULE_SCOPE int TclNokia770Doubles(void); MODULE_SCOPE void TclNsDecrRefCount(Namespace *nsPtr); MODULE_SCOPE int TclNamespaceDeleted(Namespace *nsPtr); @@ -3324,12 +3345,12 @@ MODULE_SCOPE int TclProcessReturn(Tcl_Interp *interp, int code, int level, Tcl_Obj *returnOpts); MODULE_SCOPE int TclpObjLstat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); MODULE_SCOPE Tcl_Obj * TclpTempFileName(void); -MODULE_SCOPE Tcl_Obj * TclpTempFileNameForLibrary(Tcl_Interp *interp, +MODULE_SCOPE Tcl_Obj * TclpTempFileNameForLibrary(Tcl_Interp *interp, Tcl_Obj* pathPtr); MODULE_SCOPE Tcl_Obj * TclNewFSPathObj(Tcl_Obj *dirPtr, const char *addStrRep, Tcl_Size len); MODULE_SCOPE void TclpAlertNotifier(void *clientData); -MODULE_SCOPE void *TclpNotifierData(void); +MODULE_SCOPE void * TclpNotifierData(void); MODULE_SCOPE void TclpServiceModeHook(int mode); MODULE_SCOPE void TclpSetTimer(const Tcl_Time *timePtr); MODULE_SCOPE int TclpWaitForEvent(const Tcl_Time *timePtr); @@ -3359,7 +3380,7 @@ MODULE_SCOPE Tcl_Size TclpFindVariable(const char *name, Tcl_Size *lengthPtr); MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr, TCL_HASH_TYPE *lengthPtr, Tcl_Encoding *encodingPtr); MODULE_SCOPE void TclpInitLock(void); -MODULE_SCOPE void *TclpInitNotifier(void); +MODULE_SCOPE void * TclpInitNotifier(void); MODULE_SCOPE void TclpInitPlatform(void); MODULE_SCOPE void TclpInitUnlock(void); MODULE_SCOPE Tcl_Obj * TclpObjListVolumes(void); @@ -3441,7 +3462,8 @@ MODULE_SCOPE int TclSubstTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr, Tcl_Size count, int *tokensLeftPtr, Tcl_Size line, Tcl_Size *clNextOuter, const char *outerScript); MODULE_SCOPE Tcl_Size TclTrim(const char *bytes, Tcl_Size numBytes, - const char *trim, Tcl_Size numTrim, Tcl_Size *trimRight); + const char *trim, Tcl_Size numTrim, + Tcl_Size *trimRight); MODULE_SCOPE Tcl_Size TclTrimLeft(const char *bytes, Tcl_Size numBytes, const char *trim, Tcl_Size numTrim); MODULE_SCOPE Tcl_Size TclTrimRight(const char *bytes, Tcl_Size numBytes, @@ -3470,19 +3492,19 @@ MODULE_SCOPE void TclFinalizeThreadDataThread(void); MODULE_SCOPE void TclFinalizeThreadStorage(void); #ifdef TCL_WIDE_CLICKS -MODULE_SCOPE long long TclpGetWideClicks(void); +MODULE_SCOPE long long TclpGetWideClicks(void); MODULE_SCOPE double TclpWideClicksToNanoseconds(long long clicks); MODULE_SCOPE double TclpWideClickInMicrosec(void); #else # ifdef _WIN32 # define TCL_WIDE_CLICKS 1 -MODULE_SCOPE long long TclpGetWideClicks(void); +MODULE_SCOPE long long TclpGetWideClicks(void); MODULE_SCOPE double TclpWideClickInMicrosec(void); -# define TclpWideClicksToNanoseconds(clicks) \ - ((double)(clicks) * TclpWideClickInMicrosec() * 1000) +# define TclpWideClicksToNanoseconds(clicks) \ + ((double)(clicks) * TclpWideClickInMicrosec() * 1000) # endif #endif -MODULE_SCOPE long long TclpGetMicroseconds(void); +MODULE_SCOPE long long TclpGetMicroseconds(void); MODULE_SCOPE int TclZlibInit(Tcl_Interp *interp); MODULE_SCOPE void * TclpThreadCreateKey(void); @@ -3515,8 +3537,8 @@ MODULE_SCOPE int TclUtfNmemcmp(const void *s1, const void *s2, size_t n); */ MODULE_SCOPE int TclIsSpaceProc(int byte); -# define TclIsSpaceProcM(byte) \ - (((byte) > 0x20) ? 0 : TclIsSpaceProc(byte)) +#define TclIsSpaceProcM(byte) \ + (((byte) > 0x20) ? 0 : TclIsSpaceProc(byte)) /* *---------------------------------------------------------------- @@ -3937,8 +3959,8 @@ MODULE_SCOPE int TclIndexEncode(Tcl_Interp *interp, Tcl_Obj *objPtr, MODULE_SCOPE Tcl_Size TclIndexDecode(int encoded, Tcl_Size endValue); /* Constants used in index value encoding routines. */ -#define TCL_INDEX_END ((Tcl_Size)-2) -#define TCL_INDEX_START ((Tcl_Size)0) +#define TCL_INDEX_END ((Tcl_Size)-2) +#define TCL_INDEX_START ((Tcl_Size)0) /* *---------------------------------------------------------------------- @@ -4017,20 +4039,20 @@ TclScaleTime( # define TclIncrObjsFreed() #endif /* TCL_COMPILE_STATS */ -# define TclAllocObjStorage(objPtr) \ +# define TclAllocObjStorage(objPtr) \ TclAllocObjStorageEx(NULL, (objPtr)) -# define TclFreeObjStorage(objPtr) \ +# define TclFreeObjStorage(objPtr) \ TclFreeObjStorageEx(NULL, (objPtr)) #ifndef TCL_MEM_DEBUG # define TclNewObj(objPtr) \ - TclIncrObjsAllocated(); \ - TclAllocObjStorage(objPtr); \ - (objPtr)->refCount = 0; \ - (objPtr)->bytes = &tclEmptyString; \ - (objPtr)->length = 0; \ - (objPtr)->typePtr = NULL; \ + TclIncrObjsAllocated(); \ + TclAllocObjStorage(objPtr); \ + (objPtr)->refCount = 0; \ + (objPtr)->bytes = &tclEmptyString; \ + (objPtr)->length = 0; \ + (objPtr)->typePtr = NULL; \ TCL_DTRACE_OBJ_CREATE(objPtr) /* @@ -4041,19 +4063,19 @@ TclScaleTime( */ # define TclDecrRefCount(objPtr) \ - if ((objPtr)->refCount-- > 1) ; else { \ - if (!(objPtr)->typePtr || !(objPtr)->typePtr->freeIntRepProc) { \ - TCL_DTRACE_OBJ_FREE(objPtr); \ - if ((objPtr)->bytes \ - && ((objPtr)->bytes != &tclEmptyString)) { \ - ckfree((objPtr)->bytes); \ - } \ - (objPtr)->length = TCL_INDEX_NONE; \ - TclFreeObjStorage(objPtr); \ - TclIncrObjsFreed(); \ - } else { \ - TclFreeObj(objPtr); \ - } \ + if ((objPtr)->refCount-- > 1) ; else { \ + if (!(objPtr)->typePtr || !(objPtr)->typePtr->freeIntRepProc) { \ + TCL_DTRACE_OBJ_FREE(objPtr); \ + if ((objPtr)->bytes \ + && ((objPtr)->bytes != &tclEmptyString)) { \ + ckfree((objPtr)->bytes); \ + } \ + (objPtr)->length = TCL_INDEX_NONE; \ + TclFreeObjStorage(objPtr); \ + TclIncrObjsFreed(); \ + } else { \ + TclFreeObj(objPtr); \ + } \ } #if TCL_THREADS && !defined(USE_THREAD_ALLOC) @@ -4160,11 +4182,11 @@ MODULE_SCOPE Tcl_Mutex tclObjMutex; } while (0) # define TclFreeObjStorageEx(interp, objPtr) \ - do { \ - Tcl_MutexLock(&tclObjMutex); \ + do { \ + Tcl_MutexLock(&tclObjMutex); \ (objPtr)->internalRep.twoPtrValue.ptr1 = (void *) tclFreeObjList; \ - tclFreeObjList = (objPtr); \ - Tcl_MutexUnlock(&tclObjMutex); \ + tclFreeObjList = (objPtr); \ + Tcl_MutexUnlock(&tclObjMutex); \ } while (0) #endif @@ -4215,27 +4237,26 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, */ #define TclInitEmptyStringRep(objPtr) \ - ((objPtr)->length = (((objPtr)->bytes = &tclEmptyString), 0)) - + ((objPtr)->length = (((objPtr)->bytes = &tclEmptyString), 0)) #define TclInitStringRep(objPtr, bytePtr, len) \ - if ((len) == 0) { \ - TclInitEmptyStringRep(objPtr); \ - } else { \ - (objPtr)->bytes = (char *)ckalloc((len) + 1U); \ + if ((len) == 0) { \ + TclInitEmptyStringRep(objPtr); \ + } else { \ + (objPtr)->bytes = (char *)ckalloc((len) + 1U); \ memcpy((objPtr)->bytes, (bytePtr) ? (bytePtr) : &tclEmptyString, (len)); \ - (objPtr)->bytes[len] = '\0'; \ - (objPtr)->length = (len); \ + (objPtr)->bytes[len] = '\0'; \ + (objPtr)->length = (len); \ } #define TclAttemptInitStringRep(objPtr, bytePtr, len) \ - ((((len) == 0) ? ( \ - TclInitEmptyStringRep(objPtr) \ - ) : ( \ - (objPtr)->bytes = (char *)attemptckalloc((len) + 1U), \ - (objPtr)->length = ((objPtr)->bytes) ? \ + ((((len) == 0) ? ( \ + TclInitEmptyStringRep(objPtr) \ + ) : ( \ + (objPtr)->bytes = (char *)attemptckalloc((len) + 1U), \ + (objPtr)->length = ((objPtr)->bytes) ? \ (memcpy((objPtr)->bytes, (bytePtr) ? (bytePtr) : &tclEmptyString, (len)), \ - (objPtr)->bytes[len] = '\0', (len)) : (-1) \ + (objPtr)->bytes[len] = '\0', (len)) : (-1) \ )), (objPtr)->bytes) /* @@ -4254,8 +4275,8 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, ((objPtr)->bytes? (objPtr)->bytes : Tcl_GetString(objPtr)) #define TclGetStringFromObj(objPtr, lenPtr) \ - ((objPtr)->bytes \ - ? (*(lenPtr) = (objPtr)->length, (objPtr)->bytes) \ + ((objPtr)->bytes \ + ? (*(lenPtr) = (objPtr)->length, (objPtr)->bytes) \ : (Tcl_GetStringFromObj)((objPtr), (lenPtr))) /* @@ -4269,11 +4290,11 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, */ #define TclFreeInternalRep(objPtr) \ - if ((objPtr)->typePtr != NULL) { \ - if ((objPtr)->typePtr->freeIntRepProc != NULL) { \ - (objPtr)->typePtr->freeIntRepProc(objPtr); \ - } \ - (objPtr)->typePtr = NULL; \ + if ((objPtr)->typePtr != NULL) { \ + if ((objPtr)->typePtr->freeIntRepProc != NULL) { \ + (objPtr)->typePtr->freeIntRepProc(objPtr); \ + } \ + (objPtr)->typePtr = NULL; \ } #if !defined(TCL_NO_DEPRECATED) @@ -4290,14 +4311,14 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, */ #define TclInvalidateStringRep(objPtr) \ - do { \ - Tcl_Obj *_isobjPtr = (Tcl_Obj *)(objPtr); \ - if (_isobjPtr->bytes != NULL) { \ - if (_isobjPtr->bytes != &tclEmptyString) { \ - ckfree((char *)_isobjPtr->bytes); \ - } \ - _isobjPtr->bytes = NULL; \ - } \ + do { \ + Tcl_Obj *_isobjPtr = (Tcl_Obj *)(objPtr); \ + if (_isobjPtr->bytes != NULL) { \ + if (_isobjPtr->bytes != &tclEmptyString) { \ + ckfree((char *)_isobjPtr->bytes); \ + } \ + _isobjPtr->bytes = NULL; \ + } \ } while (0) /* @@ -4340,8 +4361,8 @@ MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[]; #define TclUnpackBignum(objPtr, bignum) \ do { \ - Tcl_Obj *bignumObj = (objPtr); \ - int bignumPayload = \ + Tcl_Obj *bignumObj = (objPtr); \ + int bignumPayload = \ PTR2INT(bignumObj->internalRep.twoPtrValue.ptr2); \ if (bignumPayload == -1) { \ (bignum) = *((mp_int *) bignumObj->internalRep.twoPtrValue.ptr1); \ @@ -4400,20 +4421,20 @@ MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[]; if (allocated > TCL_MAX_TOKENS) { \ allocated = TCL_MAX_TOKENS; \ } \ - newPtr = (Tcl_Token *) attemptckrealloc((char *) oldPtr, \ - allocated * sizeof(Tcl_Token)); \ + newPtr = (Tcl_Token *)attemptckrealloc((char *) oldPtr, \ + allocated * sizeof(Tcl_Token)); \ if (newPtr == NULL) { \ allocated = _needed + (append) + TCL_MIN_TOKEN_GROWTH; \ if (allocated > TCL_MAX_TOKENS) { \ allocated = TCL_MAX_TOKENS; \ } \ - newPtr = (Tcl_Token *) ckrealloc((char *) oldPtr, \ - allocated * sizeof(Tcl_Token)); \ + newPtr = (Tcl_Token *)ckrealloc((char *) oldPtr, \ + allocated * sizeof(Tcl_Token)); \ } \ (available) = allocated; \ if (oldPtr == NULL) { \ memcpy(newPtr, staticPtr, \ - (used) * sizeof(Tcl_Token)); \ + (used) * sizeof(Tcl_Token)); \ } \ (tokenPtr) = newPtr; \ } \ @@ -4437,8 +4458,8 @@ MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[]; */ #define TclUtfToUniChar(str, chPtr) \ - (((UCHAR(*(str))) < 0x80) ? \ - ((*(chPtr) = UCHAR(*(str))), 1) \ + (((UCHAR(*(str))) < 0x80) ? \ + ((*(chPtr) = UCHAR(*(str))), 1) \ : Tcl_UtfToUniChar(str, chPtr)) /* @@ -4455,15 +4476,15 @@ MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[]; */ #define TclNumUtfCharsM(numChars, bytes, numBytes) \ - do { \ - Tcl_Size _count, _i = (numBytes); \ - unsigned char *_str = (unsigned char *) (bytes); \ - while (_i > 0 && (*_str < 0xC0)) { _i--; _str++; } \ - _count = (numBytes) - _i; \ - if (_i) { \ - _count += TclNumUtfChars((bytes) + _count, _i); \ - } \ - (numChars) = _count; \ + do { \ + Tcl_Size _count, _i = (numBytes); \ + unsigned char *_str = (unsigned char *) (bytes); \ + while (_i > 0 && (*_str < 0xC0)) { _i--; _str++; } \ + _count = (numBytes) - _i; \ + if (_i) { \ + _count += TclNumUtfChars((bytes) + _count, _i); \ + } \ + (numChars) = _count; \ } while (0); /* @@ -4483,12 +4504,11 @@ MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[]; MODULE_SCOPE int TclIsPureByteArray(Tcl_Obj *objPtr); #define TclIsPureDict(objPtr) \ - (((objPtr)->bytes==NULL) && ((objPtr)->typePtr==&tclDictType)) + (((objPtr)->bytes == NULL) && ((objPtr)->typePtr==&tclDictType)) #define TclHasInternalRep(objPtr, type) \ - ((objPtr)->typePtr == (type)) + ((objPtr)->typePtr == (type)) #define TclFetchInternalRep(objPtr, type) \ - (TclHasInternalRep((objPtr), (type)) ? &((objPtr)->internalRep) : NULL) - + (TclHasInternalRep((objPtr), (type)) ? &(objPtr)->internalRep : NULL) /* *---------------------------------------------------------------- @@ -4533,7 +4553,6 @@ MODULE_SCOPE Tcl_LibraryInitProc TclThread_Init; MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_Init; MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit; - /* *---------------------------------------------------------------- * Macro used by the Tcl core to check whether a pattern has any characters @@ -4559,18 +4578,18 @@ MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit; */ #define TclSetIntObj(objPtr, i) \ - do { \ - Tcl_ObjInternalRep ir; \ - ir.wideValue = (Tcl_WideInt) i; \ - TclInvalidateStringRep(objPtr); \ - Tcl_StoreInternalRep(objPtr, &tclIntType, &ir); \ + do { \ + Tcl_ObjInternalRep ir; \ + ir.wideValue = (Tcl_WideInt) i; \ + TclInvalidateStringRep(objPtr); \ + Tcl_StoreInternalRep(objPtr, &tclIntType, &ir); \ } while (0) #define TclSetDoubleObj(objPtr, d) \ - do { \ - Tcl_ObjInternalRep ir; \ - ir.doubleValue = (double) d; \ - TclInvalidateStringRep(objPtr); \ + do { \ + Tcl_ObjInternalRep ir; \ + ir.doubleValue = (double) d; \ + TclInvalidateStringRep(objPtr); \ Tcl_StoreInternalRep(objPtr, &tclDoubleType, &ir); \ } while (0) @@ -4590,58 +4609,58 @@ MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit; #ifndef TCL_MEM_DEBUG #define TclNewIntObj(objPtr, w) \ - do { \ - TclIncrObjsAllocated(); \ - TclAllocObjStorage(objPtr); \ - (objPtr)->refCount = 0; \ - (objPtr)->bytes = NULL; \ - (objPtr)->internalRep.wideValue = (Tcl_WideInt)(w); \ - (objPtr)->typePtr = &tclIntType; \ - TCL_DTRACE_OBJ_CREATE(objPtr); \ + do { \ + TclIncrObjsAllocated(); \ + TclAllocObjStorage(objPtr); \ + (objPtr)->refCount = 0; \ + (objPtr)->bytes = NULL; \ + (objPtr)->internalRep.wideValue = (Tcl_WideInt)(w); \ + (objPtr)->typePtr = &tclIntType; \ + TCL_DTRACE_OBJ_CREATE(objPtr); \ } while (0) #define TclNewUIntObj(objPtr, uw) \ - do { \ - TclIncrObjsAllocated(); \ - TclAllocObjStorage(objPtr); \ - (objPtr)->refCount = 0; \ - (objPtr)->bytes = NULL; \ - Tcl_WideUInt uw_ = (uw); \ - if (uw_ > WIDE_MAX) { \ - mp_int bignumValue_; \ - if (mp_init_u64(&bignumValue_, uw_) != MP_OKAY) { \ + do { \ + TclIncrObjsAllocated(); \ + TclAllocObjStorage(objPtr); \ + (objPtr)->refCount = 0; \ + (objPtr)->bytes = NULL; \ + Tcl_WideUInt uw_ = (uw); \ + if (uw_ > WIDE_MAX) { \ + mp_int bignumValue_; \ + if (mp_init_u64(&bignumValue_, uw_) != MP_OKAY) { \ Tcl_Panic("%s: memory overflow", "TclNewUIntObj"); \ - } \ - TclSetBignumInternalRep((objPtr), &bignumValue_); \ - } else { \ + } \ + TclSetBignumInternalRep((objPtr), &bignumValue_); \ + } else { \ (objPtr)->internalRep.wideValue = (Tcl_WideInt)(uw_); \ - (objPtr)->typePtr = &tclIntType; \ - } \ - TCL_DTRACE_OBJ_CREATE(objPtr); \ + (objPtr)->typePtr = &tclIntType; \ + } \ + TCL_DTRACE_OBJ_CREATE(objPtr); \ } while (0) #define TclNewIndexObj(objPtr, w) \ TclNewIntObj(objPtr, w) #define TclNewDoubleObj(objPtr, d) \ - do { \ - TclIncrObjsAllocated(); \ - TclAllocObjStorage(objPtr); \ - (objPtr)->refCount = 0; \ - (objPtr)->bytes = NULL; \ - (objPtr)->internalRep.doubleValue = (double)(d); \ - (objPtr)->typePtr = &tclDoubleType; \ - TCL_DTRACE_OBJ_CREATE(objPtr); \ + do { \ + TclIncrObjsAllocated(); \ + TclAllocObjStorage(objPtr); \ + (objPtr)->refCount = 0; \ + (objPtr)->bytes = NULL; \ + (objPtr)->internalRep.doubleValue = (double)(d); \ + (objPtr)->typePtr = &tclDoubleType; \ + TCL_DTRACE_OBJ_CREATE(objPtr); \ } while (0) #define TclNewStringObj(objPtr, s, len) \ - do { \ - TclIncrObjsAllocated(); \ - TclAllocObjStorage(objPtr); \ - (objPtr)->refCount = 0; \ - TclInitStringRep((objPtr), (s), (len)); \ - (objPtr)->typePtr = NULL; \ - TCL_DTRACE_OBJ_CREATE(objPtr); \ + do { \ + TclIncrObjsAllocated(); \ + TclAllocObjStorage(objPtr); \ + (objPtr)->refCount = 0; \ + TclInitStringRep((objPtr), (s), (len)); \ + (objPtr)->typePtr = NULL; \ + TCL_DTRACE_OBJ_CREATE(objPtr); \ } while (0) #else /* TCL_MEM_DEBUG */ @@ -4649,18 +4668,18 @@ MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit; (objPtr) = Tcl_NewWideIntObj(w) #define TclNewUIntObj(objPtr, uw) \ - do { \ - Tcl_WideUInt uw_ = (uw); \ - if (uw_ > WIDE_MAX) { \ - mp_int bignumValue_; \ - if (mp_init_u64(&bignumValue_, uw_) == MP_OKAY) { \ - (objPtr) = Tcl_NewBignumObj(&bignumValue_); \ - } else { \ - (objPtr) = NULL; \ - } \ - } else { \ - (objPtr) = Tcl_NewWideIntObj(uw_); \ - } \ + do { \ + Tcl_WideUInt uw_ = (uw); \ + if (uw_ > WIDE_MAX) { \ + mp_int bignumValue_; \ + if (mp_init_u64(&bignumValue_, uw_) == MP_OKAY) { \ + (objPtr) = Tcl_NewBignumObj(&bignumValue_); \ + } else { \ + (objPtr) = NULL; \ + } \ + } else { \ + (objPtr) = Tcl_NewWideIntObj(uw_); \ + } \ } while (0) #define TclNewIndexObj(objPtr, w) \ @@ -4739,28 +4758,26 @@ MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit; * the internal stubs, but the core can use the macro instead. */ -#define TclCleanupCommandMacro(cmdPtr) \ +#define TclCleanupCommandMacro(cmdPtr) \ do { \ if ((cmdPtr)->refCount-- <= 1) { \ ckfree(cmdPtr); \ } \ } while (0) - /* * inside this routine crement refCount first incase cmdPtr is replacing itself */ -#define TclRoutineAssign(location, cmdPtr) \ - do { \ - (cmdPtr)->refCount++; \ - if ((location) != NULL \ - && (location--) <= 1) { \ - ckfree(((location))); \ - } \ - (location) = (cmdPtr); \ +#define TclRoutineAssign(location, cmdPtr) \ + do { \ + (cmdPtr)->refCount++; \ + if ((location) != NULL \ + && (location--) <= 1) { \ + ckfree(((location))); \ + } \ + (location) = (cmdPtr); \ } while (0) - #define TclRoutineHasName(cmdPtr) \ ((cmdPtr)->hPtr != NULL) @@ -4773,9 +4790,10 @@ MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit; * to the non-inline version. */ -#define TclLimitExceeded(limit) ((limit).exceeded != 0) +#define TclLimitExceeded(limit) \ + ((limit).exceeded != 0) -#define TclLimitReady(limit) \ +#define TclLimitReady(limit) \ (((limit).active == 0) ? 0 : \ (++(limit).granularityTicker, \ ((((limit).active & TCL_LIMIT_COMMANDS) && \ @@ -4893,7 +4911,8 @@ typedef struct NRE_callback { struct NRE_callback *nextPtr; } NRE_callback; -#define TOP_CB(iPtr) (((Interp *)(iPtr))->execEnvPtr->callbackPtr) +#define TOP_CB(iPtr) \ + (((Interp *)(iPtr))->execEnvPtr->callbackPtr) /* * Inline version of Tcl_NRAddCallback. @@ -4932,9 +4951,9 @@ typedef struct NRE_callback { #include "tclIntPlatDecls.h" #if !defined(USE_TCL_STUBS) && !defined(TCL_MEM_DEBUG) -#define Tcl_AttemptAlloc TclpAlloc -#define Tcl_AttemptRealloc TclpRealloc -#define Tcl_Free TclpFree +#define Tcl_AttemptAlloc TclpAlloc +#define Tcl_AttemptRealloc TclpRealloc +#define Tcl_Free TclpFree #endif /* diff --git a/generic/tclVar.c b/generic/tclVar.c index d2922ec..ed3ea7a 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -209,7 +209,7 @@ static void UnsetVarStruct(Var *varPtr, Var *arrayPtr, * TIP #508: [array default] */ -static Tcl_ObjCmdProc ArrayDefaultCmd; +static Tcl_ObjCmdProc ArrayDefaultCmd; static void DeleteArrayVar(Var *arrayPtr); static void SetArrayDefault(Var *arrayPtr, Tcl_Obj *defaultObj); @@ -248,7 +248,7 @@ static const Tcl_ObjType localVarNameType = { FreeLocalVarName, DupLocalVarName, NULL, NULL }; -#define LocalSetInternalRep(objPtr, index, namePtr) \ +#define LocalSetInternalRep(objPtr, index, namePtr) \ do { \ Tcl_ObjInternalRep ir; \ Tcl_Obj *ptr = (namePtr); \ @@ -258,12 +258,12 @@ static const Tcl_ObjType localVarNameType = { Tcl_StoreInternalRep((objPtr), &localVarNameType, &ir); \ } while (0) -#define LocalGetInternalRep(objPtr, index, name) \ +#define LocalGetInternalRep(objPtr, index, name) \ do { \ - const Tcl_ObjInternalRep *irPtr; \ - irPtr = TclFetchInternalRep((objPtr), &localVarNameType); \ - (name) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr1 : NULL; \ - (index) = irPtr ? PTR2INT(irPtr->twoPtrValue.ptr2) : TCL_INDEX_NONE; \ + const Tcl_ObjInternalRep *irPtr; \ + irPtr = TclFetchInternalRep((objPtr), &localVarNameType); \ + (name) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr1 : NULL; \ + (index) = irPtr ? PTR2INT(irPtr->twoPtrValue.ptr2) : TCL_INDEX_NONE; \ } while (0) static const Tcl_ObjType parsedVarNameType = { @@ -271,7 +271,7 @@ static const Tcl_ObjType parsedVarNameType = { FreeParsedVarName, DupParsedVarName, NULL, NULL }; -#define ParsedSetInternalRep(objPtr, arrayPtr, elem) \ +#define ParsedSetInternalRep(objPtr, arrayPtr, elem) \ do { \ Tcl_ObjInternalRep ir; \ Tcl_Obj *ptr1 = (arrayPtr); \ @@ -280,16 +280,16 @@ static const Tcl_ObjType parsedVarNameType = { if (ptr2) {Tcl_IncrRefCount(ptr2);} \ ir.twoPtrValue.ptr1 = ptr1; \ ir.twoPtrValue.ptr2 = ptr2; \ - Tcl_StoreInternalRep((objPtr), &parsedVarNameType, &ir); \ + Tcl_StoreInternalRep((objPtr), &parsedVarNameType, &ir); \ } while (0) -#define ParsedGetInternalRep(objPtr, parsed, array, elem) \ +#define ParsedGetInternalRep(objPtr, parsed, array, elem) \ do { \ - const Tcl_ObjInternalRep *irPtr; \ - irPtr = TclFetchInternalRep((objPtr), &parsedVarNameType); \ + const Tcl_ObjInternalRep *irPtr; \ + irPtr = TclFetchInternalRep((objPtr), &parsedVarNameType); \ (parsed) = (irPtr != NULL); \ - (array) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr1 : NULL; \ - (elem) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr2 : NULL; \ + (array) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr1 : NULL; \ + (elem) = irPtr ? (Tcl_Obj *)irPtr->twoPtrValue.ptr2 : NULL; \ } while (0) Var * @@ -526,7 +526,7 @@ TclLookupVar( Var * TclObjLookupVar( Tcl_Interp *interp, /* Interpreter to use for lookup. */ - Tcl_Obj *part1Ptr, /* If part2 isn't NULL, this is the name of an + Tcl_Obj *part1Ptr, /* If part2 isn't NULL, this is the name of an * array. Otherwise, this is a full variable * name that could include a parenthesized * array element. */ @@ -536,10 +536,10 @@ TclObjLookupVar( const char *msg, /* Verb to use in error messages, e.g. "read" * or "set". Only needed if TCL_LEAVE_ERR_MSG * is set in flags. */ - int createPart1, /* If 1, create hash table entry for part 1 of + int createPart1, /* If 1, create hash table entry for part 1 of * name, if it doesn't already exist. If 0, * return error if it doesn't exist. */ - int createPart2, /* If 1, create hash table entry for part 2 of + int createPart2, /* If 1, create hash table entry for part 2 of * name, if it doesn't already exist. If 0, * return error if it doesn't exist. */ Var **arrayPtrPtr) /* If the name refers to an element of an @@ -586,10 +586,10 @@ TclObjLookupVarEx( const char *msg, /* Verb to use in error messages, e.g. "read" * or "set". Only needed if TCL_LEAVE_ERR_MSG * is set in flags. */ - int createPart1, /* If 1, create hash table entry for part 1 of + int createPart1, /* If 1, create hash table entry for part 1 of * name, if it doesn't already exist. If 0, * return error if it doesn't exist. */ - int createPart2, /* If 1, create hash table entry for part 2 of + int createPart2, /* If 1, create hash table entry for part 2 of * name, if it doesn't already exist. If 0, * return error if it doesn't exist. */ Var **arrayPtrPtr) /* If the name refers to an element of an @@ -822,7 +822,7 @@ TclLookupSimpleVar( int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_AVOID_RESOLVERS and TCL_LEAVE_ERR_MSG * bits matter. */ - int create, /* If 1, create hash table entry for varname, + int create, /* If 1, create hash table entry for varname, * if it doesn't already exist. If 0, return * error if it doesn't exist. */ const char **errMsgPtr, @@ -909,7 +909,7 @@ TclLookupSimpleVar( const char *tail; int lookGlobal = (flags & TCL_GLOBAL_ONLY) || (cxtNsPtr == iPtr->globalNsPtr) - || ((*varName == ':') && (*(varName+1) == ':')); + || ((varName[0] == ':') && (varName[1] == ':')); if (lookGlobal) { *indexPtr = -1; @@ -985,7 +985,7 @@ TclLookupSimpleVar( localNameStr = TclGetStringFromObj(objPtr, &localLen); if ((varLen == localLen) && (varName[0] == localNameStr[0]) - && !memcmp(varName, localNameStr, varLen)) { + && !memcmp(varName, localNameStr, varLen)) { *indexPtr = i; return (Var *) &varFramePtr->compiledLocals[i]; } @@ -1058,15 +1058,15 @@ TclLookupArrayElement( Tcl_Obj *arrayNamePtr, /* This is the name of the array, or NULL if * index>= 0. */ Tcl_Obj *elNamePtr, /* Name of element within array. */ - int flags, /* Only TCL_LEAVE_ERR_MSG bit matters. */ + int flags, /* Only TCL_LEAVE_ERR_MSG bit matters. */ const char *msg, /* Verb to use in error messages, e.g. "read" * or "set". Only needed if TCL_LEAVE_ERR_MSG * is set in flags. */ - int createArray, /* If 1, transform arrayName to be an array if + int createArray, /* If 1, transform arrayName to be an array if * it isn't one yet and the transformation is * possible. If 0, return error if it isn't * already an array. */ - int createElem, /* If 1, create hash table entry for the + int createElem, /* If 1, create hash table entry for the * element, if it doesn't already exist. If 0, * return error if it doesn't exist. */ Var *arrayPtr, /* Pointer to the array's Var structure. */ @@ -1320,10 +1320,10 @@ Tcl_Obj * Tcl_ObjGetVar2( Tcl_Interp *interp, /* Command interpreter in which variable is to * be looked up. */ - Tcl_Obj *part1Ptr, /* Points to an object holding the name of an + Tcl_Obj *part1Ptr, /* Points to an object holding the name of an * array (if part2 is non-NULL) or the name of * a variable. */ - Tcl_Obj *part2Ptr, /* If non-null, points to an object holding + Tcl_Obj *part2Ptr, /* If non-null, points to an object holding * the name of an element in the array * part1Ptr. */ int flags) /* OR-ed combination of TCL_GLOBAL_ONLY and @@ -1379,7 +1379,7 @@ TclPtrGetVar( * the name of a variable. */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ - int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and + int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ { if (varPtr == NULL) { @@ -1418,14 +1418,14 @@ Tcl_Obj * TclPtrGetVarIdx( Tcl_Interp *interp, /* Command interpreter in which variable is to * be looked up. */ - Var *varPtr, /* The variable to be read.*/ + Var *varPtr, /* The variable to be read.*/ Var *arrayPtr, /* NULL for scalar variables, pointer to the * containing array otherwise. */ Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or * the name of a variable. */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ - int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and + int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ int index) /* Index into the local variable table of the * variable, or -1. Only used when part1Ptr is @@ -1523,7 +1523,7 @@ TclPtrGetVarIdx( int Tcl_SetObjCmd( TCL_UNUSED(void *), - Tcl_Interp *interp,/* Current interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { @@ -1747,10 +1747,10 @@ Tcl_Obj * Tcl_ObjSetVar2( Tcl_Interp *interp, /* Command interpreter in which variable is to * be found. */ - Tcl_Obj *part1Ptr, /* Points to an object holding the name of an + Tcl_Obj *part1Ptr, /* Points to an object holding the name of an * array (if part2 is non-NULL) or the name of * a variable. */ - Tcl_Obj *part2Ptr, /* If non-NULL, points to an object holding + Tcl_Obj *part2Ptr, /* If non-NULL, points to an object holding * the name of an element in the array * part1Ptr. */ Tcl_Obj *newValuePtr, /* New value for variable. */ @@ -1818,7 +1818,7 @@ TclPtrSetVar( Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ Tcl_Obj *newValuePtr, /* New value for variable. */ - int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and + int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ { if (varPtr == NULL) { @@ -1987,7 +1987,7 @@ Tcl_Obj * TclPtrSetVarIdx( Tcl_Interp *interp, /* Command interpreter in which variable is to * be looked up. */ - Var *varPtr, /* Reference to the variable to set. */ + Var *varPtr, /* Reference to the variable to set. */ Var *arrayPtr, /* Reference to the array containing the * variable, or NULL if the variable is a * scalar. */ @@ -1997,7 +1997,7 @@ TclPtrSetVarIdx( Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ Tcl_Obj *newValuePtr, /* New value for variable. */ - int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and + int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ int index) /* Index of local var where part1 is to be * found. */ @@ -2243,7 +2243,7 @@ TclPtrIncrObjVar( * part1Ptr. */ Tcl_Obj *incrPtr, /* Increment value. */ /* TODO: Which of these flag values really make sense? */ - int flags) /* Various flags that tell how to incr value: + int flags) /* Various flags that tell how to incr value: * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_APPEND_VALUE, TCL_LIST_ELEMENT, * TCL_LEAVE_ERR_MSG. */ @@ -2299,7 +2299,7 @@ TclPtrIncrObjVarIdx( * part1Ptr. */ Tcl_Obj *incrPtr, /* Increment value. */ /* TODO: Which of these flag values really make sense? */ - int flags, /* Various flags that tell how to incr value: + int flags, /* Various flags that tell how to incr value: * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_APPEND_VALUE, TCL_LIST_ELEMENT, * TCL_LEAVE_ERR_MSG. */ @@ -2528,7 +2528,7 @@ TclPtrUnsetVar( * the name of a variable. */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ - int flags) /* OR-ed combination of any of + int flags) /* OR-ed combination of any of * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_LEAVE_ERR_MSG. */ { @@ -2568,14 +2568,14 @@ int TclPtrUnsetVarIdx( Tcl_Interp *interp, /* Command interpreter in which varName is to * be looked up. */ - Var *varPtr, /* The variable to be unset. */ + Var *varPtr, /* The variable to be unset. */ Var *arrayPtr, /* NULL for scalar variables, pointer to the * containing array otherwise. */ Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or * the name of a variable. */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ - int flags, /* OR-ed combination of any of + int flags, /* OR-ed combination of any of * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_LEAVE_ERR_MSG. */ int index) /* Index into the local variable table of the @@ -4058,7 +4058,7 @@ TclFindArrayPtrElements( continue; } nameObj = VarHashGetKey(varPtr); - hPtr = Tcl_CreateHashEntry(tablePtr, (char *) nameObj, &dummy); + hPtr = Tcl_CreateHashEntry(tablePtr, (char *)nameObj, &dummy); Tcl_SetHashValue(hPtr, nameObj); } } @@ -4566,7 +4566,7 @@ ObjMakeUpvar( * NULL means use global :: context. */ Tcl_Obj *otherP1Ptr, const char *otherP2, /* Two-part name of variable in framePtr. */ - int otherFlags, /* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY: + int otherFlags, /* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY: * indicates scope of "other" variable. */ Tcl_Obj *myNamePtr, /* Name of variable which will refer to * otherP1/otherP2. Must be a scalar. */ @@ -5039,7 +5039,7 @@ Tcl_GlobalObjCmd( for (tail=varName ; *tail!='\0' ; tail++) { /* empty body */ } - while ((tail > varName) && ((*tail != ':') || (*(tail-1) != ':'))) { + while ((tail > varName) && ((tail[0] != ':') || (tail[-1] != ':'))) { tail--; } if ((*tail == ':') && (tail > varName)) { @@ -5405,7 +5405,7 @@ ParseSearchId( static void DeleteSearches( Interp *iPtr, - Var *arrayVarPtr) /* Variable whose searches are to be + Var *arrayVarPtr) /* Variable whose searches are to be * deleted. */ { ArraySearch *searchPtr, *nextPtr; @@ -5564,7 +5564,7 @@ TclDeleteVars( } for (varPtr = VarHashFirstVar(tablePtr, &search); varPtr != NULL; - varPtr = VarHashFirstVar(tablePtr, &search)) { + varPtr = VarHashFirstVar(tablePtr, &search)) { UnsetVarStruct(varPtr, NULL, iPtr, VarHashGetKey(varPtr), NULL, flags, -1); VarHashDeleteEntry(varPtr); @@ -6062,8 +6062,8 @@ TclInfoVarsCmd( Tcl_HashSearch search; Var *varPtr; Namespace *nsPtr; - Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp); - Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp); + Namespace *globalNsPtr = (Namespace *)Tcl_GetGlobalNamespace(interp); + Namespace *currNsPtr = (Namespace *)Tcl_GetCurrentNamespace(interp); Tcl_Obj *listPtr, *elemObjPtr, *varNamePtr; int specificNsInPattern = 0;/* Init. to avoid compiler warning. */ Tcl_Obj *simplePatternPtr = NULL; @@ -6420,7 +6420,7 @@ AppendLocals( */ if (*varNamePtr && !TclIsVarUndefined(varPtr) - && (includeLinks || !TclIsVarLink(varPtr))) { + && (includeLinks || !TclIsVarLink(varPtr))) { varName = TclGetString(*varNamePtr); if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) { Tcl_ListObjAppendElement(interp, listPtr, *varNamePtr); @@ -6592,7 +6592,7 @@ FreeVarEntry( static int CompareVarKeys( - void *keyPtr, /* New key to compare. */ + void *keyPtr, /* New key to compare. */ Tcl_HashEntry *hPtr) /* Existing key to compare. */ { Tcl_Obj *objPtr1 = (Tcl_Obj *)keyPtr; -- cgit v0.12 From d6f30e2ddf1da885a5a64f8b2f5ce0cab24aecef Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Wed, 7 Aug 2024 03:34:46 +0000 Subject: Make realclean/hose target consistent with clean with respect to pkgs cleanup --- win/makefile.vc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/win/makefile.vc b/win/makefile.vc index cba51ee..a4b1b26 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -708,6 +708,14 @@ clean-pkgs: popd \ ) +hose-pkgs: + @for /d %d in ($(PKGSDIR)\*) do \ + @if exist "%~fd\win\makefile.vc" ( \ + pushd "%~fd\win" & \ + $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) hose &\ + popd \ + ) + #--------------------------------------------------------------------- # Regenerate the stubs files. [Development use only] #--------------------------------------------------------------------- @@ -1188,7 +1196,7 @@ tidy: @if exist $(TCLREGLIB) del $(TCLREGLIB) clean: default-clean clean-pkgs -hose: default-hose +hose: default-hose hose-pkgs realclean: hose .PHONY: -- cgit v0.12 From 69dc97db364c6a381c86db6b4cf03335580d48c6 Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Wed, 7 Aug 2024 05:19:52 +0000 Subject: Streamline ICU symbol lookup. --- generic/tclIcu.c | 85 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 22 deletions(-) diff --git a/generic/tclIcu.c b/generic/tclIcu.c index c72acda..91b6650 100644 --- a/generic/tclIcu.c +++ b/generic/tclIcu.c @@ -515,6 +515,59 @@ TclIcuCleanup( /* *------------------------------------------------------------------------ * + * IcuFindSymbol -- + * + * Finds an ICU symbol in a shared library and returns its value. + * + * Caller must be holding icu_mutex lock. + * + * Results: + * Returns the symbol value or NULL if not found. + * + *------------------------------------------------------------------------ + */ +static void * +IcuFindSymbol( + Tcl_LoadHandle loadH, /* Handle to shared library containing symbol */ + const char *name, /* Name of function */ + const char *suffix /* Suffix that may be present */ +) +{ + /* + * ICU symbols may have a version suffix depending on how it was built. + * Rather than try both forms every time, suffixConvention remembers if a + * suffix is needed (all functions will have it, or none will) + * 0 - don't know, 1 - have suffix, -1 - no suffix + */ + static int suffixConvention = 0; + char symbol[256]; + void *value = NULL; + + /* Note we only update suffixConvention on a positive result */ + + strcpy(symbol, name); + if (suffixConvention <= 0) { + /* Either don't need suffix or don't know if we do */ + value = Tcl_FindSymbol(NULL, loadH, symbol); + if (value) { + suffixConvention = -1; /* Remember that no suffixes present */ + return value; + } + } + if (suffixConvention >= 0) { + /* Either need suffix or don't know if we do */ + strcat(symbol, suffix); + value = Tcl_FindSymbol(NULL, loadH, symbol); + if (value) { + suffixConvention = 1; + } + } + return value; +} + +/* + *------------------------------------------------------------------------ + * * TclIcuInit -- * * Load the ICU commands into the given interpreter. If the ICU @@ -528,7 +581,6 @@ TclIcuInit( Tcl_Interp *interp) { Tcl_MutexLock(&icu_mutex); - char symbol[256]; char icuversion[4] = "_80"; /* Highest ICU version + 1 */ /* @@ -640,17 +692,12 @@ TclIcuInit( } #endif // _WIN32 - /* Try for symbol without version (Windows, FreeBSD), then with version */ -#define ICUUC_SYM(name) \ - do { \ - strcpy(symbol, #name); \ - icu_fns._##name = (fn_##name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ - if (icu_fns._##name == NULL) { \ - strcat(symbol, icuversion); \ - icu_fns._##name = (fn_##name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[0], symbol); \ - } \ + /* Symbol may have version (Windows, FreeBSD), or not (Linux) */ + +#define ICUUC_SYM(name) \ + do { \ + icu_fns._##name = \ + (fn_##name)IcuFindSymbol(icu_fns.libs[0], #name, icuversion); \ } while (0) if (icu_fns.libs[0] != NULL) { @@ -677,16 +724,10 @@ TclIcuInit( #undef ICUUC_SYM } -#define ICUIN_SYM(name) \ - do { \ - strcpy(symbol, #name); \ - icu_fns._##name = (fn_##name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ - if (icu_fns._##name == NULL) { \ - strcat(symbol, icuversion); \ - icu_fns._##name = (fn_##name) \ - Tcl_FindSymbol(NULL, icu_fns.libs[1], symbol); \ - } \ +#define ICUIN_SYM(name) \ + do { \ + icu_fns._##name = \ + (fn_##name)IcuFindSymbol(icu_fns.libs[1], #name, icuversion); \ } while (0) if (icu_fns.libs[1] != NULL) { -- cgit v0.12 From 700bdf53e3244f96e9d9ee8fcc33b13103e023b1 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 7 Aug 2024 09:06:32 +0000 Subject: An imperfect fix for [2da1cb0c80] given that can't do the right thing --- generic/tclOOBasic.c | 29 +++++++++++++++++++++-------- tests/oo.test | 25 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 13749b2..0397474 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -686,12 +686,14 @@ TclOO_Object_VarName( Var *varPtr, *aryVar; Tcl_Obj *varNamePtr, *argPtr; const char *arg; + Tcl_Namespace *namespacePtr; if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "varName"); return TCL_ERROR; } + namespacePtr = Tcl_GetObjectNamespace(Tcl_ObjectContextObject(context)); argPtr = objv[objc-1]; arg = Tcl_GetString(argPtr); @@ -707,9 +709,6 @@ TclOO_Object_VarName( if (arg[0] == ':' && arg[1] == ':') { varNamePtr = argPtr; } else { - Tcl_Namespace *namespacePtr = - Tcl_GetObjectNamespace(Tcl_ObjectContextObject(context)); - varNamePtr = Tcl_NewStringObj(namespacePtr->fullName, -1); Tcl_AppendToObj(varNamePtr, "::", 2); Tcl_AppendObjToObj(varNamePtr, argPtr); @@ -726,7 +725,9 @@ TclOO_Object_VarName( /* * The variable reference must not disappear too soon. [Bug 74b6110204] */ - TclSetVarNamespaceVar(varPtr); + if (!TclIsVarArrayElement(varPtr)) { + TclSetVarNamespaceVar(varPtr); + } /* * Now that we've pinned down what variable we're really talking about @@ -748,15 +749,27 @@ TclOO_Object_VarName( &search); while (hPtr != NULL) { if (varPtr == Tcl_GetHashValue(hPtr)) { - Tcl_AppendToObj(varNamePtr, "(", -1); - Tcl_AppendObjToObj(varNamePtr, hPtr->key.objPtr); - Tcl_AppendToObj(varNamePtr, ")", -1); + Tcl_AppendPrintfToObj(varNamePtr, "(%s)", + TclGetString(hPtr->key.objPtr)); break; } hPtr = Tcl_NextHashEntry(&search); } - } else { + } else if (!TclIsVarArrayElement(varPtr)) { Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, varNamePtr); + } else { + /* + * Target is an element of an array but we don't know which one. + * The name in the object's namespace is the best we can do. + * [Bug 2da1cb0c80] + */ + if (arg[0] == ':' && arg[1] == ':') { + Tcl_DecrRefCount(varNamePtr); + varNamePtr = argPtr; + } else { + Tcl_AppendPrintfToObj(varNamePtr, "%s::%s", + namespacePtr->fullName, arg); + } } Tcl_SetObjResult(interp, varNamePtr); return TCL_OK; diff --git a/tests/oo.test b/tests/oo.test index 6bf9c70..cc25007 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -2947,6 +2947,31 @@ test oo-19.4 {OO: varname ghosts [Bug 74b6110204]} -setup { } -cleanup { testClass destroy } -result {::testoo19_4::foo 0 ::testoo19_4::foo} +test oo-19.5 {OO: varname array elements [Bug 2da1cb0c80]} -setup { + set obj [oo::object new] + oo::objdefine $obj export eval varname +} -constraints knownBug -body { + $obj eval { + namespace upvar :: tcl_platform(platform) foo + } + $obj varname foo +} -cleanup { + $obj destroy +} -result ::tcl_platform(platform) +test oo-19.5.1 {OO: varname array elements before Tcl 9 [Bug 2da1cb0c80]} -setup { + oo::class create testClass { + self export createWithNamespace + export eval varname + } +} -body { + set obj [testClass createWithNamespace obj oo-19.5.1] + $obj eval { + namespace upvar :: tcl_platform(platform) foo + } + $obj varname foo +} -cleanup { + testClass destroy +} -result ::oo-19.5.1::foo test oo-20.1 {OO: variable method} -body { oo::class create testClass { -- cgit v0.12 From 13ee7872b779ea11a07831d6309e4b61b847e790 Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Fri, 9 Aug 2024 02:53:11 +0000 Subject: Proposed fix for crash [201c7a3aa6] - crash on non-BMP --- generic/tclEncoding.c | 9 +++++++++ tests/encoding.test | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 624705d..ee80ba4 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -3983,6 +3983,15 @@ EscapeFromUtfProc( break; } len = TclUtfToUniChar(src, &ch); + if (ch > 0xFFFF) { + /* Bug 201c7a3aa6 crash - tables are 256x256 (64K) */ + if (PROFILE_STRICT(flags)) { + result = TCL_CONVERT_SYNTAX; + break; + } + /* Will be encoded as encoding specific replacement below */ + ch = UNICODE_REPLACE_CHAR; + } word = tableFromUnicode[(ch >> 8)][ch & 0xFF]; if ((word == 0) && (ch != 0)) { diff --git a/tests/encoding.test b/tests/encoding.test index e18e0f1..58f0956 100644 --- a/tests/encoding.test +++ b/tests/encoding.test @@ -1176,7 +1176,17 @@ test encoding-bug-66ffafd309-2-replace {Bug [66ffafd309] - invalid DBCS} -body { encoding convertfrom -profile replace jis0208 \x78\x79 } -result \uFFFD\uFFFD +test encoding-bug-201c7a3aa6-strict {Crash encoding non-BMP to iso2022} -body { + encoding convertto -profile strict iso2022 \U1f600 +} -result {unexpected character at index 0: 'U+01F600'} -returnCodes error +test encoding-bug-201c7a3aa6-replace {Crash encoding non-BMP to iso2022} -body { + encoding convertto -profile replace iso2022 \U1f600 +} -result ? + +test encoding-bug-201c7a3aa6-tcl8 {Crash encoding non-BMP to iso2022} -body { + encoding convertto -profile tcl8 iso2022 \U1f600 +} -result ? # cleanup namespace delete ::tcl::test::encoding -- cgit v0.12 From 97f067908718a69efcb8129decd9ee9fc01ae1bf Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Fri, 9 Aug 2024 13:24:23 +0000 Subject: Tweak unixInit-3.2 to return encoding --- tests/unixInit.test | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/unixInit.test b/tests/unixInit.test index 099dccb..29ff300 100644 --- a/tests/unixInit.test +++ b/tests/unixInit.test @@ -114,12 +114,13 @@ test unixInit-3.2 {TclpSetInitialEncodings} -setup { # reports that newer HP-UX systems report euc-jp like everybody else. lappend validEncodings shiftjis } - expr {$enc ni $validEncodings} + #expr {$enc ni $validEncodings} + set enc } -cleanup { unset -nocomplain env(LANG) env(LC_ALL) catch {set env(LC_ALL) $oldlc_all} catch {set env(TCL_LIBRARY) $oldtcl_library} -} -result 0 +} -result euc-jp test unixInit-4.1 {TclpSetVariables} {unix} { # just make sure they exist -- cgit v0.12 From 703ea115384607aa7bfc8e0ab8984150ea52b01d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 9 Aug 2024 14:59:59 +0000 Subject: (cherry-pick): Make realclean/hose target consistent with clean with respect to pkgs cleanup --- win/makefile.vc | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/win/makefile.vc b/win/makefile.vc index 5642155..8a4a368 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -20,10 +20,10 @@ # or examine Sections 7-9 in rules.vc. # # Possible values for TARGET are: -# release -- Builds the core, the shell and the dlls. (default) +# release -- Builds everything that ships with a release. (default) +# core -- Builds the core [tclXX.(dll|lib)] +# shell -- Builds tclsh and the core. # dlls -- Just builds the windows extensions. -# shell -- Just builds the shell and the core. -# core -- Only builds the core [tclXX.(dll|lib)]. # all -- Builds everything. # test -- Builds and runs the test suite. # tcltest -- Just builds the test shell. @@ -440,13 +440,37 @@ TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT) #--------------------------------------------------------------------- # Project specific targets +# There are 4 primary build configurations to consider from the combination +# of static/shared and embed/noembed of the library zip. The targets are +# done in the following order. +# $(TCLLIB) - this is either the core static .lib or the .dll. The target +# build does not embed the library zip in the DLL irrespective +# of the noembed setting. A copy is made as $(TCLLIBRAW) +# as the $(TCLLIB) binary is potentially modified later. +# dlls - these are the registry and dde DLL's or static libraries +# $(TCLSH) - the Tcl shell. This needs $(TCLLIB) to be built first as +# it links against it. +# $(TCLSCRIPTZIP) - the zip file that is to be embedded. Note this also +# ships separately and needs to be built irrespective of the +# whether it is embedded or not. All above targets need to +# be built prior as they are used to build the zip (unlike +# Unix where the external zip program is used.) +# core - this virtual target builds the final release ready Tcl +# library. For shared, embedded builds it appends $(TCLSCRIPTZIP) +# to the $(TCLLIB). For other build configurations, this +# is a no-op. +# shell - this virtual target builds the final release ready tclsh shell. +# For static, embedded builds it appends $(TCLSCRIPTZIP) +# to the $(TCLSH). For other build configurations, this +# is a no-op. +# release - Everything that builds as part of a release #--------------------------------------------------------------------- release: setup $(TCLSH) $(TCLSTUBLIB) dlls pkgs +all: setup $(TCLSH) $(TCLSTUBLIB) dlls $(CAT32) pkgs core: setup $(TCLLIB) $(TCLSTUBLIB) shell: setup $(TCLSH) dlls: setup $(TCLREGLIB) $(TCLDDELIB) $(OUT_DIR)\zlib1.dll -all: setup $(TCLSH) $(TCLSTUBLIB) dlls $(CAT32) pkgs tcltest: setup $(TCLTEST) dlls $(CAT32) install: install-binaries install-libraries install-docs install-pkgs !if $(SYMBOLS) @@ -569,6 +593,14 @@ clean-pkgs: popd \ ) +hose-pkgs: + @for /d %d in ($(PKGSDIR)\*) do \ + @if exist "%~fd\win\makefile.vc" ( \ + pushd "%~fd\win" & \ + $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) hose &\ + popd \ + ) + $(CAT32): $(WIN_DIR)\cat.c $(cc32) $(cflags) $(crt) /D_CRT_NONSTDC_NO_DEPRECATE /DCONSOLE \ /DUNICODE /D_UNICODE -Fo$(TMP_DIR)\ $? @@ -1035,7 +1067,7 @@ tidy: @if exist $(TCLREGLIB) del $(TCLREGLIB) clean: default-clean clean-pkgs -hose: default-hose +hose: default-hose hose-pkgs realclean: hose .PHONY: -- cgit v0.12 From 4fa03abc95d589e34369a0e05fba9aa1daebce96 Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Fri, 9 Aug 2024 15:25:12 +0000 Subject: Also fix the non-zipfs build --- generic/tclInterp.c | 2 +- tests/unixInit.test | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 985190f..0abbebd 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -448,7 +448,7 @@ Tcl_Init( " }\n" "}\n" "tclInit", TCL_INDEX_NONE, 0); - + TclpSetInitialEncodings(); end: *names = (*names)->nextPtr; return result; diff --git a/tests/unixInit.test b/tests/unixInit.test index 29ff300..099dccb 100644 --- a/tests/unixInit.test +++ b/tests/unixInit.test @@ -114,13 +114,12 @@ test unixInit-3.2 {TclpSetInitialEncodings} -setup { # reports that newer HP-UX systems report euc-jp like everybody else. lappend validEncodings shiftjis } - #expr {$enc ni $validEncodings} - set enc + expr {$enc ni $validEncodings} } -cleanup { unset -nocomplain env(LANG) env(LC_ALL) catch {set env(LC_ALL) $oldlc_all} catch {set env(TCL_LIBRARY) $oldtcl_library} -} -result euc-jp +} -result 0 test unixInit-4.1 {TclpSetVariables} {unix} { # just make sure they exist -- cgit v0.12 From c03cb200cd9d4b8443ece3431781ae34bbeb8ade Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Sat, 10 Aug 2024 12:55:35 +0000 Subject: Compensate test case for XCode test config --- tests/unixInit.test | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/unixInit.test b/tests/unixInit.test index 099dccb..899779c 100644 --- a/tests/unixInit.test +++ b/tests/unixInit.test @@ -96,11 +96,26 @@ test unixInit-3.1 {TclpSetInitialEncodings} -constraints { } -cleanup { unset -nocomplain env(LANG) } -match regexp -result {^(iso8859-15?|utf-8)$} + +# unixInit-3.2 depends on the *spawned* [interpreter] being able to locate +# tcl_library without setting of TCL_LIBRARY env. This in turn depends on +# Tcl's "library" directory being under the parent or grandparent of the +# executable directory (the initScript search path in tclInterp.c). +# Thus this constraint. On GiuHub CI, the only time this is not true +# is for the XCode builds. +if {[string match [zipfs root]* [info library]] || + [file isfile [file normalize [file join [info nameofexecutable] .. .. library init.tcl]]] || + [file isfile [file normalize [file join [info nameofexecutable] .. .. .. library init.tcl]]] +} { + tcltest::testConstraint enableUnixInit32 1 +} else { + tcltest::testConstraint enableUnixInit32 0 +} test unixInit-3.2 {TclpSetInitialEncodings} -setup { catch {set oldlc_all $env(LC_ALL)} catch {set oldtcl_library $env(TCL_LIBRARY)} unset -nocomplain env(TCL_LIBRARY) -} -constraints {unix stdio} -body { +} -constraints {unix stdio enableUnixInit32} -body { set env(LANG) japanese set env(LC_ALL) japanese set f [open "|[list [interpreter]]" w+] -- cgit v0.12 From 684e879c59c1bafb270b2ca91b6467fc9252ce08 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 11 Aug 2024 20:37:38 +0000 Subject: Update Unicode tables to version 16 (in BETA, Unicode release will be Sept 10) --- generic/regc_locale.c | 526 ++++++++------- generic/tclUniData.c | 1765 +++++++++++++++++++++++++------------------------ 2 files changed, 1168 insertions(+), 1123 deletions(-) diff --git a/generic/regc_locale.c b/generic/regc_locale.c index 3f2fc46..764df83 100644 --- a/generic/regc_locale.c +++ b/generic/regc_locale.c @@ -169,7 +169,7 @@ static const crange alphaRangeTable[] = { {0x1950, 0x196D}, {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x1A00, 0x1A16}, {0x1A20, 0x1A54}, {0x1B05, 0x1B33}, {0x1B45, 0x1B4C}, {0x1B83, 0x1BA0}, {0x1BBA, 0x1BE5}, {0x1C00, 0x1C23}, {0x1C4D, 0x1C4F}, - {0x1C5A, 0x1C7D}, {0x1C80, 0x1C88}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, + {0x1C5A, 0x1C7D}, {0x1C80, 0x1C8A}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1CE9, 0x1CEC}, {0x1CEE, 0x1CF3}, {0x1D00, 0x1DBF}, {0x1E00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FBC}, {0x1FC2, 0x1FC4}, @@ -184,7 +184,7 @@ static const crange alphaRangeTable[] = { {0x3131, 0x318E}, {0x31A0, 0x31BF}, {0x31F0, 0x31FF}, {0x3400, 0x4DBF}, {0x4E00, 0xA48C}, {0xA4D0, 0xA4FD}, {0xA500, 0xA60C}, {0xA610, 0xA61F}, {0xA640, 0xA66E}, {0xA67F, 0xA69D}, {0xA6A0, 0xA6E5}, {0xA717, 0xA71F}, - {0xA722, 0xA788}, {0xA78B, 0xA7CA}, {0xA7D5, 0xA7D9}, {0xA7F2, 0xA801}, + {0xA722, 0xA788}, {0xA78B, 0xA7CD}, {0xA7D5, 0xA7DC}, {0xA7F2, 0xA801}, {0xA803, 0xA805}, {0xA807, 0xA80A}, {0xA80C, 0xA822}, {0xA840, 0xA873}, {0xA882, 0xA8B3}, {0xA8F2, 0xA8F7}, {0xA90A, 0xA925}, {0xA930, 0xA946}, {0xA960, 0xA97C}, {0xA984, 0xA9B2}, {0xA9E0, 0xA9E4}, {0xA9E6, 0xA9EF}, @@ -206,51 +206,54 @@ static const crange alphaRangeTable[] = { {0x10380, 0x1039D}, {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x10400, 0x1049D}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10597, 0x105A1}, - {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x10600, 0x10736}, {0x10740, 0x10755}, - {0x10760, 0x10767}, {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, - {0x10800, 0x10805}, {0x1080A, 0x10835}, {0x1083F, 0x10855}, {0x10860, 0x10876}, - {0x10880, 0x1089E}, {0x108E0, 0x108F2}, {0x10900, 0x10915}, {0x10920, 0x10939}, - {0x10980, 0x109B7}, {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, - {0x10A60, 0x10A7C}, {0x10A80, 0x10A9C}, {0x10AC0, 0x10AC7}, {0x10AC9, 0x10AE4}, - {0x10B00, 0x10B35}, {0x10B40, 0x10B55}, {0x10B60, 0x10B72}, {0x10B80, 0x10B91}, - {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10D00, 0x10D23}, - {0x10E80, 0x10EA9}, {0x10F00, 0x10F1C}, {0x10F30, 0x10F45}, {0x10F70, 0x10F81}, + {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105C0, 0x105F3}, {0x10600, 0x10736}, + {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785}, {0x10787, 0x107B0}, + {0x107B2, 0x107BA}, {0x10800, 0x10805}, {0x1080A, 0x10835}, {0x1083F, 0x10855}, + {0x10860, 0x10876}, {0x10880, 0x1089E}, {0x108E0, 0x108F2}, {0x10900, 0x10915}, + {0x10920, 0x10939}, {0x10980, 0x109B7}, {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, + {0x10A19, 0x10A35}, {0x10A60, 0x10A7C}, {0x10A80, 0x10A9C}, {0x10AC0, 0x10AC7}, + {0x10AC9, 0x10AE4}, {0x10B00, 0x10B35}, {0x10B40, 0x10B55}, {0x10B60, 0x10B72}, + {0x10B80, 0x10B91}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, + {0x10D00, 0x10D23}, {0x10D4A, 0x10D65}, {0x10D6F, 0x10D85}, {0x10E80, 0x10EA9}, + {0x10EC2, 0x10EC4}, {0x10F00, 0x10F1C}, {0x10F30, 0x10F45}, {0x10F70, 0x10F81}, {0x10FB0, 0x10FC4}, {0x10FE0, 0x10FF6}, {0x11003, 0x11037}, {0x11083, 0x110AF}, {0x110D0, 0x110E8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111B2}, {0x111C1, 0x111C4}, {0x11200, 0x11211}, {0x11213, 0x1122B}, {0x11280, 0x11286}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112B0, 0x112DE}, {0x11305, 0x1130C}, {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11335, 0x11339}, - {0x1135D, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144A}, {0x1145F, 0x11461}, - {0x11480, 0x114AF}, {0x11580, 0x115AE}, {0x115D8, 0x115DB}, {0x11600, 0x1162F}, - {0x11680, 0x116AA}, {0x11700, 0x1171A}, {0x11740, 0x11746}, {0x11800, 0x1182B}, - {0x118A0, 0x118DF}, {0x118FF, 0x11906}, {0x1190C, 0x11913}, {0x11918, 0x1192F}, - {0x119A0, 0x119A7}, {0x119AA, 0x119D0}, {0x11A0B, 0x11A32}, {0x11A5C, 0x11A89}, - {0x11AB0, 0x11AF8}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C72, 0x11C8F}, - {0x11D00, 0x11D06}, {0x11D0B, 0x11D30}, {0x11D60, 0x11D65}, {0x11D6A, 0x11D89}, - {0x11EE0, 0x11EF2}, {0x11F04, 0x11F10}, {0x11F12, 0x11F33}, {0x12000, 0x12399}, - {0x12480, 0x12543}, {0x12F90, 0x12FF0}, {0x13000, 0x1342F}, {0x13441, 0x13446}, - {0x14400, 0x14646}, {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A70, 0x16ABE}, - {0x16AD0, 0x16AED}, {0x16B00, 0x16B2F}, {0x16B40, 0x16B43}, {0x16B63, 0x16B77}, - {0x16B7D, 0x16B8F}, {0x16E40, 0x16E7F}, {0x16F00, 0x16F4A}, {0x16F93, 0x16F9F}, - {0x17000, 0x187F7}, {0x18800, 0x18CD5}, {0x18D00, 0x18D08}, {0x1AFF0, 0x1AFF3}, - {0x1AFF5, 0x1AFFB}, {0x1B000, 0x1B122}, {0x1B150, 0x1B152}, {0x1B164, 0x1B167}, - {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, - {0x1BC90, 0x1BC99}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D4A9, 0x1D4AC}, - {0x1D4AE, 0x1D4B9}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, - {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, - {0x1D540, 0x1D544}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, - {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6FA}, {0x1D6FC, 0x1D714}, {0x1D716, 0x1D734}, - {0x1D736, 0x1D74E}, {0x1D750, 0x1D76E}, {0x1D770, 0x1D788}, {0x1D78A, 0x1D7A8}, - {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7CB}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, - {0x1E030, 0x1E06D}, {0x1E100, 0x1E12C}, {0x1E137, 0x1E13D}, {0x1E290, 0x1E2AD}, - {0x1E2C0, 0x1E2EB}, {0x1E4D0, 0x1E4EB}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, - {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E900, 0x1E943}, {0x1EE00, 0x1EE03}, - {0x1EE05, 0x1EE1F}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE4D, 0x1EE4F}, - {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, - {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, - {0x1EEAB, 0x1EEBB}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B739}, {0x2B740, 0x2B81D}, - {0x2B820, 0x2CEA1}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, - {0x30000, 0x3134A}, {0x31350, 0x323AF} + {0x1135D, 0x11361}, {0x11380, 0x11389}, {0x11390, 0x113B5}, {0x11400, 0x11434}, + {0x11447, 0x1144A}, {0x1145F, 0x11461}, {0x11480, 0x114AF}, {0x11580, 0x115AE}, + {0x115D8, 0x115DB}, {0x11600, 0x1162F}, {0x11680, 0x116AA}, {0x11700, 0x1171A}, + {0x11740, 0x11746}, {0x11800, 0x1182B}, {0x118A0, 0x118DF}, {0x118FF, 0x11906}, + {0x1190C, 0x11913}, {0x11918, 0x1192F}, {0x119A0, 0x119A7}, {0x119AA, 0x119D0}, + {0x11A0B, 0x11A32}, {0x11A5C, 0x11A89}, {0x11AB0, 0x11AF8}, {0x11BC0, 0x11BE0}, + {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C72, 0x11C8F}, {0x11D00, 0x11D06}, + {0x11D0B, 0x11D30}, {0x11D60, 0x11D65}, {0x11D6A, 0x11D89}, {0x11EE0, 0x11EF2}, + {0x11F04, 0x11F10}, {0x11F12, 0x11F33}, {0x12000, 0x12399}, {0x12480, 0x12543}, + {0x12F90, 0x12FF0}, {0x13000, 0x1342F}, {0x13441, 0x13446}, {0x13460, 0x143FA}, + {0x14400, 0x14646}, {0x16100, 0x1611D}, {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, + {0x16A70, 0x16ABE}, {0x16AD0, 0x16AED}, {0x16B00, 0x16B2F}, {0x16B40, 0x16B43}, + {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16D40, 0x16D6C}, {0x16E40, 0x16E7F}, + {0x16F00, 0x16F4A}, {0x16F93, 0x16F9F}, {0x17000, 0x187F7}, {0x18800, 0x18CD5}, + {0x18CFF, 0x18D08}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1B000, 0x1B122}, + {0x1B150, 0x1B152}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, + {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1D400, 0x1D454}, + {0x1D456, 0x1D49C}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BD, 0x1D4C3}, + {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, + {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D54A, 0x1D550}, + {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6FA}, + {0x1D6FC, 0x1D714}, {0x1D716, 0x1D734}, {0x1D736, 0x1D74E}, {0x1D750, 0x1D76E}, + {0x1D770, 0x1D788}, {0x1D78A, 0x1D7A8}, {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7CB}, + {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E030, 0x1E06D}, {0x1E100, 0x1E12C}, + {0x1E137, 0x1E13D}, {0x1E290, 0x1E2AD}, {0x1E2C0, 0x1E2EB}, {0x1E4D0, 0x1E4EB}, + {0x1E5D0, 0x1E5ED}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7F0, 0x1E7FE}, + {0x1E800, 0x1E8C4}, {0x1E900, 0x1E943}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, + {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE4D, 0x1EE4F}, {0x1EE67, 0x1EE6A}, + {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE80, 0x1EE89}, + {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, + {0x20000, 0x2A6DF}, {0x2A700, 0x2B739}, {0x2B740, 0x2B81D}, {0x2B820, 0x2CEA1}, + {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, + {0x31350, 0x323AF} #endif }; @@ -279,15 +282,15 @@ static const chr alphaCharTable[] = { ,0x1003C, 0x1003D, 0x10594, 0x10595, 0x105BB, 0x105BC, 0x10808, 0x10837, 0x10838, 0x1083C, 0x108F4, 0x108F5, 0x109BE, 0x109BF, 0x10A00, 0x10EB0, 0x10EB1, 0x10F27, 0x11071, 0x11072, 0x11075, 0x11144, 0x11147, 0x11176, 0x111DA, 0x111DC, 0x1123F, - 0x11240, 0x11288, 0x1130F, 0x11310, 0x11332, 0x11333, 0x1133D, 0x11350, 0x114C4, - 0x114C5, 0x114C7, 0x11644, 0x116B8, 0x11909, 0x11915, 0x11916, 0x1193F, 0x11941, - 0x119E1, 0x119E3, 0x11A00, 0x11A3A, 0x11A50, 0x11A9D, 0x11C40, 0x11D08, 0x11D09, - 0x11D46, 0x11D67, 0x11D68, 0x11D98, 0x11F02, 0x11FB0, 0x16F50, 0x16FE0, 0x16FE1, - 0x16FE3, 0x1AFFD, 0x1AFFE, 0x1B132, 0x1B155, 0x1D49E, 0x1D49F, 0x1D4A2, 0x1D4A5, - 0x1D4A6, 0x1D4BB, 0x1D546, 0x1E14E, 0x1E7ED, 0x1E7EE, 0x1E94B, 0x1EE21, 0x1EE22, - 0x1EE24, 0x1EE27, 0x1EE39, 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE51, - 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, 0x1EE5D, 0x1EE5F, 0x1EE61, 0x1EE62, - 0x1EE64, 0x1EE7E + 0x11240, 0x11288, 0x1130F, 0x11310, 0x11332, 0x11333, 0x1133D, 0x11350, 0x1138B, + 0x1138E, 0x113B7, 0x113D1, 0x113D3, 0x114C4, 0x114C5, 0x114C7, 0x11644, 0x116B8, + 0x11909, 0x11915, 0x11916, 0x1193F, 0x11941, 0x119E1, 0x119E3, 0x11A00, 0x11A3A, + 0x11A50, 0x11A9D, 0x11C40, 0x11D08, 0x11D09, 0x11D46, 0x11D67, 0x11D68, 0x11D98, + 0x11F02, 0x11FB0, 0x16F50, 0x16FE0, 0x16FE1, 0x16FE3, 0x1AFFD, 0x1AFFE, 0x1B132, + 0x1B155, 0x1D49E, 0x1D49F, 0x1D4A2, 0x1D4A5, 0x1D4A6, 0x1D4BB, 0x1D546, 0x1E14E, + 0x1E5F0, 0x1E7ED, 0x1E7EE, 0x1E94B, 0x1EE21, 0x1EE22, 0x1EE24, 0x1EE27, 0x1EE39, + 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, + 0x1EE59, 0x1EE5B, 0x1EE5D, 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE7E #endif }; @@ -332,13 +335,15 @@ static const crange digitRangeTable[] = { {0xA9D0, 0xA9D9}, {0xA9F0, 0xA9F9}, {0xAA50, 0xAA59}, {0xABF0, 0xABF9}, {0xFF10, 0xFF19} #if CHRBITS > 16 - ,{0x104A0, 0x104A9}, {0x10D30, 0x10D39}, {0x11066, 0x1106F}, {0x110F0, 0x110F9}, - {0x11136, 0x1113F}, {0x111D0, 0x111D9}, {0x112F0, 0x112F9}, {0x11450, 0x11459}, - {0x114D0, 0x114D9}, {0x11650, 0x11659}, {0x116C0, 0x116C9}, {0x11730, 0x11739}, - {0x118E0, 0x118E9}, {0x11950, 0x11959}, {0x11C50, 0x11C59}, {0x11D50, 0x11D59}, - {0x11DA0, 0x11DA9}, {0x11F50, 0x11F59}, {0x16A60, 0x16A69}, {0x16AC0, 0x16AC9}, - {0x16B50, 0x16B59}, {0x1D7CE, 0x1D7FF}, {0x1E140, 0x1E149}, {0x1E2F0, 0x1E2F9}, - {0x1E4F0, 0x1E4F9}, {0x1E950, 0x1E959}, {0x1FBF0, 0x1FBF9} + ,{0x104A0, 0x104A9}, {0x10D30, 0x10D39}, {0x10D40, 0x10D49}, {0x11066, 0x1106F}, + {0x110F0, 0x110F9}, {0x11136, 0x1113F}, {0x111D0, 0x111D9}, {0x112F0, 0x112F9}, + {0x11450, 0x11459}, {0x114D0, 0x114D9}, {0x11650, 0x11659}, {0x116C0, 0x116C9}, + {0x116D0, 0x116E3}, {0x11730, 0x11739}, {0x118E0, 0x118E9}, {0x11950, 0x11959}, + {0x11BF0, 0x11BF9}, {0x11C50, 0x11C59}, {0x11D50, 0x11D59}, {0x11DA0, 0x11DA9}, + {0x11F50, 0x11F59}, {0x16130, 0x16139}, {0x16A60, 0x16A69}, {0x16AC0, 0x16AC9}, + {0x16B50, 0x16B59}, {0x16D70, 0x16D79}, {0x1CCF0, 0x1CCF9}, {0x1D7CE, 0x1D7FF}, + {0x1E140, 0x1E149}, {0x1E2F0, 0x1E2F9}, {0x1E4F0, 0x1E4F9}, {0x1E5F1, 0x1E5FA}, + {0x1E950, 0x1E959}, {0x1FBF0, 0x1FBF9} #endif }; @@ -358,15 +363,15 @@ static const crange punctRangeTable[] = { {0x7F7, 0x7F9}, {0x830, 0x83E}, {0xF04, 0xF12}, {0xF3A, 0xF3D}, {0xFD0, 0xFD4}, {0x104A, 0x104F}, {0x1360, 0x1368}, {0x16EB, 0x16ED}, {0x17D4, 0x17D6}, {0x17D8, 0x17DA}, {0x1800, 0x180A}, {0x1AA0, 0x1AA6}, - {0x1AA8, 0x1AAD}, {0x1B5A, 0x1B60}, {0x1BFC, 0x1BFF}, {0x1C3B, 0x1C3F}, - {0x1CC0, 0x1CC7}, {0x2010, 0x2027}, {0x2030, 0x2043}, {0x2045, 0x2051}, - {0x2053, 0x205E}, {0x2308, 0x230B}, {0x2768, 0x2775}, {0x27E6, 0x27EF}, - {0x2983, 0x2998}, {0x29D8, 0x29DB}, {0x2CF9, 0x2CFC}, {0x2E00, 0x2E2E}, - {0x2E30, 0x2E4F}, {0x2E52, 0x2E5D}, {0x3001, 0x3003}, {0x3008, 0x3011}, - {0x3014, 0x301F}, {0xA60D, 0xA60F}, {0xA6F2, 0xA6F7}, {0xA874, 0xA877}, - {0xA8F8, 0xA8FA}, {0xA9C1, 0xA9CD}, {0xAA5C, 0xAA5F}, {0xFE10, 0xFE19}, - {0xFE30, 0xFE52}, {0xFE54, 0xFE61}, {0xFF01, 0xFF03}, {0xFF05, 0xFF0A}, - {0xFF0C, 0xFF0F}, {0xFF3B, 0xFF3D}, {0xFF5F, 0xFF65} + {0x1AA8, 0x1AAD}, {0x1B5A, 0x1B60}, {0x1B7D, 0x1B7F}, {0x1BFC, 0x1BFF}, + {0x1C3B, 0x1C3F}, {0x1CC0, 0x1CC7}, {0x2010, 0x2027}, {0x2030, 0x2043}, + {0x2045, 0x2051}, {0x2053, 0x205E}, {0x2308, 0x230B}, {0x2768, 0x2775}, + {0x27E6, 0x27EF}, {0x2983, 0x2998}, {0x29D8, 0x29DB}, {0x2CF9, 0x2CFC}, + {0x2E00, 0x2E2E}, {0x2E30, 0x2E4F}, {0x2E52, 0x2E5D}, {0x3001, 0x3003}, + {0x3008, 0x3011}, {0x3014, 0x301F}, {0xA60D, 0xA60F}, {0xA6F2, 0xA6F7}, + {0xA874, 0xA877}, {0xA8F8, 0xA8FA}, {0xA9C1, 0xA9CD}, {0xAA5C, 0xAA5F}, + {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, {0xFE54, 0xFE61}, {0xFF01, 0xFF03}, + {0xFF05, 0xFF0A}, {0xFF0C, 0xFF0F}, {0xFF3B, 0xFF3D}, {0xFF5F, 0xFF65} #if CHRBITS > 16 ,{0x10100, 0x10102}, {0x10A50, 0x10A58}, {0x10AF0, 0x10AF6}, {0x10B39, 0x10B3F}, {0x10B99, 0x10B9C}, {0x10F55, 0x10F59}, {0x10F86, 0x10F89}, {0x11047, 0x1104D}, @@ -374,8 +379,8 @@ static const crange punctRangeTable[] = { {0x11238, 0x1123D}, {0x1144B, 0x1144F}, {0x115C1, 0x115D7}, {0x11641, 0x11643}, {0x11660, 0x1166C}, {0x1173C, 0x1173E}, {0x11944, 0x11946}, {0x11A3F, 0x11A46}, {0x11A9A, 0x11A9C}, {0x11A9E, 0x11AA2}, {0x11B00, 0x11B09}, {0x11C41, 0x11C45}, - {0x11F43, 0x11F4F}, {0x12470, 0x12474}, {0x16B37, 0x16B3B}, {0x16E97, 0x16E9A}, - {0x1DA87, 0x1DA8B} + {0x11F43, 0x11F4F}, {0x12470, 0x12474}, {0x16B37, 0x16B3B}, {0x16D6D, 0x16D6F}, + {0x16E97, 0x16E9A}, {0x1DA87, 0x1DA8B} #endif }; @@ -388,7 +393,7 @@ static const chr punctCharTable[] = { 0x60D, 0x61B, 0x6D4, 0x85E, 0x964, 0x965, 0x970, 0x9FD, 0xA76, 0xAF0, 0xC77, 0xC84, 0xDF4, 0xE4F, 0xE5A, 0xE5B, 0xF14, 0xF85, 0xFD9, 0xFDA, 0x10FB, 0x1400, 0x166E, 0x169B, 0x169C, 0x1735, 0x1736, - 0x1944, 0x1945, 0x1A1E, 0x1A1F, 0x1B7D, 0x1B7E, 0x1C7E, 0x1C7F, 0x1CD3, + 0x1944, 0x1945, 0x1A1E, 0x1A1F, 0x1B4E, 0x1B4F, 0x1C7E, 0x1C7F, 0x1CD3, 0x207D, 0x207E, 0x208D, 0x208E, 0x2329, 0x232A, 0x27C5, 0x27C6, 0x29FC, 0x29FD, 0x2CFE, 0x2CFF, 0x2D70, 0x3030, 0x303D, 0x30A0, 0x30FB, 0xA4FE, 0xA4FF, 0xA673, 0xA67E, 0xA8CE, 0xA8CF, 0xA8FC, 0xA92E, 0xA92F, 0xA95F, @@ -396,11 +401,11 @@ static const chr punctCharTable[] = { 0xFE63, 0xFE68, 0xFE6A, 0xFE6B, 0xFF1A, 0xFF1B, 0xFF1F, 0xFF20, 0xFF3F, 0xFF5B, 0xFF5D #if CHRBITS > 16 - ,0x1039F, 0x103D0, 0x1056F, 0x10857, 0x1091F, 0x1093F, 0x10A7F, 0x10EAD, 0x110BB, - 0x110BC, 0x11174, 0x11175, 0x111CD, 0x111DB, 0x112A9, 0x1145A, 0x1145B, 0x1145D, - 0x114C6, 0x116B9, 0x1183B, 0x119E2, 0x11C70, 0x11C71, 0x11EF7, 0x11EF8, 0x11FFF, - 0x12FF1, 0x12FF2, 0x16A6E, 0x16A6F, 0x16AF5, 0x16B44, 0x16FE2, 0x1BC9F, 0x1E95E, - 0x1E95F + ,0x1039F, 0x103D0, 0x1056F, 0x10857, 0x1091F, 0x1093F, 0x10A7F, 0x10D6E, 0x10EAD, + 0x110BB, 0x110BC, 0x11174, 0x11175, 0x111CD, 0x111DB, 0x112A9, 0x113D4, 0x113D5, + 0x113D7, 0x113D8, 0x1145A, 0x1145B, 0x1145D, 0x114C6, 0x116B9, 0x1183B, 0x119E2, + 0x11BE1, 0x11C70, 0x11C71, 0x11EF7, 0x11EF8, 0x11FFF, 0x12FF1, 0x12FF2, 0x16A6E, + 0x16A6F, 0x16AF5, 0x16B44, 0x16FE2, 0x1BC9F, 0x1E5FF, 0x1E95E, 0x1E95F #endif }; @@ -443,15 +448,15 @@ static const crange lowerRangeTable[] = { {0xAB70, 0xABBF}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFF41, 0xFF5A} #if CHRBITS > 16 ,{0x10428, 0x1044F}, {0x104D8, 0x104FB}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, - {0x105B3, 0x105B9}, {0x10CC0, 0x10CF2}, {0x118C0, 0x118DF}, {0x16E60, 0x16E7F}, - {0x1D41A, 0x1D433}, {0x1D44E, 0x1D454}, {0x1D456, 0x1D467}, {0x1D482, 0x1D49B}, - {0x1D4B6, 0x1D4B9}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D4CF}, {0x1D4EA, 0x1D503}, - {0x1D51E, 0x1D537}, {0x1D552, 0x1D56B}, {0x1D586, 0x1D59F}, {0x1D5BA, 0x1D5D3}, - {0x1D5EE, 0x1D607}, {0x1D622, 0x1D63B}, {0x1D656, 0x1D66F}, {0x1D68A, 0x1D6A5}, - {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6E1}, {0x1D6FC, 0x1D714}, {0x1D716, 0x1D71B}, - {0x1D736, 0x1D74E}, {0x1D750, 0x1D755}, {0x1D770, 0x1D788}, {0x1D78A, 0x1D78F}, - {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7C9}, {0x1DF00, 0x1DF09}, {0x1DF0B, 0x1DF1E}, - {0x1DF25, 0x1DF2A}, {0x1E922, 0x1E943} + {0x105B3, 0x105B9}, {0x10CC0, 0x10CF2}, {0x10D70, 0x10D85}, {0x118C0, 0x118DF}, + {0x16E60, 0x16E7F}, {0x1D41A, 0x1D433}, {0x1D44E, 0x1D454}, {0x1D456, 0x1D467}, + {0x1D482, 0x1D49B}, {0x1D4B6, 0x1D4B9}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D4CF}, + {0x1D4EA, 0x1D503}, {0x1D51E, 0x1D537}, {0x1D552, 0x1D56B}, {0x1D586, 0x1D59F}, + {0x1D5BA, 0x1D5D3}, {0x1D5EE, 0x1D607}, {0x1D622, 0x1D63B}, {0x1D656, 0x1D66F}, + {0x1D68A, 0x1D6A5}, {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6E1}, {0x1D6FC, 0x1D714}, + {0x1D716, 0x1D71B}, {0x1D736, 0x1D74E}, {0x1D750, 0x1D755}, {0x1D770, 0x1D788}, + {0x1D78A, 0x1D78F}, {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7C9}, {0x1DF00, 0x1DF09}, + {0x1DF0B, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E922, 0x1E943} #endif }; @@ -487,42 +492,43 @@ static const chr lowerCharTable[] = { 0x4F1, 0x4F3, 0x4F5, 0x4F7, 0x4F9, 0x4FB, 0x4FD, 0x4FF, 0x501, 0x503, 0x505, 0x507, 0x509, 0x50B, 0x50D, 0x50F, 0x511, 0x513, 0x515, 0x517, 0x519, 0x51B, 0x51D, 0x51F, 0x521, 0x523, 0x525, - 0x527, 0x529, 0x52B, 0x52D, 0x52F, 0x1E01, 0x1E03, 0x1E05, 0x1E07, - 0x1E09, 0x1E0B, 0x1E0D, 0x1E0F, 0x1E11, 0x1E13, 0x1E15, 0x1E17, 0x1E19, - 0x1E1B, 0x1E1D, 0x1E1F, 0x1E21, 0x1E23, 0x1E25, 0x1E27, 0x1E29, 0x1E2B, - 0x1E2D, 0x1E2F, 0x1E31, 0x1E33, 0x1E35, 0x1E37, 0x1E39, 0x1E3B, 0x1E3D, - 0x1E3F, 0x1E41, 0x1E43, 0x1E45, 0x1E47, 0x1E49, 0x1E4B, 0x1E4D, 0x1E4F, - 0x1E51, 0x1E53, 0x1E55, 0x1E57, 0x1E59, 0x1E5B, 0x1E5D, 0x1E5F, 0x1E61, - 0x1E63, 0x1E65, 0x1E67, 0x1E69, 0x1E6B, 0x1E6D, 0x1E6F, 0x1E71, 0x1E73, - 0x1E75, 0x1E77, 0x1E79, 0x1E7B, 0x1E7D, 0x1E7F, 0x1E81, 0x1E83, 0x1E85, - 0x1E87, 0x1E89, 0x1E8B, 0x1E8D, 0x1E8F, 0x1E91, 0x1E93, 0x1E9F, 0x1EA1, - 0x1EA3, 0x1EA5, 0x1EA7, 0x1EA9, 0x1EAB, 0x1EAD, 0x1EAF, 0x1EB1, 0x1EB3, - 0x1EB5, 0x1EB7, 0x1EB9, 0x1EBB, 0x1EBD, 0x1EBF, 0x1EC1, 0x1EC3, 0x1EC5, - 0x1EC7, 0x1EC9, 0x1ECB, 0x1ECD, 0x1ECF, 0x1ED1, 0x1ED3, 0x1ED5, 0x1ED7, - 0x1ED9, 0x1EDB, 0x1EDD, 0x1EDF, 0x1EE1, 0x1EE3, 0x1EE5, 0x1EE7, 0x1EE9, - 0x1EEB, 0x1EED, 0x1EEF, 0x1EF1, 0x1EF3, 0x1EF5, 0x1EF7, 0x1EF9, 0x1EFB, - 0x1EFD, 0x1FB6, 0x1FB7, 0x1FBE, 0x1FC6, 0x1FC7, 0x1FD6, 0x1FD7, 0x1FF6, - 0x1FF7, 0x210A, 0x210E, 0x210F, 0x2113, 0x212F, 0x2134, 0x2139, 0x213C, - 0x213D, 0x214E, 0x2184, 0x2C61, 0x2C65, 0x2C66, 0x2C68, 0x2C6A, 0x2C6C, - 0x2C71, 0x2C73, 0x2C74, 0x2C81, 0x2C83, 0x2C85, 0x2C87, 0x2C89, 0x2C8B, - 0x2C8D, 0x2C8F, 0x2C91, 0x2C93, 0x2C95, 0x2C97, 0x2C99, 0x2C9B, 0x2C9D, - 0x2C9F, 0x2CA1, 0x2CA3, 0x2CA5, 0x2CA7, 0x2CA9, 0x2CAB, 0x2CAD, 0x2CAF, - 0x2CB1, 0x2CB3, 0x2CB5, 0x2CB7, 0x2CB9, 0x2CBB, 0x2CBD, 0x2CBF, 0x2CC1, - 0x2CC3, 0x2CC5, 0x2CC7, 0x2CC9, 0x2CCB, 0x2CCD, 0x2CCF, 0x2CD1, 0x2CD3, - 0x2CD5, 0x2CD7, 0x2CD9, 0x2CDB, 0x2CDD, 0x2CDF, 0x2CE1, 0x2CE3, 0x2CE4, - 0x2CEC, 0x2CEE, 0x2CF3, 0x2D27, 0x2D2D, 0xA641, 0xA643, 0xA645, 0xA647, - 0xA649, 0xA64B, 0xA64D, 0xA64F, 0xA651, 0xA653, 0xA655, 0xA657, 0xA659, - 0xA65B, 0xA65D, 0xA65F, 0xA661, 0xA663, 0xA665, 0xA667, 0xA669, 0xA66B, - 0xA66D, 0xA681, 0xA683, 0xA685, 0xA687, 0xA689, 0xA68B, 0xA68D, 0xA68F, - 0xA691, 0xA693, 0xA695, 0xA697, 0xA699, 0xA69B, 0xA723, 0xA725, 0xA727, - 0xA729, 0xA72B, 0xA72D, 0xA733, 0xA735, 0xA737, 0xA739, 0xA73B, 0xA73D, - 0xA73F, 0xA741, 0xA743, 0xA745, 0xA747, 0xA749, 0xA74B, 0xA74D, 0xA74F, - 0xA751, 0xA753, 0xA755, 0xA757, 0xA759, 0xA75B, 0xA75D, 0xA75F, 0xA761, - 0xA763, 0xA765, 0xA767, 0xA769, 0xA76B, 0xA76D, 0xA76F, 0xA77A, 0xA77C, - 0xA77F, 0xA781, 0xA783, 0xA785, 0xA787, 0xA78C, 0xA78E, 0xA791, 0xA797, - 0xA799, 0xA79B, 0xA79D, 0xA79F, 0xA7A1, 0xA7A3, 0xA7A5, 0xA7A7, 0xA7A9, - 0xA7AF, 0xA7B5, 0xA7B7, 0xA7B9, 0xA7BB, 0xA7BD, 0xA7BF, 0xA7C1, 0xA7C3, - 0xA7C8, 0xA7CA, 0xA7D1, 0xA7D3, 0xA7D5, 0xA7D7, 0xA7D9, 0xA7F6, 0xA7FA + 0x527, 0x529, 0x52B, 0x52D, 0x52F, 0x1C8A, 0x1E01, 0x1E03, 0x1E05, + 0x1E07, 0x1E09, 0x1E0B, 0x1E0D, 0x1E0F, 0x1E11, 0x1E13, 0x1E15, 0x1E17, + 0x1E19, 0x1E1B, 0x1E1D, 0x1E1F, 0x1E21, 0x1E23, 0x1E25, 0x1E27, 0x1E29, + 0x1E2B, 0x1E2D, 0x1E2F, 0x1E31, 0x1E33, 0x1E35, 0x1E37, 0x1E39, 0x1E3B, + 0x1E3D, 0x1E3F, 0x1E41, 0x1E43, 0x1E45, 0x1E47, 0x1E49, 0x1E4B, 0x1E4D, + 0x1E4F, 0x1E51, 0x1E53, 0x1E55, 0x1E57, 0x1E59, 0x1E5B, 0x1E5D, 0x1E5F, + 0x1E61, 0x1E63, 0x1E65, 0x1E67, 0x1E69, 0x1E6B, 0x1E6D, 0x1E6F, 0x1E71, + 0x1E73, 0x1E75, 0x1E77, 0x1E79, 0x1E7B, 0x1E7D, 0x1E7F, 0x1E81, 0x1E83, + 0x1E85, 0x1E87, 0x1E89, 0x1E8B, 0x1E8D, 0x1E8F, 0x1E91, 0x1E93, 0x1E9F, + 0x1EA1, 0x1EA3, 0x1EA5, 0x1EA7, 0x1EA9, 0x1EAB, 0x1EAD, 0x1EAF, 0x1EB1, + 0x1EB3, 0x1EB5, 0x1EB7, 0x1EB9, 0x1EBB, 0x1EBD, 0x1EBF, 0x1EC1, 0x1EC3, + 0x1EC5, 0x1EC7, 0x1EC9, 0x1ECB, 0x1ECD, 0x1ECF, 0x1ED1, 0x1ED3, 0x1ED5, + 0x1ED7, 0x1ED9, 0x1EDB, 0x1EDD, 0x1EDF, 0x1EE1, 0x1EE3, 0x1EE5, 0x1EE7, + 0x1EE9, 0x1EEB, 0x1EED, 0x1EEF, 0x1EF1, 0x1EF3, 0x1EF5, 0x1EF7, 0x1EF9, + 0x1EFB, 0x1EFD, 0x1FB6, 0x1FB7, 0x1FBE, 0x1FC6, 0x1FC7, 0x1FD6, 0x1FD7, + 0x1FF6, 0x1FF7, 0x210A, 0x210E, 0x210F, 0x2113, 0x212F, 0x2134, 0x2139, + 0x213C, 0x213D, 0x214E, 0x2184, 0x2C61, 0x2C65, 0x2C66, 0x2C68, 0x2C6A, + 0x2C6C, 0x2C71, 0x2C73, 0x2C74, 0x2C81, 0x2C83, 0x2C85, 0x2C87, 0x2C89, + 0x2C8B, 0x2C8D, 0x2C8F, 0x2C91, 0x2C93, 0x2C95, 0x2C97, 0x2C99, 0x2C9B, + 0x2C9D, 0x2C9F, 0x2CA1, 0x2CA3, 0x2CA5, 0x2CA7, 0x2CA9, 0x2CAB, 0x2CAD, + 0x2CAF, 0x2CB1, 0x2CB3, 0x2CB5, 0x2CB7, 0x2CB9, 0x2CBB, 0x2CBD, 0x2CBF, + 0x2CC1, 0x2CC3, 0x2CC5, 0x2CC7, 0x2CC9, 0x2CCB, 0x2CCD, 0x2CCF, 0x2CD1, + 0x2CD3, 0x2CD5, 0x2CD7, 0x2CD9, 0x2CDB, 0x2CDD, 0x2CDF, 0x2CE1, 0x2CE3, + 0x2CE4, 0x2CEC, 0x2CEE, 0x2CF3, 0x2D27, 0x2D2D, 0xA641, 0xA643, 0xA645, + 0xA647, 0xA649, 0xA64B, 0xA64D, 0xA64F, 0xA651, 0xA653, 0xA655, 0xA657, + 0xA659, 0xA65B, 0xA65D, 0xA65F, 0xA661, 0xA663, 0xA665, 0xA667, 0xA669, + 0xA66B, 0xA66D, 0xA681, 0xA683, 0xA685, 0xA687, 0xA689, 0xA68B, 0xA68D, + 0xA68F, 0xA691, 0xA693, 0xA695, 0xA697, 0xA699, 0xA69B, 0xA723, 0xA725, + 0xA727, 0xA729, 0xA72B, 0xA72D, 0xA733, 0xA735, 0xA737, 0xA739, 0xA73B, + 0xA73D, 0xA73F, 0xA741, 0xA743, 0xA745, 0xA747, 0xA749, 0xA74B, 0xA74D, + 0xA74F, 0xA751, 0xA753, 0xA755, 0xA757, 0xA759, 0xA75B, 0xA75D, 0xA75F, + 0xA761, 0xA763, 0xA765, 0xA767, 0xA769, 0xA76B, 0xA76D, 0xA76F, 0xA77A, + 0xA77C, 0xA77F, 0xA781, 0xA783, 0xA785, 0xA787, 0xA78C, 0xA78E, 0xA791, + 0xA797, 0xA799, 0xA79B, 0xA79D, 0xA79F, 0xA7A1, 0xA7A3, 0xA7A5, 0xA7A7, + 0xA7A9, 0xA7AF, 0xA7B5, 0xA7B7, 0xA7B9, 0xA7BB, 0xA7BD, 0xA7BF, 0xA7C1, + 0xA7C3, 0xA7C8, 0xA7CA, 0xA7CD, 0xA7D1, 0xA7D3, 0xA7D5, 0xA7D7, 0xA7D9, + 0xA7DB, 0xA7F6, 0xA7FA #if CHRBITS > 16 ,0x105BB, 0x105BC, 0x1D4BB, 0x1D7CB #endif @@ -548,13 +554,14 @@ static const crange upperRangeTable[] = { {0xA7B0, 0xA7B4}, {0xA7C4, 0xA7C7}, {0xFF21, 0xFF3A} #if CHRBITS > 16 ,{0x10400, 0x10427}, {0x104B0, 0x104D3}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, - {0x1058C, 0x10592}, {0x10C80, 0x10CB2}, {0x118A0, 0x118BF}, {0x16E40, 0x16E5F}, - {0x1D400, 0x1D419}, {0x1D434, 0x1D44D}, {0x1D468, 0x1D481}, {0x1D4A9, 0x1D4AC}, - {0x1D4AE, 0x1D4B5}, {0x1D4D0, 0x1D4E9}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, - {0x1D516, 0x1D51C}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D54A, 0x1D550}, - {0x1D56C, 0x1D585}, {0x1D5A0, 0x1D5B9}, {0x1D5D4, 0x1D5ED}, {0x1D608, 0x1D621}, - {0x1D63C, 0x1D655}, {0x1D670, 0x1D689}, {0x1D6A8, 0x1D6C0}, {0x1D6E2, 0x1D6FA}, - {0x1D71C, 0x1D734}, {0x1D756, 0x1D76E}, {0x1D790, 0x1D7A8}, {0x1E900, 0x1E921} + {0x1058C, 0x10592}, {0x10C80, 0x10CB2}, {0x10D50, 0x10D65}, {0x118A0, 0x118BF}, + {0x16E40, 0x16E5F}, {0x1D400, 0x1D419}, {0x1D434, 0x1D44D}, {0x1D468, 0x1D481}, + {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B5}, {0x1D4D0, 0x1D4E9}, {0x1D507, 0x1D50A}, + {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, + {0x1D54A, 0x1D550}, {0x1D56C, 0x1D585}, {0x1D5A0, 0x1D5B9}, {0x1D5D4, 0x1D5ED}, + {0x1D608, 0x1D621}, {0x1D63C, 0x1D655}, {0x1D670, 0x1D689}, {0x1D6A8, 0x1D6C0}, + {0x1D6E2, 0x1D6FA}, {0x1D71C, 0x1D734}, {0x1D756, 0x1D76E}, {0x1D790, 0x1D7A8}, + {0x1E900, 0x1E921} #endif }; @@ -591,41 +598,41 @@ static const chr upperCharTable[] = { 0x4F8, 0x4FA, 0x4FC, 0x4FE, 0x500, 0x502, 0x504, 0x506, 0x508, 0x50A, 0x50C, 0x50E, 0x510, 0x512, 0x514, 0x516, 0x518, 0x51A, 0x51C, 0x51E, 0x520, 0x522, 0x524, 0x526, 0x528, 0x52A, 0x52C, - 0x52E, 0x10C7, 0x10CD, 0x1E00, 0x1E02, 0x1E04, 0x1E06, 0x1E08, 0x1E0A, - 0x1E0C, 0x1E0E, 0x1E10, 0x1E12, 0x1E14, 0x1E16, 0x1E18, 0x1E1A, 0x1E1C, - 0x1E1E, 0x1E20, 0x1E22, 0x1E24, 0x1E26, 0x1E28, 0x1E2A, 0x1E2C, 0x1E2E, - 0x1E30, 0x1E32, 0x1E34, 0x1E36, 0x1E38, 0x1E3A, 0x1E3C, 0x1E3E, 0x1E40, - 0x1E42, 0x1E44, 0x1E46, 0x1E48, 0x1E4A, 0x1E4C, 0x1E4E, 0x1E50, 0x1E52, - 0x1E54, 0x1E56, 0x1E58, 0x1E5A, 0x1E5C, 0x1E5E, 0x1E60, 0x1E62, 0x1E64, - 0x1E66, 0x1E68, 0x1E6A, 0x1E6C, 0x1E6E, 0x1E70, 0x1E72, 0x1E74, 0x1E76, - 0x1E78, 0x1E7A, 0x1E7C, 0x1E7E, 0x1E80, 0x1E82, 0x1E84, 0x1E86, 0x1E88, - 0x1E8A, 0x1E8C, 0x1E8E, 0x1E90, 0x1E92, 0x1E94, 0x1E9E, 0x1EA0, 0x1EA2, - 0x1EA4, 0x1EA6, 0x1EA8, 0x1EAA, 0x1EAC, 0x1EAE, 0x1EB0, 0x1EB2, 0x1EB4, - 0x1EB6, 0x1EB8, 0x1EBA, 0x1EBC, 0x1EBE, 0x1EC0, 0x1EC2, 0x1EC4, 0x1EC6, - 0x1EC8, 0x1ECA, 0x1ECC, 0x1ECE, 0x1ED0, 0x1ED2, 0x1ED4, 0x1ED6, 0x1ED8, - 0x1EDA, 0x1EDC, 0x1EDE, 0x1EE0, 0x1EE2, 0x1EE4, 0x1EE6, 0x1EE8, 0x1EEA, - 0x1EEC, 0x1EEE, 0x1EF0, 0x1EF2, 0x1EF4, 0x1EF6, 0x1EF8, 0x1EFA, 0x1EFC, - 0x1EFE, 0x1F59, 0x1F5B, 0x1F5D, 0x1F5F, 0x2102, 0x2107, 0x2115, 0x2124, - 0x2126, 0x2128, 0x213E, 0x213F, 0x2145, 0x2183, 0x2C60, 0x2C67, 0x2C69, - 0x2C6B, 0x2C72, 0x2C75, 0x2C82, 0x2C84, 0x2C86, 0x2C88, 0x2C8A, 0x2C8C, - 0x2C8E, 0x2C90, 0x2C92, 0x2C94, 0x2C96, 0x2C98, 0x2C9A, 0x2C9C, 0x2C9E, - 0x2CA0, 0x2CA2, 0x2CA4, 0x2CA6, 0x2CA8, 0x2CAA, 0x2CAC, 0x2CAE, 0x2CB0, - 0x2CB2, 0x2CB4, 0x2CB6, 0x2CB8, 0x2CBA, 0x2CBC, 0x2CBE, 0x2CC0, 0x2CC2, - 0x2CC4, 0x2CC6, 0x2CC8, 0x2CCA, 0x2CCC, 0x2CCE, 0x2CD0, 0x2CD2, 0x2CD4, - 0x2CD6, 0x2CD8, 0x2CDA, 0x2CDC, 0x2CDE, 0x2CE0, 0x2CE2, 0x2CEB, 0x2CED, - 0x2CF2, 0xA640, 0xA642, 0xA644, 0xA646, 0xA648, 0xA64A, 0xA64C, 0xA64E, - 0xA650, 0xA652, 0xA654, 0xA656, 0xA658, 0xA65A, 0xA65C, 0xA65E, 0xA660, - 0xA662, 0xA664, 0xA666, 0xA668, 0xA66A, 0xA66C, 0xA680, 0xA682, 0xA684, - 0xA686, 0xA688, 0xA68A, 0xA68C, 0xA68E, 0xA690, 0xA692, 0xA694, 0xA696, - 0xA698, 0xA69A, 0xA722, 0xA724, 0xA726, 0xA728, 0xA72A, 0xA72C, 0xA72E, - 0xA732, 0xA734, 0xA736, 0xA738, 0xA73A, 0xA73C, 0xA73E, 0xA740, 0xA742, - 0xA744, 0xA746, 0xA748, 0xA74A, 0xA74C, 0xA74E, 0xA750, 0xA752, 0xA754, - 0xA756, 0xA758, 0xA75A, 0xA75C, 0xA75E, 0xA760, 0xA762, 0xA764, 0xA766, - 0xA768, 0xA76A, 0xA76C, 0xA76E, 0xA779, 0xA77B, 0xA77D, 0xA77E, 0xA780, - 0xA782, 0xA784, 0xA786, 0xA78B, 0xA78D, 0xA790, 0xA792, 0xA796, 0xA798, - 0xA79A, 0xA79C, 0xA79E, 0xA7A0, 0xA7A2, 0xA7A4, 0xA7A6, 0xA7A8, 0xA7B6, - 0xA7B8, 0xA7BA, 0xA7BC, 0xA7BE, 0xA7C0, 0xA7C2, 0xA7C9, 0xA7D0, 0xA7D6, - 0xA7D8, 0xA7F5 + 0x52E, 0x10C7, 0x10CD, 0x1C89, 0x1E00, 0x1E02, 0x1E04, 0x1E06, 0x1E08, + 0x1E0A, 0x1E0C, 0x1E0E, 0x1E10, 0x1E12, 0x1E14, 0x1E16, 0x1E18, 0x1E1A, + 0x1E1C, 0x1E1E, 0x1E20, 0x1E22, 0x1E24, 0x1E26, 0x1E28, 0x1E2A, 0x1E2C, + 0x1E2E, 0x1E30, 0x1E32, 0x1E34, 0x1E36, 0x1E38, 0x1E3A, 0x1E3C, 0x1E3E, + 0x1E40, 0x1E42, 0x1E44, 0x1E46, 0x1E48, 0x1E4A, 0x1E4C, 0x1E4E, 0x1E50, + 0x1E52, 0x1E54, 0x1E56, 0x1E58, 0x1E5A, 0x1E5C, 0x1E5E, 0x1E60, 0x1E62, + 0x1E64, 0x1E66, 0x1E68, 0x1E6A, 0x1E6C, 0x1E6E, 0x1E70, 0x1E72, 0x1E74, + 0x1E76, 0x1E78, 0x1E7A, 0x1E7C, 0x1E7E, 0x1E80, 0x1E82, 0x1E84, 0x1E86, + 0x1E88, 0x1E8A, 0x1E8C, 0x1E8E, 0x1E90, 0x1E92, 0x1E94, 0x1E9E, 0x1EA0, + 0x1EA2, 0x1EA4, 0x1EA6, 0x1EA8, 0x1EAA, 0x1EAC, 0x1EAE, 0x1EB0, 0x1EB2, + 0x1EB4, 0x1EB6, 0x1EB8, 0x1EBA, 0x1EBC, 0x1EBE, 0x1EC0, 0x1EC2, 0x1EC4, + 0x1EC6, 0x1EC8, 0x1ECA, 0x1ECC, 0x1ECE, 0x1ED0, 0x1ED2, 0x1ED4, 0x1ED6, + 0x1ED8, 0x1EDA, 0x1EDC, 0x1EDE, 0x1EE0, 0x1EE2, 0x1EE4, 0x1EE6, 0x1EE8, + 0x1EEA, 0x1EEC, 0x1EEE, 0x1EF0, 0x1EF2, 0x1EF4, 0x1EF6, 0x1EF8, 0x1EFA, + 0x1EFC, 0x1EFE, 0x1F59, 0x1F5B, 0x1F5D, 0x1F5F, 0x2102, 0x2107, 0x2115, + 0x2124, 0x2126, 0x2128, 0x213E, 0x213F, 0x2145, 0x2183, 0x2C60, 0x2C67, + 0x2C69, 0x2C6B, 0x2C72, 0x2C75, 0x2C82, 0x2C84, 0x2C86, 0x2C88, 0x2C8A, + 0x2C8C, 0x2C8E, 0x2C90, 0x2C92, 0x2C94, 0x2C96, 0x2C98, 0x2C9A, 0x2C9C, + 0x2C9E, 0x2CA0, 0x2CA2, 0x2CA4, 0x2CA6, 0x2CA8, 0x2CAA, 0x2CAC, 0x2CAE, + 0x2CB0, 0x2CB2, 0x2CB4, 0x2CB6, 0x2CB8, 0x2CBA, 0x2CBC, 0x2CBE, 0x2CC0, + 0x2CC2, 0x2CC4, 0x2CC6, 0x2CC8, 0x2CCA, 0x2CCC, 0x2CCE, 0x2CD0, 0x2CD2, + 0x2CD4, 0x2CD6, 0x2CD8, 0x2CDA, 0x2CDC, 0x2CDE, 0x2CE0, 0x2CE2, 0x2CEB, + 0x2CED, 0x2CF2, 0xA640, 0xA642, 0xA644, 0xA646, 0xA648, 0xA64A, 0xA64C, + 0xA64E, 0xA650, 0xA652, 0xA654, 0xA656, 0xA658, 0xA65A, 0xA65C, 0xA65E, + 0xA660, 0xA662, 0xA664, 0xA666, 0xA668, 0xA66A, 0xA66C, 0xA680, 0xA682, + 0xA684, 0xA686, 0xA688, 0xA68A, 0xA68C, 0xA68E, 0xA690, 0xA692, 0xA694, + 0xA696, 0xA698, 0xA69A, 0xA722, 0xA724, 0xA726, 0xA728, 0xA72A, 0xA72C, + 0xA72E, 0xA732, 0xA734, 0xA736, 0xA738, 0xA73A, 0xA73C, 0xA73E, 0xA740, + 0xA742, 0xA744, 0xA746, 0xA748, 0xA74A, 0xA74C, 0xA74E, 0xA750, 0xA752, + 0xA754, 0xA756, 0xA758, 0xA75A, 0xA75C, 0xA75E, 0xA760, 0xA762, 0xA764, + 0xA766, 0xA768, 0xA76A, 0xA76C, 0xA76E, 0xA779, 0xA77B, 0xA77D, 0xA77E, + 0xA780, 0xA782, 0xA784, 0xA786, 0xA78B, 0xA78D, 0xA790, 0xA792, 0xA796, + 0xA798, 0xA79A, 0xA79C, 0xA79E, 0xA7A0, 0xA7A2, 0xA7A4, 0xA7A6, 0xA7A8, + 0xA7B6, 0xA7B8, 0xA7BA, 0xA7BC, 0xA7BE, 0xA7C0, 0xA7C2, 0xA7C9, 0xA7CB, + 0xA7CC, 0xA7D0, 0xA7D6, 0xA7D8, 0xA7DA, 0xA7DC, 0xA7F5 #if CHRBITS > 16 ,0x10594, 0x10595, 0x1D49C, 0x1D49E, 0x1D49F, 0x1D4A2, 0x1D4A5, 0x1D4A6, 0x1D504, 0x1D505, 0x1D538, 0x1D539, 0x1D546, 0x1D7CA @@ -645,7 +652,7 @@ static const crange graphRangeTable[] = { {0x5EF, 0x5F4}, {0x606, 0x61B}, {0x61D, 0x6DC}, {0x6DE, 0x70D}, {0x710, 0x74A}, {0x74D, 0x7B1}, {0x7C0, 0x7FA}, {0x7FD, 0x82D}, {0x830, 0x83E}, {0x840, 0x85B}, {0x860, 0x86A}, {0x870, 0x88E}, - {0x898, 0x8E1}, {0x8E3, 0x983}, {0x985, 0x98C}, {0x993, 0x9A8}, + {0x897, 0x8E1}, {0x8E3, 0x983}, {0x985, 0x98C}, {0x993, 0x9A8}, {0x9AA, 0x9B0}, {0x9B6, 0x9B9}, {0x9BC, 0x9C4}, {0x9CB, 0x9CE}, {0x9DF, 0x9E3}, {0x9E6, 0x9FE}, {0xA01, 0xA03}, {0xA05, 0xA0A}, {0xA13, 0xA28}, {0xA2A, 0xA30}, {0xA3E, 0xA42}, {0xA4B, 0xA4D}, @@ -683,34 +690,34 @@ static const crange graphRangeTable[] = { {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA}, {0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD}, {0x1AB0, 0x1ACE}, {0x1B00, 0x1B4C}, - {0x1B50, 0x1B7E}, {0x1B80, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49}, - {0x1C4D, 0x1C88}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CC7}, {0x1CD0, 0x1CFA}, - {0x1D00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, - {0x1F50, 0x1F57}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FC4}, - {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB}, {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, - {0x1FF6, 0x1FFE}, {0x2010, 0x2027}, {0x2030, 0x205E}, {0x2074, 0x208E}, - {0x2090, 0x209C}, {0x20A0, 0x20C0}, {0x20D0, 0x20F0}, {0x2100, 0x218B}, - {0x2190, 0x2426}, {0x2440, 0x244A}, {0x2460, 0x2B73}, {0x2B76, 0x2B95}, - {0x2B97, 0x2CF3}, {0x2CF9, 0x2D25}, {0x2D30, 0x2D67}, {0x2D7F, 0x2D96}, - {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, - {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, - {0x2DE0, 0x2E5D}, {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, - {0x2FF0, 0x2FFF}, {0x3001, 0x303F}, {0x3041, 0x3096}, {0x3099, 0x30FF}, - {0x3105, 0x312F}, {0x3131, 0x318E}, {0x3190, 0x31E3}, {0x31EF, 0x321E}, - {0x3220, 0xA48C}, {0xA490, 0xA4C6}, {0xA4D0, 0xA62B}, {0xA640, 0xA6F7}, - {0xA700, 0xA7CA}, {0xA7D5, 0xA7D9}, {0xA7F2, 0xA82C}, {0xA830, 0xA839}, - {0xA840, 0xA877}, {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9}, {0xA8E0, 0xA953}, - {0xA95F, 0xA97C}, {0xA980, 0xA9CD}, {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, - {0xAA00, 0xAA36}, {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2}, - {0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, {0xAB11, 0xAB16}, - {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, {0xAB30, 0xAB6B}, {0xAB70, 0xABED}, - {0xABF0, 0xABF9}, {0xAC00, 0xD7A3}, {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, - {0xF900, 0xFA6D}, {0xFA70, 0xFAD9}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, - {0xFB1D, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB46, 0xFBC2}, {0xFBD3, 0xFD8F}, - {0xFD92, 0xFDC7}, {0xFDF0, 0xFE19}, {0xFE20, 0xFE52}, {0xFE54, 0xFE66}, - {0xFE68, 0xFE6B}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, {0xFF01, 0xFFBE}, - {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7}, {0xFFDA, 0xFFDC}, - {0xFFE0, 0xFFE6}, {0xFFE8, 0xFFEE} + {0x1B4E, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49}, {0x1C4D, 0x1C8A}, + {0x1C90, 0x1CBA}, {0x1CBD, 0x1CC7}, {0x1CD0, 0x1CFA}, {0x1D00, 0x1F15}, + {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, + {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, + {0x1FD6, 0x1FDB}, {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE}, + {0x2010, 0x2027}, {0x2030, 0x205E}, {0x2074, 0x208E}, {0x2090, 0x209C}, + {0x20A0, 0x20C0}, {0x20D0, 0x20F0}, {0x2100, 0x218B}, {0x2190, 0x2429}, + {0x2440, 0x244A}, {0x2460, 0x2B73}, {0x2B76, 0x2B95}, {0x2B97, 0x2CF3}, + {0x2CF9, 0x2D25}, {0x2D30, 0x2D67}, {0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, + {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, + {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2E5D}, + {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFF}, + {0x3001, 0x303F}, {0x3041, 0x3096}, {0x3099, 0x30FF}, {0x3105, 0x312F}, + {0x3131, 0x318E}, {0x3190, 0x31E5}, {0x31EF, 0x321E}, {0x3220, 0xA48C}, + {0xA490, 0xA4C6}, {0xA4D0, 0xA62B}, {0xA640, 0xA6F7}, {0xA700, 0xA7CD}, + {0xA7D5, 0xA7DC}, {0xA7F2, 0xA82C}, {0xA830, 0xA839}, {0xA840, 0xA877}, + {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9}, {0xA8E0, 0xA953}, {0xA95F, 0xA97C}, + {0xA980, 0xA9CD}, {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36}, + {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2}, {0xAADB, 0xAAF6}, + {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, + {0xAB28, 0xAB2E}, {0xAB30, 0xAB6B}, {0xAB70, 0xABED}, {0xABF0, 0xABF9}, + {0xAC00, 0xD7A3}, {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xF900, 0xFA6D}, + {0xFA70, 0xFAD9}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36}, + {0xFB38, 0xFB3C}, {0xFB46, 0xFBC2}, {0xFBD3, 0xFD8F}, {0xFD92, 0xFDC7}, + {0xFDF0, 0xFE19}, {0xFE20, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, + {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, {0xFF01, 0xFFBE}, {0xFFC2, 0xFFC7}, + {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7}, {0xFFDA, 0xFFDC}, {0xFFE0, 0xFFE6}, + {0xFFE8, 0xFFEE} #if CHRBITS > 16 ,{0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133}, @@ -720,17 +727,18 @@ static const crange graphRangeTable[] = { {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, {0x1056F, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, - {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785}, - {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805}, {0x1080A, 0x10835}, - {0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF}, {0x108E0, 0x108F2}, - {0x108FB, 0x1091B}, {0x1091F, 0x10939}, {0x10980, 0x109B7}, {0x109BC, 0x109CF}, - {0x109D2, 0x10A03}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, - {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, {0x10A50, 0x10A58}, {0x10A60, 0x10A9F}, - {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6}, {0x10B00, 0x10B35}, {0x10B39, 0x10B55}, - {0x10B58, 0x10B72}, {0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, - {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10CFA, 0x10D27}, - {0x10D30, 0x10D39}, {0x10E60, 0x10E7E}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, - {0x10EFD, 0x10F27}, {0x10F30, 0x10F59}, {0x10F70, 0x10F89}, {0x10FB0, 0x10FCB}, + {0x105C0, 0x105F3}, {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, + {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805}, + {0x1080A, 0x10835}, {0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF}, + {0x108E0, 0x108F2}, {0x108FB, 0x1091B}, {0x1091F, 0x10939}, {0x10980, 0x109B7}, + {0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, + {0x10A19, 0x10A35}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, {0x10A50, 0x10A58}, + {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6}, {0x10B00, 0x10B35}, + {0x10B39, 0x10B55}, {0x10B58, 0x10B72}, {0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, + {0x10BA9, 0x10BAF}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, + {0x10CFA, 0x10D27}, {0x10D30, 0x10D39}, {0x10D40, 0x10D65}, {0x10D69, 0x10D85}, + {0x10E60, 0x10E7E}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, {0x10EC2, 0x10EC4}, + {0x10EFC, 0x10F27}, {0x10F30, 0x10F59}, {0x10F70, 0x10F89}, {0x10FB0, 0x10FCB}, {0x10FE0, 0x10FF6}, {0x11000, 0x1104D}, {0x11052, 0x11075}, {0x1107F, 0x110BC}, {0x110BE, 0x110C2}, {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11147}, {0x11150, 0x11176}, {0x11180, 0x111DF}, {0x111E1, 0x111F4}, @@ -738,56 +746,59 @@ static const crange graphRangeTable[] = { {0x1128F, 0x1129D}, {0x1129F, 0x112A9}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11303}, {0x11305, 0x1130C}, {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11335, 0x11339}, {0x1133B, 0x11344}, {0x1134B, 0x1134D}, {0x1135D, 0x11363}, - {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x1145B}, {0x1145D, 0x11461}, - {0x11480, 0x114C7}, {0x114D0, 0x114D9}, {0x11580, 0x115B5}, {0x115B8, 0x115DD}, - {0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, {0x11680, 0x116B9}, - {0x116C0, 0x116C9}, {0x11700, 0x1171A}, {0x1171D, 0x1172B}, {0x11730, 0x11746}, - {0x11800, 0x1183B}, {0x118A0, 0x118F2}, {0x118FF, 0x11906}, {0x1190C, 0x11913}, - {0x11918, 0x11935}, {0x1193B, 0x11946}, {0x11950, 0x11959}, {0x119A0, 0x119A7}, - {0x119AA, 0x119D7}, {0x119DA, 0x119E4}, {0x11A00, 0x11A47}, {0x11A50, 0x11AA2}, - {0x11AB0, 0x11AF8}, {0x11B00, 0x11B09}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, + {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11380, 0x11389}, {0x11390, 0x113B5}, + {0x113B7, 0x113C0}, {0x113C7, 0x113CA}, {0x113CC, 0x113D5}, {0x11400, 0x1145B}, + {0x1145D, 0x11461}, {0x11480, 0x114C7}, {0x114D0, 0x114D9}, {0x11580, 0x115B5}, + {0x115B8, 0x115DD}, {0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, + {0x11680, 0x116B9}, {0x116C0, 0x116C9}, {0x116D0, 0x116E3}, {0x11700, 0x1171A}, + {0x1171D, 0x1172B}, {0x11730, 0x11746}, {0x11800, 0x1183B}, {0x118A0, 0x118F2}, + {0x118FF, 0x11906}, {0x1190C, 0x11913}, {0x11918, 0x11935}, {0x1193B, 0x11946}, + {0x11950, 0x11959}, {0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E4}, + {0x11A00, 0x11A47}, {0x11A50, 0x11AA2}, {0x11AB0, 0x11AF8}, {0x11B00, 0x11B09}, + {0x11BC0, 0x11BE1}, {0x11BF0, 0x11BF9}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45}, {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D0B, 0x11D36}, {0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65}, {0x11D6A, 0x11D8E}, {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11EE0, 0x11EF8}, {0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, - {0x11F3E, 0x11F59}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399}, {0x12400, 0x1246E}, + {0x11F3E, 0x11F5A}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399}, {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, {0x12F90, 0x12FF2}, {0x13000, 0x1342F}, - {0x13440, 0x13455}, {0x14400, 0x14646}, {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, - {0x16A60, 0x16A69}, {0x16A6E, 0x16ABE}, {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED}, - {0x16AF0, 0x16AF5}, {0x16B00, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, - {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16E40, 0x16E9A}, {0x16F00, 0x16F4A}, - {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F}, {0x16FE0, 0x16FE4}, {0x17000, 0x187F7}, - {0x18800, 0x18CD5}, {0x18D00, 0x18D08}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, - {0x1B000, 0x1B122}, {0x1B150, 0x1B152}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, - {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, - {0x1BC9C, 0x1BC9F}, {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1CF50, 0x1CFC3}, - {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D172}, {0x1D17B, 0x1D1EA}, - {0x1D200, 0x1D245}, {0x1D2C0, 0x1D2D3}, {0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356}, - {0x1D360, 0x1D378}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D4A9, 0x1D4AC}, - {0x1D4AE, 0x1D4B9}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, - {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, - {0x1D540, 0x1D544}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, - {0x1D7CE, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1DF00, 0x1DF1E}, - {0x1DF25, 0x1DF2A}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, - {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D}, - {0x1E140, 0x1E149}, {0x1E290, 0x1E2AE}, {0x1E2C0, 0x1E2F9}, {0x1E4D0, 0x1E4F9}, - {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, - {0x1E8C7, 0x1E8D6}, {0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1EC71, 0x1ECB4}, - {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE29, 0x1EE32}, - {0x1EE34, 0x1EE37}, {0x1EE4D, 0x1EE4F}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, - {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, - {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1F000, 0x1F02B}, - {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CF}, - {0x1F0D1, 0x1F0F5}, {0x1F100, 0x1F1AD}, {0x1F1E6, 0x1F202}, {0x1F210, 0x1F23B}, - {0x1F240, 0x1F248}, {0x1F260, 0x1F265}, {0x1F300, 0x1F6D7}, {0x1F6DC, 0x1F6EC}, - {0x1F6F0, 0x1F6FC}, {0x1F700, 0x1F776}, {0x1F77B, 0x1F7D9}, {0x1F7E0, 0x1F7EB}, - {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, {0x1F860, 0x1F887}, - {0x1F890, 0x1F8AD}, {0x1F900, 0x1FA53}, {0x1FA60, 0x1FA6D}, {0x1FA70, 0x1FA7C}, - {0x1FA80, 0x1FA88}, {0x1FA90, 0x1FABD}, {0x1FABF, 0x1FAC5}, {0x1FACE, 0x1FADB}, - {0x1FAE0, 0x1FAE8}, {0x1FAF0, 0x1FAF8}, {0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBCA}, - {0x1FBF0, 0x1FBF9}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B739}, {0x2B740, 0x2B81D}, - {0x2B820, 0x2CEA1}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, - {0x30000, 0x3134A}, {0x31350, 0x323AF}, {0xE0100, 0xE01EF} + {0x13440, 0x13455}, {0x13460, 0x143FA}, {0x14400, 0x14646}, {0x16100, 0x16139}, + {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16ABE}, + {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5}, {0x16B00, 0x16B45}, + {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, + {0x16D40, 0x16D79}, {0x16E40, 0x16E9A}, {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, + {0x16F8F, 0x16F9F}, {0x16FE0, 0x16FE4}, {0x17000, 0x187F7}, {0x18800, 0x18CD5}, + {0x18CFF, 0x18D08}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1B000, 0x1B122}, + {0x1B150, 0x1B152}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, + {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9F}, + {0x1CC00, 0x1CCF9}, {0x1CD00, 0x1CEB3}, {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, + {0x1CF50, 0x1CFC3}, {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D172}, + {0x1D17B, 0x1D1EA}, {0x1D200, 0x1D245}, {0x1D2C0, 0x1D2D3}, {0x1D2E0, 0x1D2F3}, + {0x1D300, 0x1D356}, {0x1D360, 0x1D378}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, + {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, + {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, + {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, + {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, + {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, + {0x1E01B, 0x1E021}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D}, {0x1E100, 0x1E12C}, + {0x1E130, 0x1E13D}, {0x1E140, 0x1E149}, {0x1E290, 0x1E2AE}, {0x1E2C0, 0x1E2F9}, + {0x1E4D0, 0x1E4F9}, {0x1E5D0, 0x1E5FA}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, + {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6}, {0x1E900, 0x1E94B}, + {0x1E950, 0x1E959}, {0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03}, + {0x1EE05, 0x1EE1F}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE4D, 0x1EE4F}, + {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, + {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, + {0x1EEAB, 0x1EEBB}, {0x1F000, 0x1F02B}, {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, + {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CF}, {0x1F0D1, 0x1F0F5}, {0x1F100, 0x1F1AD}, + {0x1F1E6, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, {0x1F260, 0x1F265}, + {0x1F300, 0x1F6D7}, {0x1F6DC, 0x1F6EC}, {0x1F6F0, 0x1F6FC}, {0x1F700, 0x1F776}, + {0x1F77B, 0x1F7D9}, {0x1F7E0, 0x1F7EB}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, + {0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0x1F8B0, 0x1F8BB}, + {0x1F900, 0x1FA53}, {0x1FA60, 0x1FA6D}, {0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FA89}, + {0x1FA8F, 0x1FAC6}, {0x1FACE, 0x1FADC}, {0x1FADF, 0x1FAE9}, {0x1FAF0, 0x1FAF8}, + {0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBF9}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B739}, + {0x2B740, 0x2B81D}, {0x2B820, 0x2CEA1}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, + {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x323AF}, {0xE0100, 0xE01EF} #endif }; @@ -806,16 +817,17 @@ static const chr graphCharTable[] = { 0xFB41, 0xFB43, 0xFB44, 0xFDCF, 0xFFFC, 0xFFFD #if CHRBITS > 16 ,0x1003C, 0x1003D, 0x101A0, 0x10594, 0x10595, 0x105BB, 0x105BC, 0x10808, 0x10837, - 0x10838, 0x1083C, 0x108F4, 0x108F5, 0x1093F, 0x10A05, 0x10A06, 0x10EB0, 0x10EB1, - 0x11288, 0x1130F, 0x11310, 0x11332, 0x11333, 0x11347, 0x11348, 0x11350, 0x11357, - 0x11909, 0x11915, 0x11916, 0x11937, 0x11938, 0x11D08, 0x11D09, 0x11D3A, 0x11D3C, - 0x11D3D, 0x11D67, 0x11D68, 0x11D90, 0x11D91, 0x11FB0, 0x16FF0, 0x16FF1, 0x1AFFD, - 0x1AFFE, 0x1B132, 0x1B155, 0x1D49E, 0x1D49F, 0x1D4A2, 0x1D4A5, 0x1D4A6, 0x1D4BB, - 0x1D546, 0x1E023, 0x1E024, 0x1E08F, 0x1E14E, 0x1E14F, 0x1E2FF, 0x1E7ED, 0x1E7EE, - 0x1E95E, 0x1E95F, 0x1EE21, 0x1EE22, 0x1EE24, 0x1EE27, 0x1EE39, 0x1EE3B, 0x1EE42, - 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, - 0x1EE5D, 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE7E, 0x1EEF0, 0x1EEF1, 0x1F250, - 0x1F251, 0x1F7F0, 0x1F8B0, 0x1F8B1 + 0x10838, 0x1083C, 0x108F4, 0x108F5, 0x1093F, 0x10A05, 0x10A06, 0x10D8E, 0x10D8F, + 0x10EB0, 0x10EB1, 0x11288, 0x1130F, 0x11310, 0x11332, 0x11333, 0x11347, 0x11348, + 0x11350, 0x11357, 0x1138B, 0x1138E, 0x113C2, 0x113C5, 0x113D7, 0x113D8, 0x113E1, + 0x113E2, 0x11909, 0x11915, 0x11916, 0x11937, 0x11938, 0x11D08, 0x11D09, 0x11D3A, + 0x11D3C, 0x11D3D, 0x11D67, 0x11D68, 0x11D90, 0x11D91, 0x11FB0, 0x16FF0, 0x16FF1, + 0x1AFFD, 0x1AFFE, 0x1B132, 0x1B155, 0x1D49E, 0x1D49F, 0x1D4A2, 0x1D4A5, 0x1D4A6, + 0x1D4BB, 0x1D546, 0x1E023, 0x1E024, 0x1E08F, 0x1E14E, 0x1E14F, 0x1E2FF, 0x1E5FF, + 0x1E7ED, 0x1E7EE, 0x1E95E, 0x1E95F, 0x1EE21, 0x1EE22, 0x1EE24, 0x1EE27, 0x1EE39, + 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, + 0x1EE59, 0x1EE5B, 0x1EE5D, 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE7E, 0x1EEF0, + 0x1EEF1, 0x1F250, 0x1F251, 0x1F7F0, 0x1F8C0, 0x1F8C1 #endif }; diff --git a/generic/tclUniData.c b/generic/tclUniData.c index eb45735..c1ad45e 100644 --- a/generic/tclUniData.c +++ b/generic/tclUniData.c @@ -200,53 +200,53 @@ static const unsigned short pageMap[] = { 10816, 10848, 10880, 10912, 8032, 10944, 3296, 3296, 3296, 3296, 9216, 1344, 10976, 11008, 1344, 11040, 11072, 11104, 11136, 1344, 11168, 3296, 11200, 11232, 11264, 1344, 11296, 11328, 11360, 11392, 1344, - 11424, 1344, 11456, 11488, 11520, 3296, 3296, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 7776, 4704, 11552, 11584, 11616, 3296, - 3296, 11648, 11680, 11712, 11744, 4736, 11776, 3296, 11808, 11840, - 11872, 3296, 3296, 1344, 11904, 11936, 6880, 11968, 12000, 12032, 12064, - 12096, 3296, 12128, 12160, 1344, 12192, 12224, 12256, 12288, 12320, - 3296, 3296, 1344, 1344, 12352, 3296, 12384, 12416, 12448, 12480, 1344, - 12512, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 12544, - 1344, 12576, 3296, 12608, 12096, 12640, 12672, 12704, 12736, 12704, - 12768, 7776, 12800, 12832, 12864, 12896, 5280, 12928, 12960, 12992, - 13024, 13056, 13088, 13120, 5280, 13152, 13184, 13216, 13248, 13280, - 13312, 3296, 13344, 13376, 13408, 13440, 13472, 13504, 13536, 13568, - 3296, 3296, 3296, 3296, 1344, 13600, 13632, 13664, 1344, 13696, 13728, - 3296, 3296, 3296, 3296, 3296, 1344, 13760, 13792, 3296, 1344, 13824, - 13856, 13888, 1344, 13920, 13952, 3296, 4032, 13984, 14016, 3296, 3296, - 3296, 3296, 3296, 1344, 14048, 3296, 3296, 3296, 14080, 14112, 14144, - 14176, 14208, 14240, 3296, 3296, 14272, 14304, 14336, 14368, 14400, - 14432, 1344, 14464, 14496, 1344, 4608, 14528, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 14560, 14592, 14624, 14656, 14688, 14720, 3296, 3296, - 14752, 14784, 14816, 14848, 14880, 13952, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 14912, 14944, 14976, 15008, 3296, 3296, 15040, - 15072, 15104, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 11424, 1344, 11456, 11488, 11520, 1344, 11552, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 7776, 4704, 11584, 11616, 11648, 3296, + 3296, 11680, 11712, 11744, 11776, 4736, 11808, 3296, 11840, 11872, + 11904, 3296, 3296, 1344, 11936, 11968, 6880, 12000, 12032, 12064, 12096, + 12128, 3296, 12160, 12192, 1344, 12224, 12256, 12288, 12320, 12352, + 3296, 3296, 1344, 1344, 12384, 3296, 12416, 12448, 12480, 12512, 1344, + 12544, 12576, 12608, 12640, 3296, 3296, 3296, 3296, 3296, 3296, 12672, + 1344, 12704, 12736, 12768, 12128, 12800, 12832, 12864, 12896, 12864, + 12928, 7776, 12960, 12992, 13024, 13056, 5280, 13088, 13120, 13152, + 13184, 13216, 13248, 13280, 5280, 13312, 13344, 13376, 13408, 13440, + 13472, 3296, 13504, 13536, 13568, 13600, 13632, 13664, 13696, 13728, + 13760, 13792, 13824, 13856, 1344, 13888, 13920, 13952, 1344, 13984, + 14016, 3296, 3296, 3296, 3296, 3296, 1344, 14048, 14080, 3296, 1344, + 14112, 14144, 14176, 1344, 14208, 14240, 14272, 14304, 14336, 14368, + 3296, 3296, 3296, 3296, 3296, 1344, 14400, 3296, 3296, 3296, 14432, + 14464, 14496, 14528, 14560, 14592, 3296, 3296, 14624, 14656, 14688, + 14720, 14752, 14784, 1344, 14816, 14848, 1344, 4608, 14880, 3296, 3296, + 3296, 3296, 3296, 1344, 14912, 14944, 14976, 15008, 15040, 15072, 15104, + 3296, 3296, 15136, 15168, 15200, 15232, 15264, 15296, 3296, 3296, 3296, + 3296, 3296, 3296, 3296, 3296, 3296, 15328, 15360, 15392, 15424, 3296, + 3296, 15456, 15488, 15520, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 9920, 3296, 3296, 3296, 10816, - 10816, 10816, 15136, 1344, 1344, 1344, 1344, 1344, 1344, 15168, 3296, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 9920, 3296, 3296, + 3296, 10816, 10816, 10816, 15552, 1344, 1344, 1344, 1344, 1344, 1344, + 15584, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 12704, 1344, 1344, - 15200, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 12864, + 1344, 1344, 15616, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 15232, - 15264, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 14016, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 1344, 15648, 15680, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 10720, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 14368, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, @@ -264,17 +264,17 @@ static const unsigned short pageMap[] = { 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 3296, 3296, 3296, 15712, 15744, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 4608, 4736, 15296, 1344, 4736, 15328, 15360, 1344, 15392, 15424, - 15456, 15488, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 14080, 14112, 15520, 3296, 3296, 3296, 1344, 1344, 15552, 15584, 15616, - 3296, 3296, 15648, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 4608, 4736, 15776, 1344, 4736, 15808, + 15840, 1344, 15872, 15904, 15936, 15968, 3296, 3296, 3296, 3296, 3296, + 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 16000, 16032, 3296, + 3296, 3296, 3296, 3296, 3296, 14432, 14464, 16064, 3296, 3296, 3296, + 1344, 1344, 16096, 16128, 16160, 3296, 3296, 16192, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -290,15 +290,11 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 15680, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 16224, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 4704, 3296, 12352, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 4704, 16256, 12384, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, @@ -317,19 +313,20 @@ static const unsigned short pageMap[] = { 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 15712, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 15744, 15776, 15808, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 9792, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 3296, 3296, 3296, 3296, 3296, 3296, 16288, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 16320, 16352, 16384, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 9792, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 1344, 1344, 1344, 15840, 15872, 15904, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 1344, 1344, 1344, + 16416, 16448, 16480, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, @@ -338,42 +335,45 @@ static const unsigned short pageMap[] = { 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 704, 15936, 15968, 4928, 4928, 4928, 16000, 3296, 4928, 4928, - 4928, 4928, 4928, 4928, 4928, 8000, 4928, 16032, 4928, 16064, 16096, - 16128, 4928, 6848, 4928, 4928, 16160, 3296, 3296, 3296, 16192, 16192, - 4928, 4928, 16224, 16256, 3296, 3296, 3296, 3296, 16288, 16320, 16352, - 16384, 16416, 16448, 16480, 16512, 16544, 16576, 16608, 16640, 16672, - 16288, 16320, 16704, 16384, 16736, 16768, 16800, 16512, 16832, 16864, - 16896, 16928, 16960, 16992, 17024, 17056, 17088, 17120, 17152, 4928, - 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, - 4928, 4928, 4928, 704, 17184, 704, 17216, 17248, 17280, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 3296, 3296, 3296, 3296, 3296, 3296, 4928, 4928, 4928, 4928, 4928, 4928, + 4928, 16512, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, + 4928, 4928, 4928, 4928, 7968, 3296, 3296, 704, 16544, 16576, 4928, + 4928, 4928, 16608, 3296, 4928, 4928, 4928, 4928, 4928, 4928, 4928, + 8000, 4928, 16640, 4928, 16672, 16704, 16736, 4928, 6848, 4928, 4928, + 16768, 3296, 3296, 3296, 16800, 16800, 4928, 4928, 16832, 16864, 3296, + 3296, 3296, 3296, 16896, 16928, 16960, 16992, 17024, 17056, 17088, + 17120, 17152, 17184, 17216, 17248, 17280, 16896, 16928, 17312, 16992, + 17344, 17376, 17408, 17120, 17440, 17472, 17504, 17536, 17568, 17600, + 17632, 17664, 17696, 17728, 17760, 4928, 4928, 4928, 4928, 4928, 4928, + 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 704, 17792, + 704, 17824, 17856, 17888, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 17312, 17344, 3296, - 3296, 3296, 3296, 3296, 3296, 17376, 17408, 5664, 17440, 17472, 3296, - 3296, 3296, 1344, 17504, 17536, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 12704, 17568, 1344, 17600, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 12704, - 17632, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 17664, 1344, 1344, 1344, 1344, 1344, 1344, 17696, 3296, 17728, - 17760, 17792, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 3296, 3296, 3296, 17920, 17952, 3296, 3296, 3296, 3296, 3296, 3296, + 17984, 18016, 5664, 18048, 18080, 3296, 3296, 3296, 1344, 18112, 18144, + 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 12864, 18176, + 1344, 18208, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 3296, 3296, 3296, 3296, 3296, 12864, 18240, 3296, 3296, 3296, 3296, + 3296, 3296, 12864, 18272, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 18304, 1344, 1344, + 1344, 1344, 1344, 1344, 18336, 3296, 18368, 18400, 18432, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 17824, 6880, 17856, 3296, 3296, 17888, 17920, 3296, - 3296, 3296, 3296, 3296, 3296, 17952, 17984, 18016, 18048, 18080, 18112, - 3296, 18144, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 4928, - 18176, 4928, 4928, 7968, 18208, 18240, 8000, 18272, 4928, 4928, 4928, - 4928, 18304, 3296, 18336, 18368, 18400, 18432, 18464, 3296, 3296, 3296, - 3296, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 18496, 4928, 4928, + 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 18464, + 6880, 18496, 3296, 3296, 18528, 18560, 3296, 3296, 3296, 3296, 3296, + 3296, 18592, 18624, 18656, 18688, 18720, 18752, 3296, 18784, 3296, + 3296, 3296, 3296, 3296, 3296, 3296, 3296, 4928, 18816, 4928, 4928, + 7968, 18848, 18880, 8000, 18912, 4928, 4928, 4928, 4928, 18944, 3296, + 18976, 19008, 19040, 19072, 19104, 3296, 3296, 3296, 3296, 4928, 4928, + 4928, 4928, 4928, 4928, 4928, 19136, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, - 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 18528, 18560, 4928, - 4928, 4928, 18592, 4928, 4928, 18624, 18656, 18176, 4928, 18688, 4928, - 18720, 18752, 3296, 3296, 4928, 4928, 4928, 4928, 4928, 4928, 4928, - 4928, 4928, 4928, 7968, 18784, 18816, 18848, 18880, 18912, 4928, 4928, - 4928, 4928, 18944, 4928, 6848, 18976, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 4928, 4928, 4928, 4928, 4928, 19168, 19200, 4928, 4928, 4928, 19232, + 4928, 4928, 19264, 19296, 18816, 4928, 19328, 4928, 19360, 19392, 19424, + 3296, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 7968, + 19456, 19488, 4928, 19520, 19552, 4928, 4928, 4928, 4928, 19584, 4928, + 4928, 16512, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -484,8 +484,8 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 3296, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 3296, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -495,8 +495,8 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 9920, 1344, 1344, 1344, 1344, 1344, 1344, 11296, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 9920, 1344, 1344, 1344, 1344, 1344, 1344, 11296, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -511,7 +511,7 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 19008, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 19616, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -530,21 +530,21 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 19040, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 11296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 1344, 1344, 1344, 1344, 19648, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 11296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 11296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, + 3296, 3296, 3296, 3296, 3296, 3296, 3296, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 11296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, - 3296, 3296, 3296, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 3296, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -557,7 +557,7 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -568,7 +568,7 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 15488 + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 15968 #endif /* TCL_UTF_MAX > 3 */ }; @@ -600,205 +600,205 @@ static const unsigned char groupMap[] = { 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 27, 23, 24, 23, 24, 23, 24, 28, 29, 30, 23, 24, 23, 24, 31, 23, 24, 32, 32, 23, 24, 21, 33, 34, 35, 23, 24, 32, 36, 37, 38, 39, 23, 24, 40, - 21, 38, 41, 42, 43, 23, 24, 23, 24, 23, 24, 44, 23, 24, 44, 21, 21, - 23, 24, 44, 23, 24, 45, 45, 23, 24, 23, 24, 46, 23, 24, 21, 15, 23, - 24, 21, 47, 15, 15, 15, 15, 48, 49, 50, 48, 49, 50, 48, 49, 50, 23, - 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 51, 23, + 41, 38, 42, 43, 44, 23, 24, 23, 24, 23, 24, 45, 23, 24, 45, 21, 21, + 23, 24, 45, 23, 24, 46, 46, 23, 24, 23, 24, 47, 23, 24, 21, 15, 23, + 24, 21, 48, 15, 15, 15, 15, 49, 50, 51, 49, 50, 51, 49, 50, 51, 23, + 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 52, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 21, 48, 49, 50, 23, 24, 52, 53, 23, 24, 23, 24, 23, 24, 23, 24, 54, + 21, 49, 50, 51, 23, 24, 53, 54, 23, 24, 23, 24, 23, 24, 23, 24, 55, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 23, 24, 21, 21, 21, 21, 21, 21, 55, 23, 24, 56, 57, 58, 58, 23, 24, - 59, 60, 61, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 62, 63, 64, 65, - 66, 21, 67, 67, 21, 68, 21, 69, 70, 21, 21, 21, 67, 71, 21, 72, 21, - 73, 74, 21, 75, 76, 74, 77, 78, 21, 21, 76, 21, 79, 80, 21, 21, 81, - 21, 21, 21, 21, 21, 21, 21, 82, 21, 21, 83, 21, 84, 83, 21, 21, 21, - 85, 83, 86, 87, 87, 88, 21, 21, 21, 21, 21, 89, 21, 15, 21, 21, 21, - 21, 21, 21, 21, 21, 90, 91, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 11, 11, 11, 11, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 92, 92, 92, 92, 92, 11, 11, 11, 11, 11, 11, 11, 92, - 11, 92, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 23, 24, 23, - 24, 92, 11, 23, 24, 0, 0, 92, 42, 42, 42, 3, 95, 0, 0, 0, 0, 11, 11, - 96, 3, 97, 97, 97, 0, 98, 0, 99, 99, 21, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 100, 101, 101, 101, 21, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 102, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 103, 104, 104, 105, 106, 107, 108, 108, 108, 109, 110, 111, - 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 112, 113, 114, 115, 116, 117, 7, 23, 24, - 118, 23, 24, 21, 54, 54, 54, 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, 10, 10, 10, 10, 10, 10, 10, + 23, 24, 21, 21, 21, 21, 21, 21, 56, 23, 24, 57, 58, 59, 59, 23, 24, + 60, 61, 62, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 63, 64, 65, 66, + 67, 21, 68, 68, 21, 69, 21, 70, 71, 21, 21, 21, 68, 72, 21, 73, 74, + 75, 76, 21, 77, 78, 76, 79, 80, 21, 21, 78, 21, 81, 82, 21, 21, 83, + 21, 21, 21, 21, 21, 21, 21, 84, 21, 21, 85, 21, 86, 85, 21, 21, 21, + 87, 85, 88, 89, 89, 90, 21, 21, 21, 21, 21, 91, 21, 15, 21, 21, 21, + 21, 21, 21, 21, 21, 92, 93, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 11, 11, 11, 11, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 94, 94, 94, 94, 94, 11, 11, 11, 11, 11, 11, 11, 94, + 11, 94, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 96, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 23, 24, 23, + 24, 94, 11, 23, 24, 0, 0, 94, 43, 43, 43, 3, 97, 0, 0, 0, 0, 11, 11, + 98, 3, 99, 99, 99, 0, 100, 0, 101, 101, 21, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 102, 103, 103, 103, 21, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 104, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 105, 106, 106, 107, 108, 109, 110, 110, 110, 111, 112, + 113, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, + 23, 24, 23, 24, 23, 24, 23, 24, 114, 115, 116, 117, 118, 119, 7, 23, + 24, 120, 23, 24, 21, 55, 55, 55, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 23, 24, 14, 93, 93, 93, 93, 93, - 120, 120, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 121, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 122, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 23, 24, 23, 24, 0, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 0, 0, 92, 3, 3, 3, 3, 3, 3, 21, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 21, 21, 3, 8, 0, 0, 14, 14, 4, 0, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 8, 93, 3, 93, 93, 3, 93, 93, 3, 93, 0, 0, 0, - 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, - 15, 15, 15, 15, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, - 17, 17, 17, 7, 7, 7, 3, 3, 4, 3, 3, 14, 14, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 3, 17, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 15, - 93, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 3, 15, 93, 93, 93, 93, 93, 93, 93, 17, 14, 93, 93, 93, 93, - 93, 93, 92, 92, 93, 93, 14, 93, 93, 93, 93, 15, 15, 9, 9, 9, 9, 9, + 13, 13, 13, 13, 13, 13, 13, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 23, 24, 14, 95, 95, 95, 95, + 95, 122, 122, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, + 23, 24, 23, 24, 23, 24, 23, 24, 123, 23, 24, 23, 24, 23, 24, 23, 24, + 23, 24, 23, 24, 23, 24, 124, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, + 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, + 24, 23, 24, 23, 24, 0, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 0, 0, 94, 3, 3, 3, 3, 3, 3, 21, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 21, 21, 3, 8, 0, 0, 14, 14, 4, 0, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 8, 95, 3, 95, 95, 3, 95, 95, 3, 95, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, + 0, 15, 15, 15, 15, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, + 17, 17, 17, 7, 7, 7, 3, 3, 4, 3, 3, 14, 14, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 3, 17, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 94, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 15, + 95, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 3, 15, 95, 95, 95, 95, 95, 95, 95, 17, 14, 95, 95, 95, 95, + 95, 95, 94, 94, 95, 95, 14, 95, 95, 95, 95, 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 14, 14, 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 0, 17, 15, 93, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 3, 3, 3, 3, 0, 17, 15, 95, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 0, 0, 15, 15, 15, + 15, 15, 15, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 15, + 15, 15, 15, 15, 15, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 92, 92, 14, 3, 3, 3, 92, 0, 0, - 93, 4, 4, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 93, 93, 93, 93, 92, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 92, 93, 93, 93, 92, 93, 93, 93, 93, 93, 0, 0, 3, 3, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 94, 14, 3, 3, 3, 94, 0, 0, + 95, 4, 4, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 95, 95, 95, 95, 94, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 94, 95, 95, 95, 94, 95, 95, 95, 95, 95, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 93, 93, 93, 0, 0, 3, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 95, 95, 95, 0, 0, 3, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 11, 15, 15, 15, 15, - 15, 15, 0, 17, 17, 0, 0, 0, 0, 0, 0, 93, 93, 93, 93, 93, 93, 93, 93, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 17, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 125, + 15, 15, 0, 17, 17, 0, 0, 0, 0, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 94, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 17, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 127, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 93, 125, 93, 15, 125, 125, 125, 93, 93, 93, 93, 93, 93, - 93, 93, 125, 125, 125, 125, 93, 125, 125, 15, 93, 93, 93, 93, 93, 93, - 93, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 93, 3, 3, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 3, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 93, 125, 125, 0, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 95, 127, 95, 15, 127, 127, 127, 95, 95, 95, 95, 95, 95, + 95, 95, 127, 127, 127, 127, 95, 127, 127, 15, 95, 95, 95, 95, 95, 95, + 95, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 3, 3, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 3, 94, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 95, 127, 127, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, - 15, 0, 15, 0, 0, 0, 15, 15, 15, 15, 0, 0, 93, 15, 125, 125, 125, 93, - 93, 93, 93, 0, 0, 125, 125, 0, 0, 125, 125, 93, 15, 0, 0, 0, 0, 0, - 0, 0, 0, 125, 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 93, 93, 0, 0, 9, 9, + 15, 0, 15, 0, 0, 0, 15, 15, 15, 15, 0, 0, 95, 15, 127, 127, 127, 95, + 95, 95, 95, 0, 0, 127, 127, 0, 0, 127, 127, 95, 15, 0, 0, 0, 0, 0, + 0, 0, 0, 127, 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 95, 95, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 4, 4, 18, 18, 18, 18, 18, 18, 14, 4, - 15, 3, 93, 0, 0, 93, 93, 125, 0, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, + 15, 3, 95, 0, 0, 95, 95, 127, 0, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, - 15, 0, 15, 15, 0, 15, 15, 0, 0, 93, 0, 125, 125, 125, 93, 93, 0, 0, - 0, 0, 93, 93, 0, 0, 93, 93, 93, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 15, + 15, 0, 15, 15, 0, 15, 15, 0, 0, 95, 0, 127, 127, 127, 95, 95, 0, 0, + 0, 0, 95, 95, 0, 0, 95, 95, 95, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 93, 93, 15, 15, 15, 93, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 93, - 125, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, + 9, 95, 95, 15, 15, 15, 95, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 95, + 127, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, - 15, 15, 0, 0, 93, 15, 125, 125, 125, 93, 93, 93, 93, 93, 0, 93, 93, - 125, 0, 125, 125, 93, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 15, 15, 93, 93, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 4, - 0, 0, 0, 0, 0, 0, 0, 15, 93, 93, 93, 93, 93, 93, 0, 93, 125, 125, 0, + 15, 15, 0, 0, 95, 15, 127, 127, 127, 95, 95, 95, 95, 95, 0, 95, 95, + 127, 0, 127, 127, 95, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 15, 95, 95, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 4, + 0, 0, 0, 0, 0, 0, 0, 15, 95, 95, 95, 95, 95, 95, 0, 95, 127, 127, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, - 0, 0, 93, 15, 125, 93, 125, 93, 93, 93, 93, 0, 0, 125, 125, 0, 0, 125, - 125, 93, 0, 0, 0, 0, 0, 0, 0, 93, 93, 125, 0, 0, 0, 0, 15, 15, 0, 15, - 15, 15, 93, 93, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 15, 18, 18, - 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 15, 0, 15, 15, 15, + 0, 0, 95, 15, 127, 95, 127, 95, 95, 95, 95, 0, 0, 127, 127, 0, 0, 127, + 127, 95, 0, 0, 0, 0, 0, 0, 0, 95, 95, 127, 0, 0, 0, 0, 15, 15, 0, 15, + 15, 15, 95, 95, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 15, 18, 18, + 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 15, 0, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 0, 15, 15, 0, 15, 0, 15, 15, 0, 0, 0, 15, 15, 0, 0, 0, 15, 15, 15, 0, 0, 0, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 125, 125, 93, - 125, 125, 0, 0, 0, 125, 125, 125, 0, 125, 125, 125, 93, 0, 0, 15, 0, - 0, 0, 0, 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 127, 127, 95, + 127, 127, 0, 0, 0, 127, 127, 127, 0, 127, 127, 127, 95, 0, 0, 15, 0, + 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 14, 14, 14, 14, 14, 14, 4, 14, - 0, 0, 0, 0, 0, 93, 125, 125, 125, 93, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 0, 0, 0, 95, 127, 127, 127, 95, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 93, 15, 93, 93, 93, 125, - 125, 125, 125, 0, 93, 93, 93, 0, 93, 93, 93, 93, 0, 0, 0, 0, 0, 0, - 0, 93, 93, 0, 15, 15, 15, 0, 0, 15, 0, 0, 15, 15, 93, 93, 0, 0, 9, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 95, 15, 95, 95, 95, 127, + 127, 127, 127, 0, 95, 95, 95, 0, 95, 95, 95, 95, 0, 0, 0, 0, 0, 0, + 0, 95, 95, 0, 15, 15, 15, 0, 0, 15, 0, 0, 15, 15, 95, 95, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 3, 18, 18, 18, 18, - 18, 18, 18, 14, 15, 93, 125, 125, 3, 15, 15, 15, 15, 15, 15, 15, 15, + 18, 18, 18, 14, 15, 95, 127, 127, 3, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 93, 15, 125, 93, 125, - 125, 125, 125, 125, 0, 93, 125, 125, 0, 125, 125, 93, 93, 0, 0, 0, - 0, 0, 0, 0, 125, 125, 0, 0, 0, 0, 0, 0, 15, 15, 0, 15, 15, 93, 93, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 15, 15, 125, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 93, 93, 125, 125, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 95, 15, 127, 95, 127, + 127, 127, 127, 127, 0, 95, 127, 127, 0, 127, 127, 95, 95, 0, 0, 0, + 0, 0, 0, 0, 127, 127, 0, 0, 0, 0, 0, 0, 15, 15, 0, 15, 15, 95, 95, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 15, 15, 127, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 95, 95, 127, 127, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 93, 15, 125, - 125, 125, 93, 93, 93, 93, 0, 125, 125, 125, 0, 125, 125, 125, 93, 15, - 14, 0, 0, 0, 0, 15, 15, 15, 125, 18, 18, 18, 18, 18, 18, 18, 15, 15, - 15, 93, 93, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 14, 15, 15, 15, 15, 15, 15, 0, 93, 125, 125, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 15, 127, + 127, 127, 95, 95, 95, 95, 0, 127, 127, 127, 0, 127, 127, 127, 95, 15, + 14, 0, 0, 0, 0, 15, 15, 15, 127, 18, 18, 18, 18, 18, 18, 18, 15, 15, + 15, 95, 95, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 14, 15, 15, 15, 15, 15, 15, 0, 95, 127, 127, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 93, 0, 0, - 0, 0, 125, 125, 125, 93, 93, 93, 0, 93, 0, 125, 125, 125, 125, 125, - 125, 125, 125, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 125, 125, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, + 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 95, 0, 0, + 0, 0, 127, 127, 127, 95, 95, 95, 0, 95, 0, 127, 127, 127, 127, 127, + 127, 127, 127, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 127, 127, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 15, 15, 93, 93, 93, 93, 93, - 93, 93, 0, 0, 0, 0, 4, 15, 15, 15, 15, 15, 15, 92, 93, 93, 93, 93, - 93, 93, 93, 93, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 0, 0, 0, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 15, 15, 95, 95, 95, 95, 95, + 95, 95, 0, 0, 0, 0, 4, 15, 15, 15, 15, 15, 15, 94, 95, 95, 95, 95, + 95, 95, 95, 95, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 15, 0, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 93, 15, 15, 93, 93, 93, 93, 93, 93, 93, 93, 93, 15, 0, - 0, 15, 15, 15, 15, 15, 0, 92, 0, 93, 93, 93, 93, 93, 93, 93, 0, 9, + 15, 15, 15, 95, 15, 15, 95, 95, 95, 95, 95, 95, 95, 95, 95, 15, 0, + 0, 15, 15, 15, 15, 15, 0, 94, 0, 95, 95, 95, 95, 95, 95, 95, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 15, 15, 15, 15, 15, 14, 14, 14, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 14, 14, 14, 93, 93, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 14, 14, 14, 95, 95, 14, 14, 14, 14, 14, 14, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 14, 93, 14, 93, 14, 93, 5, 6, 5, 6, 125, 125, + 18, 18, 18, 18, 18, 18, 14, 95, 14, 95, 14, 95, 5, 6, 5, 6, 127, 127, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 125, 93, 93, 93, 93, 93, - 3, 93, 93, 15, 15, 15, 15, 15, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 0, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 0, 14, 14, 14, 14, 14, 14, 14, 14, 93, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 127, 95, 95, 95, 95, 95, + 3, 95, 95, 15, 15, 15, 15, 15, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 0, 14, 14, 14, 14, 14, 14, 14, 14, 95, 14, 14, 14, 14, 14, 14, 0, 14, 14, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3, 3, 0, - 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 125, 125, 93, - 93, 93, 93, 125, 93, 93, 93, 93, 93, 93, 125, 93, 93, 125, 125, 93, - 93, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 15, 15, 15, - 15, 15, 15, 125, 125, 93, 93, 15, 15, 15, 15, 93, 93, 93, 15, 125, - 125, 125, 15, 15, 125, 125, 125, 125, 125, 125, 125, 15, 15, 15, 93, - 93, 93, 93, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, - 125, 125, 93, 93, 125, 125, 125, 125, 125, 125, 93, 15, 125, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 125, 125, 125, 93, 14, 14, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 0, 126, 0, 0, 0, 0, 0, 126, 0, 0, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 3, 92, 127, 127, 127, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 127, 95, + 95, 95, 95, 127, 95, 95, 95, 95, 95, 95, 127, 95, 95, 127, 127, 95, + 95, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 15, 15, 15, + 15, 15, 15, 127, 127, 95, 95, 15, 15, 15, 15, 95, 95, 95, 15, 127, + 127, 127, 15, 15, 127, 127, 127, 127, 127, 127, 127, 15, 15, 15, 95, + 95, 95, 95, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, + 127, 127, 95, 95, 127, 127, 127, 127, 127, 127, 95, 15, 127, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 127, 127, 127, 95, 14, 14, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 0, 128, 0, 0, 0, 0, 0, 128, 0, 0, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 3, 94, 129, 129, 129, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, @@ -809,48 +809,48 @@ static const unsigned char groupMap[] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 93, 93, 93, 3, 3, 3, 3, 3, 3, 3, 3, 3, 18, 18, 18, 18, 18, 18, + 0, 0, 95, 95, 95, 3, 3, 3, 3, 3, 3, 3, 3, 3, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 105, 105, 105, 105, 105, 105, 0, 0, 111, 111, 111, 111, 111, - 111, 0, 0, 8, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 107, 107, 107, 107, 107, 107, 0, 0, 113, 113, 113, 113, 113, + 113, 0, 0, 8, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 5, 6, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 3, 3, 3, 129, 129, 129, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 3, 3, 3, 131, 131, 131, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 93, 93, 125, 0, 0, 0, 0, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 95, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 93, 93, 125, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 15, 15, 15, 15, 15, 95, 95, 127, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 93, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 93, 93, 0, 0, 0, 0, 0, + 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 93, 93, 125, 93, 93, 93, 93, 93, 93, - 93, 125, 125, 125, 125, 125, 125, 125, 125, 93, 125, 125, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 3, 3, 3, 92, 3, 3, 3, 4, 15, 93, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 127, 95, 95, 95, 95, 95, 95, + 95, 127, 127, 127, 127, 127, 127, 127, 127, 95, 127, 127, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 3, 3, 3, 94, 3, 3, 3, 4, 15, 95, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 8, 3, 3, - 3, 3, 93, 93, 93, 17, 93, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 15, 15, 15, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 3, 3, 95, 95, 95, 17, 95, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 15, 15, 15, 94, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 93, 93, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 95, 95, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 93, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 95, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, - 93, 93, 93, 125, 125, 125, 125, 93, 93, 125, 125, 125, 0, 0, 0, 0, - 125, 125, 93, 125, 125, 125, 125, 125, 125, 93, 93, 93, 0, 0, 0, 0, + 95, 95, 95, 127, 127, 127, 127, 95, 95, 127, 127, 127, 0, 0, 0, 0, + 127, 127, 95, 127, 127, 127, 127, 127, 127, 95, 95, 95, 0, 0, 0, 0, 14, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 0, 0, 0, @@ -861,91 +861,91 @@ static const unsigned char groupMap[] = { 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 93, 93, 125, 125, 93, 0, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 125, 93, 125, 93, 93, - 93, 93, 93, 93, 93, 0, 93, 125, 93, 125, 125, 93, 93, 93, 93, 93, 93, - 93, 93, 125, 125, 125, 125, 125, 125, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 0, 0, 93, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 92, - 3, 3, 3, 3, 3, 3, 0, 0, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 120, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, - 93, 93, 93, 125, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 95, 95, 127, 127, 95, 0, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 95, 127, 95, 95, + 95, 95, 95, 95, 95, 0, 95, 127, 95, 127, 127, 95, 95, 95, 95, 95, 95, + 95, 95, 127, 127, 127, 127, 127, 127, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 0, 0, 95, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 94, + 3, 3, 3, 3, 3, 3, 0, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 122, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, + 95, 95, 95, 127, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 93, 125, 93, 93, 93, 93, 93, 125, 93, 125, 125, 125, 125, 125, 93, - 125, 125, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 95, 127, 95, 95, 95, 95, 95, 127, 95, 127, 127, 127, 127, 127, 95, + 127, 127, 15, 15, 15, 15, 15, 15, 15, 15, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 93, 93, 93, 93, 93, 93, 93, 93, 93, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 3, 3, 0, 93, 93, 125, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 14, 95, 95, 95, 95, 95, 95, 95, 95, 95, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 3, 3, 3, 95, 95, 127, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 125, 93, 93, 93, 93, 125, 125, 93, 93, 125, 93, 93, 93, + 15, 15, 15, 127, 95, 95, 95, 95, 127, 127, 95, 95, 127, 95, 95, 95, 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 93, 125, 93, 93, 125, 125, 125, 93, 125, 93, 93, 93, - 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 15, 15, 15, 15, 125, - 125, 125, 125, 125, 125, 125, 125, 93, 93, 93, 93, 93, 93, 93, 93, - 125, 125, 93, 93, 0, 0, 0, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 15, 15, 15, 15, 95, 127, 95, 95, 127, 127, 127, 95, 127, 95, 95, 95, + 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 15, 15, 15, 15, 127, + 127, 127, 127, 127, 127, 127, 127, 95, 95, 95, 95, 95, 95, 95, 95, + 127, 127, 95, 95, 0, 0, 0, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 15, 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 3, 3, 130, - 131, 132, 133, 133, 134, 135, 136, 137, 0, 0, 0, 0, 0, 0, 0, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 0, - 0, 138, 138, 138, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 93, - 93, 93, 3, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 125, - 93, 93, 93, 93, 93, 93, 93, 15, 15, 15, 15, 93, 15, 15, 15, 15, 15, - 15, 93, 15, 15, 125, 93, 93, 15, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 94, 94, 94, 94, 94, 94, 3, 3, 132, + 133, 134, 135, 135, 136, 137, 138, 139, 23, 24, 0, 0, 0, 0, 0, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 0, 0, 140, 140, 140, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 95, 95, 95, 3, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 127, 95, 95, 95, 95, 95, 95, 95, 15, 15, 15, 15, 95, 15, 15, 15, 15, + 15, 15, 95, 15, 15, 127, 95, 95, 15, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 92, 139, 21, 21, - 21, 140, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 141, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 92, 92, 92, - 92, 92, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 21, 21, 21, 21, 21, 142, 21, 21, 143, 21, - 144, 144, 144, 144, 144, 144, 144, 144, 145, 145, 145, 145, 145, 145, - 145, 145, 144, 144, 144, 144, 144, 144, 0, 0, 145, 145, 145, 145, 145, - 145, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 145, 145, 145, 145, - 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 144, 144, 145, 145, - 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 0, 0, 145, - 145, 145, 145, 145, 145, 0, 0, 21, 144, 21, 144, 21, 144, 21, 144, - 0, 145, 0, 145, 0, 145, 0, 145, 144, 144, 144, 144, 144, 144, 144, - 144, 145, 145, 145, 145, 145, 145, 145, 145, 146, 146, 147, 147, 147, - 147, 148, 148, 149, 149, 150, 150, 151, 151, 0, 0, 144, 144, 144, 144, - 144, 144, 144, 144, 152, 152, 152, 152, 152, 152, 152, 152, 144, 144, - 144, 144, 144, 144, 144, 144, 152, 152, 152, 152, 152, 152, 152, 152, - 144, 144, 144, 144, 144, 144, 144, 144, 152, 152, 152, 152, 152, 152, - 152, 152, 144, 144, 21, 153, 21, 0, 21, 21, 145, 145, 154, 154, 155, - 11, 156, 11, 11, 11, 21, 153, 21, 0, 21, 21, 157, 157, 157, 157, 155, - 11, 11, 11, 144, 144, 21, 21, 0, 0, 21, 21, 145, 145, 158, 158, 0, - 11, 11, 11, 144, 144, 21, 21, 21, 114, 21, 21, 145, 145, 159, 159, - 118, 11, 11, 11, 0, 0, 21, 153, 21, 0, 21, 21, 160, 160, 161, 161, - 155, 11, 11, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 17, + 21, 21, 21, 21, 21, 21, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 94, 141, 21, + 21, 21, 142, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 143, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 94, 94, + 94, 94, 94, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, + 23, 24, 23, 24, 23, 24, 23, 24, 21, 21, 21, 21, 21, 144, 21, 21, 145, + 21, 146, 146, 146, 146, 146, 146, 146, 146, 147, 147, 147, 147, 147, + 147, 147, 147, 146, 146, 146, 146, 146, 146, 0, 0, 147, 147, 147, 147, + 147, 147, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 147, 147, 147, + 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 147, + 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 0, + 0, 147, 147, 147, 147, 147, 147, 0, 0, 21, 146, 21, 146, 21, 146, 21, + 146, 0, 147, 0, 147, 0, 147, 0, 147, 146, 146, 146, 146, 146, 146, + 146, 146, 147, 147, 147, 147, 147, 147, 147, 147, 148, 148, 149, 149, + 149, 149, 150, 150, 151, 151, 152, 152, 153, 153, 0, 0, 146, 146, 146, + 146, 146, 146, 146, 146, 154, 154, 154, 154, 154, 154, 154, 154, 146, + 146, 146, 146, 146, 146, 146, 146, 154, 154, 154, 154, 154, 154, 154, + 154, 146, 146, 146, 146, 146, 146, 146, 146, 154, 154, 154, 154, 154, + 154, 154, 154, 146, 146, 21, 155, 21, 0, 21, 21, 147, 147, 156, 156, + 157, 11, 158, 11, 11, 11, 21, 155, 21, 0, 21, 21, 159, 159, 159, 159, + 157, 11, 11, 11, 146, 146, 21, 21, 0, 0, 21, 21, 147, 147, 160, 160, + 0, 11, 11, 11, 146, 146, 21, 21, 21, 116, 21, 21, 147, 147, 161, 161, + 120, 11, 11, 11, 0, 0, 21, 155, 21, 0, 21, 21, 162, 162, 163, 163, + 157, 11, 11, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 17, 8, 8, 8, 8, 8, 8, 3, 3, 16, 20, 5, 16, 16, 20, 5, 16, 3, 3, 3, 3, 3, - 3, 3, 3, 162, 163, 17, 17, 17, 17, 17, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 164, 165, 17, 17, 17, 17, 17, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 16, 20, 3, 3, 3, 3, 12, 12, 3, 3, 3, 7, 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 12, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 17, 17, 17, - 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 92, 0, 0, 18, - 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 92, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 7, 7, 7, 5, 6, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 94, 0, 0, 18, + 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 94, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 7, 7, 7, 5, 6, 0, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 120, 120, 120, 120, 93, 120, 120, 120, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 14, 14, 108, 14, 14, 14, 14, 108, 14, 14, 21, 108, 108, 108, - 21, 21, 108, 108, 108, 21, 14, 108, 14, 14, 7, 108, 108, 108, 108, - 108, 14, 14, 14, 14, 14, 14, 108, 14, 164, 14, 108, 14, 165, 166, 108, - 108, 14, 21, 108, 108, 167, 108, 21, 15, 15, 15, 15, 21, 14, 14, 21, - 21, 108, 108, 7, 7, 7, 7, 7, 108, 21, 21, 21, 21, 14, 7, 14, 14, 168, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 122, 122, 122, 122, 95, 122, 122, 122, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 14, 14, 110, 14, 14, 14, 14, 110, 14, 14, 21, 110, 110, 110, + 21, 21, 110, 110, 110, 21, 14, 110, 14, 14, 7, 110, 110, 110, 110, + 110, 14, 14, 14, 14, 14, 14, 110, 14, 166, 14, 110, 14, 167, 168, 110, + 110, 14, 21, 110, 110, 169, 110, 21, 15, 15, 15, 15, 21, 14, 14, 21, + 21, 110, 110, 7, 7, 7, 7, 7, 110, 21, 21, 21, 21, 14, 7, 14, 14, 170, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 129, 129, 129, 23, 24, 129, 129, 129, 129, 18, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 131, 131, 131, 23, 24, 131, 131, 131, 131, 18, 14, 14, 0, 0, 0, 0, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 7, 7, 14, 14, 14, 14, 7, 14, 14, 7, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, @@ -966,19 +966,19 @@ static const unsigned char groupMap[] = { 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, @@ -1004,29 +1004,29 @@ static const unsigned char groupMap[] = { 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 23, 24, 173, 174, 175, 176, 177, 23, 24, 23, - 24, 23, 24, 178, 179, 180, 181, 21, 23, 24, 21, 23, 24, 21, 21, 21, - 21, 21, 92, 92, 182, 182, 23, 24, 23, 24, 21, 14, 14, 14, 14, 14, 14, - 23, 24, 23, 24, 93, 93, 93, 23, 24, 0, 0, 0, 0, 0, 3, 3, 3, 3, 18, - 3, 3, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 0, 183, 0, 0, - 0, 0, 0, 183, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 23, 24, 175, 176, 177, 178, 179, 23, 24, 23, + 24, 23, 24, 180, 181, 182, 183, 21, 23, 24, 21, 23, 24, 21, 21, 21, + 21, 21, 94, 94, 184, 184, 23, 24, 23, 24, 21, 14, 14, 14, 14, 14, 14, + 23, 24, 23, 24, 95, 95, 95, 23, 24, 0, 0, 0, 0, 0, 3, 3, 3, 3, 18, + 3, 3, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 0, 185, 0, 0, + 0, 0, 0, 185, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, - 92, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 15, 15, 15, 15, + 94, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 3, 3, 16, 20, 16, 20, 3, 3, 3, 16, 20, 3, 16, 20, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 3, 3, 8, 3, 16, 20, 3, 3, 16, 20, 5, - 6, 5, 6, 5, 6, 5, 6, 3, 3, 3, 3, 3, 92, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 6, 5, 6, 5, 6, 5, 6, 3, 3, 3, 3, 3, 94, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 8, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 14, 3, 3, 3, 5, 6, 5, 6, 5, 6, 5, 6, 8, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, @@ -1035,117 +1035,117 @@ static const unsigned char groupMap[] = { 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 3, 3, 3, 14, 92, - 15, 129, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 14, 14, 5, 6, 5, 6, 5, 6, 5, - 6, 8, 5, 6, 6, 14, 129, 129, 129, 129, 129, 129, 129, 129, 129, 93, - 93, 93, 93, 125, 125, 8, 92, 92, 92, 92, 92, 14, 14, 129, 129, 129, - 92, 15, 3, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 93, 93, 11, 11, 92, - 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 92, 92, 92, 15, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 3, 3, 3, 14, 94, + 15, 131, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 14, 14, 5, 6, 5, 6, 5, 6, 5, + 6, 8, 5, 6, 6, 14, 131, 131, 131, 131, 131, 131, 131, 131, 131, 95, + 95, 95, 95, 127, 127, 8, 94, 94, 94, 94, 94, 14, 14, 131, 131, 131, + 94, 15, 3, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 95, 95, 11, 11, 94, + 94, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 94, 94, 94, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 14, 14, 18, 18, 18, 18, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, + 14, 14, 14, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, - 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, + 18, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 94, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 92, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 15, 93, 120, 120, 120, 3, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 3, 92, 23, 24, 23, 24, 23, 24, 23, 24, 23, + 15, 94, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, + 24, 23, 24, 23, 24, 23, 24, 15, 95, 122, 122, 122, 3, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 3, 94, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 23, 24, 92, 92, 93, 93, 15, 15, 15, 15, 15, 15, 129, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 93, 93, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, + 23, 24, 94, 94, 95, 95, 15, 15, 15, 15, 15, 15, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 95, 95, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 11, 11, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 11, 11, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 21, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 92, 21, - 21, 21, 21, 21, 21, 21, 21, 23, 24, 23, 24, 184, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 92, 11, 11, 23, 24, 185, 21, 15, 23, 24, 23, 24, - 186, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 187, 188, 189, 190, 187, 21, 191, 192, 193, 194, - 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 195, - 196, 197, 23, 24, 23, 24, 0, 0, 0, 0, 0, 23, 24, 0, 21, 0, 21, 23, - 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 92, 92, 92, 23, 24, 15, 92, 92, 21, 15, 15, 15, 15, - 15, 15, 15, 93, 15, 15, 15, 93, 15, 15, 15, 15, 93, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 125, 125, 93, 93, 125, 14, 14, 14, 14, 93, 0, 0, 0, 18, 18, - 18, 18, 18, 18, 14, 14, 4, 14, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 3, 3, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 125, 125, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 93, 93, 0, 0, 0, 0, 0, - 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 15, 15, 15, 15, 15, 15, 3, 3, 3, 15, 3, 15, 15, 93, 15, 15, 15, 15, - 15, 15, 93, 93, 93, 93, 93, 93, 93, 93, 3, 3, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 125, 125, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 93, 125, 125, 93, 93, 93, 93, 125, 125, 93, 93, 125, - 125, 125, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 92, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 15, 15, 15, 15, 15, 93, 92, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, - 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 93, 93, 93, - 93, 93, 125, 125, 93, 93, 125, 125, 93, 93, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 15, 15, 93, 15, 15, 15, 15, 15, 15, 15, 15, 93, 125, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 15, 15, 15, 15, 15, 15, - 14, 14, 14, 15, 125, 93, 125, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 93, 15, 93, 93, 93, 15, 15, 93, 93, - 15, 15, 15, 15, 15, 93, 93, 15, 93, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 92, 3, 3, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 125, 93, 93, 125, 125, 3, 3, - 15, 92, 92, 125, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, - 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, - 15, 15, 15, 15, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 94, 21, + 21, 21, 21, 21, 21, 21, 21, 23, 24, 23, 24, 186, 23, 24, 23, 24, 23, + 24, 23, 24, 23, 24, 94, 11, 11, 23, 24, 187, 21, 15, 23, 24, 23, 24, + 188, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, + 24, 23, 24, 23, 24, 189, 190, 191, 192, 189, 21, 193, 194, 195, 196, + 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 197, + 198, 199, 23, 24, 23, 24, 200, 23, 24, 0, 0, 23, 24, 0, 21, 0, 21, + 23, 24, 23, 24, 23, 24, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 94, 94, 94, 23, 24, 15, 94, 94, 21, 15, 15, + 15, 15, 15, 15, 15, 95, 15, 15, 15, 95, 15, 15, 15, 15, 95, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 127, 127, 95, 95, 127, 14, 14, 14, 14, 95, 0, 0, 0, + 18, 18, 18, 18, 18, 18, 14, 14, 4, 14, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 95, 95, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 15, 15, 15, 15, 15, 15, 3, 3, 3, 15, 3, 15, 15, 95, 15, 15, 15, + 15, 15, 15, 95, 95, 95, 95, 95, 95, 95, 95, 3, 3, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 127, 127, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 95, 127, 127, 95, 95, 95, 95, 127, 127, 95, + 95, 127, 127, 127, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 94, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 15, 15, 15, 15, 15, 95, + 94, 15, 15, 15, 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, + 95, 95, 95, 95, 127, 127, 95, 95, 127, 127, 95, 95, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 95, 15, 15, 15, 15, 15, 15, 15, 15, 95, 127, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 3, 3, 3, 3, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 94, 15, 15, 15, 15, + 15, 15, 14, 14, 14, 15, 127, 95, 127, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 15, 95, 95, 95, 15, 15, + 95, 95, 15, 15, 15, 15, 15, 95, 95, 15, 95, 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 94, 3, 3, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 95, 95, 127, 127, + 3, 3, 15, 94, 94, 127, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, + 15, 15, 15, 15, 15, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 198, 21, 21, 21, 21, 21, 21, 21, 11, 92, 92, - 92, 92, 21, 21, 21, 21, 21, 21, 21, 21, 21, 92, 11, 11, 0, 0, 0, 0, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 15, 15, 15, 125, 125, 93, 125, 125, 93, - 125, 125, 3, 125, 93, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, + 21, 21, 21, 21, 21, 21, 21, 202, 21, 21, 21, 21, 21, 21, 21, 11, 94, + 94, 94, 94, 21, 21, 21, 21, 21, 21, 21, 21, 21, 94, 11, 11, 0, 0, 0, + 0, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 15, 15, 15, 127, 127, 95, 127, 127, + 95, 127, 127, 3, 127, 95, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 0, 0, 0, 0, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, 201, 201, - 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, - 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, - 201, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, + 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 0, - 0, 0, 0, 0, 15, 93, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 15, + 0, 0, 0, 0, 15, 95, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 15, 0, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, @@ -1161,9 +1161,9 @@ static const unsigned char groupMap[] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 4, 14, 14, 14, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 3, 3, 3, 3, 3, 3, 3, 5, 6, 3, 0, 0, 0, 0, 0, 0, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 3, 8, 8, + 15, 4, 14, 14, 14, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 3, 3, 3, 3, 3, 3, 3, 5, 6, 3, 0, 0, 0, 0, 0, 0, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 3, 8, 8, 12, 12, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 3, 3, 5, 6, 3, 3, 3, 3, 12, 12, 12, 3, 3, 3, 0, 3, 3, 3, 3, 8, 5, 6, 5, 6, 5, 6, 3, 3, 3, 7, 8, 7, 7, 7, 0, 3, 4, 3, 3, 0, 0, 0, 0, 15, 15, 15, 15, @@ -1173,10 +1173,10 @@ static const unsigned char groupMap[] = { 3, 7, 3, 8, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 7, 7, 7, 3, 11, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 5, 7, 6, 7, 5, 6, 3, 5, 6, 3, 3, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 94, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 92, 92, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, + 15, 15, 15, 15, 15, 94, 94, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 0, 0, 0, 4, 4, 7, 11, 14, 4, 4, 0, 14, 7, 7, 7, 7, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 14, 14, 0, 0 @@ -1191,467 +1191,499 @@ static const unsigned char groupMap[] = { 15, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 18, 18, 18, 18, 14, 14, + 18, 18, 18, 18, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 93, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 14, 14, 14, 14, 14, 95, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 93, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 0, 0, 95, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 129, 15, 15, 15, 15, - 15, 15, 15, 15, 129, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 131, 15, 15, 15, 15, + 15, 15, 15, 15, 131, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 93, 93, 93, - 93, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 95, 95, + 95, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 3, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, - 3, 129, 129, 129, 129, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 15, 15, 15, 15, 15, 15, 15, + 3, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 207, 207, 207, + 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, + 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, + 207, 207, 207, 207, 207, 207, 207, 207, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, 202, 0, 0, 0, 0, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 0, 0, 0, 0, 207, 207, + 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, + 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, + 207, 207, 207, 207, 207, 207, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 0, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 0, 204, 204, 204, 204, 204, 204, 204, 0, 204, 204, 0, 205, 205, - 205, 205, 205, 205, 205, 205, 205, 205, 205, 0, 205, 205, 205, 205, - 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 0, 205, 205, - 205, 205, 205, 205, 205, 0, 205, 205, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 15, 15, 15, - 15, 15, 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, - 15, 15, 0, 0, 0, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 3, 18, 18, 18, - 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 18, 18, 18, 18, - 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, - 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, 18, 18, - 18, 18, 18, 0, 0, 0, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 3, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 0, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 0, 208, 208, 208, 208, 208, 208, 208, 0, 208, 208, 0, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 0, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 0, 209, 209, + 209, 209, 209, 209, 209, 0, 209, 209, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, - 0, 0, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 18, 18, 15, 15, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 15, 93, 93, 93, - 0, 93, 93, 0, 0, 0, 0, 0, 93, 93, 93, 93, 15, 15, 15, 15, 0, 15, 15, - 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 93, 93, - 93, 0, 0, 0, 0, 93, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, - 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, + 94, 94, 94, 94, 94, 0, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 0, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, + 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 0, + 0, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 3, 18, 18, 18, 18, 18, 18, 18, + 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 14, 14, 18, 18, 18, 18, 18, 18, 18, 0, + 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 18, + 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, 18, 18, 18, 18, 18, 0, 0, 0, + 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, 18, 3, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 0, 0, 0, 0, 18, 18, 15, 15, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 15, 95, 95, 95, 0, 95, 95, 0, 0, 0, + 0, 0, 95, 95, 95, 95, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, - 15, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 93, 0, 0, 0, - 0, 18, 18, 18, 18, 18, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 18, - 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, - 15, 15, 15, 15, 93, 93, 93, 93, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 93, 93, 8, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 93, 93, 93, 18, 18, 18, 18, 18, 18, 18, 15, 0, - 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 18, 18, 18, 18, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 93, 93, 93, 3, - 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 15, 15, 15, 15, 15, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 93, 125, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 3, 3, 3, - 3, 3, 3, 3, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 93, - 15, 15, 93, 93, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 125, 125, 125, 93, - 93, 93, 93, 125, 125, 93, 93, 3, 3, 17, 3, 3, 3, 3, 93, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 17, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 93, 93, - 93, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 95, 95, 95, 0, 0, 0, 0, 95, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 93, 93, 93, 93, 93, 125, 93, 93, 93, 93, 93, 93, 93, 93, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 125, 125, 15, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 18, 18, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 93, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, + 15, 15, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 125, 125, 125, 93, 93, 93, 93, 93, 93, 93, 93, 93, 125, 125, 15, 15, - 15, 15, 3, 3, 3, 3, 93, 93, 93, 93, 3, 125, 93, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 15, 3, 15, 3, 3, 3, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 125, 125, 125, 93, - 93, 93, 125, 125, 93, 125, 93, 93, 3, 3, 3, 3, 3, 3, 93, 15, 15, 93, + 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 0, 0, 0, 0, 18, 18, 18, 18, + 18, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 18, 18, 18, + 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, + 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 0, 0, 0, 0, 0, 0, + 0, 18, 18, 18, 18, 18, 18, 15, 15, 15, 15, 95, 95, 95, 95, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 94, 15, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 0, 0, 0, 95, 95, 95, 95, 95, 8, 94, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 0, 95, 95, 8, 0, 0, 15, 15, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 15, 15, - 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 95, 95, 95, 95, 18, 18, 18, 18, 18, 18, 18, 15, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 18, 18, 18, 18, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 95, 95, 3, 3, 3, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 15, 15, 15, 15, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 95, 127, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 125, 125, 125, - 93, 93, 93, 93, 93, 93, 93, 93, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 93, 93, 125, 125, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, - 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 0, 93, 93, 15, 125, - 125, 93, 125, 125, 125, 125, 0, 0, 125, 125, 0, 0, 125, 125, 125, 0, - 0, 15, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 125, - 125, 0, 0, 93, 93, 93, 93, 93, 93, 93, 0, 0, 0, 93, 93, 93, 93, 93, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 125, 125, 125, 93, - 93, 93, 93, 93, 93, 93, 93, 125, 125, 93, 93, 93, 125, 93, 15, 15, - 15, 15, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 0, 3, 93, - 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 125, 125, 125, 93, 93, 93, 93, 93, 93, - 125, 93, 125, 125, 125, 125, 93, 93, 125, 93, 93, 15, 15, 3, 15, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 125, 125, - 125, 93, 93, 93, 93, 0, 0, 125, 125, 125, 125, 93, 93, 125, 93, 93, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 15, 15, 15, 15, 93, 93, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 125, 125, 125, 93, 93, 93, 93, 93, 93, 93, - 93, 125, 125, 93, 125, 93, 93, 3, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 125, - 93, 125, 125, 93, 93, 93, 93, 93, 93, 125, 93, 15, 3, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 125, 93, 93, 93, 93, 125, 93, 93, - 93, 93, 93, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 3, 3, - 3, 14, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 125, 125, 125, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 125, 93, 93, 3, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 0, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, - 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 125, 125, 125, 125, 125, 125, 0, - 125, 125, 0, 0, 93, 93, 125, 93, 15, 125, 15, 125, 93, 3, 3, 3, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 125, 125, - 125, 93, 93, 93, 93, 0, 0, 93, 93, 125, 125, 125, 125, 93, 15, 3, 15, - 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 93, 93, 93, 93, 93, 93, 125, 15, 93, 93, 93, 93, 3, - 3, 3, 3, 3, 3, 3, 3, 93, 0, 0, 0, 0, 0, 0, 0, 0, 15, 93, 93, 93, 93, - 93, 93, 125, 125, 93, 93, 93, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 125, 93, 93, 3, 3, 3, 15, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 3, 3, 3, 3, 3, 3, 3, + 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 95, 15, 15, 95, + 95, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 127, 127, 95, 95, 95, 95, + 127, 127, 95, 95, 3, 3, 17, 3, 3, 3, 3, 95, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 17, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 95, 95, 95, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 125, 93, 93, 93, 93, 93, 93, 93, 0, 93, 93, 93, - 93, 93, 93, 125, 93, 15, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 0, - 125, 93, 93, 93, 93, 93, 93, 93, 125, 93, 93, 125, 93, 93, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, + 95, 95, 95, 95, 95, 127, 95, 95, 95, 95, 95, 95, 95, 95, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 127, 127, 15, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 95, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 127, 127, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 127, 127, 15, 15, 15, 15, 3, 3, + 3, 3, 95, 95, 95, 95, 3, 127, 95, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, + 3, 15, 3, 3, 3, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 93, 93, 93, 93, 93, 93, 0, 0, 0, 93, 0, 93, 93, 0, 93, 93, - 93, 93, 93, 93, 93, 15, 93, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 15, 15, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 125, - 125, 125, 125, 125, 0, 93, 93, 0, 125, 125, 93, 125, 93, 15, 0, 0, - 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 93, 93, 125, 125, 3, 3, 0, 0, 0, 0, 0, 0, 0, - 93, 93, 15, 125, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 127, 127, 95, 95, 95, 127, + 127, 95, 127, 95, 95, 3, 3, 3, 3, 3, 3, 95, 15, 15, 95, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 15, 15, 15, 15, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 3, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 125, 125, 93, 93, 93, 93, 93, 0, 0, 0, 125, 125, 93, 125, 93, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, - 14, 14, 14, 14, 14, 14, 4, 4, 4, 4, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, - 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 127, 127, 127, 95, 95, 95, + 95, 95, 95, 95, 95, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 95, 95, 127, 127, 0, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, + 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 0, 95, 95, 15, 127, 127, 95, + 127, 127, 127, 127, 0, 0, 127, 127, 0, 0, 127, 127, 127, 0, 0, 15, + 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 127, 127, + 0, 0, 95, 95, 95, 95, 95, 95, 95, 0, 0, 0, 95, 95, 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 93, - 15, 15, 15, 15, 15, 15, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 127, 127, 127, 95, 95, 95, + 95, 95, 95, 0, 127, 0, 0, 127, 0, 127, 127, 127, 127, 0, 127, 127, + 95, 127, 95, 15, 95, 15, 3, 3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 95, + 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 127, 127, 95, 95, 95, + 95, 95, 95, 95, 95, 127, 127, 95, 95, 95, 127, 95, 15, 15, 15, 15, + 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 0, 3, 95, 15, 15, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 127, 127, 127, 95, 95, 95, 95, 95, 95, 127, + 95, 127, 127, 127, 127, 95, 95, 127, 95, 95, 15, 15, 3, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 127, 127, + 95, 95, 95, 95, 0, 0, 127, 127, 127, 127, 95, 95, 127, 95, 95, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 15, + 15, 15, 15, 95, 95, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 127, 127, 127, 95, 95, 95, 95, 95, 95, 95, 95, + 127, 127, 95, 127, 95, 95, 3, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 127, 95, + 127, 127, 95, 95, 95, 95, 95, 95, 127, 95, 15, 3, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 0, 0, 95, 127, 95, 127, 127, 95, 95, 95, 95, + 127, 95, 95, 95, 95, 95, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 18, 18, 3, 3, 3, 14, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 127, 127, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 127, 95, 95, 3, 0, 0, 0, 0, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 0, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 127, 127, 127, + 127, 127, 0, 127, 127, 0, 0, 95, 95, 127, 95, 15, 127, 15, 127, 95, + 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 127, 127, 127, 95, 95, 95, 95, 0, 0, 95, 95, 127, 127, 127, 127, + 95, 15, 3, 15, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 95, 95, 95, 95, 127, 15, 95, + 95, 95, 95, 3, 3, 3, 3, 3, 3, 3, 3, 95, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 95, 95, 95, 95, 95, 95, 127, 127, 95, 95, 95, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 127, 95, 95, 3, 3, 3, 15, 3, 3, 3, 3, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, + 95, 95, 95, 95, 95, 95, 95, 0, 95, 95, 95, 95, 95, 95, 127, 95, 15, + 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 0, 0, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 0, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 127, 95, 95, 95, 95, 95, 95, + 95, 127, 95, 95, 127, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 95, 95, 95, 95, + 0, 0, 0, 95, 0, 95, 95, 0, 95, 95, 95, 95, 95, 95, 95, 15, 95, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, + 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 127, 127, 127, 127, 127, 0, 95, 95, 0, 127, + 127, 95, 127, 95, 15, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 93, 93, - 93, 93, 93, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 93, 93, 93, 93, 93, 93, - 3, 3, 3, 3, 3, 14, 14, 14, 14, 92, 92, 92, 92, 3, 14, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 18, 18, 18, 18, 18, - 18, 18, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 15, 15, 15, 95, 95, 127, 127, 3, 3, 0, 0, 0, 0, 0, 0, 0, 95, 95, 15, + 127, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 127, + 95, 95, 95, 95, 95, 0, 0, 0, 127, 127, 95, 127, 95, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 95, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, + 14, 14, 14, 14, 4, 4, 4, 4, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, + 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 95, 15, + 15, 15, 15, 15, 15, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 127, 127, 127, 95, 95, 95, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 0, 0, 95, 95, 95, 95, 95, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 95, 95, 95, 95, 95, 95, 95, 3, 3, 3, 3, 3, 14, 14, 14, 14, + 94, 94, 94, 94, 3, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 18, 18, 18, 18, 18, 18, 18, 0, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 94, 94, 94, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 94, 94, 3, 3, 3, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 3, 3, 3, 3, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, - 0, 93, 15, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 0, 0, 0, 0, 0, 0, 0, 93, 93, 93, 93, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 3, 92, 93, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, + 0, 95, 15, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 0, 0, 0, 0, 0, 0, 0, 95, 95, 95, 95, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 3, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, - 92, 0, 92, 92, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 15, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 0, 14, 93, 93, 3, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 0, 0, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, - 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 94, 94, 94, + 0, 94, 94, 94, 94, 94, 94, 94, 0, 94, 94, 0, 15, 15, 15, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 14, 95, 95, 3, 17, 17, 17, + 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 125, 125, 93, 93, 93, 14, 14, 14, 125, 125, 125, 125, 125, 125, - 17, 17, 17, 17, 17, 17, 17, 17, 93, 93, 93, 93, 93, 93, 93, 93, 14, - 14, 93, 93, 93, 93, 93, 93, 93, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 127, 127, 95, 95, 95, 14, 14, 14, 127, 127, 127, 127, 127, + 127, 17, 17, 17, 17, 17, 17, 17, 17, 95, 95, 95, 95, 95, 95, 95, 95, + 14, 14, 95, 95, 95, 95, 95, 95, 95, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 93, 93, 93, 93, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 93, 93, 93, 14, 0, 0, 0, + 14, 14, 14, 14, 14, 95, 95, 95, 95, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 95, 95, 95, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, + 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, - 0, 0, 0, 0, 0, 0, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 21, 21, 21, 21, 21, 21, 21, 0, 21, + 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 0, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 21, 21, 21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 21, 21, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 108, 0, 108, 108, 0, 0, 108, 0, 0, 108, - 108, 0, 0, 108, 108, 108, 108, 0, 108, 108, 108, 108, 108, 108, 108, - 108, 21, 21, 21, 21, 0, 21, 0, 21, 21, 21, 21, 21, 21, 21, 0, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 108, 108, - 0, 108, 108, 108, 108, 0, 0, 108, 108, 108, 108, 108, 108, 108, 108, - 0, 108, 108, 108, 108, 108, 108, 108, 0, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 110, 0, 110, 110, 0, 0, 110, 0, 0, 110, + 110, 0, 0, 110, 110, 110, 110, 0, 110, 110, 110, 110, 110, 110, 110, + 110, 21, 21, 21, 21, 0, 21, 0, 21, 21, 21, 21, 21, 21, 21, 0, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 110, 110, + 0, 110, 110, 110, 110, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, + 0, 110, 110, 110, 110, 110, 110, 110, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 108, 108, 0, 108, 108, 108, 108, 0, 108, 108, 108, 108, 108, - 0, 108, 0, 0, 0, 108, 108, 108, 108, 108, 108, 108, 0, 21, 21, 21, + 21, 21, 110, 110, 0, 110, 110, 110, 110, 0, 110, 110, 110, 110, 110, + 0, 110, 0, 0, 0, 110, 110, 110, 110, 110, 110, 110, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 108, 108, + 21, 21, 21, 21, 21, 21, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 110, 110, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 21, 21, 21, 21, 21, 21, 0, 0, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 21, 21, 21, 21, 21, 21, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, - 21, 21, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 7, + 21, 21, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 7, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, - 21, 21, 21, 21, 21, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, - 108, 21, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 110, 21, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 14, 14, 14, 14, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 14, 14, 14, 14, 14, 14, 14, 14, 93, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 93, 14, 14, 3, 3, 3, 3, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 93, 93, 93, 93, 0, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 14, 14, 14, 14, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 14, 14, 14, 14, 14, 14, 14, 14, 95, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 95, 14, 14, 3, 3, 3, 3, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 95, 95, 95, 95, 0, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 15, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 93, 93, 93, - 93, 93, 93, 0, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 0, 0, 93, 93, 93, 93, 93, 93, 93, 0, 93, 93, 0, 93, - 93, 93, 93, 93, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 95, 95, 95, + 95, 95, 95, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 0, 0, 95, 95, 95, 95, 95, 95, 95, 0, 95, 95, 0, 95, + 95, 95, 95, 95, 0, 0, 0, 0, 0, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 0, 0, 0, 93, 93, 93, 93, 93, 93, 93, 92, 92, 92, 92, - 92, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 15, 14, + 15, 15, 15, 15, 0, 0, 0, 95, 95, 95, 95, 95, 95, 95, 94, 94, 94, 94, + 94, 94, 94, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 15, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 93, 93, 93, 93, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 4, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 93, 93, 93, 93, 9, + 15, 95, 95, 95, 95, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 4, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 94, 95, 95, 95, 95, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 0, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 93, 93, 93, 93, 93, 93, 93, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 207, 207, 207, 207, - 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, - 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, - 207, 93, 93, 93, 93, 93, 93, 93, 92, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 18, 18, 18, - 4, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, + 15, 15, 15, 15, 15, 15, 15, 15, 95, 95, 15, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 3, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, + 0, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 0, 15, 15, 15, 15, 15, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 95, 95, 95, 95, 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 210, 210, + 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, + 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, + 210, 210, 210, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, + 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, + 211, 211, 211, 211, 211, 211, 211, 211, 211, 95, 95, 95, 95, 95, 95, + 95, 94, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 14, 18, 18, 18, 4, 18, 18, 18, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 14, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 0, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 0, 0, 15, 0, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 0, 15, 0, 0, - 0, 0, 0, 0, 15, 0, 0, 0, 0, 15, 0, 15, 0, 15, 0, 15, 15, 15, 0, 15, - 15, 0, 15, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 15, 0, 15, - 0, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, - 15, 0, 15, 15, 15, 15, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 0, 0, 0, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 0, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 15, 15, 0, 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 15, 15, 15, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, + 15, 0, 15, 0, 15, 0, 15, 15, 15, 0, 15, 15, 0, 15, 0, 0, 15, 0, 15, + 0, 15, 0, 15, 0, 15, 0, 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 0, 15, + 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, + 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, + 15, 0, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, + 14, 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, + 0, 0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, + 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 11, 11, 11, 11, 11, 14, 14, 14, 14, 14, + 11, 11, 11, 11, 11, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 14, + 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 0, - 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, - 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, + 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, + 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, + 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 0, 0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, - 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 #endif /* TCL_UTF_MAX > 3 */ }; @@ -1677,27 +1709,28 @@ static const int groups[] = { 0, 15, 12, 25, 27, 21, 22, 26, 20, 9, 8257, 28, 19, 8322, 29, 5, 23, 16, 11, -190078, 24, 2, -30846, 321, 386, -50879, 59522, -30911, 76930, -49790, 53825, 52801, 52545, 20289, 51777, 52033, - 53057, -24702, 54081, 53569, -41598, 54593, -33150, 54849, 55873, - 55617, 56129, -14206, 609, 451, 674, 20354, -24767, -14271, -33215, - 2763585, -41663, 2762817, -2768510, -49855, 17729, 18241, -2760318, - -2759550, -2760062, 53890, 52866, 52610, 51842, 52098, -10833534, - -10832510, 53122, -10823550, -10830718, 53634, 54146, -2750078, - -10829950, -2751614, 54658, 54914, -2745982, 55938, -10830462, - -10824062, 17794, 55682, 18306, 56194, -10818686, -10817918, 4, - 6, -21370, 29761, 9793, 9537, 16449, 16193, 9858, 9602, 8066, - 16514, 16258, 2113, 16002, 14722, 1, 12162, 13954, 2178, 22146, - 20610, -1662, 29826, -15295, 24706, -1727, 20545, 7, 3905, 3970, - 12353, 12418, 8, 1859649, -769822, 9949249, 10, 1601154, 1600898, - 1598594, 1598082, 1598338, 1596546, 1582466, -9027966, -769983, - -9044862, -976254, -9058174, 15234, -1949375, -1918, -1983, -18814, - -21886, -25470, -32638, -28542, -32126, -1981, -2174, -18879, - -2237, 1844610, -21951, -25535, -28607, -32703, -32191, 13, 14, - -1924287, -2145983, -2115007, 7233, 7298, 4170, 4234, 6749, 6813, - -2750143, -976319, -2746047, 2763650, 2762882, -2759615, -2751679, - -2760383, -2760127, -2768575, 1859714, -9044927, -10823615, -12158, - -10830783, -10833599, -10832575, -10830015, -10817983, -10824127, - -10818751, 237633, -12223, -10830527, -9058239, 237698, 9949314, - 18, 17, 10305, 10370, 10049, 10114, 8769, 8834 + 53057, -24702, 54081, 53569, -41598, -10895486, 54593, -33150, + 54849, 55873, 55617, 56129, -14206, 609, 451, 674, 20354, -24767, + -14271, -33215, 2763585, -41663, 2762817, -2768510, -49855, 17729, + 18241, -2760318, -2759550, -2760062, 53890, 52866, 52610, 51842, + 52098, -10833534, -10832510, 53122, -10839678, -10823550, -10830718, + 53634, 54146, -2750078, -10829950, -2751614, 54658, 54914, -2745982, + 55938, -10830462, -10824062, 17794, 55682, 18306, 56194, -10818686, + -10817918, 4, 6, -21370, 29761, 9793, 9537, 16449, 16193, 9858, + 9602, 8066, 16514, 16258, 2113, 16002, 14722, 1, 12162, 13954, + 2178, 22146, 20610, -1662, 29826, -15295, 24706, -1727, 20545, + 7, 3905, 3970, 12353, 12418, 8, 1859649, -769822, 9949249, 10, + 1601154, 1600898, 1598594, 1598082, 1598338, 1596546, 1582466, + -9027966, -769983, -9044862, -976254, -9058174, 15234, -1949375, + -1918, -1983, -18814, -21886, -25470, -32638, -28542, -32126, + -1981, -2174, -18879, -2237, 1844610, -21951, -25535, -28607, + -32703, -32191, 13, 14, -1924287, -2145983, -2115007, 7233, 7298, + 4170, 4234, 6749, 6813, -2750143, -976319, -2746047, 2763650, + 2762882, -2759615, -2751679, -2760383, -2760127, -2768575, 1859714, + -9044927, -10823615, -12158, -10830783, -10833599, -10832575, + -10830015, -10817983, -10824127, -10818751, 237633, -12223, -10830527, + -9058239, -10839743, -10895551, 237698, 9949314, 18, 17, 10305, + 10370, 10049, 10114, 8769, 8834 }; #if TCL_UTF_MAX > 3 || TCL_MAJOR_VERSION > 8 || TCL_MINOR_VERSION > 6 -- cgit v0.12