Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | Tidy up some indentation and other little code style issues |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | tidy-indentation |
Files: | files | file ages | folders |
SHA3-256: |
cb11914788879343219cbe746e382112 |
User & Date: | dkf 2024-04-18 15:06:39 |
2024-04-23
| ||
16:06 | Hmm, something is broken. Leaving this here but this commit is definitely wrong somehow Leaf check-in: b356268e32 user: dkf tags: tidy-indentation | |
2024-04-18
| ||
15:06 | Tidy up some indentation and other little code style issues check-in: cb11914788 user: dkf tags: tidy-indentation | |
14:41 | Tcl_DuplicateObj can't return NULL check-in: 750dad1cdf user: dkf tags: trunk, main | |
Changes to generic/tcl.h.
︙ | ︙ | |||
763 764 765 766 767 768 769 | typedef struct Tcl_Namespace { char *name; /* The namespace's name within its parent * namespace. This contains no ::'s. The name * of the global namespace is "" although "::" * is an synonym. */ char *fullName; /* The namespace's fully qualified name. This * starts with ::. */ | | | 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 | typedef struct Tcl_Namespace { char *name; /* The namespace's name within its parent * namespace. This contains no ::'s. The name * of the global namespace is "" although "::" * is an synonym. */ char *fullName; /* The namespace's fully qualified name. This * starts with ::. */ void *clientData; /* Arbitrary value associated with this * namespace. */ Tcl_NamespaceDeleteProc *deleteProc; /* Function invoked when deleting the * namespace to, e.g., free clientData. */ struct Tcl_Namespace *parentPtr; /* Points to the namespace that contains this * one. NULL if this is the global |
︙ | ︙ | |||
837 838 839 840 841 842 843 | int isNativeObjectProc; /* 1 if objProc was registered by a call to * Tcl_CreateObjCommand; 2 if objProc was registered by * a call to Tcl_CreateObjCommand2; 0 otherwise. * Tcl_SetCmdInfo does not modify this field. */ Tcl_ObjCmdProc *objProc; /* Command's object-based function. */ void *objClientData; /* ClientData for object proc. */ Tcl_CmdProc *proc; /* Command's string-based function. */ | | | | 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 | int isNativeObjectProc; /* 1 if objProc was registered by a call to * Tcl_CreateObjCommand; 2 if objProc was registered by * a call to Tcl_CreateObjCommand2; 0 otherwise. * Tcl_SetCmdInfo does not modify this field. */ 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. */ Tcl_CmdDeleteProc *deleteProc; /* Function to call when command is * deleted. */ 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 * change a command's namespace; use * TclRenameCommand or Tcl_Eval (of 'rename') * to do that. */ Tcl_ObjCmdProc2 *objProc2; /* Command's object2-based function. */ |
︙ | ︙ | |||
960 961 962 963 964 965 966 | * o Run in iPtr->lookupNsPtr or global namespace * o Cut out of error traces * o Don't reset the flags controlling ensemble * error message rewriting. * TCL_CANCEL_UNWIND: Magical Tcl_CancelEval mode that causes the * stack for the script in progress to be * completely unwound. | | | 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 | * o Run in iPtr->lookupNsPtr or global namespace * o Cut out of error traces * o Don't reset the flags controlling ensemble * error message rewriting. * 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 * as the caller will report. */ #define TCL_NO_EVAL 0x010000 #define TCL_EVAL_GLOBAL 0x020000 #define TCL_EVAL_DIRECT 0x040000 #define TCL_EVAL_INVOKE 0x080000 |
︙ | ︙ | |||
1073 1074 1075 1076 1077 1078 1079 | */ struct Tcl_HashEntry { Tcl_HashEntry *nextPtr; /* Pointer to next entry in this hash bucket, * or NULL for end of chain. */ Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */ size_t hash; /* Hash value. */ | | | 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 | */ struct Tcl_HashEntry { Tcl_HashEntry *nextPtr; /* Pointer to next entry in this hash bucket, * 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 * Tcl_SetHashValue. */ union { /* Key has one of these forms: */ char *oneWordValue; /* One-word value for key. */ Tcl_Obj *objPtr; /* Tcl_Obj * key value. */ int words[1]; /* Multiple integer words for key. The actual * size will be as large as necessary for this * table's keys. */ |
︙ | ︙ | |||
1169 1170 1171 1172 1173 1174 1175 | struct Tcl_HashTable { Tcl_HashEntry **buckets; /* Pointer to bucket array. Each element * points to first entry in bucket's hash * chain, or NULL. */ Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; /* Bucket array used for small tables (to * avoid mallocs and frees). */ | | | | | | 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 | struct Tcl_HashTable { Tcl_HashEntry **buckets; /* Pointer to bucket array. Each element * points to first entry in bucket's hash * chain, or NULL. */ 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 * **bucketPtr. */ Tcl_Size numEntries; /* Total number of entries present in * table. */ 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. */ #endif int downShift; /* Shift count used in hashing function. * Designed to use high-order bits of * randomized keys. */ #if TCL_MAJOR_VERSION < 9 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, * TCL_ONE_WORD_KEYS, or an integer giving the * number of ints that is the size of the * key. */ Tcl_HashEntry *(*findProc) (Tcl_HashTable *tablePtr, const char *key); |
︙ | ︙ | |||
1772 1773 1774 1775 1776 1777 1778 | * token. */ 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. */ | | | | 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 | * token. */ 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, * this field tells how many of them there are * (including components of components, etc.). * The component tokens immediately follow * this one. */ } Tcl_Token; /* |
︙ | ︙ | |||
1887 1888 1889 1890 1891 1892 1893 | */ #define NUM_STATIC_TOKENS 20 typedef struct Tcl_Parse { const char *commentStart; /* Pointer to # that begins the first of one * or more comments preceding the command. */ | | | | 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 | */ #define NUM_STATIC_TOKENS 20 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 * 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 * character of first word, up through the * terminating newline, close bracket, or * semicolon. */ Tcl_Size numWords; /* Total number of words in command. May be * 0. */ Tcl_Token *tokenPtr; /* Pointer to first token representing the * words of the command. Initially points to |
︙ | ︙ | |||
1963 1964 1965 1966 1967 1968 1969 | * into UTF-8. */ Tcl_EncodingConvertProc *fromUtfProc; /* Function to convert from UTF-8 into * external encoding. */ Tcl_FreeProc *freeProc; /* If non-NULL, function to call when this * encoding is deleted. */ | | | 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 | * into UTF-8. */ Tcl_EncodingConvertProc *fromUtfProc; /* Function to convert from UTF-8 into * external encoding. */ Tcl_FreeProc *freeProc; /* If non-NULL, function to call when this * encoding is deleted. */ 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 * is used to determine the source string * length when the srcLen argument is * negative. Must be 1, 2, or 4. */ } Tcl_EncodingType; |
︙ | ︙ | |||
2169 2170 2171 2172 2173 2174 2175 | * argv array. */ void *srcPtr; /* Value to be used in setting dst; usage * depends on type.*/ void *dstPtr; /* Address of value to be modified; usage * depends on type.*/ const char *helpStr; /* Documentation message describing this * option. */ | | | 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 | * argv array. */ void *srcPtr; /* Value to be used in setting dst; usage * depends on type.*/ void *dstPtr; /* Address of value to be modified; usage * depends on type.*/ const char *helpStr; /* Documentation message describing this * option. */ void *clientData; /* Word to pass to function callbacks. */ } Tcl_ArgvInfo; /* * Legal values for the type field of a Tcl_ArgInfo: see the user * documentation for details. */ |
︙ | ︙ | |||
2497 2498 2499 2500 2501 2502 2503 | * Tcl_DecrRefCount(objPtr); * * This will free the obj if there are no references to the obj. */ # define Tcl_BounceRefCount(objPtr) \ TclBounceRefCount(objPtr, __FILE__, __LINE__) | | > > > > | | | | | | > > | 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 | * Tcl_DecrRefCount(objPtr); * * This will free the obj if there are no references to the obj. */ # define Tcl_BounceRefCount(objPtr) \ TclBounceRefCount(objPtr, __FILE__, __LINE__) static inline void TclBounceRefCount( Tcl_Obj *objPtr, const char *fn, int line) { if (objPtr) { if ((objPtr)->refCount == 0) { Tcl_DbDecrRefCount(objPtr, fn, line); } } } #else # undef Tcl_IncrRefCount # define Tcl_IncrRefCount(objPtr) \ ((void)++(objPtr)->refCount) /* * Use do/while0 idiom for optimum correctness without compiler warnings. * https://wiki.c2.com/?TrivialDoWhileLoop */ # undef Tcl_DecrRefCount # define Tcl_DecrRefCount(objPtr) \ do { \ Tcl_Obj *_objPtr = (objPtr); \ if (_objPtr->refCount-- <= 1) { \ TclFreeObj(_objPtr); \ } \ } while(0) # undef Tcl_IsShared # define Tcl_IsShared(objPtr) \ ((objPtr)->refCount > 1) /* * Declare that obj will no longer be used or referenced. * This will release the obj if there is no referece count, * otherwise let it be. */ # define Tcl_BounceRefCount(objPtr) \ TclBounceRefCount(objPtr); static inline void TclBounceRefCount( Tcl_Obj* objPtr) { if (objPtr) { if ((objPtr)->refCount == 0) { Tcl_DecrRefCount(objPtr); } } } |
︙ | ︙ |
Changes to generic/tclAlloc.c.
︙ | ︙ | |||
62 63 64 65 66 67 68 | } ovu; #define overMagic0 ovu.magic0 #define overMagic1 ovu.magic1 #define bucketIndex ovu.index #define rangeCheckMagic ovu.rmagic #define realBlockSize ovu.size }; | < | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | } ovu; #define overMagic0 ovu.magic0 #define overMagic1 ovu.magic1 #define bucketIndex ovu.index #define rangeCheckMagic ovu.rmagic #define realBlockSize ovu.size }; #define MAGIC 0xEF /* magic # on accounting info */ #define RMAGIC 0x5555 /* magic # on range info */ #ifndef NDEBUG #define RSLOP sizeof(unsigned short) #else |
︙ | ︙ |
Changes to generic/tclAssembly.c.
︙ | ︙ | |||
218 219 220 221 222 223 224 | typedef struct AssemblyEnv { CompileEnv* envPtr; /* Compilation environment being used for code * generation */ Tcl_Parse* parsePtr; /* Parse of the current line of source */ Tcl_HashTable labelHash; /* Hash table whose keys are labels and whose * values are 'label' objects storing the code * offsets of the labels. */ | | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | typedef struct AssemblyEnv { CompileEnv* envPtr; /* Compilation environment being used for code * generation */ Tcl_Parse* parsePtr; /* Parse of the current line of source */ Tcl_HashTable labelHash; /* Hash table whose keys are labels and whose * values are 'label' objects storing the code * offsets of the labels. */ Tcl_Size cmdLine; /* Current line number within the assembly * code */ Tcl_Size* clNext; /* Invisible continuation line for * [info frame] */ BasicBlock* head_bb; /* First basic block in the code */ BasicBlock* curr_bb; /* Current basic block */ int maxDepth; /* Maximum stack depth encountered */ int curCatchDepth; /* Current depth of catches */ int maxCatchDepth; /* Maximum depth of catches encountered */ int flags; /* Compilation flags (TCL_EVAL_DIRECT) */ |
︙ | ︙ | |||
273 274 275 276 277 278 279 | static void CompileEmbeddedScript(AssemblyEnv*, Tcl_Token*, const TalInstDesc*); static int DefineLabel(AssemblyEnv* envPtr, const char* label); static void DeleteMirrorJumpTable(JumptableInfo* jtPtr); static void FillInJumpOffsets(AssemblyEnv*); static int CreateMirrorJumpTable(AssemblyEnv* assemEnvPtr, Tcl_Obj* jumpTable); | | | 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | static void CompileEmbeddedScript(AssemblyEnv*, Tcl_Token*, const TalInstDesc*); static int DefineLabel(AssemblyEnv* envPtr, const char* label); static void DeleteMirrorJumpTable(JumptableInfo* jtPtr); static void FillInJumpOffsets(AssemblyEnv*); static int CreateMirrorJumpTable(AssemblyEnv* assemEnvPtr, Tcl_Obj* jumpTable); static size_t FindLocalVar(AssemblyEnv* envPtr, Tcl_Token** tokenPtrPtr); static int FinishAssembly(AssemblyEnv*); static void FreeAssemblyEnv(AssemblyEnv*); static int GetBooleanOperand(AssemblyEnv*, Tcl_Token**, int*); static int GetListIndexOperand(AssemblyEnv*, Tcl_Token**, int*); static int GetIntegerOperand(AssemblyEnv*, Tcl_Token**, int*); static int GetNextOperand(AssemblyEnv*, Tcl_Token**, Tcl_Obj**); |
︙ | ︙ | |||
1267 1268 1269 1270 1271 1272 1273 | TalInstType instType; /* Type of the instruction */ Tcl_Obj* operand1Obj = NULL; /* First operand to the instruction */ const char* operand1; /* String rep of the operand */ Tcl_Size operand1Len; /* String length of the operand */ int opnd; /* Integer representation of an operand */ int litIndex; /* Literal pool index of a constant */ | | | 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 | TalInstType instType; /* Type of the instruction */ Tcl_Obj* operand1Obj = NULL; /* First operand to the instruction */ const char* operand1; /* String rep of the operand */ Tcl_Size operand1Len; /* String length of the operand */ int opnd; /* Integer representation of an operand */ int litIndex; /* Literal pool index of a constant */ Tcl_Size localVar; /* LVT index of a local variable */ int flags; /* Flags for a basic block */ JumptableInfo* jtPtr; /* Pointer to a jumptable */ int infoIndex; /* Index of the jumptable in auxdata */ int status = TCL_ERROR; /* Return value from this function */ /* * Make sure that the instruction name is known at compile time. |
︙ | ︙ | |||
1964 1965 1966 1967 1968 1969 1970 | */ static int CreateMirrorJumpTable( AssemblyEnv* assemEnvPtr, /* Assembly environment */ Tcl_Obj* jumps) /* List of alternating keywords and labels */ { | | | 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 | */ static int CreateMirrorJumpTable( AssemblyEnv* assemEnvPtr, /* Assembly environment */ Tcl_Obj* jumps) /* List of alternating keywords and labels */ { Tcl_Size objc; /* Number of elements in the 'jumps' list */ Tcl_Obj** objv; /* Pointers to the elements in the list */ CompileEnv* envPtr = assemEnvPtr->envPtr; /* Compilation environment */ Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr; /* Tcl interpreter */ BasicBlock* bbPtr = assemEnvPtr->curr_bb; /* Current basic block */ |
︙ | ︙ |
Changes to generic/tclBasic.c.
︙ | ︙ | |||
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /* * TCL_FPCLASSIFY_MODE: * 0 - fpclassify * 1 - _fpclass * 2 - simulate * 3 - __builtin_fpclassify */ #ifndef TCL_FPCLASSIFY_MODE #if defined(__MINGW32__) && defined(_X86_) /* mingw 32-bit */ /* * MINGW x86 (tested up to gcc 8.1) seems to have a bug in fpclassify, * [fpclassify 1e-314], x86 => normal, x64 => subnormal, so switch to using a * version using a compiler built-in. | > > > > > > > > | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * TCL_FPCLASSIFY_MODE: * 0 - fpclassify * 1 - _fpclass * 2 - simulate * 3 - __builtin_fpclassify * * Not directly used; handled by preprocessor. */ enum ClassifyModes { MODE_FPCLASSIFY = 0, MODE_FPCLASS = 1, MODE_SIMULATE = 2, MODE_BUILTIN = 3 }; #ifndef TCL_FPCLASSIFY_MODE #if defined(__MINGW32__) && defined(_X86_) /* mingw 32-bit */ /* * MINGW x86 (tested up to gcc 8.1) seems to have a bug in fpclassify, * [fpclassify 1e-314], x86 => normal, x64 => subnormal, so switch to using a * version using a compiler built-in. |
︙ | ︙ | |||
58 59 60 61 62 63 64 | * assumes that we're on x86 (or at least a system with classic little-endian * double layout and a 32-bit 'int' type). */ #define TCL_FPCLASSIFY_MODE 2 #endif /* !fpclassify */ /* actually there is no fallback to builtin fpclassify */ #endif /* !TCL_FPCLASSIFY_MODE */ | < | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | * assumes that we're on x86 (or at least a system with classic little-endian * double layout and a 32-bit 'int' type). */ #define TCL_FPCLASSIFY_MODE 2 #endif /* !fpclassify */ /* actually there is no fallback to builtin fpclassify */ #endif /* !TCL_FPCLASSIFY_MODE */ /* * Bug 7371b6270b: to check C call stack depth, prefer an approach which is * compatible with AddressSanitizer (ASan) use-after-return detection. */ #if defined(_MSC_VER) && defined(HAVE_INTRIN_H) |
︙ | ︙ | |||
1172 1173 1174 1175 1176 1177 1178 | /* Export unsupported commands */ nsPtr = Tcl_FindNamespace(interp, "::tcl::unsupported", NULL, 0); if (nsPtr) { Tcl_Export(interp, nsPtr, "*", 1); } | < | 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 | /* Export unsupported commands */ nsPtr = Tcl_FindNamespace(interp, "::tcl::unsupported", NULL, 0); if (nsPtr) { Tcl_Export(interp, nsPtr, "*", 1); } #ifdef USE_DTRACE /* * Register the tcl::dtrace command. */ Tcl_CreateObjCommand(interp, "::tcl::dtrace", DTraceObjCmd, NULL, NULL); #endif /* USE_DTRACE */ |
︙ | ︙ | |||
1933 1934 1935 1936 1937 1938 1939 | for (; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { Tcl_DeleteCommandFromToken(interp, (Tcl_Command)Tcl_GetHashValue(hPtr)); } Tcl_DeleteHashTable(hTablePtr); Tcl_Free(hTablePtr); } | < | 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 | for (; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { Tcl_DeleteCommandFromToken(interp, (Tcl_Command)Tcl_GetHashValue(hPtr)); } Tcl_DeleteHashTable(hTablePtr); Tcl_Free(hTablePtr); } if (iPtr->assocData != NULL) { AssocData *dPtr; hTablePtr = iPtr->assocData; /* * Invoke deletion callbacks; note that a callback can create new * callbacks, so we iterate. |
︙ | ︙ | |||
2687 2688 2689 2690 2691 2692 2693 | typedef struct { Tcl_ObjCmdProc2 *proc; void *clientData; /* Arbitrary value to pass to proc function. */ Tcl_CmdDeleteProc *deleteProc; void *deleteData; /* Arbitrary value to pass to deleteProc function. */ Tcl_ObjCmdProc2 *nreProc; } CmdWrapperInfo; | < | 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 | typedef struct { Tcl_ObjCmdProc2 *proc; void *clientData; /* Arbitrary value to pass to proc function. */ Tcl_CmdDeleteProc *deleteProc; void *deleteData; /* Arbitrary value to pass to deleteProc function. */ Tcl_ObjCmdProc2 *nreProc; } CmdWrapperInfo; static int cmdWrapperProc( void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj * const *objv) |
︙ | ︙ | |||
9235 9236 9237 9238 9239 9240 9241 | runPtr->data[1] = NULL; corPtr->yieldPtr = NULL; break; } } } iPtr->execEnvPtr = corPtr->eePtr; | < | 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 | runPtr->data[1] = NULL; corPtr->yieldPtr = NULL; break; } } } iPtr->execEnvPtr = corPtr->eePtr; Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot yield: C stack busy", -1)); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "CANT_YIELD", (char *)NULL); return TCL_ERROR; } |
︙ | ︙ |
Changes to generic/tclBinary.c.
︙ | ︙ | |||
24 25 26 27 28 29 30 | #define BINARY_ALL -1 /* Use all elements in the argument. */ #define BINARY_NOCOUNT -2 /* No count was specified in format. */ /* * The following flags may be OR'ed together and returned by GetFormatSpec */ | | | | > | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #define BINARY_ALL -1 /* Use all elements in the argument. */ #define BINARY_NOCOUNT -2 /* No count was specified in format. */ /* * The following flags may be OR'ed together and returned by GetFormatSpec */ enum BinaryFormatFlags { BINARY_SIGNED = 0, /* Field to be read as signed data */ BINARY_UNSIGNED = 1 /* Field to be read as unsigned data */ }; /* * The following defines the maximum number of different (integer) numbers * placed in the object cache by 'binary scan' before it bails out and * switches back to Plan A (creating a new object for each value.) * Theoretically, it would be possible to keep the cache about for the values * that are already in it, but that makes the code slower in practice when |
︙ | ︙ |
Changes to generic/tclCkalloc.c.
︙ | ︙ | |||
1005 1006 1007 1008 1009 1010 1011 | Tcl_Interp *interp) /* Interpreter in which commands should be * added */ { TclInitDbCkalloc(); Tcl_CreateObjCommand(interp, "memory", MemoryCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "checkmem", CheckmemCmd, NULL, NULL); } | < | 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 | Tcl_Interp *interp) /* Interpreter in which commands should be * added */ { TclInitDbCkalloc(); Tcl_CreateObjCommand(interp, "memory", MemoryCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "checkmem", CheckmemCmd, NULL, NULL); } #else /* TCL_MEM_DEBUG */ /* This is the !TCL_MEM_DEBUG case */ #undef Tcl_InitMemory #undef Tcl_DumpActiveMemory |
︙ | ︙ |
Changes to generic/tclClock.c.
︙ | ︙ | |||
120 121 122 123 124 125 126 | * Structure containing description of "native" clock commands to create. */ struct ClockCommand { const char *name; /* The tail of the command name. The full name * is "::tcl::clock::<name>". When NULL marks * the end of the table. */ | | | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | * Structure containing description of "native" clock commands to create. */ struct ClockCommand { const char *name; /* The tail of the command name. The full name * is "::tcl::clock::<name>". When NULL marks * the end of the table. */ Tcl_ObjCmdProc *objCmdProc; /* Function that implements the command. This * will always have the ClockClientData sent * to it, but may well ignore this data. */ CompileProc *compileProc; /* The compiler for the command. */ void *clientData; /* Any clientData to give the command (if NULL * a reference to ClockClientData will be sent) */ }; |
︙ | ︙ | |||
251 252 253 254 255 256 257 | data->defFlags = 0; /* * Install the commands. */ | | | 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | data->defFlags = 0; /* * Install the commands. */ #define TCL_CLOCK_PREFIX_LEN 14 // == strlen("::tcl::clock::") memcpy(cmdName, "::tcl::clock::", TCL_CLOCK_PREFIX_LEN); for (clockCmdPtr=clockCommands ; clockCmdPtr->name!=NULL ; clockCmdPtr++) { void *clientData; strcpy(cmdName + TCL_CLOCK_PREFIX_LEN, clockCmdPtr->name); if (!(clientData = clockCmdPtr->clientData)) { clientData = data; |
︙ | ︙ | |||
642 643 644 645 646 647 648 | || (localeObj->length == dataPtr->prevUsedLocale->length && strcasecmp(loc, TclGetString(dataPtr->prevUsedLocale)) == 0))) { *mcDictObj = dataPtr->prevUsedLocaleDict; TclSetObjRef(dataPtr->prevUsedLocaleUnnorm, localeObj); return dataPtr->prevUsedLocale; } | | | | | 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 | || (localeObj->length == dataPtr->prevUsedLocale->length && strcasecmp(loc, TclGetString(dataPtr->prevUsedLocale)) == 0))) { *mcDictObj = dataPtr->prevUsedLocaleDict; TclSetObjRef(dataPtr->prevUsedLocaleUnnorm, localeObj); return dataPtr->prevUsedLocale; } if ((localeObj->length == 1 // C && strcasecmp(loc, Literals[LIT_C]) == 0) || (dataPtr->defaultLocale && (loc2 = TclGetString(dataPtr->defaultLocale)) && localeObj->length == dataPtr->defaultLocale->length && strcasecmp(loc, loc2) == 0)) { *mcDictObj = dataPtr->defaultLocaleDict; return dataPtr->defaultLocale ? dataPtr->defaultLocale : dataPtr->literals[LIT_C]; } if (localeObj->length == 7 // current && strcasecmp(loc, Literals[LIT_CURRENT]) == 0) { if (dataPtr->currentLocale == NULL) { ClockGetCurrentLocale(dataPtr, interp); } *mcDictObj = dataPtr->currentLocaleDict; return dataPtr->currentLocale; } if ((localeObj->length == 6 // system && strcasecmp(loc, Literals[LIT_SYSTEM]) == 0)) { SavePrevLocaleObj(dataPtr); TclSetObjRef(dataPtr->lastUsedLocaleUnnorm, localeObj); localeObj = ClockGetSystemLocale(dataPtr, interp); TclSetObjRef(dataPtr->lastUsedLocale, localeObj); *mcDictObj = NULL; return localeObj; |
︙ | ︙ | |||
752 753 754 755 756 757 758 | if (Tcl_EvalObjv(opts->interp, 2, callargs, 0) != TCL_OK) { return NULL; } opts->mcDictObj = Tcl_GetObjResult(opts->interp); Tcl_ResetResult(opts->interp); | | > | > > | > | 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 | if (Tcl_EvalObjv(opts->interp, 2, callargs, 0) != TCL_OK) { return NULL; } opts->mcDictObj = Tcl_GetObjResult(opts->interp); Tcl_ResetResult(opts->interp); ref = 0; // new object is not yet referenced } /* * Be sure that object reference doesn't increase (dict changeable). */ if (opts->mcDictObj->refCount > ref) { /* smart reference (shared dict as object with no ref-counter) */ opts->mcDictObj = TclDictObjSmartRef(opts->interp, opts->mcDictObj); } /* * Create exactly one reference to catalog / make it searchable for future. */ Tcl_DictObjPut(NULL, dataPtr->mcDicts, opts->localeObj, opts->mcDictObj); if (opts->localeObj == dataPtr->literals[LIT_C] || opts->localeObj == dataPtr->defaultLocale) { dataPtr->defaultLocaleDict = opts->mcDictObj; } |
︙ | ︙ | |||
817 818 819 820 821 822 823 | if (opts->mcDictObj == NULL) { return NULL; } } Tcl_DictObjGet(opts->interp, opts->mcDictObj, opts->dataPtr->mcLiterals[mcKey], &valObj); | | | 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 | if (opts->mcDictObj == NULL) { return NULL; } } Tcl_DictObjGet(opts->interp, opts->mcDictObj, opts->dataPtr->mcLiterals[mcKey], &valObj); return valObj; // or NULL in obscure case if Tcl_DictObjGet failed } /* *---------------------------------------------------------------------- * * ClockMCGetIdx -- * |
︙ | ︙ | |||
1941 1942 1943 1944 1945 1946 1947 | rangesVal) != TCL_OK) { return TCL_ERROR; } seconds = fields->seconds; /* Cache the last conversion */ | | | | < | | 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 | rangesVal) != TCL_OK) { return TCL_ERROR; } seconds = fields->seconds; /* Cache the last conversion */ if (ltzoc != NULL) { // slot was found above /* timezoneObj and changeover are the same */ TclSetObjRef(ltzoc->tzName, fields->tzName); // may be NULL } else { /* no TZ in cache - just move second slot down and use the first one */ ltzoc = &dataPtr->lastTZOffsCache[0]; TclUnsetObjRef(dataPtr->lastTZOffsCache[1].timezoneObj); TclUnsetObjRef(dataPtr->lastTZOffsCache[1].tzName); memcpy(&dataPtr->lastTZOffsCache[1], ltzoc, sizeof(*ltzoc)); TclInitObjRef(ltzoc->timezoneObj, timezoneObj); ltzoc->changeover = changeover; TclInitObjRef(ltzoc->tzName, fields->tzName); // may be NULL } ltzoc->localSeconds = fields->localSeconds; ltzoc->rangesVal[0] = rangesVal[0]; ltzoc->rangesVal[1] = rangesVal[1]; ltzoc->tzOffset = fields->tzOffset; } /* check DST-hole: if retrieved seconds is out of range */ if (ltzoc->rangesVal[0] > seconds || seconds >= ltzoc->rangesVal[1]) { dstHole: #if 0 printf("given local-time is outside the time-zone (in DST-hole): " "%d - offs %d => %d <= %d < %d\n", (int)fields->localSeconds, fields->tzOffset, (int)ltzoc->rangesVal[0], (int)seconds, (int)ltzoc->rangesVal[1]); #endif /* because we don't know real TZ (we're outsize), just invalidate local * time (which could be verified in ClockValidDate later) */ fields->localSeconds = TCL_INV_SECONDS; // not valid seconds } return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
2239 2240 2241 2242 2243 2244 2245 | return TCL_ERROR; } /* converted using table (TZ isn't :localtime) */ fields->flags &= ~CLF_CTZ; /* Cache the last conversion */ | | > | > > > | 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 | return TCL_ERROR; } /* converted using table (TZ isn't :localtime) */ fields->flags &= ~CLF_CTZ; /* Cache the last conversion */ if (ltzoc != NULL) { // slot was found above /* timezoneObj and changeover are the same */ TclSetObjRef(ltzoc->tzName, fields->tzName); } else { /* * No TZ in cache - just move second slot down and use the first * one. */ ltzoc = &dataPtr->lastTZOffsCache[0]; TclUnsetObjRef(dataPtr->lastTZOffsCache[1].timezoneObj); TclUnsetObjRef(dataPtr->lastTZOffsCache[1].tzName); memcpy(&dataPtr->lastTZOffsCache[1], ltzoc, sizeof(*ltzoc)); TclInitObjRef(ltzoc->timezoneObj, timezoneObj); ltzoc->changeover = changeover; TclInitObjRef(ltzoc->tzName, fields->tzName); |
︙ | ︙ | |||
2696 2697 2698 2699 2700 2701 2702 | int month; const int *dipm = daysInPriorMonths[IsGregorianLeapYear(fields)]; /* * Estimate month by calculating `dayOfYear / (365/12)` */ month = (day*12) / dipm[12]; | > > | > | 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 | int month; const int *dipm = daysInPriorMonths[IsGregorianLeapYear(fields)]; /* * Estimate month by calculating `dayOfYear / (365/12)` */ month = (day*12) / dipm[12]; /* * then do forwards backwards correction */ while (1) { if (day > dipm[month]) { if (month >= 11 || day <= dipm[month + 1]) { break; } month++; } else { |
︙ | ︙ | |||
2832 2833 2834 2835 2836 2837 2838 | fields->year = year; } /* * Try an initial conversion in the Gregorian calendar. */ | | | 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 | fields->year = year; } /* * Try an initial conversion in the Gregorian calendar. */ #if 0 // BUG https://core.tcl-lang.org/tcl/tktview?name=da340d4f32 ym1o4 = ym1 / 4; #else /* * Have to make sure quotient is truncated towards 0 when negative. * See above bug for details. The casts are necessary. */ if (ym1 >= 0) { |
︙ | ︙ | |||
2896 2897 2898 2899 2900 2901 2902 | * * Side effects: * Stores day number in 'julianDay' * *---------------------------------------------------------------------- */ | < | 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 | * * Side effects: * Stores day number in 'julianDay' * *---------------------------------------------------------------------- */ void GetJulianDayFromEraYearDay( TclDateFields *fields, /* Date to convert */ int changeover) /* Gregorian transition date as a Julian Day */ { Tcl_WideInt year, ym1; |
︙ | ︙ | |||
3285 3286 3287 3288 3289 3290 3291 | } ClockOperation; static int ClockParseFmtScnArgs( ClockFmtScnCmdArgs *opts, /* Result vector: format, locale, timezone... */ TclDateFields *date, /* Extracted date-time corresponding base * (by scan or add) resp. clockval (by format) */ | | | 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 | } ClockOperation; static int ClockParseFmtScnArgs( ClockFmtScnCmdArgs *opts, /* Result vector: format, locale, timezone... */ TclDateFields *date, /* Extracted date-time corresponding base * (by scan or add) resp. clockval (by format) */ Tcl_Size objc, /* Parameter count */ Tcl_Obj *const objv[], /* Parameter vector */ ClockOperation operation, /* What operation are we doing: format, scan, add */ const char *syntax) /* Syntax of the current command */ { Tcl_Interp *interp = opts->interp; ClockClientData *dataPtr = opts->dataPtr; int gmtFlag = 0; |
︙ | ︙ | |||
3310 3311 3312 3313 3314 3315 3316 | Tcl_WideInt baseVal; /* Base time, expressed in seconds from the Epoch */ if (operation == CLC_OP_SCN) { /* default flags (from configure) */ opts->flags |= dataPtr->defFlags & CLF_VALIDATE; } else { /* clock value (as current base) */ | > | | 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 | Tcl_WideInt baseVal; /* Base time, expressed in seconds from the Epoch */ if (operation == CLC_OP_SCN) { /* default flags (from configure) */ opts->flags |= dataPtr->defFlags & CLF_VALIDATE; } else { /* clock value (as current base) */ baseIdx = 1; opts->baseObj = objv[1]; saw |= 1 << CLC_ARGS_BASE; } /* * Extract values for the keywords. */ |
︙ | ︙ | |||
3361 3362 3363 3364 3365 3366 3367 | case CLC_ARGS_LOCALE: opts->localeObj = objv[i + 1]; break; case CLC_ARGS_TIMEZONE: opts->timezoneObj = objv[i + 1]; break; case CLC_ARGS_BASE: | > | | 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 | case CLC_ARGS_LOCALE: opts->localeObj = objv[i + 1]; break; case CLC_ARGS_TIMEZONE: opts->timezoneObj = objv[i + 1]; break; case CLC_ARGS_BASE: baseIdx = i + 1; opts->baseObj = objv[i + 1]; break; case CLC_ARGS_VALIDATE: if (operation != CLC_OP_SCN) { goto badOptionMsg; } else { int val; |
︙ | ︙ | |||
3715 3716 3717 3718 3719 3720 3721 | DateInfo *info, /* Clock scan info structure */ ClockFmtScnCmdArgs *opts) /* Format, locale, timezone and base */ { /* If needed assemble julianDay using year, month, etc. */ if (info->flags & CLF_ASSEMBLE_JULIANDAY) { if (info->flags & CLF_ISO8601WEEK) { GetJulianDayFromEraYearWeekDay(&yydate, GREGORIAN_CHANGE_DATE); | | | | 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 | DateInfo *info, /* Clock scan info structure */ ClockFmtScnCmdArgs *opts) /* Format, locale, timezone and base */ { /* If needed assemble julianDay using year, month, etc. */ if (info->flags & CLF_ASSEMBLE_JULIANDAY) { if (info->flags & CLF_ISO8601WEEK) { GetJulianDayFromEraYearWeekDay(&yydate, GREGORIAN_CHANGE_DATE); } else if (!(info->flags & CLF_DAYOFYEAR) // no day of year || (info->flags & (CLF_DAYOFMONTH|CLF_MONTH)) // yymmdd over yyddd == (CLF_DAYOFMONTH|CLF_MONTH)) { GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); } else { GetJulianDayFromEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); } info->flags |= CLF_ASSEMBLE_SECONDS; info->flags &= ~CLF_ASSEMBLE_JULIANDAY; |
︙ | ︙ | |||
3797 3798 3799 3800 3801 3802 3803 | yySecondOfDay, (int)yydate.localSeconds, (int)(yydate.localSeconds % SECONDS_PER_DAY), yydate.tzOffset); #endif if (!(stage & CLF_VALIDATE_S1) || !(opts->flags & CLF_VALIDATE_S1)) { goto stage_2; } | | | | 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 | yySecondOfDay, (int)yydate.localSeconds, (int)(yydate.localSeconds % SECONDS_PER_DAY), yydate.tzOffset); #endif if (!(stage & CLF_VALIDATE_S1) || !(opts->flags & CLF_VALIDATE_S1)) { goto stage_2; } opts->flags &= ~CLF_VALIDATE_S1; // stage 1 is done /* first year (used later in hath / daysInPriorMonths) */ if ((info->flags & (CLF_YEAR | CLF_ISO8601YEAR))) { if ((info->flags & CLF_ISO8601YEAR)) { if (yydate.iso8601Year < dataPtr->validMinYear || yydate.iso8601Year > dataPtr->validMaxYear) { errMsg = "invalid iso year"; errCode = "iso year"; goto error; } } if (info->flags & CLF_YEAR) { if (yyYear < dataPtr->validMinYear || yyYear > dataPtr->validMaxYear) { errMsg = "invalid year"; errCode = "year"; goto error; } } else if ((info->flags & CLF_ISO8601YEAR)) { yyYear = yydate.iso8601Year; // used to recognize leap } if ((info->flags & (CLF_ISO8601YEAR | CLF_YEAR)) == (CLF_ISO8601YEAR | CLF_YEAR)) { if (yyYear != yydate.iso8601Year) { errMsg = "ambiguous year"; errCode = "year"; goto error; |
︙ | ︙ | |||
3899 3900 3901 3902 3903 3904 3905 | goto error; } } if (!(stage & CLF_VALIDATE_S2) || !(opts->flags & CLF_VALIDATE_S2)) { return TCL_OK; } | | | 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 | goto error; } } if (!(stage & CLF_VALIDATE_S2) || !(opts->flags & CLF_VALIDATE_S2)) { return TCL_OK; } opts->flags &= ~CLF_VALIDATE_S2; // stage 2 is done /* * Further tests expected ready calculated julianDay (inclusive relative), * and time-zone conversion (local to UTC time). */ stage_2: |
︙ | ︙ | |||
4305 4306 4307 4308 4309 4310 4311 | /* adjust if we end up on a weekend */ if (resDayOfWeek > 5) { offs += 2; } return offs; } | < < | 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 | /* adjust if we end up on a weekend */ if (resDayOfWeek > 5) { offs += 2; } return offs; } /*---------------------------------------------------------------------- * * ClockAddObjCmd -- , clock add -- * * Adds an offset to a given time. * |
︙ | ︙ |
Changes to generic/tclClockFmt.c.
︙ | ︙ | |||
1859 1860 1861 1862 1863 1864 1865 | } else { /* legacy (alnum) timezone like CEST, etc. */ if (maxLen > 4) { maxLen = 4; } while (len < maxLen) { if ((*p & 0x80) | | | 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 | } else { /* legacy (alnum) timezone like CEST, etc. */ if (maxLen > 4) { maxLen = 4; } while (len < maxLen) { if ((*p & 0x80) || (!isalpha(UCHAR(*p)) && !isdigit(UCHAR(*p)))) { // INTL: ISO only break; } p++; len++; } if (len < minLen) { |
︙ | ︙ |
Changes to generic/tclCmdIL.c.
︙ | ︙ | |||
84 85 86 87 88 89 90 | * changed from TCL_OK to TCL_ERROR. */ } SortInfo; /* * The "sortMode" field of the SortInfo structure can take on any of the * following values. */ | | | | | | | | > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | * changed from TCL_OK to TCL_ERROR. */ } SortInfo; /* * The "sortMode" field of the SortInfo structure can take on any of the * following values. */ enum SortModes { SORTMODE_ASCII = 0, SORTMODE_INTEGER = 1, SORTMODE_REAL = 2, SORTMODE_COMMAND = 3, SORTMODE_DICTIONARY = 4, SORTMODE_ASCII_NC = 8 }; /* * Definitions for [lseq] command */ static const char *const seq_operations[] = { "..", "to", "count", "by", NULL }; |
︙ | ︙ | |||
5285 5286 5287 5288 5289 5290 5291 | /* * Once an error has occurred, skip any future comparisons so as * to preserve the error message in sortInterp->result. */ return 0; } | < | 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 | /* * Once an error has occurred, skip any future comparisons so as * to preserve the error message in sortInterp->result. */ return 0; } objPtr1 = elemPtr1->collationKey.objValuePtr; objPtr2 = elemPtr2->collationKey.objValuePtr; paramObjv[0] = objPtr1; paramObjv[1] = objPtr2; |
︙ | ︙ |
Changes to generic/tclCompCmds.c.
︙ | ︙ | |||
653 654 655 656 657 658 659 | /* drop the script */ dropScript = 1; TclEmitInstInt4( INST_REVERSE, 2, envPtr); TclEmitOpcode( INST_POP, envPtr); } ExceptionRangeEnds(envPtr, range); | < < | 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 | /* drop the script */ dropScript = 1; TclEmitInstInt4( INST_REVERSE, 2, envPtr); TclEmitOpcode( INST_POP, envPtr); } ExceptionRangeEnds(envPtr, range); /* * Emit the "no errors" epilogue: push "0" (TCL_OK) as the catch result, * and jump around the "error case" code. */ TclCheckStackDepth(depth+1, envPtr); PushStringLiteral(envPtr, "0"); TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup); /* * Emit the "error case" epilogue. Push the interpreter result and the * return code. */ ExceptionRangeTarget(envPtr, range, catchOffset); TclSetStackDepth(depth + dropScript, envPtr); if (dropScript) { TclEmitOpcode( INST_POP, envPtr); } /* Stack at this point is empty */ TclEmitOpcode( INST_PUSH_RESULT, envPtr); TclEmitOpcode( INST_PUSH_RETURN_CODE, envPtr); /* Stack at this point on both branches: result returnCode */ |
︙ | ︙ | |||
2846 2847 2848 2849 2850 2851 2852 | infoPtr->numLists++; for (j = 0; j < numVars; j++) { Tcl_Obj *varNameObj; const char *bytes; int varIndex; Tcl_Size length; | < | 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 | infoPtr->numLists++; for (j = 0; j < numVars; j++) { Tcl_Obj *varNameObj; const char *bytes; int varIndex; Tcl_Size length; Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj); bytes = TclGetStringFromObj(varNameObj, &length); varIndex = LocalScalar(bytes, length, envPtr); if (varIndex < 0) { code = TCL_ERROR; goto done; |
︙ | ︙ |
Changes to generic/tclCompile.c.
︙ | ︙ | |||
2216 2217 2218 2219 2220 2221 2222 | Tcl_Parse *parsePtr = (Tcl_Parse *)Tcl_Alloc(sizeof(Tcl_Parse)); do { const char *next; if (TCL_OK != Tcl_ParseCommand(interp, p, numBytes, 0, parsePtr)) { /* | | | | 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 | Tcl_Parse *parsePtr = (Tcl_Parse *)Tcl_Alloc(sizeof(Tcl_Parse)); do { const char *next; if (TCL_OK != Tcl_ParseCommand(interp, p, numBytes, 0, parsePtr)) { /* * Compile bytecodes to report the parsePtr error at runtime. */ Tcl_LogCommandInfo(interp, script, parsePtr->commandStart, parsePtr->term + 1 - parsePtr->commandStart); TclCompileSyntaxError(interp, envPtr); Tcl_Free(parsePtr); return; } |
︙ | ︙ |
Changes to generic/tclCompile.h.
︙ | ︙ | |||
401 402 403 404 405 406 407 | * The structure defining the bytecode instructions resulting from compiling a * Tcl script. Note that this structure is variable length: a single heap * object is allocated to hold the ByteCode structure immediately followed by * the code bytes, the literal object array, the ExceptionRange array, the * CmdLocation map, and the compilation AuxData array. */ | > | | | | < | | | | | < | | > | | 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | * The structure defining the bytecode instructions resulting from compiling a * Tcl script. Note that this structure is variable length: a single heap * object is allocated to hold the ByteCode structure immediately followed by * the code bytes, the literal object array, the ExceptionRange array, the * CmdLocation map, and the compilation AuxData array. */ enum ByteCodeFlags { /* * A PRECOMPILED bytecode struct is one that was generated from a compiled * image rather than implicitly compiled from source */ TCL_BYTECODE_PRECOMPILED = 0x0001, /* * When a bytecode is compiled, interp or namespace resolvers have not been * applied yet: this is indicated by the TCL_BYTECODE_RESOLVE_VARS flag. */ TCL_BYTECODE_RESOLVE_VARS = 0x0002, TCL_BYTECODE_RECOMPILE = 0x0004 }; typedef struct ByteCode { TclHandle interpHandle; /* Handle for interpreter containing the * compiled code. Commands and their compile * procs are specific to an interpreter so the * code emitted will depend on the * interpreter. */ 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. */ Namespace *nsPtr; /* Namespace context in which this code was * compiled. If the code is executed if a * different namespace, it must be * recompiled. */ |
︙ | ︙ | |||
455 456 457 458 459 460 461 | * Proc structure; otherwise NULL. This * pointer is also not owned by the ByteCode * and must not be freed by it. */ size_t structureSize; /* Number of bytes in the ByteCode structure * itself. Does not include heap space for * literal Tcl objects or storage referenced * by AuxData entries. */ | | | | | | | | | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | * Proc structure; otherwise NULL. This * pointer is also not owned by the ByteCode * and must not be freed by it. */ size_t structureSize; /* Number of bytes in the ByteCode structure * 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 numExceptRanges; /* Number of ExceptionRange array elems. */ Tcl_Size numAuxDataItems; /* Number of AuxData items. */ Tcl_Size numCmdLocBytes; /* Number of bytes needed for encoded command * location information. */ 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 * execute the code. */ unsigned char *codeStart; /* Points to the first byte of the code. This * is just after the final ByteCode member * cmdMapPtr. */ Tcl_Obj **objArrayPtr; /* Points to the start of the literal object * array. This is just after the last code * byte. */ |
︙ | ︙ | |||
521 522 523 524 525 526 527 | * variables. */ #ifdef TCL_COMPILE_STATS Tcl_Time createTime; /* Absolute time when the ByteCode was * created. */ #endif /* TCL_COMPILE_STATS */ } ByteCode; | | < < | | | | | 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 | * variables. */ #ifdef TCL_COMPILE_STATS Tcl_Time createTime; /* Absolute time when the ByteCode was * created. */ #endif /* TCL_COMPILE_STATS */ } ByteCode; #define ByteCodeSetInternalRep(objPtr, typePtr, codePtr) \ do { \ Tcl_ObjInternalRep ir; \ ir.twoPtrValue.ptr1 = (codePtr); \ ir.twoPtrValue.ptr2 = NULL; \ Tcl_StoreInternalRep((objPtr), (typePtr), &ir); \ } while (0) #define ByteCodeGetInternalRep(objPtr, typePtr, codePtr) \ do { \ const Tcl_ObjInternalRep *irPtr; \ irPtr = TclFetchInternalRep((objPtr), (typePtr)); \ (codePtr) = irPtr ? (ByteCode*)irPtr->twoPtrValue.ptr1 : NULL; \ } while (0) /* * Opcodes for the Tcl bytecode instructions. These must correspond to the * entries in the table of instruction descriptions, tclInstructionTable, in * tclCompile.c. Also, the order and number of the expression opcodes (e.g., * INST_BITOR) must match the entries in the array operatorStrings in |
︙ | ︙ | |||
1221 1222 1223 1224 1225 1226 1227 | * * void *TclFetchAuxData(CompileEng *envPtr, int index); */ #define TclFetchAuxData(envPtr, index) \ (envPtr)->auxDataArrayPtr[(index)].clientData | > | | | > | 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 | * * void *TclFetchAuxData(CompileEng *envPtr, int index); */ #define TclFetchAuxData(envPtr, index) \ (envPtr)->auxDataArrayPtr[(index)].clientData enum LiteralFlags { LITERAL_ON_HEAP = 0x01, LITERAL_CMD_NAME = 0x02, LITERAL_UNSHARED = 0x04 }; /* * Macro used to manually adjust the stack requirements; used in cases where * the stack effect cannot be computed from the opcode and its operands, but * is still known at compile time. * * void TclAdjustStackDepth(int delta, CompileEnv *envPtr); |
︙ | ︙ | |||
1275 1276 1277 1278 1279 1280 1281 | #define TclUpdateStackReqs(op, i, envPtr) \ do { \ int _delta = tclInstructionTable[(op)].stackEffect; \ if (_delta) { \ if (_delta == INT_MIN) { \ _delta = 1 - (i); \ } \ | | | 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 | #define TclUpdateStackReqs(op, i, envPtr) \ do { \ int _delta = tclInstructionTable[(op)].stackEffect; \ if (_delta) { \ if (_delta == INT_MIN) { \ _delta = 1 - (i); \ } \ TclAdjustStackDepth(_delta, envPtr); \ } \ } while (0) /* * Macros used to update the flag that indicates if we are at the start of a * command, based on whether the opcode is INST_START_COMMAND. * |
︙ | ︙ |
Changes to generic/tclEncoding.c.
︙ | ︙ | |||
125 126 127 128 129 130 131 | * EscapeSubTables. */ } EscapeEncodingData; /* * Constants used when loading an encoding file to identify the type of the * file. */ | | | | | | > | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | * EscapeSubTables. */ } EscapeEncodingData; /* * Constants used when loading an encoding file to identify the type of the * file. */ enum EncodingTypes { ENCODING_SINGLEBYTE = 0, ENCODING_DOUBLEBYTE = 1, ENCODING_MULTIBYTE = 2, ENCODING_ESCAPE = 3 }; /* * A list of directories in which Tcl should look for *.enc files. This list * is shared by all threads. Access is governed by a mutex lock. */ static TclInitProcessGlobalValueProc InitializeEncodingSearchPath; |
︙ | ︙ | |||
253 254 255 256 257 258 259 | static Tcl_EncodingConvertProc UtfToUtf32Proc; static Tcl_EncodingConvertProc Utf16ToUtfProc; static Tcl_EncodingConvertProc UtfToUtf16Proc; static Tcl_EncodingConvertProc UtfToUcs2Proc; static Tcl_EncodingConvertProc UtfToUtfProc; static Tcl_EncodingConvertProc Iso88591FromUtfProc; static Tcl_EncodingConvertProc Iso88591ToUtfProc; | < | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | static Tcl_EncodingConvertProc UtfToUtf32Proc; static Tcl_EncodingConvertProc Utf16ToUtfProc; static Tcl_EncodingConvertProc UtfToUtf16Proc; static Tcl_EncodingConvertProc UtfToUcs2Proc; static Tcl_EncodingConvertProc UtfToUtfProc; static Tcl_EncodingConvertProc Iso88591FromUtfProc; static Tcl_EncodingConvertProc Iso88591ToUtfProc; /* * A Tcl_ObjType for holding a cached Tcl_Encoding in the twoPtrValue.ptr1 field * of the internalrep. This should help the lifetime of encodings be more useful. * See concerns raised in [Bug 1077262]. */ |
︙ | ︙ | |||
508 509 510 511 512 513 514 | /* * NOTE: THESE BIT DEFINITIONS SHOULD NOT OVERLAP WITH INTERNAL USE BITS * DEFINED IN tcl.h (TCL_ENCODING_* et al). Be cognizant of this * when adding bits. TODO - should really be defined in a single file. * * To prevent conflicting bits, only define bits within 0xff00 mask here. */ | > | | | > | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 | /* * NOTE: THESE BIT DEFINITIONS SHOULD NOT OVERLAP WITH INTERNAL USE BITS * DEFINED IN tcl.h (TCL_ENCODING_* et al). Be cognizant of this * when adding bits. TODO - should really be defined in a single file. * * To prevent conflicting bits, only define bits within 0xff00 mask here. */ enum EncodingFlags { TCL_ENCODING_LE = 0x100, /* Used to distinguish LE/BE variants */ ENCODING_UTF = 0x200, /* For UTF-8 encoding, allow 4-byte output sequences */ ENCODING_INPUT = 0x400 /* For UTF-8/CESU-8 encoding, means external -> internal */ }; void TclInitEncodingSubsystem(void) { Tcl_EncodingType type; TableEncodingData *dataPtr; unsigned size; |
︙ | ︙ |
Changes to generic/tclEnv.c.
︙ | ︙ | |||
31 32 33 34 35 36 37 | # define tenviron environ # define tenviron2utfdstr(str, dsPtr) \ Tcl_ExternalToUtfDString(NULL, str, -1, dsPtr) # define utf2tenvirondstr(str, dsPtr) \ Tcl_UtfToExternalDString(NULL, str, -1, dsPtr) # define techar char #endif | < | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | # define tenviron environ # define tenviron2utfdstr(str, dsPtr) \ Tcl_ExternalToUtfDString(NULL, str, -1, dsPtr) # define utf2tenvirondstr(str, dsPtr) \ Tcl_UtfToExternalDString(NULL, str, -1, dsPtr) # define techar char #endif /* MODULE_SCOPE */ size_t TclEnvEpoch = 0; /* Epoch of the tcl environment * (if changed with tcl-env). */ static struct { Tcl_Size cacheSize; /* Number of env strings in cache. */ |
︙ | ︙ |
Changes to generic/tclExecute.c.
︙ | ︙ | |||
1020 1021 1022 1023 1024 1025 1026 | */ if (move) { moveWords = esPtr->tosPtr - MEMSTART(markerPtr) + 1; } needed = growth + moveWords + WALLOCALIGN; | < | 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 | */ if (move) { moveWords = esPtr->tosPtr - MEMSTART(markerPtr) + 1; } needed = growth + moveWords + WALLOCALIGN; /* * Check if there is enough room in the next stack (if there is one, it * should be both empty and the last one!) */ if (esPtr->nextPtr) { oldPtr = esPtr; |
︙ | ︙ | |||
5788 5789 5790 5791 5792 5793 5794 | case INST_GE: { int iResult = 0, compare = 0; value2Ptr = OBJ_AT_TOS; valuePtr = OBJ_UNDER_TOS; /* | | | | | 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 | case INST_GE: { int iResult = 0, compare = 0; value2Ptr = OBJ_AT_TOS; valuePtr = OBJ_UNDER_TOS; /* * Try to determine, without triggering generation of a string * representation, whether one value is not a number. */ if (TclCheckEmptyString(valuePtr) > 0 || TclCheckEmptyString(value2Ptr) > 0) { goto stringCompare; } if (GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK || GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK) { /* |
︙ | ︙ | |||
6599 6600 6601 6602 6603 6604 6605 | interp, listPtr, &listLen, &elements); } if (status != TCL_OK) { CACHE_STACK_INFO(); goto gotError; } CACHE_STACK_INFO(); | < | 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 | interp, listPtr, &listLen, &elements); } if (status != TCL_OK) { CACHE_STACK_INFO(); goto gotError; } CACHE_STACK_INFO(); valIndex = (iterNum * numVars); for (j = 0; j < numVars; j++) { if (valIndex >= listLen) { TclNewObj(valuePtr); } else { DECACHE_STACK_INFO(); |
︙ | ︙ |
Changes to generic/tclFileName.c.
︙ | ︙ | |||
36 37 38 39 40 41 42 | const char *separators, Tcl_Obj *pathPtr, int flags, char *pattern, Tcl_GlobTypeData *types); static int TclGlob(Tcl_Interp *interp, char *pattern, Tcl_Obj *pathPrefix, int globFlags, Tcl_GlobTypeData *types); /* Flag values used by TclGlob() */ | | | | > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | const char *separators, Tcl_Obj *pathPtr, int flags, char *pattern, Tcl_GlobTypeData *types); static int TclGlob(Tcl_Interp *interp, char *pattern, Tcl_Obj *pathPrefix, int globFlags, Tcl_GlobTypeData *types); /* Flag values used by TclGlob() */ enum TclGlobFlags { TCL_GLOBMODE_DIR = 4, TCL_GLOBMODE_TAILS = 8 }; /* * When there is no support for getting the block size of a file in a stat() * call, use this as a guess. Allow it to be overridden in the platform- * specific files. */ |
︙ | ︙ |
Changes to generic/tclIO.c.
︙ | ︙ | |||
3152 3153 3154 3155 3156 3157 3158 | } /* * Cancel any outstanding timer. */ DeleteTimerHandler(statePtr); | < | 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 | } /* * Cancel any outstanding timer. */ DeleteTimerHandler(statePtr); /* * Mark the channel as deleted by clearing the type structure. */ if (chanPtr->downChanPtr != NULL) { Channel *downChanPtr = chanPtr->downChanPtr; |
︙ | ︙ | |||
6107 6108 6109 6110 6111 6112 6113 | /* This must comes after UpdateInterest(), which may set errno */ if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR) && (!copied || !GotFlag(statePtr, CHANNEL_NONBLOCKING))) { /* Channel either is blocking or is nonblocking with no data * succesfully red before the error. Return an error so that callers * like [read] can also return an error. | | | 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 | /* This must comes after UpdateInterest(), which may set errno */ if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR) && (!copied || !GotFlag(statePtr, CHANNEL_NONBLOCKING))) { /* Channel either is blocking or is nonblocking with no data * succesfully red before the error. Return an error so that callers * like [read] can also return an error. */ ResetFlag(statePtr, CHANNEL_EOF|CHANNEL_ENCODING_ERROR); Tcl_SetErrno(EILSEQ); copied = -1; } TclChannelRelease((Tcl_Channel)chanPtr); return copied; } |
︙ | ︙ |
Changes to generic/tclIO.h.
︙ | ︙ | |||
35 36 37 38 39 40 41 | * Buffers data being sent to or from a channel. */ 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. */ | | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | * Buffers data being sent to or from a channel. */ 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 * 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 * buffer occupies this space + bufSize-1 * bytes. This must be the last field in the * structure. */ } ChannelBuffer; #define CHANNELBUFFER_HEADER_SIZE offsetof(ChannelBuffer, buf) |
︙ | ︙ | |||
92 93 94 95 96 97 98 | * data specific to the channel but which belongs to the generic part of the * Tcl channel mechanism, and it points at an instance specific (and type * specific) instance data, and at a channel type structure. */ typedef struct Channel { struct ChannelState *state; /* Split out state information */ | | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | * data specific to the channel but which belongs to the generic part of the * Tcl channel mechanism, and it points at an instance specific (and type * specific) instance data, and at a channel type structure. */ typedef struct Channel { struct ChannelState *state; /* Split out state information */ 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 * upon. This reference is NULL for normal * channels. See Tcl_StackChannel. */ struct Channel *upChanPtr; /* Refers to the channel above stacked this * one. NULL for the top most channel. */ |
︙ | ︙ | |||
156 157 158 159 160 161 162 | TclEolTranslation outputTranslation; /* What translation to use for generating end * of line sequences in output? */ int inEofChar; /* If nonzero, use this as a signal of EOF on * input. */ #if TCL_MAJOR_VERSION < 9 int outEofChar; /* If nonzero, append this to the channel when | | > | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | TclEolTranslation outputTranslation; /* What translation to use for generating end * of line sequences in output? */ int inEofChar; /* If nonzero, use this as a signal of EOF on * input. */ #if TCL_MAJOR_VERSION < 9 int outEofChar; /* If nonzero, append this to the channel when * it is closed if it is open for writing. * For Tcl 8.x only */ #endif int unreportedError; /* Non-zero if an error report was deferred * because it happened in the background. The * value is the POSIX error code. */ Tcl_Size refCount; /* How many interpreters hold references to * this IO channel? */ struct CloseCallback *closeCbPtr; |
︙ | ︙ | |||
187 188 189 190 191 192 193 | * handlers for. */ EventScriptRecord *scriptRecordPtr; /* Chain of all scripts registered for event * handlers ("fileevent") on this channel. */ Tcl_Size bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ Channel *timerChanPtr; /* Needed in order to decrement the refCount of | | | | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | * handlers for. */ EventScriptRecord *scriptRecordPtr; /* Chain of all scripts registered for event * handlers ("fileevent") on this channel. */ Tcl_Size bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ Channel *timerChanPtr; /* Needed in order to decrement the refCount of * the right channel when the timer is * deleted. */ struct CopyState *csPtrR; /* State of background copy for which channel * is input, or NULL. */ struct CopyState *csPtrW; /* State of background copy for which channel * is output, or NULL. */ Channel *topChanPtr; /* Refers to topmost channel in a stack. Never * NULL. */ Channel *bottomChanPtr; /* Refers to bottommost channel in a stack. |
︙ | ︙ | |||
228 229 230 231 232 233 234 | /* * Values for the flags field in Channel. Any OR'ed combination of the * following flags can be stored in the field. These flags record various * options and state bits about the channel. In addition to the flags below, * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. */ | > | < | | < | | < | | < | < | | | | | | < | | < | | | < | | | > | | < | | | < | | | | | > | | > | | | | | | < | | | | | > | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | /* * Values for the flags field in Channel. Any OR'ed combination of the * following flags can be stored in the field. These flags record various * options and state bits about the channel. In addition to the flags below, * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. */ enum ChannelStateFlags { CHANNEL_NONBLOCKING = 1<<6, /* Channel is currently in nonblocking mode. */ BG_FLUSH_SCHEDULED = 1<<7, /* A background flush of the queued output * output buffers has been scheduled. */ CHANNEL_CLOSED = 1<<8, /* Channel has been closed. No further * Tcl-level IO on the channel is allowed. */ CHANNEL_EOF = 1<<9, /* EOF occurred on this channel. This bit is * cleared before every input operation. */ CHANNEL_STICKY_EOF = 1<<10, /* EOF occurred on this channel because we * saw the input eofChar. This bit prevents * clearing of the EOF bit before every input * operation. */ CHANNEL_BLOCKED = 1<<11, /* EWOULDBLOCK or EAGAIN occurred on this * channel. This bit is cleared before every * input or output operation. */ INPUT_SAW_CR = 1<<12, /* Channel is in CRLF eol input translation * mode and the last byte seen was a "\r". */ CHANNEL_DEAD = 1<<13, /* The channel has been closed by the exit * handler (on exit) but not deallocated. * When any IO operation sees this flag on a * channel, it does not call driver level * functions to avoid referring to deallocated * data. */ CHANNEL_NEED_MORE_DATA = 1<<14, /* The last input operation failed because * there was not enough data to complete the * operation. This flag is set when gets fails * to get a complete line or when read fails * to get a complete character. When set, file * events will not be delivered for buffered * data until the state of the channel * changes. */ CHANNEL_ENCODING_ERROR = 1<<15, /* Set if the channel encountered an encoding * error. */ CHANNEL_RAW_MODE = 1<<16, /* When set, notes that the Raw API is being * used. */ CHANNEL_LINEBUFFERED = 1<<17, /* Output to the channel must be flushed * after every newline. */ CHANNEL_UNBUFFERED = 1<<18, /* Output to the channel must always be * flushed immediately. */ CHANNEL_INCLOSE = 1<<19, /* Channel is currently being closed. Its * structures are still live and usable, but * it may not be closed again from within the * close handler. */ CHANNEL_CLOSEDWRITE = 1<<21 /* Channel write side has been closed. No * further Tcl-level write IO on the channel * is allowed. */ }; /* * The length of time to wait between synthetic timer events. Must be zero or * bad things tend to happen. */ #define SYNTHETIC_EVENT_TIME 0 |
︙ | ︙ |
Changes to generic/tclIOCmd.c.
︙ | ︙ | |||
601 602 603 604 605 606 607 | newLoc = Tcl_Tell(chan); /* * TIP #219. * Capture error messages put by the driver into the bypass area and put * them into the regular interpreter result. */ | < | 601 602 603 604 605 606 607 608 609 610 611 612 613 614 | newLoc = Tcl_Tell(chan); /* * TIP #219. * Capture error messages put by the driver into the bypass area and put * them into the regular interpreter result. */ code = TclChanCaughtErrorBypass(interp, chan); TclChannelRelease(chan); if (code) { return TCL_ERROR; } |
︙ | ︙ |
Changes to generic/tclIOGT.c.
︙ | ︙ | |||
59 60 61 62 63 64 65 | unsigned char *buf, int bufLen, int transmit, int preserve); /* * Action codes to give to 'ExecuteCallback' (argument 'transmit'), telling * the procedure what to do with the result of the script it calls. */ | | | | | | | > | | | > | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | unsigned char *buf, int bufLen, int transmit, int preserve); /* * Action codes to give to 'ExecuteCallback' (argument 'transmit'), telling * the procedure what to do with the result of the script it calls. */ enum ExecuteCallbackActionCodes { TRANSMIT_DONT = 0, /* No transfer to do. */ TRANSMIT_DOWN = 1, /* Transfer to the underlying channel. */ TRANSMIT_SELF = 2, /* Transfer into our channel. */ TRANSMIT_IBUF = 3, /* Transfer to internal input buffer. */ TRANSMIT_NUM = 4 /* Transfer number to 'maxRead'. */ }; /* * Codes for 'preserve' of 'ExecuteCallback'. */ enum ExecuteCallbackPreserveFlags { P_PRESERVE = 1, P_NO_PRESERVE = 0 }; /* * Strings for the action codes delivered to the script implementing a * transformation. Argument 'op' of 'ExecuteCallback'. */ #define A_CREATE_WRITE (UCHARP("create/write")) |
︙ | ︙ |
Changes to generic/tclIORChan.c.
︙ | ︙ | |||
109 110 111 112 113 114 115 | int mode; /* Mask of R/W mode */ int interest; /* Mask of events the channel is interested * in. */ int dead; /* Boolean signal that some operations * should no longer be attempted. */ | | < | | < | < | | < | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | int mode; /* Mask of R/W mode */ int interest; /* Mask of events the channel is interested * in. */ 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. */ /* * Note regarding the usage of timers. * * Most channel implementations need a timer in the C level to ensure that * data in buffers is flushed out through the generation of fake file * events. |
︙ | ︙ |
Changes to generic/tclIORTrans.c.
︙ | ︙ | |||
464 465 466 467 468 469 470 | static int TransformLimit(ReflectedTransform *rtPtr, int *errorCodePtr, int *maxPtr); /* * Operation codes for TransformFlush(). */ | > | | > | 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | static int TransformLimit(ReflectedTransform *rtPtr, int *errorCodePtr, int *maxPtr); /* * Operation codes for TransformFlush(). */ enum TransformFlushOpCodes { FLUSH_WRITE = 1, FLUSH_DISCARD = 0 }; /* * Main methods to plug into the 'chan' ensemble'. ================== */ /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1101 1102 1103 1104 1105 1106 1107 | goto stop; } if (rtPtr->eofPending) { goto stop; } | < | 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 | goto stop; } if (rtPtr->eofPending) { goto stop; } /* * The buffer is exhausted, but the caller wants even more. We now * have to go to the underlying channel, get more bytes and then * transform them for delivery. We may not get what we want (full EOF * or temporarily out of data). * * Length (rtPtr->result) == 0, toRead > 0 here. Use 'buf'! as target |
︙ | ︙ | |||
1136 1137 1138 1139 1140 1141 1142 | } } /* else: 'maxRead < 0' == Accept the current value of toRead */ } if (toRead <= 0) { goto stop; } | < | 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 | } } /* else: 'maxRead < 0' == Accept the current value of toRead */ } if (toRead <= 0) { goto stop; } readBytes = Tcl_ReadRaw(rtPtr->parent, (char *) Tcl_SetByteArrayLength(bufObj, toRead), toRead); if (readBytes < 0) { if (Tcl_InputBlocked(rtPtr->parent) && (gotBytes > 0)) { /* |
︙ | ︙ |
Changes to generic/tclIOUtil.c.
︙ | ︙ | |||
102 103 104 105 106 107 108 | * are the same for win/unix, and not in tclInt.h because they are and should * be used only here. */ MODULE_SCOPE const char *const tclpFileAttrStrings[]; MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[]; | < | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | * are the same for win/unix, and not in tclInt.h because they are and should * be used only here. */ MODULE_SCOPE const char *const tclpFileAttrStrings[]; MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[]; /* * These these functions are not static either because routines in the native * (win/unix) directories call them or they are actually implemented in those * directories. They should be called from outside Tcl's native filesystem * routines. If we ever built the native filesystem support into a separate * code library, this could actually be enforced. */ |
︙ | ︙ | |||
325 326 327 328 329 330 331 | } return ret; } /* Obsolete */ int Tcl_Access( | | | | 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | } return ret; } /* Obsolete */ int Tcl_Access( const char *path, /* Pathname of file to access (in current * CP). */ int mode) /* Permission setting. */ { int ret; Tcl_Obj *pathPtr = Tcl_NewStringObj(path,-1); Tcl_IncrRefCount(pathPtr); ret = Tcl_FSAccess(pathPtr,mode); |
︙ | ︙ | |||
1166 1167 1168 1169 1170 1171 1172 | /* * Deal with the root of the volume. */ len--; } len++; /* account for '/' in the mElt [Bug 1602539] */ | < | 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 | /* * Deal with the root of the volume. */ len--; } len++; /* account for '/' in the mElt [Bug 1602539] */ mElt = TclNewFSPathObj(pathPtr, mount + len, mlen - len); Tcl_ListObjAppendElement(NULL, resultPtr, mElt); } /* * Not comparing mounts to mounts, so no need to increment gLength */ |
︙ | ︙ | |||
2196 2197 2198 2199 2200 2201 2202 | * as "rw". */ int permissions) /* What modes to use if opening the file involves creating it. */ { const Tcl_Filesystem *fsPtr; Tcl_Channel retVal = NULL; | < | 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 | * as "rw". */ int permissions) /* What modes to use if opening the file involves creating it. */ { const Tcl_Filesystem *fsPtr; Tcl_Channel retVal = NULL; if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) { /* * Return the correct error message. */ return NULL; } |
︙ | ︙ | |||
3016 3017 3018 3019 3020 3021 3022 | * *---------------------------------------------------------------------- */ int Tcl_FSLoadFile( Tcl_Interp *interp, /* Used for error reporting. */ | | | | 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 | * *---------------------------------------------------------------------- */ int Tcl_FSLoadFile( Tcl_Interp *interp, /* Used for error reporting. */ 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. */ Tcl_LibraryInitProc **proc1Ptr, Tcl_LibraryInitProc **proc2Ptr, /* Places to store pointers to the functions * named by sym1 and sym2. */ Tcl_LoadHandle *handlePtr, /* A place to store the token for the loaded |
︙ | ︙ | |||
3111 3112 3113 3114 3115 3116 3117 | * * 2. If the environment variable TCL_TEMPLOAD_NO_UNLINK is present and * set to true (an integer > 0) * * 3. TCL_TEMPLOAD_NO_UNLINK is not true (an integer > 0) and AUFS filesystem can be detected (using statfs, if available). * */ | < | 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 | * * 2. If the environment variable TCL_TEMPLOAD_NO_UNLINK is present and * set to true (an integer > 0) * * 3. TCL_TEMPLOAD_NO_UNLINK is not true (an integer > 0) and AUFS filesystem can be detected (using statfs, if available). * */ #ifdef hpux (void)shlibFile; return 1; #else WCHAR *skipstr = getenv("TCL_TEMPLOAD_NO_UNLINK"); |
︙ | ︙ | |||
4451 4452 4453 4454 4455 4456 4457 | if (TclFSEnsureEpochOk(pathPtr, &retVal) != TCL_OK) { /* not a valid pathname */ Disclaim(); return NULL; } else if (retVal != NULL) { /* * Found the filesystem in the internal representation of pathPtr. | | | 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 | if (TclFSEnsureEpochOk(pathPtr, &retVal) != TCL_OK) { /* not a valid pathname */ Disclaim(); return NULL; } else if (retVal != NULL) { /* * Found the filesystem in the internal representation of pathPtr. */ Disclaim(); return retVal; } /* * Call each of the "pathInFilesystem" functions in succession until the * corresponding filesystem is found. |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
406 407 408 409 410 411 412 | * code unit that refers to the namespace has been freed (i.e., * when the namespace's refCount is 0), the namespace's storage * will be freed. * NS_SUPPRESS_COMPILATION - * Marks the commands in this namespace for not being compiled, * forcing them to be looked up every time. */ | | | | | | | > | | | | > | | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 | * code unit that refers to the namespace has been freed (i.e., * when the namespace's refCount is 0), the namespace's storage * will be freed. * NS_SUPPRESS_COMPILATION - * Marks the commands in this namespace for not being compiled, * forcing them to be looked up every time. */ enum NamespaceFlags { NS_DYING = 0x01, NS_DEAD = 0x02, NS_TEARDOWN = 0x04, NS_KILLED = 0x04, /* Same as NS_TEARDOWN (Deprecated) */ NS_SUPPRESS_COMPILATION = 0x08 }; /* * Flags passed to TclGetNamespaceForQualName: * * TCL_GLOBAL_ONLY - (see tcl.h) Look only in the global ns. * 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 ::). */ enum NamespaceQualNameFlags { TCL_CREATE_NS_IF_UNKNOWN = 0x800, TCL_FIND_ONLY_NS = 0x1000, TCL_FIND_IF_NOT_SIMPLE = 0x2000 }; /* * The client data for an ensemble command. This consists of the table of * commands that are actually exported by the namespace, and an epoch counter * that, combined with the exportLookupEpoch field of the namespace structure, * defines whether the table contains valid data or will need to be recomputed * next time the ensemble command is called. */ typedef struct EnsembleConfig { Namespace *nsPtr; /* The namespace backing this ensemble up. */ Tcl_Command token; /* The token for the command that provides * ensemble support for the namespace, or NULL * 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 * exported commands is valid. */ char **subcommandArrayPtr; /* Array of ensemble subcommand names. At all * consistent points, this will have the same * number of entries as there are entries in * the subcommandTable hash. */ Tcl_HashTable subcommandTable; /* Hash table of ensemble subcommand names, |
︙ | ︙ | |||
500 501 502 503 504 505 506 | * results passed directly back to the caller * (including the error code) unless the code * is TCL_CONTINUE in which case the * subcommand will be re-parsed by the ensemble * core, presumably because the ensemble * itself has been updated. */ Tcl_Obj *parameterList; /* List of ensemble parameter names. */ | | | | | > | | | 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 | * results passed directly back to the caller * (including the error code) unless the code * is TCL_CONTINUE in which case the * subcommand will be re-parsed by the ensemble * 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 * 0 (if the parameterList field is NULL) or * the length of the list in the parameterList * field. */ } EnsembleConfig; /* * Various bits for the EnsembleConfig.flags field. */ enum EnsembleConfigFlags { ENSEMBLE_DEAD = 0x1, /* Flag value to say that the ensemble is dead * and on its way out. */ ENSEMBLE_COMPILE = 0x4 /* Flag to enable bytecode compilation of an * ensemble. */ }; /* *---------------------------------------------------------------- * Data structures related to variables. These are used primarily in tclVar.c *---------------------------------------------------------------- */ /* * The following structure defines a variable trace, which is used to invoke a * specific C procedure whenever certain operations are performed on a * variable. */ 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. */ int flags; /* What events the trace procedure is * interested in: OR-ed combination of * TCL_TRACE_READS, TCL_TRACE_WRITES, * TCL_TRACE_UNSETS and TCL_TRACE_ARRAY. */ struct VarTrace *nextPtr; /* Next in list of traces associated with a * particular variable. */ } VarTrace; /* * The following structure defines a command trace, which is used to invoke a * specific C procedure whenever certain operations are performed on a * command. */ 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. */ int flags; /* What events the trace procedure is * interested in: OR-ed combination of * TCL_TRACE_RENAME, TCL_TRACE_DELETE. */ struct CommandTrace *nextPtr; /* Next in list of traces associated with a * particular command. */ Tcl_Size refCount; /* Used to ensure this structure is not |
︙ | ︙ | |||
725 726 727 728 729 730 731 | * * IMPORTANT: skip the values 0x10, 0x20, 0x40, 0x800 corresponding to * TCL_TRACE_(READS/WRITES/UNSETS/ARRAY): makes code simpler in tclTrace.c * * Keep the flag values for VAR_ARGUMENT and VAR_TEMPORARY so that old values * in precompiled scripts keep working. */ | | | | | | | | | | | | | | | | | | | | | | | | | | | > | 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 | * * IMPORTANT: skip the values 0x10, 0x20, 0x40, 0x800 corresponding to * TCL_TRACE_(READS/WRITES/UNSETS/ARRAY): makes code simpler in tclTrace.c * * Keep the flag values for VAR_ARGUMENT and VAR_TEMPORARY so that old values * in precompiled scripts keep working. */ enum TclVarFlags { /* Type of value (0 is scalar) */ VAR_ARRAY = 0x1, VAR_LINK = 0x2, VAR_CONSTANT = 0x10000, /* Type of storage (0 is compiled local) */ VAR_IN_HASHTABLE = 0x4, VAR_DEAD_HASH = 0x8, VAR_ARRAY_ELEMENT = 0x1000, VAR_NAMESPACE_VAR = 0x80, /* KEEP OLD VALUE for Itcl */ VAR_ALL_HASH = (VAR_IN_HASHTABLE|VAR_DEAD_HASH|VAR_NAMESPACE_VAR|VAR_ARRAY_ELEMENT), /* Trace and search state. */ VAR_TRACED_READ = 0x10, /* TCL_TRACE_READS */ VAR_TRACED_WRITE = 0x20, /* TCL_TRACE_WRITES */ VAR_TRACED_UNSET = 0x40, /* TCL_TRACE_UNSETS */ VAR_TRACED_ARRAY = 0x800, /* TCL_TRACE_ARRAY */ VAR_TRACE_ACTIVE = 0x2000, VAR_SEARCH_ACTIVE = 0x4000, VAR_ALL_TRACES = (VAR_TRACED_READ|VAR_TRACED_WRITE|VAR_TRACED_ARRAY|VAR_TRACED_UNSET), /* Special handling on initialisation (only CompiledLocal). */ VAR_ARGUMENT = 0x100, /* KEEP OLD VALUE! See tclProc.c */ VAR_TEMPORARY = 0x200, /* KEEP OLD VALUE! See tclProc.c */ VAR_IS_ARGS = 0x400, VAR_RESOLVED = 0x8000 }; /* * Macros to ensure that various flag bits are set properly for variables. * The ANSI C "prototypes" for these macros are: * * MODULE_SCOPE void TclSetVarScalar(Var *varPtr); * MODULE_SCOPE void TclSetVarArray(Var *varPtr); |
︙ | ︙ | |||
806 807 808 809 810 811 812 | (varPtr)->flags |= VAR_NAMESPACE_VAR;\ if (TclIsVarInHash(varPtr)) {\ ((VarInHash *)(varPtr))->refCount++;\ }\ } #define TclClearVarNamespaceVar(varPtr) \ | | | | | | | 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 | (varPtr)->flags |= VAR_NAMESPACE_VAR;\ if (TclIsVarInHash(varPtr)) {\ ((VarInHash *)(varPtr))->refCount++;\ }\ } #define TclClearVarNamespaceVar(varPtr) \ if (TclIsVarNamespaceVar(varPtr)) { \ (varPtr)->flags &= ~VAR_NAMESPACE_VAR; \ if (TclIsVarInHash(varPtr)) { \ ((VarInHash *)(varPtr))->refCount--; \ } \ } /* * Macros to read various flag bits of variables. * The ANSI C "prototypes" for these macros are: * * MODULE_SCOPE int TclIsVarScalar(Var *varPtr); |
︙ | ︙ | |||
969 970 971 972 973 974 975 | */ typedef struct CompiledLocal { struct CompiledLocal *nextPtr; /* Next compiler-recognized local variable for * this procedure, or NULL if this is the last * local. */ | | | | | 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 | */ typedef struct CompiledLocal { struct CompiledLocal *nextPtr; /* 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. * Among others used to speed up var lookups. */ Tcl_Size frameIndex; /* Index in the array of compiler-assigned * variables in the procedure call frame. */ #if TCL_MAJOR_VERSION < 9 int flags; #endif Tcl_Obj *defValuePtr; /* Pointer to the default value of an * argument, if any. NULL if not an argument * or, if an argument, no default value. */ Tcl_ResolvedVarInfo *resolveInfo; /* Customized variable resolution info * supplied by the Tcl_ResolveCompiledVarProc * associated with a namespace. Each variable * is marked by a unique tag during * compilation, and that same tag is used to * find the variable at runtime. */ #if TCL_MAJOR_VERSION > 8 int flags; /* Flag bits for the local variable. Same as * the flags for the Var structure above, * although only VAR_ARGUMENT, VAR_TEMPORARY, * and VAR_RESOLVED make sense. */ #endif 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 * FIELD IN THE STRUCTURE! */ } CompiledLocal; /* |
︙ | ︙ | |||
1093 1094 1095 1096 1097 1098 1099 | * TCL_TRACE_ENTER_EXEC - triggers enter/enterstep traces. * - passed to Tcl_CreateObjTrace to set up * "enterstep" traces. * TCL_TRACE_LEAVE_EXEC - triggers leave/leavestep traces. * - passed to Tcl_CreateObjTrace to set up * "leavestep" traces. */ | | | | > < | > > > > > > > > | > > | > < | | 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 | * TCL_TRACE_ENTER_EXEC - triggers enter/enterstep traces. * - passed to Tcl_CreateObjTrace to set up * "enterstep" traces. * TCL_TRACE_LEAVE_EXEC - triggers leave/leavestep traces. * - passed to Tcl_CreateObjTrace to set up * "leavestep" traces. */ enum TclExecTraceTypeFlags { TCL_TRACE_ENTER_EXEC = 1, TCL_TRACE_LEAVE_EXEC = 2 }; #if TCL_MAJOR_VERSION > 8 #define TclObjTypeHasProc(objPtr, proc) (((objPtr)->typePtr \ && ((offsetof(Tcl_ObjType, proc) < offsetof(Tcl_ObjType, version)) \ || (offsetof(Tcl_ObjType, proc) < (objPtr)->typePtr->version))) ? \ ((objPtr)->typePtr)->proc : NULL) MODULE_SCOPE Tcl_Size TclLengthOne(Tcl_Obj *); /* * Abstract List * * This structure provides the functions used in List operations to emulate a * List for AbstractList types. */ static inline Tcl_Size TclObjTypeLength( Tcl_Obj *objPtr) { Tcl_ObjTypeLengthProc *proc = TclObjTypeHasProc(objPtr, lengthProc); return proc(objPtr); } static inline int TclObjTypeIndex( Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Size index, Tcl_Obj **elemObjPtr) { Tcl_ObjTypeIndexProc *proc = TclObjTypeHasProc(objPtr, indexProc); return proc(interp, objPtr, index, elemObjPtr); } static inline int TclObjTypeSlice( Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Size fromIdx, Tcl_Size toIdx, Tcl_Obj **newObjPtr) { Tcl_ObjTypeSliceProc *proc = TclObjTypeHasProc(objPtr, sliceProc); return proc(interp, objPtr, fromIdx, toIdx, newObjPtr); } static inline int TclObjTypeReverse( Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj **newObjPtr) { Tcl_ObjTypeReverseProc *proc = TclObjTypeHasProc(objPtr, reverseProc); return proc(interp, objPtr, newObjPtr); } static inline int TclObjTypeGetElements( Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Size *objCPtr, Tcl_Obj ***objVPtr) { Tcl_ObjTypeGetElements *proc = TclObjTypeHasProc(objPtr, getElementsProc); return proc(interp, objPtr, objCPtr, objVPtr); } static inline Tcl_Obj* TclObjTypeSetElement( Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Size indexCount, Tcl_Obj *const indexArray[], Tcl_Obj *valueObj) { Tcl_ObjTypeSetElement *proc = TclObjTypeHasProc(objPtr, setElementProc); return proc(interp, objPtr, indexCount, indexArray, valueObj); } static inline int TclObjTypeReplace( Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Size first, Tcl_Size numToDelete, Tcl_Size numToInsert, Tcl_Obj *const insertObjs[]) { Tcl_ObjTypeReplaceProc *proc = TclObjTypeHasProc(objPtr, replaceProc); return proc(interp, objPtr, first, numToDelete, numToInsert, insertObjs); } static inline int TclObjTypeInOperator( Tcl_Interp *interp, Tcl_Obj *valueObj, Tcl_Obj *listObj, int *boolResult) { Tcl_ObjTypeInOperatorProc *proc = TclObjTypeHasProc(listObj, inOperProc); return proc(interp, valueObj, listObj, boolResult); } #endif /* TCL_MAJOR_VERSION > 8 */ /* * The structure below defines an entry in the assocData hash table which is * associated with an interpreter. The entry contains a pointer to a function * to call when the interpreter is deleted, and a pointer to a user-defined * piece of data. */ typedef struct AssocData { Tcl_InterpDeleteProc *proc; /* Proc to call when deleting. */ void *clientData; /* Value to pass to proc. */ } AssocData; /* * The structure below defines a call frame. A call frame defines a naming * context for a procedure call: its local naming scope (for local variables) * and its global naming scope (a namespace, perhaps the global :: namespace). * A call frame can also define the naming context for a namespace eval or |
︙ | ︙ | |||
1246 1247 1248 1249 1250 1251 1252 | int isProcCallFrame; /* If 0, the frame was pushed to execute a * namespace command and var references are * treated as references to namespace vars; * varTablePtr and compiledLocals are ignored. * If FRAME_IS_PROC is set, the frame was * pushed to execute a Tcl procedure and may * have local vars. */ | | | | 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 | int isProcCallFrame; /* If 0, the frame was pushed to execute a * namespace command and var references are * treated as references to namespace vars; * varTablePtr and compiledLocals are ignored. * 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 * for this procedure call. */ Tcl_Obj *const *objv; /* Array of argument objects. */ 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; /* Value of interp->varFramePtr when this * procedure was invoked (i.e. determines * variable scoping within caller). Same as * callerPtr unless an "uplevel" command or * something equivalent was active in the * caller). */ 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. */ Proc *procPtr; /* Points to the structure defining the called * procedure. Used to get information such as * the number of compiled local variables * (local variables assigned entries ["slots"] |
︙ | ︙ | |||
1290 1291 1292 1293 1294 1295 1296 | * sets it, and it should only ever be set by * the code that is pushing the frame. In that * case, the code that sets it should also * have some means of discovering what the * meaning of the value is, which we do not * specify. */ LocalCache *localCachePtr; | < | > | | | | | > | 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 | * sets it, and it should only ever be set by * the code that is pushing the frame. In that * case, the code that sets it should also * 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 */ } CallFrame; enum CallFrameFlags { FRAME_IS_PROC = 0x1, FRAME_IS_LAMBDA = 0x2, FRAME_IS_METHOD = 0x4, /* The frame is a method body, and the frame's * clientData field contains a CallContext * reference. Part of TIP#257. */ FRAME_IS_OO_DEFINE = 0x8, /* The frame is part of the inside workings of * the [oo::define] command; the clientData * field contains an Object reference that has * been confirmed to refer to a class. Part of * TIP#257. */ FRAME_IS_PRIVATE_DEFINE = 0x10 /* Marks this frame as being used for private * declarations with [oo::define]. Usually * OR'd with FRAME_IS_OO_DEFINE. TIP#500. */ }; /* * TIP #280 * The structure below defines a command frame. A command frame provides * location information for all commands executing a tcl script (source, eval, * uplevel, procedure bodies, ...). The runtime structure essentially contains * the stack trace as it would be if the currently executing command were to |
︙ | ︙ | |||
1380 1381 1382 1383 1384 1385 1386 | struct { const void *codePtr;/* Byte code currently executed... */ const char *pc; /* ... and instruction pointer. */ } tebc; } data; Tcl_Obj *cmdObj; const char *cmd; /* The executed command, if possible... */ | | | | | | 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 | struct { const void *codePtr;/* Byte code currently executed... */ const char *pc; /* ... and instruction pointer. */ } tebc; } data; Tcl_Obj *cmdObj; const char *cmd; /* The executed command, if possible... */ 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 * TclArgumentBCEnter(). These will be removed * by TclArgumentBCRelease. */ } CmdFrame; typedef struct CFWord { CmdFrame *framePtr; /* CmdFrame to access. */ 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 * ExtCmdLoc.loc[.] */ 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 * CmdFrame litarg field for the list start. */ Tcl_Obj *obj; /* Back reference to hash table key */ } CFWordBC; |
︙ | ︙ | |||
1428 1429 1430 1431 1432 1433 1434 | * released by the function TclFreeObj(), in the file "tclObj.c", and also by * the function TclThreadFinalizeObjects(), in the same file. */ #define CLL_END (-1) typedef struct ContLineLoc { | | | 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 | * released by the function TclFreeObj(), in the file "tclObj.c", and also by * the function TclThreadFinalizeObjects(), in the same file. */ #define CLL_END (-1) typedef struct ContLineLoc { 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 * structure, extending behind the nominal end * of the structure. An entry containing the * value -1 is put after the last location, as * end-marker/sentinel. */ |
︙ | ︙ | |||
1454 1455 1456 1457 1458 1459 1460 | * sourced file. * TCL_LOCATION_PROC : Frame is for bytecode of a procedure. * * A TCL_LOCATION_BC type in a frame can be overridden by _SOURCE and _PROC * types, per the context of the byte code in execution. */ | > | | | | | | | > > | | > | | 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 | * sourced file. * TCL_LOCATION_PROC : Frame is for bytecode of a procedure. * * A TCL_LOCATION_BC type in a frame can be overridden by _SOURCE and _PROC * types, per the context of the byte code in execution. */ enum TclCodeLocationTypes { TCL_LOCATION_EVAL = 0, /* Location in a dynamic eval script. */ TCL_LOCATION_BC = 2, /* Location in byte code. */ TCL_LOCATION_PREBC = 3, /* Location in precompiled byte code, no * location. */ TCL_LOCATION_SOURCE = 4, /* Location in a file. */ TCL_LOCATION_PROC = 5, /* Location in a dynamic proc. */ TCL_LOCATION_LAST = 6 /* Number of values in the enum. */ }; /* * Structure passed to describe procedure-like "procedures" that are not * procedures (e.g. a lambda) so that their details can be reported correctly * by [info frame]. Contains a sub-structure for each extra field. */ 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 * clientData, or just use the clientData * directly (after casting) if NULL. */ void *clientData; /* Context for above function, or Tcl_Obj* if * proc field is NULL. */ } ExtraFrameInfoField; typedef struct { Tcl_Size length; /* Length of array. */ ExtraFrameInfoField fields[2]; /* Really as long as necessary, but this is * long enough for nearly anything. */ } ExtraFrameInfo; /* *---------------------------------------------------------------- |
︙ | ︙ | |||
1587 1588 1589 1590 1591 1592 1593 | * There is one ExecEnv structure per Tcl interpreter. It holds the evaluation * stack that holds command operands and results. The stack grows towards * increasing addresses. The member stackPtr points to the stackItems of the * currently active execution stack. */ typedef struct CorContext { | | | | | | | | | < | | | 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 | * There is one ExecEnv structure per Tcl interpreter. It holds the evaluation * stack that holds command operands and results. The stack grows towards * increasing addresses. The member stackPtr points to the stackItems of the * currently active execution stack. */ typedef struct CorContext { CallFrame *framePtr; CallFrame *varFramePtr; 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, * etc.) for the coroutine. */ struct ExecEnv *callerEEPtr;/* The execution environment for the caller of * 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 * 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_Obj *yieldPtr; /* The command to yield to. Stored here in * order to reset splice point in * TclNRCoroutineActivateCallback if the * 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. */ Tcl_Interp *interp; struct NRE_callback *callbackPtr; /* Top callback in NRE's stack. */ CoroutineData *corPtr; int rewind; } ExecEnv; #define COR_IS_SUSPENDED(corPtr) \ ((corPtr)->stackLevel == NULL) /* |
︙ | ︙ | |||
1673 1674 1675 1676 1677 1678 1679 | typedef struct LiteralTable { LiteralEntry **buckets; /* Pointer to bucket array. Each element * points to first entry in bucket's hash * chain, or NULL. */ LiteralEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; /* Bucket array used for small tables to avoid * mallocs and frees. */ | | | | | 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 | typedef struct LiteralTable { LiteralEntry **buckets; /* Pointer to bucket array. Each element * points to first entry in bucket's hash * chain, or NULL. */ 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 * **buckets. */ TCL_HASH_TYPE numEntries; /* Total number of entries present in * table. */ TCL_HASH_TYPE rebuildSize; /* Enlarge table when numEntries gets to be * this large. */ TCL_HASH_TYPE mask; /* Mask value used in hashing function. */ } LiteralTable; /* * The following structure defines for each Tcl interpreter various * statistics-related information about the bytecode compiler and |
︙ | ︙ | |||
1731 1732 1733 1734 1735 1736 1737 | */ typedef struct { const char *name; /* The name of the subcommand. */ Tcl_ObjCmdProc *proc; /* The implementation of the subcommand. */ CompileProc *compileProc; /* The compiler for the subcommand. */ Tcl_ObjCmdProc *nreProc; /* NRE implementation of this command. */ | | | 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 | */ typedef struct { const char *name; /* The name of the subcommand. */ 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. */ int unsafe; /* Whether this command is to be hidden by * default in a safe interpreter. */ } EnsembleImplMap; /* *---------------------------------------------------------------- * Data structures related to commands. |
︙ | ︙ | |||
1810 1811 1812 1813 1814 1815 1816 | * that point to this command when it is * renamed, deleted, hidden, or exposed. */ CompileProc *compileProc; /* Procedure called to compile command. NULL * if no compile proc exists for command. */ Tcl_ObjCmdProc *objProc; /* Object-based command procedure. */ void *objClientData; /* Arbitrary value passed to object proc. */ Tcl_CmdProc *proc; /* String-based command procedure. */ | | | | > | | | | | | > | < | | | > | | | < < < < < < < < < < < | | | | | 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 | * that point to this command when it is * renamed, deleted, hidden, or exposed. */ CompileProc *compileProc; /* Procedure called to compile command. NULL * if no compile proc exists for 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. */ Tcl_CmdDeleteProc *deleteProc; /* Procedure invoked when deleting command to, * e.g., free all client data. */ 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 * another namespace when this command is * imported. These imported commands redirect * invocations back to this command. The list * is used to remove all those imported * commands when deleting this "real" * command. */ CommandTrace *tracePtr; /* First in list of all traces set for this * command. */ Tcl_ObjCmdProc *nreProc; /* NRE implementation of this command. */ } Command; /* * Flag bits for commands. */ enum CommandFlags { CMD_DYING = 0x01, /* The command is in the process of being * deleted (its deleteProc is currently * executing). Other attempts to delete the * command should be ignored. */ CMD_TRACE_ACTIVE = 0x02, /* Trace processing is currently underway for * a rename/delete change. See other flags * (TCL_TRACE_RENAME and TCL_TRACE_DELETE) * for which is currently being processed. */ CMD_HAS_EXEC_TRACES = 0x04, /* This command has at least one execution * trace (as opposed to simple delete/rename * traces) in its tracePtr list.*/ CMD_COMPILES_EXPANDED = 0x08, /* This command has a compiler that can handle * expansion (provided it is not the * first word).*/ CMD_REDEF_IN_PROGRESS = 0x10, CMD_VIA_RESOLVER = 0x20, CMD_DEAD = 0x40 }; /* *---------------------------------------------------------------- * Data structures related to name resolution procedures. *---------------------------------------------------------------- */ |
︙ | ︙ | |||
1971 1972 1973 1974 1975 1976 1977 | * interp is deleted. */ Namespace *globalNsPtr; /* The interpreter's global namespace. */ Tcl_HashTable *hiddenCmdTablePtr; /* Hash table used by tclBasic.c to keep track * of hidden commands on a per-interp * basis. */ | | | 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 | * interp is deleted. */ Namespace *globalNsPtr; /* The interpreter's global namespace. */ Tcl_HashTable *hiddenCmdTablePtr; /* 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 * track of parent/child interps on a * per-interp basis. */ #if TCL_MAJOR_VERSION > 8 void (*optimizer)(void *envPtr); #else union { void (*optimizer)(void *envPtr); |
︙ | ︙ | |||
2050 2051 2052 2053 2054 2055 2056 | int unused1; /* No longer used (was termOffset) */ #endif LiteralTable literalTable; /* Contains LiteralEntry's describing all Tcl * objects holding literals of scripts * compiled by the interpreter. Indexed by the * string representations of literals. Used to * avoid creating duplicate objects. */ | | | 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 | int unused1; /* No longer used (was termOffset) */ #endif LiteralTable literalTable; /* Contains LiteralEntry's describing all Tcl * objects holding literals of scripts * compiled by the interpreter. Indexed by the * string representations of literals. Used to * avoid creating duplicate objects. */ Tcl_Size compileEpoch; /* Holds the current "compilation epoch" for * this interpreter. This is incremented to * invalidate existing ByteCodes when, e.g., a * command with a compile procedure is * redefined. */ Proc *compiledProcPtr; /* If a procedure is being compiled, a pointer * to its Proc structure; otherwise, this is * NULL. Set by ObjInterpProc in tclProc.c and |
︙ | ︙ | |||
2097 2098 2099 2100 2101 2102 2103 | ActiveCommandTrace *activeCmdTracePtr; /* First in list of active command traces for * interp, or NULL if no active traces. */ ActiveInterpTrace *activeInterpTracePtr; /* First in list of active traces for interp, * or NULL if no active traces. */ | | > | 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 | ActiveCommandTrace *activeCmdTracePtr; /* First in list of active command traces for * interp, or NULL if no active traces. */ 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 * compilation. */ /* * Fields used to manage extensible return options (TIP 90). */ |
︙ | ︙ | |||
2126 2127 2128 2129 2130 2131 2132 | int active; /* Flag values defining which limits have been * set. */ int granularityTicker; /* Counter used to determine how often to * check the limits. */ int exceeded; /* Which limits have been exceeded, described * as flag values the same as the 'active' * field. */ | < | < | 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 | int active; /* Flag values defining which limits have been * set. */ int granularityTicker; /* Counter used to determine how often to * check the limits. */ int exceeded; /* Which limits have been exceeded, described * as flag values the same as the 'active' * field. */ Tcl_Size cmdCount; /* Limit for how many commands to execute in * the interpreter. */ LimitHandler *cmdHandlers; /* Handlers to execute when the limit is * reached. */ int cmdGranularity; /* Mod factor used to determine how often to * evaluate the limit check. */ Tcl_Time time; /* Time limit for execution within the * interpreter. */ LimitHandler *timeHandlers; /* Handlers to execute when the limit is * reached. */ int timeGranularity; /* Mod factor used to determine how often to * evaluate the limit check. */ |
︙ | ︙ | |||
2163 2164 2165 2166 2167 2168 2169 | struct { Tcl_Obj *const *sourceObjs; /* What arguments were actually input into the * *root* ensemble command? (Nested ensembles * don't rewrite this.) NULL if we're not * processing an ensemble. */ | | | > | 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 | struct { Tcl_Obj *const *sourceObjs; /* What arguments were actually input into the * *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 * because of ensemble processing. */ Tcl_Size numInsertedObjs; /* How many of the current arguments were * inserted by an ensemble. */ } ensembleRewrite; /* * TIP #219: Global info for the I/O system. */ |
︙ | ︙ | |||
2225 2226 2227 2228 2229 2230 2231 | ContLineLoc *scriptCLLocPtr;/* This table points to the location data for * invisible continuation lines in the script, * if any. This pointer is set by the function * TclEvalObjEx() in file "tclBasic.c", and * used by function ...() in the same file. * It does for the eval/direct path of script * execution what CompileEnv.clLoc does for | | < | 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 | ContLineLoc *scriptCLLocPtr;/* This table points to the location data for * invisible continuation lines in the script, * if any. This pointer is set by the function * TclEvalObjEx() in file "tclBasic.c", and * 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. */ /* * TIP #268. The currently active selection mode, i.e. the package require * preferences. */ int packagePrefer; /* Current package selection mode. */ |
︙ | ︙ | |||
2290 2291 2292 2293 2294 2295 2296 | Tcl_Obj *asyncCancelMsg; /* Error message set by async cancel handler * for the propagation of arbitrary Tcl * errors. This information, if present * (asyncCancelMsg not NULL), takes precedence * over the default error messages returned by * a script cancellation operation. */ | | | | > | 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 | Tcl_Obj *asyncCancelMsg; /* Error message set by async cancel handler * for the propagation of arbitrary Tcl * errors. This information, if present * (asyncCancelMsg not NULL), takes precedence * over the default error messages returned by * a script cancellation operation. */ /* * 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 */ |
︙ | ︙ | |||
2363 2364 2365 2366 2367 2368 2369 | } \ if ((a)->nextPtr != NULL) { \ (a)->nextPtr->prevPtr = (a)->prevPtr; \ } /* * EvalFlag bits for Interp structures: | | > > | | > | < < < < | | | > | 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 | } \ if ((a)->nextPtr != NULL) { \ (a)->nextPtr->prevPtr = (a)->prevPtr; \ } /* * EvalFlag bits for Interp structures: */ enum EvalFlags { TCL_EVAL_FILE = 0x2, TCL_ALLOW_EXCEPTIONS = 0x4, /* It's OK for the script to terminate with a * code other than TCL_OK or TCL_ERROR; if * unset, it means codes other than these * should be turned into errors. */ TCL_EVAL_SOURCE_IN_FRAME = 0x10, TCL_EVAL_NORESOLVE = 0x20, TCL_EVAL_DISCARD_RESULT = 0x40 }; /* * Flag bits for Interp structures: * * DELETED: Non-zero means the interpreter has been deleted: * don't process any more commands for it, and destroy * the structure as soon as all nested invocations of |
︙ | ︙ | |||
2421 2422 2423 2424 2425 2426 2427 | * the evaluation stack for the interp to be fully * unwound. * * WARNING: For the sake of some extensions that have made use of former * internal values, do not re-use the flag values 2 (formerly ERR_IN_PROGRESS) * or 8 (formerly ERROR_CODE_SET). */ | | | | | | | | | | | | > | 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 | * the evaluation stack for the interp to be fully * unwound. * * WARNING: For the sake of some extensions that have made use of former * internal values, do not re-use the flag values 2 (formerly ERR_IN_PROGRESS) * or 8 (formerly ERROR_CODE_SET). */ enum InterpFlags { DELETED = 1, ERR_ALREADY_LOGGED = 4, INTERP_DEBUG_FRAME = 0x10, DONT_COMPILE_CMDS_INLINE = 0x20, RAND_SEED_INITIALIZED = 0x40, SAFE_INTERP = 0x80, INTERP_TRACE_IN_PROGRESS = 0x200, INTERP_ALTERNATE_WRONG_ARGS = 0x400, ERR_LEGACY_COPY = 0x800, CANCELED = 0x1000 }; /* * Maximum number of levels of nesting permitted in Tcl commands (used to * catch infinite recursion). */ #define MAX_NESTING_DEPTH 1000 |
︙ | ︙ | |||
2533 2534 2535 2536 2537 2538 2539 | * an effect if invoking an exposed command, * i.e. if TCL_INVOKE_HIDDEN is not also set. * TCL_INVOKE_NO_TRACEBACK Does not record traceback information if the * invoked command returns an error. Used if the * caller plans on recording its own traceback * information. */ | | | | | > | 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 | * an effect if invoking an exposed command, * i.e. if TCL_INVOKE_HIDDEN is not also set. * TCL_INVOKE_NO_TRACEBACK Does not record traceback information if the * invoked command returns an error. Used if the * caller plans on recording its own traceback * information. */ enum TclInvokeFlags { TCL_INVOKE_HIDDEN = (1<<0), TCL_INVOKE_NO_UNKNOWN = (1<<1), TCL_INVOKE_NO_TRACEBACK = (1<<2) }; /* * ListStore -- * * A Tcl list's internal representation is defined through three structures. * * A ListStore struct is a structure that includes a variable size array that |
︙ | ︙ | |||
2564 2565 2566 2567 2568 2569 2570 | * define the content of the list. The ListSpan specifies the range of slots * within the ListStore that hold elements for this list. The ListSpan is * optional in which case the list includes all the "in-use" slots of the * ListStore. * */ typedef struct ListStore { | | | | | | | > | | | > | > | | | > | > | | > | | | 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 | * define the content of the list. The ListSpan specifies the range of slots * within the ListStore that hold elements for this list. The ListSpan is * optional in which case the list includes all the "in-use" slots of the * ListStore. * */ 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 */ } ListStore; enum ListStoreFlags { 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 \ ((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 *)))) /* * 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 */ } ListSpan; #ifndef LIST_SPAN_THRESHOLD /* May be set on build line */ #define LIST_SPAN_THRESHOLD 101 #endif /* * ListRep -- * 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. */ } ListRep; /* * Macros used to get access list internal representations. * * Naming conventions: * ListRep* - expect a pointer to a valid ListRep * ListObj* - expect a pointer to a Tcl_Obj whose internal type is known to * be a list (tclListType). Will crash otherwise. * TclListObj* - expect a pointer to a Tcl_Obj whose internal type may or may not * be tclListType. These will convert as needed and return error if * conversion not possible. */ /* Returns the starting slot for this listRep in the contained ListStore */ #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) /* Returns a pointer to the first slot containing this ListRep elements */ #define ListRepElementsBase(listRepPtr_) \ (&(listRepPtr_)->storePtr->slots[ListRepStart(listRepPtr_)]) |
︙ | ︙ | |||
2650 2651 2652 2653 2654 2655 2656 | ((ListStore *)((listObj_)->internalRep.twoPtrValue.ptr1)) /* Returns a pointer to the ListSpan component */ #define ListObjSpanPtr(listObj_) \ ((ListSpan *)((listObj_)->internalRep.twoPtrValue.ptr2)) /* Returns the ListRep internal representaton in a Tcl_Obj */ | | | | < | > | | | | | | | | | | | | > | | | | | | | | | | | 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 | ((ListStore *)((listObj_)->internalRep.twoPtrValue.ptr1)) /* Returns a pointer to the ListSpan component */ #define ListObjSpanPtr(listObj_) \ ((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_); \ } while (0) /* Returns the length of the list */ #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) /* 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) /* * Certain commands like concat are optimized if an existing string * representation of a list object is known to be in canonical format (i.e. * generated from the list representation). There are three conditions when * this will be the case: * (1) No string representation exists which means it will obviously have * to be generated from the list representation when needed * (2) The ListStore flags is marked canonical. This is done at the time * the string representation is generated from the list under certain * conditions (see comments in UpdateStringOfList). * (3) The list representation does not have a span component. This is * because list Tcl_Obj's with spans are always created from existing lists * and never from strings (see SetListFromAny) and thus their string * representation will always be canonical. */ #define ListObjIsCanonical(listObj_) \ (((listObj_)->bytes == NULL) \ || (ListObjStorePtr(listObj_)->flags & LISTSTORE_CANONICAL) \ || ListObjSpanPtr(listObj_) != NULL) /* * Converts the Tcl_Obj to a list if it isn't one and stores the element * count and base address of this list's elements in objcPtr_ and objvPtr_. * Return TCL_OK on success or TCL_ERROR if the Tcl_Obj cannot be * converted to a list. */ #define TclListObjGetElements(interp_, listObj_, objcPtr_, objvPtr_) \ ((TclHasInternalRep((listObj_), &tclListType)) \ ? ((ListObjGetElements((listObj_), *(objcPtr_), *(objvPtr_))), \ TCL_OK) \ : Tcl_ListObjGetElements( \ (interp_), (listObj_), (objcPtr_), (objvPtr_))) /* * Converts the Tcl_Obj to a list if it isn't one and stores the element * count in lenPtr_. Returns TCL_OK on success or TCL_ERROR if the * Tcl_Obj cannot be converted to a list. */ #define TclListObjLength(interp_, listObj_, lenPtr_) \ ((TclHasInternalRep((listObj_), &tclListType)) \ ? ((ListObjLength((listObj_), *(lenPtr_))), TCL_OK) \ : Tcl_ListObjLength((interp_), (listObj_), (lenPtr_))) #define TclListObjIsCanonical(listObj_) \ ((TclHasInternalRep((listObj_), &tclListType)) ? ListObjIsCanonical((listObj_)) : 0) /* * Modes for collecting (or not) in the implementations of TclNRForeachCmd, * TclNRLmapCmd and their compilations. */ enum TclForeachModes { TCL_EACH_KEEP_NONE = 0, /* Discard iteration result like [foreach] */ TCL_EACH_COLLECT = 1 /* Collect iteration result like [lmap] */ }; /* * Macros providing a faster path to booleans and integers: * Tcl_GetBooleanFromObj, Tcl_GetLongFromObj, Tcl_GetIntFromObj * and Tcl_GetIntForIndex. * * WARNING: these macros eval their args more than once. */ #if TCL_MAJOR_VERSION > 8 #define TclGetBooleanFromObj(interp, objPtr, intPtr) \ ((TclHasInternalRep((objPtr), &tclIntType) \ || TclHasInternalRep((objPtr), &tclBooleanType)) \ ? (*(intPtr) = ((objPtr)->internalRep.wideValue!=0), TCL_OK) \ : Tcl_GetBooleanFromObj((interp), (objPtr), (intPtr))) #else #define TclGetBooleanFromObj(interp, objPtr, intPtr) \ ((TclHasInternalRep((objPtr), &tclIntType)) \ ? (*(intPtr) = ((objPtr)->internalRep.wideValue!=0), TCL_OK) \ : (TclHasInternalRep((objPtr), &tclBooleanType)) \ ? (*(intPtr) = ((objPtr)->internalRep.longValue!=0), TCL_OK) \ : Tcl_GetBooleanFromObj((interp), (objPtr), (intPtr))) #endif #ifdef TCL_WIDE_INT_IS_LONG #define TclGetLongFromObj(interp, objPtr, longPtr) \ ((TclHasInternalRep((objPtr), &tclIntType)) \ ? ((*(longPtr) = (objPtr)->internalRep.wideValue), TCL_OK) \ : Tcl_GetLongFromObj((interp), (objPtr), (longPtr))) #else #define TclGetLongFromObj(interp, objPtr, longPtr) \ ((TclHasInternalRep((objPtr), &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))) #endif #define TclGetIntFromObj(interp, objPtr, intPtr) \ ((TclHasInternalRep((objPtr), &tclIntType) \ && (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(INT_MIN) \ && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(INT_MAX)) \ ? ((*(intPtr) = (int)(objPtr)->internalRep.wideValue), TCL_OK) \ : Tcl_GetIntFromObj((interp), (objPtr), (intPtr))) #define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \ (((TclHasInternalRep((objPtr), &tclIntType)) && ((objPtr)->internalRep.wideValue >= 0) \ && ((objPtr)->internalRep.wideValue <= endValue)) \ ? ((*(idxPtr) = (objPtr)->internalRep.wideValue), TCL_OK) \ : Tcl_GetIntForIndex((interp), (objPtr), (endValue), (idxPtr))) /* * Macro used to save a function call for common uses of * Tcl_GetWideIntFromObj(). The ANSI C "prototype" is: * * MODULE_SCOPE int TclGetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, * Tcl_WideInt *wideIntPtr); */ #define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \ ((TclHasInternalRep((objPtr), &tclIntType)) \ ? (*(wideIntPtr) = \ ((objPtr)->internalRep.wideValue), TCL_OK) : \ Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr))) /* * Flag values for TclTraceDictPath(). * |
︙ | ︙ | |||
2814 2815 2816 2817 2818 2819 2820 | * lookup failure should therefore not be an error. If (and only if) this flag * is set, TclTraceDictPath() will return the special value * DICT_PATH_NON_EXISTENT if the path is not traceable. * * DICT_PATH_CREATE (which also requires the DICT_PATH_UPDATE bit to be set) * indicates that we are to create non-existent dictionaries on the path. */ | | | | | | > | 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 | * lookup failure should therefore not be an error. If (and only if) this flag * is set, TclTraceDictPath() will return the special value * DICT_PATH_NON_EXISTENT if the path is not traceable. * * DICT_PATH_CREATE (which also requires the DICT_PATH_UPDATE bit to be set) * indicates that we are to create non-existent dictionaries on the path. */ enum TclDictPathFlags { DICT_PATH_READ = 0, DICT_PATH_UPDATE = 1, DICT_PATH_EXISTS = 2, DICT_PATH_CREATE = 5 }; #define DICT_PATH_NON_EXISTENT ((Tcl_Obj *) (void *) 1) /* *---------------------------------------------------------------- * Data structures related to the filesystem internals *---------------------------------------------------------------- |
︙ | ︙ | |||
2908 2909 2910 2911 2912 2913 2914 | * to be shared among several threads. Each thread sees a (Tcl_Obj) copy of * the value, and the gobal value is kept as a counted string, with epoch and * mutex control. Each ProcessGlobalValue struct should be a static variable in * some file. */ typedef struct ProcessGlobalValue { | | | < | < | | < | | | < | | | > | > > | | | | > > | | | | | < | > | > > > > | > | | | | | | | | > | > > > | > > | > | > > > > > | > > > | > > > > > > | > > > > > < | | | | | | 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 | * to be shared among several threads. Each thread sees a (Tcl_Obj) copy of * the value, and the gobal value is kept as a counted string, with epoch and * mutex control. Each ProcessGlobalValue struct should be a static variable in * some file. */ typedef struct ProcessGlobalValue { 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 * copy when a "get" request comes in before * any "set" request has been received. */ Tcl_Mutex mutex; /* Enforce orderly access from multiple * threads. */ Tcl_ThreadDataKey key; /* Key for per-thread data holding the * (Tcl_Obj) copy for each thread. */ } ProcessGlobalValue; /* *---------------------------------------------------------------------- * Flags for TclParseNumber *---------------------------------------------------------------------- */ enum TclParseNumberFlags { TCL_PARSE_DECIMAL_ONLY = 1, /* Leading zero doesn't denote octal or * hex. */ TCL_PARSE_OCTAL_ONLY = 2, /* Parse octal even without prefix. */ TCL_PARSE_HEXADECIMAL_ONLY = 4, /* Parse hexadecimal even without prefix. */ TCL_PARSE_INTEGER_ONLY = 8, /* Disable floating point parsing. */ TCL_PARSE_SCAN_PREFIXES = 16, /* Use [scan] rules dealing with 0? * prefixes. */ TCL_PARSE_NO_WHITESPACE = 32, /* Reject leading/trailing whitespace. */ TCL_PARSE_BINARY_ONLY = 64, /* Parse binary even without prefix. */ TCL_PARSE_NO_UNDERSCORE = 128 /* Reject underscore digit separator */ }; /* *---------------------------------------------------------------------- * Internal convenience macros for manipulating encoding flags. See * TCL_ENCODING_PROFILE_* in tcl.h *---------------------------------------------------------------------- */ #define ENCODING_PROFILE_MASK 0xFF000000 #define ENCODING_PROFILE_GET(flags_) \ ((flags_) & ENCODING_PROFILE_MASK) #define ENCODING_PROFILE_SET(flags_, profile_) \ do { \ (flags_) &= ~ENCODING_PROFILE_MASK; \ (flags_) |= ((profile_) & ENCODING_PROFILE_MASK); \ } while (0) /* *---------------------------------------------------------------------- * 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 * 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. * *---------------------------------------------------------------------- */ 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) { /* assert (oldCapacity < needed <= limit) */ if (needed < (limit - needed/2)) { return needed + needed / 2; } else { return limit; } } 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; } else { 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); /* 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) { 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) { return TclAllocElemsEx(numBytes, 1, 0, capacityPtr); } /* Alloc numByte bytes, returning actual capacity in *capacityPtr. */ static inline void * 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) { 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) { return TclAttemptReallocElemsEx(oldPtr, numBytes, 1, 0, capacityPtr); } /* *---------------------------------------------------------------- * Variables shared among Tcl modules but not used by the outside world. *---------------------------------------------------------------- */ MODULE_SCOPE char *tclNativeExecutableName; MODULE_SCOPE int tclFindExecutableSearchDone; MODULE_SCOPE char *tclMemDumpFileName; MODULE_SCOPE TclPlatformType tclPlatform; /* * Declarations related to internal encoding functions. */ MODULE_SCOPE Tcl_Encoding tclIdentityEncoding; MODULE_SCOPE Tcl_Encoding tclUtf8Encoding; 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); /* * TIP #233 (Virtualized Time) * Data for the time hooks, if any. */ MODULE_SCOPE Tcl_GetTimeProc *tclGetTimeProcPtr; |
︙ | ︙ | |||
3155 3156 3157 3158 3159 3160 3161 | MODULE_SCOPE Tcl_ObjCmdProc TclNRCoroutineObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldmObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldToObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRInvoke; MODULE_SCOPE Tcl_NRPostProc TclNRReleaseValues; | | | | | | | | < | < | < | < | | > | 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 | MODULE_SCOPE Tcl_ObjCmdProc TclNRCoroutineObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldmObjCmd; 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); /* These two can be considered for the public api */ 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 * NRE the 'for' and 'while' commands. We need a separate structure because we * have more than the 4 client data entries we can provide directly thorugh * the callback API. It is the 'word' information which puts us over the * limit. It is needed because the loop body is argument 4 of 'for' and * argument 2 of 'while'. Not providing the correct index confuses the #280 * code. We TclSmallAlloc/Free this. */ typedef struct ForIterData { Tcl_Obj *cond; /* Loop condition expression. */ 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 */ } ForIterData; /* TIP #357 - Structure doing the bookkeeping of handles for Tcl_LoadFile * and Tcl_FindSymbol. This structure corresponds to an opaque * typedef in tcl.h */ typedef void* TclFindSymbolProc(Tcl_Interp* interp, Tcl_LoadHandle loadHandle, const char* symbol); struct Tcl_LoadHandle_ { 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 * and load-from-memory */ TclFindSymbolProc* findSymbolProcPtr; /* Procedure that resolves symbols in a * loaded module */ Tcl_FSUnloadFileProc* unloadFileProcPtr; /* Procedure that unloads a loaded module */ }; /* Flags for conversion of doubles to digit strings */ enum TclDoubleFormatFlags { TCL_DD_E_FORMAT = 0x2, /* Use a fixed-length string of digits, * suitable for E format*/ TCL_DD_F_FORMAT = 0x3, /* Use a fixed number of digits after the * decimal point, suitable for F format */ TCL_DD_SHORTEST = 0x4, /* Use the shortest possible string */ TCL_DD_NO_QUICK = 0x8, /* Debug flag: forbid quick FP conversion */ TCL_DD_CONVERSION_TYPE_MASK = 0x3 /* Mask to isolate the conversion type */ }; /* *---------------------------------------------------------------- * Procedures shared among Tcl modules but not used by the outside world: *---------------------------------------------------------------- */ |
︙ | ︙ | |||
4011 4012 4013 4014 4015 4016 4017 | 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); | < | 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 | 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); /* * Just for the purposes of command-type registration. */ MODULE_SCOPE Tcl_ObjCmdProc TclEnsembleImplementationCmd; MODULE_SCOPE Tcl_ObjCmdProc TclAliasObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclLocalAliasObjCmd; |
︙ | ︙ | |||
4354 4355 4356 4357 4358 4359 4360 | * *---------------------------------------------------------------- */ #define TclInitEmptyStringRep(objPtr) \ ((objPtr)->length = (((objPtr)->bytes = &tclEmptyString), 0)) | < | 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 | * *---------------------------------------------------------------- */ #define TclInitEmptyStringRep(objPtr) \ ((objPtr)->length = (((objPtr)->bytes = &tclEmptyString), 0)) #define TclInitStringRep(objPtr, bytePtr, len) \ if ((len) == 0) { \ TclInitEmptyStringRep(objPtr); \ } else { \ (objPtr)->bytes = (char *)Tcl_Alloc((len) + 1U); \ memcpy((objPtr)->bytes, (bytePtr) ? (bytePtr) : &tclEmptyString, (len)); \ (objPtr)->bytes[len] = '\0'; \ |
︙ | ︙ | |||
4612 4613 4614 4615 4616 4617 4618 | #define TclIsPureDict(objPtr) \ (((objPtr)->bytes==NULL) && TclHasInternalRep((objPtr), &tclDictType)) #define TclHasInternalRep(objPtr, type) \ ((objPtr)->typePtr == (type)) #define TclFetchInternalRep(objPtr, type) \ (TclHasInternalRep((objPtr), (type)) ? &((objPtr)->internalRep) : NULL) | < | 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 | #define TclIsPureDict(objPtr) \ (((objPtr)->bytes==NULL) && TclHasInternalRep((objPtr), &tclDictType)) #define TclHasInternalRep(objPtr, type) \ ((objPtr)->typePtr == (type)) #define TclFetchInternalRep(objPtr, type) \ (TclHasInternalRep((objPtr), (type)) ? &((objPtr)->internalRep) : NULL) /* *---------------------------------------------------------------- * Macro used by the Tcl core to increment a namespace's export epoch * counter. The ANSI C "prototype" for this macro is: * * MODULE_SCOPE void TclInvalidateNsCmdLookup(Namespace *nsPtr); *---------------------------------------------------------------- |
︙ | ︙ | |||
4656 4657 4658 4659 4660 4661 4662 | MODULE_SCOPE Tcl_LibraryInitProc TclplatformtestInit; MODULE_SCOPE Tcl_LibraryInitProc TclObjTest_Init; MODULE_SCOPE Tcl_LibraryInitProc TclThread_Init; MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_Init; MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit; MODULE_SCOPE Tcl_LibraryInitProc Tcl_ABSListTest_Init; | < | 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 | MODULE_SCOPE Tcl_LibraryInitProc TclplatformtestInit; MODULE_SCOPE Tcl_LibraryInitProc TclObjTest_Init; MODULE_SCOPE Tcl_LibraryInitProc TclThread_Init; MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_Init; MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit; MODULE_SCOPE Tcl_LibraryInitProc Tcl_ABSListTest_Init; /* *---------------------------------------------------------------- * Macro used by the Tcl core to check whether a pattern has any characters * special to [string match]. The ANSI C "prototype" for this macro is: * * MODULE_SCOPE int TclMatchIsTrivial(const char *pattern); |
︙ | ︙ | |||
4843 4844 4845 4846 4847 4848 4849 | #define TclCleanupCommandMacro(cmdPtr) \ do { \ if ((cmdPtr)->refCount-- <= 1) { \ Tcl_Free(cmdPtr); \ } \ } while (0) | < < | 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 | #define TclCleanupCommandMacro(cmdPtr) \ do { \ if ((cmdPtr)->refCount-- <= 1) { \ Tcl_Free(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) { \ Tcl_Free(((location))); \ } \ (location) = (cmdPtr); \ } while (0) #define TclRoutineHasName(cmdPtr) \ ((cmdPtr)->hPtr != NULL) /* *---------------------------------------------------------------- * Inline versions of Tcl_LimitReady() and Tcl_LimitExceeded to limit number |
︙ | ︙ |
Changes to generic/tclInterp.c.
︙ | ︙ | |||
192 193 194 195 196 197 198 | LimitHandler *prevPtr; /* Previous item in linked list of * handlers. */ LimitHandler *nextPtr; /* Next item in linked list of handlers. */ }; /* * Values for the LimitHandler flags field. | > > | | > | | > | | < | < < < < | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | LimitHandler *prevPtr; /* Previous item in linked list of * handlers. */ LimitHandler *nextPtr; /* Next item in linked list of handlers. */ }; /* * Values for the LimitHandler flags field. */ enum LimitHandlerFlags { LIMIT_HANDLER_ACTIVE = 1, /* Whether the handler is currently being * processed; handlers are never to be * reentered.*/ LIMIT_HANDLER_DELETED = 2 /* Whether the handler has been deleted. This * should not normally be observed because * when a handler is deleted it is also * spliced out of the list of handlers, but * even so we will be careful.*/ }; /* * Prototypes for local static functions: */ static int AliasCreate(Tcl_Interp *interp, Tcl_Interp *childInterp, Tcl_Interp *parentInterp, |
︙ | ︙ |
Changes to generic/tclLink.c.
︙ | ︙ | |||
71 72 73 74 75 76 77 | * avoid string conversions. */ int flags; /* Miscellaneous one-bit values; see below for * definitions. */ } Link; /* * Definitions for flag bits: | > > | | | | | > | < | | < | < < < < | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | * avoid string conversions. */ int flags; /* Miscellaneous one-bit values; see below for * definitions. */ } Link; /* * Definitions for flag bits: */ enum LinkFlags { LINK_READ_ONLY = 1, /* Errors should be generated if Tcl script * attempts to write variable.*/ LINK_BEING_UPDATED = 2, /* A call to Tcl_UpdateLinkedVar is in * progress for this variable, so trace * callbacks on the variable should be * ignored. */ LINK_ALLOC_ADDR = 4, /* linkPtr->addr was allocated on the heap. */ LINK_ALLOC_LAST = 8 /* linkPtr->valueLast.p was allocated on the * heap. */ }; /* * Forward references to functions defined later in this file: */ static char * LinkTraceProc(void *clientData,Tcl_Interp *interp, const char *name1, const char *name2, int flags); |
︙ | ︙ |
Changes to generic/tclListObj.c.
︙ | ︙ | |||
101 102 103 104 105 106 107 | * - Conversely, if only LISTREP_FAVOR_BACK is present extra space is allocated * with more to the back. * - If both flags are present (LISTREP_SPACE_FAVOR_NONE), the extra space * is equally apportioned. * - Finally if LISTREP_SPACE_ONLY_BACK is present, ALL extra space is at * the back. */ | > | | | | | | | | | > | | | > | > | < | < | > | | > | | < | < | | | | | | | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | * - Conversely, if only LISTREP_FAVOR_BACK is present extra space is allocated * with more to the back. * - If both flags are present (LISTREP_SPACE_FAVOR_NONE), the extra space * is equally apportioned. * - Finally if LISTREP_SPACE_ONLY_BACK is present, ALL extra space is at * the back. */ enum ListRepFlags { LISTREP_PANIC_ON_FAIL = 1, LISTREP_SPACE_FAVOR_FRONT = 2, LISTREP_SPACE_FAVOR_BACK = 4, LISTREP_SPACE_ONLY_BACK = 8, LISTREP_SPACE_FAVOR_NONE = ( LISTREP_SPACE_FAVOR_FRONT | LISTREP_SPACE_FAVOR_BACK), LISTREP_SPACE_FLAGS = ( LISTREP_SPACE_FAVOR_FRONT | LISTREP_SPACE_FAVOR_BACK | LISTREP_SPACE_ONLY_BACK) }; /* * Prototypes for non-inline static functions defined later in this file: */ static int MemoryAllocationError(Tcl_Interp *, size_t size); static int ListLimitExceededError(Tcl_Interp *); static ListStore * ListStoreNew(Tcl_Size objc, Tcl_Obj *const objv[], int flags); static int ListRepInit(Tcl_Size objc, Tcl_Obj *const objv[], int flags, ListRep *); static int ListRepInitAttempt(Tcl_Interp *, Tcl_Size objc, Tcl_Obj *const objv[], ListRep *); static void ListRepClone(ListRep *fromRepPtr, ListRep *toRepPtr, int flags); static void ListRepUnsharedFreeUnreferenced(const ListRep *repPtr); static int TclListObjGetRep(Tcl_Interp *, Tcl_Obj *listPtr, ListRep *repPtr); static void ListRepRange(ListRep *srcRepPtr, Tcl_Size rangeStart, Tcl_Size rangeEnd, int preserveSrcRep, ListRep *rangeRepPtr); static ListStore * ListStoreReallocate(ListStore *storePtr, Tcl_Size numSlots); static void ListRepValidate(const ListRep *repPtr, const char *file, int lineNum); static void DupListInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); static void FreeListInternalRep(Tcl_Obj *listPtr); static int SetListFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static void UpdateStringOfList(Tcl_Obj *listPtr); static Tcl_Size ListLength(Tcl_Obj *listPtr); /* * The structure below defines the list Tcl object type by means of functions * that can be invoked by generic object code. * * The internal representation of a list object is ListRep defined in tcl.h. */ |
︙ | ︙ | |||
235 236 237 238 239 240 241 | * Side effects: * The function will panic on memory allocation failure. * *------------------------------------------------------------------------ */ static inline ListSpan * ListSpanNew( | | | | 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | * Side effects: * The function will panic on memory allocation failure. * *------------------------------------------------------------------------ */ static inline ListSpan * ListSpanNew( Tcl_Size firstSlot, /* Starting slot index of the span */ Tcl_Size numSlots) /* Number of slots covered by the span */ { ListSpan *spanPtr = (ListSpan *) Tcl_Alloc(sizeof(*spanPtr)); spanPtr->refCount = 0; spanPtr->spanStart = firstSlot; spanPtr->spanLength = numSlots; return spanPtr; } |
︙ | ︙ | |||
262 263 264 265 266 267 268 | * * Side effects: * The memory may be freed. * *------------------------------------------------------------------------ */ static inline void | | > | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | * * Side effects: * The memory may be freed. * *------------------------------------------------------------------------ */ static inline void ListSpanDecrRefs( ListSpan *spanPtr) { if (spanPtr->refCount <= 1) { Tcl_Free(spanPtr); } else { spanPtr->refCount -= 1; } } |
︙ | ︙ | |||
339 340 341 342 343 344 345 | * * Side effects: * See comments for ListRepUnsharedFreeUnreferenced. * *------------------------------------------------------------------------ */ static inline void | | > | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 | * * Side effects: * See comments for ListRepUnsharedFreeUnreferenced. * *------------------------------------------------------------------------ */ static inline void ListRepFreeUnreferenced( const ListRep *repPtr) { if (! ListRepIsShared(repPtr) && repPtr->spanPtr) { /* T:listrep-1.5.1 */ ListRepUnsharedFreeUnreferenced(repPtr); } } |
︙ | ︙ | |||
364 365 366 367 368 369 370 | * Side effects: * As above. * *------------------------------------------------------------------------ */ static inline void ObjArrayIncrRefs( | | | | | 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | * Side effects: * As above. * *------------------------------------------------------------------------ */ static inline void ObjArrayIncrRefs( Tcl_Obj *const *objv, /* Pointer to the array */ Tcl_Size startIdx, /* Starting index of subarray within objv */ Tcl_Size count) /* Number of elements in the subarray */ { Tcl_Obj *const *end; LIST_INDEX_ASSERT(startIdx); LIST_COUNT_ASSERT(count); objv += startIdx; end = objv + count; while (objv < end) { |
︙ | ︙ | |||
396 397 398 399 400 401 402 | * Side effects: * As above. * *------------------------------------------------------------------------ */ static inline void ObjArrayDecrRefs( | | | | | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | * Side effects: * As above. * *------------------------------------------------------------------------ */ static inline void ObjArrayDecrRefs( Tcl_Obj *const *objv, /* Pointer to the array */ Tcl_Size startIdx, /* Starting index of subarray within objv */ Tcl_Size count) /* Number of elements in the subarray */ { Tcl_Obj * const *end; LIST_INDEX_ASSERT(startIdx); LIST_COUNT_ASSERT(count); objv += startIdx; end = objv + count; while (objv < end) { |
︙ | ︙ | |||
2013 2014 2015 2016 2017 2018 2019 | return TCL_OK; } if (TclObjTypeHasProc(listObj, lengthProc)) { *lenPtr = TclObjTypeLength(listObj); return TCL_OK; } | < | 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 | return TCL_OK; } if (TclObjTypeHasProc(listObj, lengthProc)) { *lenPtr = TclObjTypeLength(listObj); return TCL_OK; } if (TclListObjGetRep(interp, listObj, &listRep) != TCL_OK) { return TCL_ERROR; } *lenPtr = ListRepLength(&listRep); return TCL_OK; } |
︙ | ︙ |
Changes to generic/tclLoad.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" | < | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" /* * The following structure describes a library that has been loaded either * dynamically (with the "load" command) or statically (as indicated by a call * to Tcl_StaticLibrary). All such libraries are linked together into a * single list for the process. */ |
︙ | ︙ | |||
817 818 819 820 821 822 823 | code = TCL_ERROR; goto done; } } unloadProc = libraryPtr->unloadProc; } | < < | 816 817 818 819 820 821 822 823 824 825 826 827 828 829 | code = TCL_ERROR; goto done; } } unloadProc = libraryPtr->unloadProc; } /* * We are ready to unload the library. First, evaluate the unload * function. If this fails, we cannot proceed with unload. Also, we must * specify the proper flag to pass to the unload callback. * TCL_UNLOAD_DETACH_FROM_INTERPRETER is defined when the callback should * only remove itself from the interpreter; the library will be unloaded * in a future call of unload. In case the library will be unloaded just |
︙ | ︙ | |||
852 853 854 855 856 857 858 | if (safeRefCount <= 0 && trustedRefCount <= 0) { code = TCL_UNLOAD_DETACH_FROM_PROCESS; } } code = unloadProc(target, code); } | < < | 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 | if (safeRefCount <= 0 && trustedRefCount <= 0) { code = TCL_UNLOAD_DETACH_FROM_PROCESS; } } code = unloadProc(target, code); } if (code != TCL_OK) { Tcl_TransferResult(target, code, interp); goto done; } /* * Remove this library from the interpreter's library cache. */ ipFirstPtr = (InterpLibrary *)Tcl_GetAssocData(target, "tclLoad", NULL); ipPtr = ipFirstPtr; |
︙ | ︙ | |||
880 881 882 883 884 885 886 | ipPrevPtr->nextPtr = ipPtr->nextPtr; break; } } } Tcl_Free(ipPtr); Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc, ipFirstPtr); | < | 875 876 877 878 879 880 881 882 883 884 885 886 887 888 | ipPrevPtr->nextPtr = ipPtr->nextPtr; break; } } } Tcl_Free(ipPtr); Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc, ipFirstPtr); if (IsStatic(libraryPtr)) { goto done; } /* * The unload function was called succesfully. |
︙ | ︙ |
Changes to generic/tclOO.c.
︙ | ︙ | |||
298 299 300 301 302 303 304 | */ static int InitFoundation( Tcl_Interp *interp) { static Tcl_ThreadDataKey tsdKey; | | | | 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | */ static int InitFoundation( Tcl_Interp *interp) { static Tcl_ThreadDataKey tsdKey; ThreadLocalData *tsdPtr = (ThreadLocalData *) Tcl_GetThreadData(&tsdKey, sizeof(ThreadLocalData)); Foundation *fPtr = (Foundation *)Tcl_Alloc(sizeof(Foundation)); Tcl_Obj *namePtr; Tcl_DString buffer; Command *cmdPtr; size_t i; /* |
︙ | ︙ | |||
349 350 351 352 353 354 355 | /* * 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::"); | | | | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | /* * 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, TCL_AUTO_LENGTH); Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer), 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, TCL_AUTO_LENGTH); Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer), objdefCmds[i].objProc, INT2PTR(objdefCmds[i].flag), NULL); Tcl_DStringFree(&buffer); } Tcl_CallWhenDeleted(interp, KillFoundation, NULL); |
︙ | ︙ | |||
428 429 430 431 432 433 434 | /* * Evaluate the remaining definitions, which are a compiled-in Tcl script. */ return Tcl_EvalEx(interp, tclOOSetupScript, TCL_INDEX_NONE, 0); } | | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | /* * Evaluate the remaining definitions, which are a compiled-in Tcl script. */ return Tcl_EvalEx(interp, tclOOSetupScript, TCL_INDEX_NONE, 0); } /* * ---------------------------------------------------------------------- * * InitClassSystemRoots -- * * Creates the objects at the core of the object system. These need to be * spliced manually. |
︙ | ︙ | |||
572 573 574 575 576 577 578 | * * ---------------------------------------------------------------------- */ static void KillFoundation( TCL_UNUSED(void *), | | | | 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 | * * ---------------------------------------------------------------------- */ static void KillFoundation( TCL_UNUSED(void *), Tcl_Interp *interp) /* The interpreter containing the OO system * foundation. */ { Foundation *fPtr = GetFoundation(interp); TclDecrRefCount(fPtr->unknownMethodNameObj); TclDecrRefCount(fPtr->constructorName); TclDecrRefCount(fPtr->destructorName); TclDecrRefCount(fPtr->clonedName); |
︙ | ︙ | |||
652 653 654 655 656 657 658 | } Tcl_ResetResult(interp); } while (1) { char objName[10 + TCL_INTEGER_SPACE]; | | > | 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 | } Tcl_ResetResult(interp); } while (1) { char objName[10 + TCL_INTEGER_SPACE]; 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; break; } /* |
︙ | ︙ | |||
787 788 789 790 791 792 793 | * of those commands when the object itself is deleted. * * ---------------------------------------------------------------------- */ static void MyDeleted( | | < | 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 | * of those commands when the object itself is deleted. * * ---------------------------------------------------------------------- */ static void MyDeleted( void *clientData) /* Reference to the object whose [my] has been * squelched. */ { Object *oPtr = (Object *)clientData; oPtr->myCommand = NULL; } static void MyClassDeleted( void *clientData) { |
︙ | ︙ | |||
818 819 820 821 822 823 824 | * object data structures. * * ---------------------------------------------------------------------- */ static void ObjectRenamedTrace( | | | 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 | * object data structures. * * ---------------------------------------------------------------------- */ static void ObjectRenamedTrace( void *clientData, /* The object being deleted. */ TCL_UNUSED(Tcl_Interp *), TCL_UNUSED(const char *) /*oldName*/, TCL_UNUSED(const char *) /*newName*/, int flags) /* Why was the object deleted? */ { Object *oPtr = (Object *)clientData; |
︙ | ︙ | |||
1131 1132 1133 1134 1135 1136 1137 | * (interpreter teardown is complex!) * * ---------------------------------------------------------------------- */ static void ObjectNamespaceDeleted( | | | 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 | * (interpreter teardown is complex!) * * ---------------------------------------------------------------------- */ static void ObjectNamespaceDeleted( void *clientData) /* Pointer to the class whose namespace is * being deleted. */ { Object *oPtr = (Object *)clientData; Foundation *fPtr = oPtr->fPtr; FOREACH_HASH_DECLS; Class *mixinPtr; Method *mPtr; |
︙ | ︙ | |||
1365 1366 1367 1368 1369 1370 1371 | */ int TclOODecrRefCount( Object *oPtr) { if (oPtr->refCount-- <= 1) { | < | 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 | */ int TclOODecrRefCount( Object *oPtr) { if (oPtr->refCount-- <= 1) { if (oPtr->classPtr != NULL) { Tcl_Free(oPtr->classPtr); } Tcl_Free(oPtr); return 1; } return 0; |
︙ | ︙ | |||
1714 1715 1716 1717 1718 1719 1720 | Tcl_Interp *interp, /* Interpreter context. */ Tcl_Class cls, /* Class to create an instance of. */ const char *nameStr, /* Name of object to create, or NULL to ask * the code to pick its own unique name. */ const char *nsNameStr, /* Name of namespace to create inside object, * or NULL to ask the code to pick its own * unique name. */ | | | | 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 | Tcl_Interp *interp, /* Interpreter context. */ Tcl_Class cls, /* Class to create an instance of. */ const char *nameStr, /* Name of object to create, or NULL to ask * the code to pick its own unique name. */ 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 * do not call constructor. */ Tcl_Obj *const *objv, /* Argument list. */ Tcl_Size skip) /* Number of arguments to _not_ pass to the * constructor. */ { Class *classPtr = (Class *) cls; Object *oPtr; void *clientData[4]; oPtr = TclNewObjectInstanceCommon(interp, classPtr, nameStr, nsNameStr); |
︙ | ︙ | |||
1782 1783 1784 1785 1786 1787 1788 | Tcl_Interp *interp, /* Interpreter context. */ Tcl_Class cls, /* Class to create an instance of. */ const char *nameStr, /* Name of object to create, or NULL to ask * the code to pick its own unique name. */ const char *nsNameStr, /* Name of namespace to create inside object, * or NULL to ask the code to pick its own * unique name. */ | | | | 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 | Tcl_Interp *interp, /* Interpreter context. */ Tcl_Class cls, /* Class to create an instance of. */ const char *nameStr, /* Name of object to create, or NULL to ask * the code to pick its own unique name. */ 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 * do not call constructor. */ Tcl_Obj *const *objv, /* Argument list. */ Tcl_Size skip, /* Number of arguments to _not_ pass to the * constructor. */ Tcl_Object *objectPtr) /* Place to write the object reference upon * successful allocation. */ { Class *classPtr = (Class *) cls; CallContext *contextPtr; Tcl_InterpState state; |
︙ | ︙ | |||
1917 1918 1919 1920 1921 1922 1923 | /* * Ensure an error if the object was deleted in the constructor. Don't * want to lose errors by accident. [Bug 2903011] */ if (result != TCL_ERROR && Destructing(oPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 | /* * Ensure an error if the object was deleted in the constructor. Don't * want to lose errors by accident. [Bug 2903011] */ if (result != TCL_ERROR && Destructing(oPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "object deleted in constructor", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "STILLBORN", (char *)NULL); result = TCL_ERROR; } if (result != TCL_OK) { Tcl_DiscardInterpState(state); /* |
︙ | ︙ | |||
1988 1989 1990 1991 1992 1993 1994 | /* * Sanity check. */ if (IsRootClass(oPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 | /* * Sanity check. */ if (IsRootClass(oPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not clone the class of classes", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "CLONING_CLASS", (char *)NULL); return NULL; } /* * Build the instance. Note that this does not run any constructors. */ |
︙ | ︙ | |||
2603 2604 2605 2606 2607 2608 2609 | * invoke from, or NULL to traverse the whole * chain including filters. */ int publicPrivate, /* Whether this is an invoke from a public * context (PUBLIC_METHOD), a private context * (PRIVATE_METHOD), or a *really* private * context (any other value; conventionally * 0). */ | | | 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 | * invoke from, or NULL to traverse the whole * chain including filters. */ int publicPrivate, /* Whether this is an invoke from a public * context (PUBLIC_METHOD), a private context * (PRIVATE_METHOD), or a *really* private * context (any other value; conventionally * 0). */ 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. */ { switch (publicPrivate) { case PUBLIC_METHOD: return TclOOObjectCmdCore((Object *) object, interp, objc, objv, |
︙ | ︙ | |||
2674 2675 2676 2677 2678 2679 2680 | * ---------------------------------------------------------------------- */ int TclOOObjectCmdCore( Object *oPtr, /* The object being invoked. */ Tcl_Interp *interp, /* The interpreter containing the object. */ | | | 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 | * ---------------------------------------------------------------------- */ 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_Obj *const *objv, /* The array of arguments. */ int flags, /* Whether this is an invocation through the * public or the private command interface. */ Class *startCls) /* Where to start in the call chain, or NULL * if we are to start at the front with * filters and the object's methods (which is * the normal case). */ |
︙ | ︙ | |||
2796 2797 2798 2799 2800 2801 2802 | } if (miPtr->mPtr->declaringClassPtr == startCls) { break; } } if (contextPtr->index >= contextPtr->callPtr->numChain) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 | } if (miPtr->mPtr->declaringClassPtr == startCls) { break; } } if (contextPtr->index >= contextPtr->callPtr->numChain) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no valid method implementation", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(methodNamePtr), (char *)NULL); TclOODeleteContext(contextPtr); return TCL_ERROR; } } |
︙ | ︙ |
Changes to generic/tclOOBasic.c.
︙ | ︙ | |||
96 97 98 99 100 101 102 | } /* * Make the class definition delegate. This is special; it doesn't reenter * here (and the class definition delegate doesn't run any constructors). */ | | | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | } /* * Make the class definition delegate. This is special; it doesn't reenter * here (and the class definition delegate doesn't run any constructors). */ nameObj = Tcl_NewStringObj(oPtr->namespacePtr->fullName, TCL_AUTO_LENGTH); Tcl_AppendToObj(nameObj, ":: oo ::delegate", TCL_AUTO_LENGTH); Tcl_NewObjectInstance(interp, (Tcl_Class) oPtr->fPtr->classCls, TclGetString(nameObj), NULL, -1, NULL, -1); Tcl_DecrRefCount(nameObj); /* * Delegate to [oo::define] to do the work. */ invoke = (Tcl_Obj **)Tcl_Alloc(3 * sizeof(Tcl_Obj *)); invoke[0] = oPtr->fPtr->defineName; invoke[1] = TclOOObjectName(interp, oPtr); invoke[2] = objv[objc - 1]; /* * Must add references or errors in configuration script will cause * trouble. */ Tcl_IncrRefCount(invoke[0]); |
︙ | ︙ | |||
144 145 146 147 148 149 150 | Object *oPtr = (Object *)data[1]; Tcl_InterpState saved; int code; TclDecrRefCount(invoke[0]); TclDecrRefCount(invoke[1]); TclDecrRefCount(invoke[2]); | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | Object *oPtr = (Object *)data[1]; Tcl_InterpState saved; int code; TclDecrRefCount(invoke[0]); TclDecrRefCount(invoke[1]); TclDecrRefCount(invoke[2]); invoke[0] = Tcl_NewStringObj("::oo::MixinClassDelegates", TCL_AUTO_LENGTH); invoke[1] = TclOOObjectName(interp, oPtr); Tcl_IncrRefCount(invoke[0]); Tcl_IncrRefCount(invoke[1]); saved = Tcl_SaveInterpState(interp, result); code = Tcl_EvalObjv(interp, 2, invoke, 0); TclDecrRefCount(invoke[0]); TclDecrRefCount(invoke[1]); |
︙ | ︙ | |||
210 211 212 213 214 215 216 | "objectName ?arg ...?"); return TCL_ERROR; } objName = Tcl_GetStringFromObj( objv[Tcl_ObjectContextSkippedArgs(context)], &len); if (len == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | "objectName ?arg ...?"); return TCL_ERROR; } objName = Tcl_GetStringFromObj( objv[Tcl_ObjectContextSkippedArgs(context)], &len); if (len == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "object name must not be empty", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", (char *)NULL); return TCL_ERROR; } /* * Make the object and return its name. */ |
︙ | ︙ | |||
275 276 277 278 279 280 281 | "objectName namespaceName ?arg ...?"); return TCL_ERROR; } objName = Tcl_GetStringFromObj( objv[Tcl_ObjectContextSkippedArgs(context)], &len); if (len == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | "objectName namespaceName ?arg ...?"); return TCL_ERROR; } objName = Tcl_GetStringFromObj( objv[Tcl_ObjectContextSkippedArgs(context)], &len); if (len == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "object name must not be empty", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", (char *)NULL); return TCL_ERROR; } nsName = Tcl_GetStringFromObj( objv[Tcl_ObjectContextSkippedArgs(context)+1], &len); if (len == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "namespace name must not be empty", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", (char *)NULL); return TCL_ERROR; } /* * Make the object and return its name. */ |
︙ | ︙ | |||
596 597 598 599 600 601 602 | return TCL_ERROR; } errorMsg = Tcl_ObjPrintf("unknown method \"%s\": must be ", TclGetString(objv[skip])); for (i=0 ; i<numMethodNames-1 ; i++) { if (i) { | | | | | | 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 | return TCL_ERROR; } errorMsg = Tcl_ObjPrintf("unknown method \"%s\": must be ", TclGetString(objv[skip])); for (i=0 ; i<numMethodNames-1 ; i++) { if (i) { Tcl_AppendToObj(errorMsg, ", ", TCL_AUTO_LENGTH); } Tcl_AppendToObj(errorMsg, methodNames[i], TCL_AUTO_LENGTH); } if (i) { Tcl_AppendToObj(errorMsg, " or ", TCL_AUTO_LENGTH); } Tcl_AppendToObj(errorMsg, methodNames[i], TCL_AUTO_LENGTH); Tcl_Free((void *)methodNames); Tcl_SetObjResult(interp, errorMsg); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[skip]), (char *)NULL); return TCL_ERROR; } |
︙ | ︙ | |||
706 707 708 709 710 711 712 | * This is copied out of Tcl_VariableObjCmd... */ if (!TclIsVarNamespaceVar(varPtr)) { TclSetVarNamespaceVar(varPtr); } | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < < < < < < < < | < < < < < | < < < < < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < | | 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 | * This is copied out of Tcl_VariableObjCmd... */ if (!TclIsVarNamespaceVar(varPtr)) { TclSetVarNamespaceVar(varPtr); } if (TclPtrMakeUpvar(interp, varPtr, varName, 0, TCL_INDEX_NONE) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; } /* * ---------------------------------------------------------------------- * * TclOO_Object_VarName -- * * Implementation of the oo::object->varname method. * * ---------------------------------------------------------------------- */ /* * Private method handling. [TIP 500] * * If we're in a context that can see some private methods of an * object, we may need to precede a variable name with its prefix. * This is a little tricky as we need to check through the inheritance * hierarchy when the method was declared by a class to see if the * current object is an instance of that class. */ static inline Tcl_Obj * MapPrivateVarName( Tcl_Object object, CallFrame *framePtr, Tcl_Obj *argPtr) { Object *oPtr = (Object *) object; // NB: NOT the context we got the object from! CallContext *callerCtxt = (CallContext *) framePtr->clientData; Method *mPtr = callerCtxt->callPtr->chain[callerCtxt->index].mPtr; PrivateVariableMapping *pvPtr; Tcl_Size i; if (mPtr->declaringObjectPtr == oPtr) { FOREACH_STRUCT(pvPtr, oPtr->privateVariables) { if (!strcmp(TclGetString(pvPtr->variableObj), TclGetString(argPtr))) { return pvPtr->fullNameObj; } } } else if (mPtr->declaringClassPtr && mPtr->declaringClassPtr->privateVariables.num) { Class *clsPtr = mPtr->declaringClassPtr; int isInstance = TclOOIsReachable(clsPtr, oPtr->selfCls); Class *mixinCls; if (!isInstance) { FOREACH(mixinCls, oPtr->mixins) { if (TclOOIsReachable(clsPtr, mixinCls)) { isInstance = 1; break; } } } if (isInstance) { FOREACH_STRUCT(pvPtr, clsPtr->privateVariables) { if (!strcmp(TclGetString(pvPtr->variableObj), TclGetString(argPtr))) { return pvPtr->fullNameObj; } } } } return argPtr; } 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. */ { 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); /* * Convert the variable name to fully-qualified form if it wasn't already. * This has to be done prior to lookup because we can run into problems * with resolvers otherwise. [Bug 3603695] * * We still need to do the lookup; the variable could be linked to another * variable and we want the target's name. */ if (arg[0] == ':' && arg[1] == ':') { varNamePtr = argPtr; } else { Tcl_Namespace *namespacePtr = Tcl_GetObjectNamespace(Tcl_ObjectContextObject(context)); if (framePtr->isProcCallFrame & FRAME_IS_METHOD) { argPtr = MapPrivateVarName(Tcl_ObjectContextObject(context), framePtr, argPtr); } varNamePtr = Tcl_NewStringObj(namespacePtr->fullName, TCL_AUTO_LENGTH); Tcl_AppendToObj(varNamePtr, "::", 2); Tcl_AppendObjToObj(varNamePtr, argPtr); } Tcl_IncrRefCount(varNamePtr); varPtr = TclObjLookupVar(interp, varNamePtr, NULL, TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG, "refer to", 1, 1, &aryVar); Tcl_DecrRefCount(varNamePtr); |
︙ | ︙ | |||
838 839 840 841 842 843 844 | if (aryVar != NULL) { Tcl_GetVariableFullName(interp, (Tcl_Var) aryVar, varNamePtr); /* * WARNING! This code pokes inside the implementation of hash tables! */ | | | | 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 | if (aryVar != NULL) { Tcl_GetVariableFullName(interp, (Tcl_Var) aryVar, varNamePtr); /* * WARNING! This code pokes inside the implementation of hash tables! */ Tcl_AppendToObj(varNamePtr, "(", TCL_AUTO_LENGTH); Tcl_AppendObjToObj(varNamePtr, ((VarInHash *) varPtr)->entry.key.objPtr); Tcl_AppendToObj(varNamePtr, ")", TCL_AUTO_LENGTH); } else { Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, varNamePtr); } Tcl_SetObjResult(interp, varNamePtr); return TCL_OK; } |
︙ | ︙ | |||
964 965 966 967 968 969 970 | /* * Invoke the (advanced) method call context in the caller * context. Note that this is like [uplevel 1] and not [eval]. */ TclNRAddCallback(interp, NextRestoreFrame, framePtr, contextPtr, INT2PTR(contextPtr->index), NULL); | | | 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 | /* * Invoke the (advanced) method call context in the caller * context. Note that this is like [uplevel 1] and not [eval]. */ TclNRAddCallback(interp, NextRestoreFrame, framePtr, contextPtr, INT2PTR(contextPtr->index), NULL); contextPtr->index = i - 1; iPtr->varFramePtr = framePtr->callerVarPtr; return TclNRObjectContextInvokeNext(interp, (Tcl_ObjectContext) contextPtr, objc, objv, 2); } } /* |
︙ | ︙ | |||
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 | iPtr->varFramePtr = (CallFrame *)data[0]; if (contextPtr != NULL) { contextPtr->index = PTR2UINT(data[2]); } return result; } /* * ---------------------------------------------------------------------- * * TclOOSelfObjCmd -- * * Implementation of the [self] command, which provides introspection of | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 | iPtr->varFramePtr = (CallFrame *)data[0]; if (contextPtr != NULL) { contextPtr->index = PTR2UINT(data[2]); } return result; } /* * ---------------------------------------------------------------------- * * GetDeclarer, GetMethodName -- * * Helpers for the [self] command implementation. * * ---------------------------------------------------------------------- */ /* Get (class?) object that declared a method. */ static inline Object * GetDeclarer( Method *mPtr) /* Method impl to get declarer of. */ { if (mPtr->declaringClassPtr != NULL) { return mPtr->declaringClassPtr->thisPtr; } else if (mPtr->declaringObjectPtr != NULL) { return mPtr->declaringObjectPtr; } Tcl_Panic("method without declarer!"); return NULL; } /* Get the official name of a method. */ static inline Tcl_Obj * GetMethodName( CallContext *contextPtr, /* Context in which we're asking. */ Method *mPtr) /* What method implementation to name. */ { if (contextPtr->callPtr->flags & CONSTRUCTOR) { return contextPtr->oPtr->fPtr->constructorName; } else if (contextPtr->callPtr->flags & DESTRUCTOR) { return contextPtr->oPtr->fPtr->destructorName; } else { return mPtr->namePtr; } } /* * ---------------------------------------------------------------------- * * TclOOSelfObjCmd -- * * Implementation of the [self] command, which provides introspection of |
︙ | ︙ | |||
1088 1089 1090 1091 1092 1093 1094 | switch (index) { case SELF_OBJECT: Tcl_SetObjResult(interp, TclOOObjectName(interp, contextPtr->oPtr)); return TCL_OK; case SELF_NS: Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | < < < < < | | < | | | | < < < < < < < < < < < < < < < < < < < | < | | < < < < < < < < < < < < < < < < < < < | < | | < < < | < < < < < < < < < | | 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 | switch (index) { case SELF_OBJECT: Tcl_SetObjResult(interp, TclOOObjectName(interp, contextPtr->oPtr)); return TCL_OK; case SELF_NS: Tcl_SetObjResult(interp, Tcl_NewStringObj( contextPtr->oPtr->namespacePtr->fullName, TCL_AUTO_LENGTH)); return TCL_OK; case SELF_CLASS: { Class *clsPtr = CurrentlyInvoked(contextPtr).mPtr->declaringClassPtr; if (clsPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "method not defined by a class", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", (char *)NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOOObjectName(interp, clsPtr->thisPtr)); return TCL_OK; } case SELF_METHOD: Tcl_SetObjResult(interp, GetMethodName(contextPtr, CurrentlyInvoked(contextPtr).mPtr)); return TCL_OK; case SELF_FILTER: if (!CurrentlyInvoked(contextPtr).isFilter) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "not inside a filtering context", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", (char *)NULL); return TCL_ERROR; } else { struct MInvoke *miPtr = &CurrentlyInvoked(contextPtr); Object *oPtr; const char *type; if (miPtr->filterDeclarer != NULL) { oPtr = miPtr->filterDeclarer->thisPtr; type = "class"; } else { oPtr = contextPtr->oPtr; type = "object"; } result[0] = TclOOObjectName(interp, oPtr); result[1] = Tcl_NewStringObj(type, TCL_AUTO_LENGTH); result[2] = miPtr->mPtr->namePtr; Tcl_SetObjResult(interp, Tcl_NewListObj(3, result)); return TCL_OK; } case SELF_CALLER: if ((framePtr->callerVarPtr == NULL) || !(framePtr->callerVarPtr->isProcCallFrame & FRAME_IS_METHOD)){ Tcl_SetObjResult(interp, Tcl_NewStringObj( "caller is not an object", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", (char *)NULL); return TCL_ERROR; } else { CallContext *callerPtr = (CallContext *)framePtr->callerVarPtr->clientData; Method *mPtr = callerPtr->callPtr->chain[callerPtr->index].mPtr; Object *declarerPtr = GetDeclarer(mPtr); result[0] = TclOOObjectName(interp, declarerPtr); result[1] = TclOOObjectName(interp, callerPtr->oPtr); result[2] = GetMethodName(callerPtr, mPtr); Tcl_SetObjResult(interp, Tcl_NewListObj(3, result)); return TCL_OK; } case SELF_NEXT: if (contextPtr->index < contextPtr->callPtr->numChain - 1) { Method *mPtr = contextPtr->callPtr->chain[contextPtr->index+1].mPtr; Object *declarerPtr = GetDeclarer(mPtr); result[0] = TclOOObjectName(interp, declarerPtr); result[1] = GetMethodName(contextPtr, mPtr); Tcl_SetObjResult(interp, Tcl_NewListObj(2, result)); } return TCL_OK; case SELF_TARGET: if (!CurrentlyInvoked(contextPtr).isFilter) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "not inside a filtering context", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", (char *)NULL); return TCL_ERROR; } else { Method *mPtr; Object *declarerPtr; Tcl_Size i; for (i=contextPtr->index ; i<contextPtr->callPtr->numChain ; i++) { if (!contextPtr->callPtr->chain[i].isFilter) { break; } } if (i == contextPtr->callPtr->numChain) { Tcl_Panic("filtering call chain without terminal non-filter"); } mPtr = contextPtr->callPtr->chain[i].mPtr; declarerPtr = GetDeclarer(mPtr); result[0] = TclOOObjectName(interp, declarerPtr); result[1] = GetMethodName(contextPtr, mPtr); Tcl_SetObjResult(interp, Tcl_NewListObj(2, result)); return TCL_OK; } case SELF_CALL: result[0] = TclOORenderCallChain(interp, contextPtr->callPtr); TclNewIndexObj(result[1], contextPtr->index); Tcl_SetObjResult(interp, Tcl_NewListObj(2, result)); |
︙ | ︙ |
Changes to generic/tclOOCall.c.
︙ | ︙ | |||
48 49 50 51 52 53 54 | int size; } DefineChain; /* * Extra flags used for call chain management. */ | > | | > | | | | | | > | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | int size; } DefineChain; /* * Extra flags used for call chain management. */ enum CallChainExtraFlags { DEFINITE_PROTECTED = 0x100000, DEFINITE_PUBLIC = 0x200000, DEFINITE_NOT_PUBLIC = (PRIVATE_METHOD | TRUE_PRIVATE_METHOD), 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 MIXIN_CONSISTENT(flags) \ (((flags) & OBJECT_MIXIN) || \ !((flags) & BUILDING_MIXINS) == !((flags) & TRAVERSED_MIXIN)) /* * Note that the flag bit PRIVATE_METHOD has a confusing name; it's just for * Itcl's special type of private. */ #define IS_PUBLIC(mPtr) \ (((mPtr)->flags & PUBLIC_METHOD) != 0) #define IS_UNEXPORTED(mPtr) \ (((mPtr)->flags & SCOPE_FLAGS) == 0) #define IS_ITCLPRIVATE(mPtr) \ (((mPtr)->flags & PRIVATE_METHOD) != 0) #define IS_PRIVATE(mPtr) \ (((mPtr)->flags & TRUE_PRIVATE_METHOD) != 0) #define WANT_PUBLIC(flags) \ (((flags) & PUBLIC_METHOD) != 0) #define WANT_UNEXPORTED(flags) \ (((flags) & DEFINITE_NOT_PUBLIC) == 0) #define WANT_ITCLPRIVATE(flags) \ (((flags) & PRIVATE_METHOD) != 0) #define WANT_PRIVATE(flags) \ (((flags) & TRUE_PRIVATE_METHOD) != 0) /* * Function declarations for things defined in this file. |
︙ | ︙ | |||
151 152 153 154 155 156 157 158 159 160 161 162 163 164 | "TclOO method name", FreeMethodNameRep, DupMethodNameRep, NULL, NULL, TCL_OBJTYPE_V0 }; /* * ---------------------------------------------------------------------- * * TclOODeleteContext -- * | > > > > > > > > | 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | "TclOO method name", FreeMethodNameRep, DupMethodNameRep, NULL, NULL, TCL_OBJTYPE_V0 }; /* * Name the bits used in the names table values. */ enum NamesTableFlags { IN_LIST = 1, NO_IMPLEMENTATION = 2 }; /* * ---------------------------------------------------------------------- * * TclOODeleteContext -- * |
︙ | ︙ | |||
305 306 307 308 309 310 311 | * in stack usage as possible. * * ---------------------------------------------------------------------- */ int TclOOInvokeContext( | | | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | * in stack usage as possible. * * ---------------------------------------------------------------------- */ int TclOOInvokeContext( 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 * implementation. */ int objc, /* The number of arguments. */ Tcl_Obj *const objv[]) /* The arguments as actually seen. */ { |
︙ | ︙ | |||
371 372 373 374 375 376 377 | /* * Run the method implementation. */ if (mPtr->typePtr->version < TCL_OO_METHOD_VERSION_2) { return (mPtr->typePtr->callProc)(mPtr->clientData, interp, (Tcl_ObjectContext) contextPtr, objc, objv); | | > | > > | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | /* * Run the method implementation. */ if (mPtr->typePtr->version < TCL_OO_METHOD_VERSION_2) { return (mPtr->typePtr->callProc)(mPtr->clientData, interp, (Tcl_ObjectContext) contextPtr, objc, objv); } else { Tcl_MethodCallProc2 *callProc = (Tcl_MethodCallProc2 *) (void *) mPtr->typePtr->callProc; return callProc(mPtr->clientData, interp, (Tcl_ObjectContext) contextPtr, objc, objv); } } static int SetFilterFlags( void *data[], TCL_UNUSED(Tcl_Interp *), int result) |
︙ | ︙ | |||
456 457 458 459 460 461 462 | Class *mixinPtr; Tcl_Obj *namePtr; Method *mPtr; Tcl_InitObjHashTable(&names); Tcl_InitHashTable(&examinedClasses, TCL_ONE_WORD_KEYS); | < < < < < < | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | Class *mixinPtr; Tcl_Obj *namePtr; Method *mPtr; Tcl_InitObjHashTable(&names); Tcl_InitHashTable(&examinedClasses, TCL_ONE_WORD_KEYS); /* * Process method names due to the object. */ if (oPtr->methodsPtr) { FOREACH_HASH(namePtr, mPtr, oPtr->methodsPtr) { if (IS_PRIVATE(mPtr)) { |
︙ | ︙ | |||
674 675 676 677 678 679 680 | * * ---------------------------------------------------------------------- */ static void AddClassMethodNames( Class *clsPtr, /* Class to get method names from. */ | | | 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 | * * ---------------------------------------------------------------------- */ static void AddClassMethodNames( Class *clsPtr, /* Class to get method names from. */ int flags, /* Whether we are interested in just the * public method names. */ Tcl_HashTable *const namesPtr, /* Reference to the hash table to put the * information in. The hash table maps the * Tcl_Obj * method name to an integral value * describing whether the method is wanted. * This ensures that public/private override |
︙ | ︙ | |||
805 806 807 808 809 810 811 | int isWanted = PTR2INT(Tcl_GetHashValue(hPtr)); isWanted &= ~NO_IMPLEMENTATION; Tcl_SetHashValue(hPtr, INT2PTR(isWanted)); } } } | < < < | 813 814 815 816 817 818 819 820 821 822 823 824 825 826 | int isWanted = PTR2INT(Tcl_GetHashValue(hPtr)); isWanted &= ~NO_IMPLEMENTATION; Tcl_SetHashValue(hPtr, INT2PTR(isWanted)); } } } /* * ---------------------------------------------------------------------- * * AddInstancePrivateToCallContext -- * * Add private methods from the instance. Called when the calling Tcl |
︙ | ︙ | |||
1040 1041 1042 1043 1044 1045 1046 | /* * Need to really add the method. This is made a bit more complex by the * fact that we are using some "static" space initially, and only start * realloc-ing if the chain gets long. */ if (callPtr->numChain == CALL_CHAIN_STATIC_SIZE) { | | | | 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 | /* * Need to really add the method. This is made a bit more complex by the * fact that we are using some "static" space initially, and only start * realloc-ing if the chain gets long. */ if (callPtr->numChain == CALL_CHAIN_STATIC_SIZE) { callPtr->chain = (struct MInvoke *) Tcl_Alloc(sizeof(struct MInvoke) * (callPtr->numChain + 1)); memcpy(callPtr->chain, callPtr->staticChain, sizeof(struct 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[i].mPtr = mPtr; |
︙ | ︙ | |||
1340 1341 1342 1343 1344 1345 1346 | return NULL; } } else if (doFilters && !donePrivate) { if (hPtr == NULL) { int isNew; if (oPtr->flags & USE_CLASS_CACHE) { if (oPtr->selfCls->classChainCache == NULL) { | | | | > | 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 | return NULL; } } else if (doFilters && !donePrivate) { if (hPtr == NULL) { int isNew; if (oPtr->flags & USE_CLASS_CACHE) { if (oPtr->selfCls->classChainCache == NULL) { oPtr->selfCls->classChainCache = (Tcl_HashTable *) Tcl_Alloc(sizeof(Tcl_HashTable)); Tcl_InitObjHashTable(oPtr->selfCls->classChainCache); } hPtr = Tcl_CreateHashEntry(oPtr->selfCls->classChainCache, methodNameObj, &isNew); } else { if (oPtr->chainCache == NULL) { oPtr->chainCache = (Tcl_HashTable *) Tcl_Alloc(sizeof(Tcl_HashTable)); Tcl_InitObjHashTable(oPtr->chainCache); } hPtr = Tcl_CreateHashEntry(oPtr->chainCache, methodNameObj, &isNew); } } |
︙ | ︙ | |||
1375 1376 1377 1378 1379 1380 1381 | TclOODeleteChain(oPtr->selfCls->destructorChainPtr); } oPtr->selfCls->destructorChainPtr = callPtr; callPtr->refCount++; } returnContext: | > | | 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 | TclOODeleteChain(oPtr->selfCls->destructorChainPtr); } oPtr->selfCls->destructorChainPtr = callPtr; callPtr->refCount++; } returnContext: contextPtr = (CallContext *) TclStackAlloc(oPtr->fPtr->interp, sizeof(CallContext)); contextPtr->oPtr = oPtr; /* * Corresponding TclOODecrRefCount() in TclOODeleteContext */ AddRef(oPtr); |
︙ | ︙ |
Changes to generic/tclOODefineCmds.c.
︙ | ︙ | |||
683 684 685 686 687 688 689 | } if (toPtr) { newHPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, toPtr, &isNew); if (hPtr == newHPtr) { renameToSelf: Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | } if (toPtr) { newHPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, toPtr, &isNew); if (hPtr == newHPtr) { renameToSelf: Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot rename method to itself", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "RENAME_TO_SELF", (char *)NULL); return TCL_ERROR; } else if (!isNew) { renameToExisting: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "method called %s already exists", TclGetString(toPtr))); |
︙ | ︙ | |||
759 760 761 762 763 764 765 | Tcl_HashSearch search; Tcl_HashEntry *hPtr; Tcl_Size soughtLen; const char *soughtStr, *matchedStr = NULL; if (objc < 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 | Tcl_HashSearch search; Tcl_HashEntry *hPtr; Tcl_Size soughtLen; const char *soughtStr, *matchedStr = NULL; if (objc < 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad call of unknown handler", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_UNKNOWN", (char *)NULL); return TCL_ERROR; } if (TclOOGetDefineCmdContext(interp) == NULL) { return TCL_ERROR; } |
︙ | ︙ | |||
793 794 795 796 797 798 799 | * Got one match, and only one match! */ Tcl_Obj **newObjv = (Tcl_Obj **) TclStackAlloc(interp, sizeof(Tcl_Obj*) * (objc - 1)); int result; | | | 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 | * Got one match, and only one match! */ Tcl_Obj **newObjv = (Tcl_Obj **) TclStackAlloc(interp, sizeof(Tcl_Obj*) * (objc - 1)); int result; newObjv[0] = Tcl_NewStringObj(matchedStr, TCL_AUTO_LENGTH); Tcl_IncrRefCount(newObjv[0]); if (objc > 2) { memcpy(newObjv + 1, objv + 2, sizeof(Tcl_Obj *) * (objc - 2)); } result = Tcl_EvalObjv(interp, objc - 1, newObjv, 0); Tcl_DecrRefCount(newObjv[0]); TclStackFree(interp, newObjv); |
︙ | ︙ | |||
896 897 898 899 900 901 902 | int objc, Tcl_Obj *const objv[]) { CallFrame *framePtr, **framePtrPtr = &framePtr; if (namespacePtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 | int objc, Tcl_Obj *const objv[]) { CallFrame *framePtr, **framePtrPtr = &framePtr; if (namespacePtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no definition namespace available", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); return TCL_ERROR; } /* * framePtrPtr is needed to satisfy GCC 3.3's strict aliasing rules. */ |
︙ | ︙ | |||
937 938 939 940 941 942 943 | Tcl_Object object; if ((iPtr->varFramePtr == NULL) || (iPtr->varFramePtr->isProcCallFrame != FRAME_IS_OO_DEFINE && iPtr->varFramePtr->isProcCallFrame != PRIVATE_FRAME)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "this command may only be called from within the context of" | | | > > > > > > > > > > > > > > > > > > > > > > > > > | 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 | Tcl_Object object; if ((iPtr->varFramePtr == NULL) || (iPtr->varFramePtr->isProcCallFrame != FRAME_IS_OO_DEFINE && iPtr->varFramePtr->isProcCallFrame != PRIVATE_FRAME)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "this command may only be called from within the context of" " an ::oo::define or ::oo::objdefine command", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); return NULL; } 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" " deleted", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); return NULL; } return object; } static inline void ReportMisuse( Tcl_Interp *interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); } static inline Class * GetDefineClass( Tcl_Interp *interp) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (!oPtr) { return NULL; } if (!oPtr->classPtr) { ReportMisuse(interp); return NULL; } return oPtr->classPtr; } /* * ---------------------------------------------------------------------- * * GetClassInOuterContext, GetNamespaceInOuterContext -- * * Wrappers round Tcl_GetObjectFromObj and TclGetNamespaceFromObj to |
︙ | ︙ | |||
988 989 990 991 992 993 994 | } oPtr = (Object *) Tcl_GetObjectFromObj(interp, className); iPtr->varFramePtr = savedFramePtr; if (oPtr == NULL) { return NULL; } if (oPtr->classPtr == NULL) { | | | 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 | } oPtr = (Object *) Tcl_GetObjectFromObj(interp, className); iPtr->varFramePtr = savedFramePtr; if (oPtr == NULL) { return NULL; } if (oPtr->classPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS", TclGetString(className), (char *)NULL); return NULL; } return oPtr->classPtr; } |
︙ | ︙ | |||
1487 1488 1489 1490 1491 1492 1493 | oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (oPtr->flags & ROOT_OBJECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | > | > | 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 | oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (oPtr->flags & ROOT_OBJECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not modify the class of the root object class", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); return TCL_ERROR; } if (oPtr->flags & ROOT_CLASS) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not modify the class of the class of classes", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); return TCL_ERROR; } /* * Parse the argument to get the class to set the object's class to. */ if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "className"); return TCL_ERROR; } clsPtr = GetClassInOuterContext(interp, objv[1], "the class of an object must be a class"); if (clsPtr == NULL) { return TCL_ERROR; } if (oPtr == clsPtr->thisPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not change classes into an instance of themselves", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); return TCL_ERROR; } /* * Set the object's class. */ |
︙ | ︙ | |||
1656 1657 1658 1659 1660 1661 1662 | { static const char *kindList[] = { "-class", "-instance", NULL }; int kind = 0; | < | < < < | | < < < | | | 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 | { static const char *kindList[] = { "-class", "-instance", NULL }; int kind = 0; Tcl_Namespace *nsPtr; Tcl_Obj *nsNamePtr, **storagePtr; Class *classPtr = GetDefineClass(interp); if (classPtr == NULL) { return TCL_ERROR; } if (classPtr->thisPtr->flags & (ROOT_OBJECT | ROOT_CLASS)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not modify the definition namespace of the root classes", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); return TCL_ERROR; } /* * Parse the arguments and work out what the user wants to do. */ |
︙ | ︙ | |||
1697 1698 1699 1700 1701 1702 1703 | if (!TclGetString(objv[objc - 1])[0]) { nsNamePtr = NULL; } else { nsPtr = GetNamespaceInOuterContext(interp, objv[objc - 1]); if (nsPtr == NULL) { return TCL_ERROR; } | | | | | 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 | if (!TclGetString(objv[objc - 1])[0]) { nsNamePtr = NULL; } else { nsPtr = GetNamespaceInOuterContext(interp, objv[objc - 1]); if (nsPtr == NULL) { return TCL_ERROR; } nsNamePtr = Tcl_NewStringObj(nsPtr->fullName, TCL_AUTO_LENGTH); Tcl_IncrRefCount(nsNamePtr); } /* * Update the correct field of the class definition. */ if (kind) { storagePtr = &classPtr->objDefinitionNs; } else { storagePtr = &classPtr->clsDefinitionNs; } if (*storagePtr != NULL) { Tcl_DecrRefCount(*storagePtr); } *storagePtr = nsNamePtr; return TCL_OK; } |
︙ | ︙ | |||
1749 1750 1751 1752 1753 1754 1755 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceDeleteMethod && !oPtr->classPtr) { | | < < | 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceDeleteMethod && !oPtr->classPtr) { ReportMisuse(interp); return TCL_ERROR; } for (i = 1; i < objc; i++) { /* * Delete the method structure from the appropriate hash table. */ |
︙ | ︙ | |||
1875 1876 1877 1878 1879 1880 1881 | oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } clsPtr = oPtr->classPtr; if (!isInstanceExport && !clsPtr) { | | < < | 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 | oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } clsPtr = oPtr->classPtr; if (!isInstanceExport && !clsPtr) { ReportMisuse(interp); return TCL_ERROR; } for (i = 1; i < objc; i++) { /* * Exporting is done by adding the PUBLIC_METHOD flag to the method * record. If there is no such method in this object or class (i.e. |
︙ | ︙ | |||
1969 1970 1971 1972 1973 1974 1975 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceForward && !oPtr->classPtr) { | | < < | 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceForward && !oPtr->classPtr) { ReportMisuse(interp); return TCL_ERROR; } isPublic = Tcl_StringMatch(TclGetString(objv[1]), PUBLIC_PATTERN) ? PUBLIC_METHOD : 0; if (IsPrivateDefine(interp)) { isPublic = TRUE_PRIVATE_METHOD; } |
︙ | ︙ | |||
2047 2048 2049 2050 2051 2052 2053 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceMethod && !oPtr->classPtr) { | | < < | 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceMethod && !oPtr->classPtr) { ReportMisuse(interp); return TCL_ERROR; } if (objc == 5) { if (Tcl_GetIndexFromObj(interp, objv[2], exportModes, "export flag", 0, &exportMode) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
2126 2127 2128 2129 2130 2131 2132 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceRenameMethod && !oPtr->classPtr) { | | < < | 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceRenameMethod && !oPtr->classPtr) { ReportMisuse(interp); return TCL_ERROR; } /* * Delete the method entry from the appropriate hash table, and transfer * the thing it points to to its new entry. To do this, we first need to * get the entries from the appropriate hash tables (this can generate a |
︙ | ︙ | |||
2188 2189 2190 2191 2192 2193 2194 | oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } clsPtr = oPtr->classPtr; if (!isInstanceUnexport && !clsPtr) { | | < < | 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 | oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } clsPtr = oPtr->classPtr; if (!isInstanceUnexport && !clsPtr) { ReportMisuse(interp); return TCL_ERROR; } for (i = 1; i < objc; i++) { /* * Unexporting is done by removing the PUBLIC_METHOD flag from the * method record. If there is no such method in this object or class |
︙ | ︙ | |||
2318 2319 2320 2321 2322 2323 2324 | */ int TclOODefineSlots( Foundation *fPtr) { const struct DeclaredSlot *slotInfoPtr; | | | | | 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 | */ int TclOODefineSlots( Foundation *fPtr) { const struct DeclaredSlot *slotInfoPtr; Tcl_Obj *getName = Tcl_NewStringObj("Get", TCL_AUTO_LENGTH); Tcl_Obj *setName = Tcl_NewStringObj("Set", TCL_AUTO_LENGTH); Tcl_Obj *resolveName = Tcl_NewStringObj("Resolve", TCL_AUTO_LENGTH); Class *slotCls; slotCls = ((Object *) Tcl_NewObjectInstance(fPtr->interp, (Tcl_Class) fPtr->classCls, "::oo::Slot", NULL, TCL_INDEX_NONE, NULL, 0))->classPtr; if (slotCls == NULL) { return TCL_ERROR; } |
︙ | ︙ | |||
2372 2373 2374 2375 2376 2377 2378 | ClassFilterGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { | | | < < < < < | | | < < < < < | | 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 | ClassFilterGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Obj *resultObj, *filterObj; Tcl_Size i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (classPtr == NULL) { return TCL_ERROR; } TclNewObj(resultObj); FOREACH(filterObj, classPtr->filters) { Tcl_ListObjAppendElement(NULL, resultObj, filterObj); } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } static int ClassFilterSet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Size filterc; Tcl_Obj **filterv; if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "filterList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (classPtr == NULL) { return TCL_ERROR; } else if (TclListObjGetElements(interp, objv[0], &filterc, &filterv) != TCL_OK) { return TCL_ERROR; } TclOOClassSetFilters(interp, classPtr, filterc, filterv); return TCL_OK; } /* * ---------------------------------------------------------------------- * * ClassMixinGet, ClassMixinSet -- |
︙ | ︙ | |||
2452 2453 2454 2455 2456 2457 2458 | ClassMixinGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { | | | < < < < < | | | < < < < < | > | | | | 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 | ClassMixinGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Obj *resultObj; Class *mixinPtr; Tcl_Size i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (classPtr == NULL) { return TCL_ERROR; } TclNewObj(resultObj); FOREACH(mixinPtr, classPtr->mixins) { Tcl_ListObjAppendElement(NULL, resultObj, TclOOObjectName(interp, mixinPtr->thisPtr)); } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } static int ClassMixinSet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Size mixinc, i; Tcl_Obj **mixinv; Class **mixins; /* The references to the classes to actually * install. */ Tcl_HashTable uniqueCheck; /* Note that this hash table is just used as a * set of class references; it has no payload * values and keys are always pointers. */ int isNew; if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "mixinList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (classPtr == NULL) { return TCL_ERROR; } else if (TclListObjGetElements(interp, objv[0], &mixinc, &mixinv) != TCL_OK) { return TCL_ERROR; } mixins = (Class **)TclStackAlloc(interp, sizeof(Class *) * mixinc); Tcl_InitHashTable(&uniqueCheck, TCL_ONE_WORD_KEYS); for (i = 0; i < mixinc; i++) { mixins[i] = GetClassInOuterContext(interp, mixinv[i], "may only mix in classes"); if (mixins[i] == NULL) { i--; goto freeAndError; } (void) Tcl_CreateHashEntry(&uniqueCheck, (void *) mixins[i], &isNew); if (!isNew) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "class should only be a direct mixin once", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS", (char *)NULL); goto freeAndError; } if (TclOOIsReachable(classPtr, mixins[i])) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not mix a class into itself", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", (char *)NULL); goto freeAndError; } } TclOOClassSetMixins(interp, classPtr, mixinc, mixins); Tcl_DeleteHashTable(&uniqueCheck); TclStackFree(interp, mixins); return TCL_OK; freeAndError: Tcl_DeleteHashTable(&uniqueCheck); TclStackFree(interp, mixins); |
︙ | ︙ | |||
2573 2574 2575 2576 2577 2578 2579 | ClassSuperGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { | | | < < < < < | | > | | < < < < < | > | 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 | ClassSuperGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Obj *resultObj; Class *superPtr; Tcl_Size i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (classPtr == NULL) { return TCL_ERROR; } TclNewObj(resultObj); FOREACH(superPtr, classPtr->superclasses) { Tcl_ListObjAppendElement(NULL, resultObj, TclOOObjectName(interp, superPtr->thisPtr)); } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } static int ClassSuperSet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Size superc, j; Tcl_Size i; Tcl_Obj **superv; Class **superclasses, *superPtr; Foundation *fPtr = (Foundation *) ((Interp *) interp)->objectFoundation; if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "superclassList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (classPtr == NULL) { return TCL_ERROR; } else if (classPtr->thisPtr->flags & ROOT_OBJECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not modify the superclass of the root object", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL); return TCL_ERROR; } else if (TclListObjGetElements(interp, objv[0], &superc, &superv) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
2654 2655 2656 2657 2658 2659 2660 | * * Note that zero classes is special, as it is equivalent to just the * class of objects. [Bug 9d61624b3d] */ if (superc == 0) { superclasses = (Class **)Tcl_Realloc(superclasses, sizeof(Class *)); | | | | | | | > | 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 | * * Note that zero classes is special, as it is equivalent to just the * class of objects. [Bug 9d61624b3d] */ if (superc == 0) { superclasses = (Class **)Tcl_Realloc(superclasses, sizeof(Class *)); if (TclOOIsReachable(fPtr->classCls, classPtr)) { superclasses[0] = fPtr->classCls; } else { superclasses[0] = fPtr->objectCls; } superc = 1; AddRef(superclasses[0]->thisPtr); } else { for (i = 0; i < superc; i++) { superclasses[i] = GetClassInOuterContext(interp, superv[i], "only a class can be a superclass"); if (superclasses[i] == NULL) { goto failedAfterAlloc; } for (j = 0; j < i; j++) { if (superclasses[j] == superclasses[i]) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "class should only be a direct superclass once", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS",(char *)NULL); goto failedAfterAlloc; } } if (TclOOIsReachable(classPtr, superclasses[i])) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to form circular dependency graph", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "CIRCULARITY", (char *)NULL); failedAfterAlloc: for (; i-- > 0 ;) { TclOODecrRefCount(superclasses[i]->thisPtr); } Tcl_Free(superclasses); return TCL_ERROR; |
︙ | ︙ | |||
2705 2706 2707 2708 2709 2710 2711 | /* * Install the list of superclasses into the class. Note that this also * involves splicing the class out of the superclasses' subclass list that * it used to be a member of and splicing it into the new superclasses' * subclass list. */ | | | | | | | | | | | 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 | /* * Install the list of superclasses into the class. Note that this also * involves splicing the class out of the superclasses' subclass list that * it used to be a member of and splicing it into the new superclasses' * subclass list. */ if (classPtr->superclasses.num != 0) { FOREACH(superPtr, classPtr->superclasses) { TclOORemoveFromSubclasses(classPtr, superPtr); TclOODecrRefCount(superPtr->thisPtr); } Tcl_Free(classPtr->superclasses.list); } classPtr->superclasses.list = superclasses; classPtr->superclasses.num = superc; FOREACH(superPtr, classPtr->superclasses) { TclOOAddToSubclasses(classPtr, superPtr); } BumpGlobalEpoch(interp, classPtr); return TCL_OK; } /* * ---------------------------------------------------------------------- * |
︙ | ︙ | |||
2741 2742 2743 2744 2745 2746 2747 | ClassVarsGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { | | | < < < < < | | | | < < < < < | 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 | ClassVarsGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Obj *resultObj; Tcl_Size i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (classPtr == NULL) { return TCL_ERROR; } TclNewObj(resultObj); if (IsPrivateDefine(interp)) { PrivateVariableMapping *privatePtr; FOREACH_STRUCT(privatePtr, classPtr->privateVariables) { Tcl_ListObjAppendElement(NULL, resultObj, privatePtr->variableObj); } } else { Tcl_Obj *variableObj; FOREACH(variableObj, classPtr->variables) { Tcl_ListObjAppendElement(NULL, resultObj, variableObj); } } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } static int ClassVarsSet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Size i; Tcl_Size varc; Tcl_Obj **varv; if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "filterList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (classPtr == NULL) { return TCL_ERROR; } else if (TclListObjGetElements(interp, objv[0], &varc, &varv) != TCL_OK) { return TCL_ERROR; } for (i = 0; i < varc; i++) { |
︙ | ︙ | |||
2829 2830 2831 2832 2833 2834 2835 | varName, "refer to an array element")); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", (char *)NULL); return TCL_ERROR; } } if (IsPrivateDefine(interp)) { | | | | | 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 | varName, "refer to an array element")); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", (char *)NULL); return TCL_ERROR; } } if (IsPrivateDefine(interp)) { InstallPrivateVariableMapping(&classPtr->privateVariables, varc, varv, classPtr->thisPtr->creationEpoch); } else { InstallStandardVariableMapping(&classPtr->variables, varc, varv); } return TCL_OK; } /* * ---------------------------------------------------------------------- * |
︙ | ︙ | |||
2991 2992 2993 2994 2995 2996 2997 | "may only mix in classes"); if (mixins[i] == NULL) { goto freeAndError; } (void) Tcl_CreateHashEntry(&uniqueCheck, (void *) mixins[i], &isNew); if (!isNew) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 | "may only mix in classes"); if (mixins[i] == NULL) { goto freeAndError; } (void) Tcl_CreateHashEntry(&uniqueCheck, (void *) mixins[i], &isNew); if (!isNew) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "class should only be a direct mixin once", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS", (char *)NULL); goto freeAndError; } } TclOOObjectSetMixins(oPtr, mixinc, mixins); TclStackFree(interp, mixins); |
︙ | ︙ | |||
3239 3240 3241 3242 3243 3244 3245 | ClassRPropsGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { | | | < < < < < | | | < < < < < | | | 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 | ClassRPropsGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Obj *resultObj, *propNameObj; int i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (classPtr == NULL) { return TCL_ERROR; } TclNewObj(resultObj); FOREACH(propNameObj, classPtr->properties.readable) { Tcl_ListObjAppendElement(NULL, resultObj, propNameObj); } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } static int ClassRPropsSet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Size varc; Tcl_Obj **varv; if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "filterList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (classPtr == NULL) { return TCL_ERROR; } else if (Tcl_ListObjGetElements(interp, objv[0], &varc, &varv) != TCL_OK) { return TCL_ERROR; } InstallReadableProps(&classPtr->properties, varc, varv); BumpGlobalEpoch(interp, classPtr); return TCL_OK; } static int ObjRPropsGet( TCL_UNUSED(void *), Tcl_Interp *interp, |
︙ | ︙ | |||
3436 3437 3438 3439 3440 3441 3442 | ClassWPropsGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { | | | < < < < < | | | < < < < < | | | 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 | ClassWPropsGet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Obj *resultObj, *propNameObj; int i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (classPtr == NULL) { return TCL_ERROR; } TclNewObj(resultObj); FOREACH(propNameObj, classPtr->properties.writable) { Tcl_ListObjAppendElement(NULL, resultObj, propNameObj); } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } static int ClassWPropsSet( TCL_UNUSED(void *), Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { Class *classPtr = GetDefineClass(interp); Tcl_Size varc; Tcl_Obj **varv; if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "propertyList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (classPtr == NULL) { return TCL_ERROR; } else if (Tcl_ListObjGetElements(interp, objv[0], &varc, &varv) != TCL_OK) { return TCL_ERROR; } InstallWritableProps(&classPtr->properties, varc, varv); BumpGlobalEpoch(interp, classPtr); return TCL_OK; } static int ObjWPropsGet( TCL_UNUSED(void *), Tcl_Interp *interp, |
︙ | ︙ |
Changes to generic/tclOOInfo.c.
︙ | ︙ | |||
121 122 123 124 125 126 127 | /* * Install into the [info] ensemble. */ infoCmd = Tcl_FindCommand(interp, "info", NULL, TCL_GLOBAL_ONLY); if (infoCmd) { Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict); | | > | | > | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | /* * Install into the [info] ensemble. */ infoCmd = Tcl_FindCommand(interp, "info", NULL, TCL_GLOBAL_ONLY); if (infoCmd) { Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict); Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("object", TCL_AUTO_LENGTH), Tcl_NewStringObj("::oo::InfoObject", TCL_AUTO_LENGTH)); Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("class", TCL_AUTO_LENGTH), Tcl_NewStringObj("::oo::InfoClass", TCL_AUTO_LENGTH)); Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict); } } /* * ---------------------------------------------------------------------- * |
︙ | ︙ | |||
265 266 267 268 269 270 271 | Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod((Method *)Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod((Method *)Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "definition not available for this kind of method", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } TclNewObj(resultObjs[0]); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_Obj *argObj; TclNewObj(argObj); Tcl_ListObjAppendElement(NULL, argObj, Tcl_NewStringObj(localPtr->name, TCL_AUTO_LENGTH)); if (localPtr->defValuePtr != NULL) { Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr); } Tcl_ListObjAppendElement(NULL, resultObjs[0], argObj); } } resultObjs[1] = TclOOGetMethodBody((Method *)Tcl_GetHashValue(hPtr)); |
︙ | ︙ | |||
377 378 379 380 381 382 383 | TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } prefixObj = TclOOGetFwdFromMethod((Method *)Tcl_GetHashValue(hPtr)); if (prefixObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "prefix argument list not available for this kind of method", | | | 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } prefixObj = TclOOGetFwdFromMethod((Method *)Tcl_GetHashValue(hPtr)); if (prefixObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "prefix argument list not available for this kind of method", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, prefixObj); return TCL_OK; |
︙ | ︙ | |||
611 612 613 614 615 616 617 | if (recurse) { const char **names; int i, numNames = TclOOGetSortedMethodList(oPtr, NULL, NULL, flag, &names); for (i=0 ; i<numNames ; i++) { Tcl_ListObjAppendElement(NULL, resultObj, | | | 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 | if (recurse) { const char **names; int i, numNames = TclOOGetSortedMethodList(oPtr, NULL, NULL, flag, &names); for (i=0 ; i<numNames ; i++) { Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(names[i], TCL_AUTO_LENGTH)); } if (numNames > 0) { Tcl_Free((void *)names); } } else if (oPtr->methodsPtr) { FOREACH_HASH(namePtr, mPtr, oPtr->methodsPtr) { if (mPtr->typePtr && (mPtr->flags & SCOPE_FLAGS) == flag) { |
︙ | ︙ | |||
680 681 682 683 684 685 686 | * Special entry for visibility control: pretend the method doesnt * exist. */ goto unknownMethod; } | | > | 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | * Special entry for visibility control: pretend the method doesnt * exist. */ goto unknownMethod; } Tcl_SetObjResult(interp, Tcl_NewStringObj( mPtr->typePtr->name, TCL_AUTO_LENGTH)); return TCL_OK; } /* * ---------------------------------------------------------------------- * * InfoObjectMixinsCmd -- |
︙ | ︙ | |||
787 788 789 790 791 792 793 | return TCL_ERROR; } oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]); if (oPtr == NULL) { return TCL_ERROR; } | | | | 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 | return TCL_ERROR; } oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]); if (oPtr == NULL) { return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewStringObj( oPtr->namespacePtr->fullName, TCL_AUTO_LENGTH)); return TCL_OK; } /* * ---------------------------------------------------------------------- * * InfoObjectVariablesCmd -- |
︙ | ︙ | |||
944 945 946 947 948 949 950 | } if (clsPtr->constructorPtr == NULL) { return TCL_OK; } procPtr = TclOOGetProcFromMethod(clsPtr->constructorPtr); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | | 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 | } if (clsPtr->constructorPtr == NULL) { return TCL_OK; } procPtr = TclOOGetProcFromMethod(clsPtr->constructorPtr); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "definition not available for this kind of method", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", (char *)NULL); return TCL_ERROR; } TclNewObj(resultObjs[0]); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_Obj *argObj; TclNewObj(argObj); Tcl_ListObjAppendElement(NULL, argObj, Tcl_NewStringObj(localPtr->name, TCL_AUTO_LENGTH)); if (localPtr->defValuePtr != NULL) { Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr); } Tcl_ListObjAppendElement(NULL, resultObjs[0], argObj); } } resultObjs[1] = TclOOGetMethodBody(clsPtr->constructorPtr); |
︙ | ︙ | |||
1011 1012 1013 1014 1015 1016 1017 | Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod((Method *)Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | | 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 | Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod((Method *)Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "definition not available for this kind of method", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } TclNewObj(resultObjs[0]); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_Obj *argObj; TclNewObj(argObj); Tcl_ListObjAppendElement(NULL, argObj, Tcl_NewStringObj(localPtr->name, TCL_AUTO_LENGTH)); if (localPtr->defValuePtr != NULL) { Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr); } Tcl_ListObjAppendElement(NULL, resultObjs[0], argObj); } } resultObjs[1] = TclOOGetMethodBody((Method *)Tcl_GetHashValue(hPtr)); |
︙ | ︙ | |||
1122 1123 1124 1125 1126 1127 1128 | if (clsPtr->destructorPtr == NULL) { return TCL_OK; } procPtr = TclOOGetProcFromMethod(clsPtr->destructorPtr); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 | if (clsPtr->destructorPtr == NULL) { return TCL_OK; } procPtr = TclOOGetProcFromMethod(clsPtr->destructorPtr); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "definition not available for this kind of method", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", (char *)NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOOGetMethodBody(clsPtr->destructorPtr)); return TCL_OK; } |
︙ | ︙ | |||
1210 1211 1212 1213 1214 1215 1216 | TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } prefixObj = TclOOGetFwdFromMethod((Method *)Tcl_GetHashValue(hPtr)); if (prefixObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "prefix argument list not available for this kind of method", | | | 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 | TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } prefixObj = TclOOGetFwdFromMethod((Method *)Tcl_GetHashValue(hPtr)); if (prefixObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "prefix argument list not available for this kind of method", TCL_AUTO_LENGTH)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, prefixObj); return TCL_OK; |
︙ | ︙ | |||
1366 1367 1368 1369 1370 1371 1372 | TclNewObj(resultObj); if (recurse) { const char **names; Tcl_Size i, numNames = TclOOGetSortedClassMethodList(clsPtr, flag, &names); for (i=0 ; i<numNames ; i++) { Tcl_ListObjAppendElement(NULL, resultObj, | | | 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 | TclNewObj(resultObj); if (recurse) { const char **names; Tcl_Size i, numNames = TclOOGetSortedClassMethodList(clsPtr, flag, &names); for (i=0 ; i<numNames ; i++) { Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(names[i], TCL_AUTO_LENGTH)); } if (numNames > 0) { Tcl_Free((void *)names); } } else { FOREACH_HASH_DECLS; |
︙ | ︙ | |||
1432 1433 1434 1435 1436 1437 1438 | /* * Special entry for visibility control: pretend the method doesnt * exist. */ goto unknownMethod; } | | > | 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 | /* * Special entry for visibility control: pretend the method doesnt * exist. */ goto unknownMethod; } Tcl_SetObjResult(interp, Tcl_NewStringObj( mPtr->typePtr->name, TCL_AUTO_LENGTH)); return TCL_OK; } /* * ---------------------------------------------------------------------- * * InfoClassMixinsCmd -- |
︙ | ︙ | |||
1664 1665 1666 1667 1668 1669 1670 | * Get the call context and render its call chain. */ contextPtr = TclOOGetCallContext(oPtr, objv[2], PUBLIC_METHOD, NULL, NULL, NULL); if (contextPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 | * Get the call context and render its call chain. */ contextPtr = TclOOGetCallContext(oPtr, objv[2], PUBLIC_METHOD, NULL, NULL, NULL); if (contextPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot construct any call chain", TCL_AUTO_LENGTH)); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOORenderCallChain(interp, contextPtr->callPtr)); TclOODeleteContext(contextPtr); return TCL_OK; } |
︙ | ︙ | |||
1709 1710 1711 1712 1713 1714 1715 | /* * Get an render the stereotypical call chain. */ callPtr = TclOOGetStereotypeCallChain(clsPtr, objv[2], PUBLIC_METHOD); if (callPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 | /* * Get an render the stereotypical call chain. */ callPtr = TclOOGetStereotypeCallChain(clsPtr, objv[2], PUBLIC_METHOD); if (callPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot construct any call chain", TCL_AUTO_LENGTH)); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOORenderCallChain(interp, callPtr)); TclOODeleteChain(callPtr); return TCL_OK; } |
︙ | ︙ | |||
1867 1868 1869 1870 1871 1872 1873 | } /* * ---------------------------------------------------------------------- * * SortPropList -- * Sort a list of names of properties. Simple support function. Assumes | | | | 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 | } /* * ---------------------------------------------------------------------- * * SortPropList -- * Sort a list of names of properties. Simple support function. Assumes * that the list Tcl_Obj is unshared, sensible to modify at all (i.e., a * simple list) and doesn't have a string representation. * * ---------------------------------------------------------------------- */ static int PropNameCompare( const void *a, |
︙ | ︙ | |||
1891 1892 1893 1894 1895 1896 1897 | static void SortPropList( Tcl_Obj *list) { Tcl_Size ec; Tcl_Obj **ev; | | | 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 | static void SortPropList( Tcl_Obj *list) { Tcl_Size ec; Tcl_Obj **ev; TclListObjGetElements(NULL, list, &ec, &ev); qsort(ev, ec, sizeof(Tcl_Obj *), PropNameCompare); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclOOInt.h.
︙ | ︙ | |||
95 96 97 98 99 100 101 | /* Callback to allow for additional cleanup * after the method executes. */ GetFrameInfoValueProc *gfivProc; /* Callback to allow for fine tuning of how * the method reports itself. */ } ProcedureMethod; | > | > | | > | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | /* Callback to allow for additional cleanup * after the method executes. */ GetFrameInfoValueProc *gfivProc; /* Callback to allow for fine tuning of how * the method reports itself. */ } ProcedureMethod; enum ProcedureMethodVersions { TCLOO_PROCEDURE_METHOD_VERSION = 0 }; /* * 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. */ enum ProcedureMethodFlags { USE_DECLARER_NS = 0x80 }; /* * Forwarded methods have the following extra information. */ typedef struct ForwardMethod { Tcl_Obj *prefixObj; /* The list of values to use to replace the |
︙ | ︙ | |||
205 206 207 208 209 210 211 | * 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; | | | | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | * 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; Tcl_Size creationEpoch; /* Unique value to make comparisons of objects * easier. */ 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 * the void *values that are the values * of each piece of attached metadata. This * field starts out as NULL and is only * allocated if metadata is attached. */ |
︙ | ︙ | |||
232 233 234 235 236 237 238 | Tcl_Command myclassCommand; /* Reference to this object's class dispatcher * command. */ PropertyStorage properties; /* Information relating to the lists of * properties that this object *claims* to * support. */ } Object; | > | | | | | | | | | | | > | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | Tcl_Command myclassCommand; /* Reference to this object's class dispatcher * command. */ PropertyStorage properties; /* Information relating to the lists of * properties that this object *claims* to * support. */ } Object; enum ObjectFlags { OBJECT_DESTRUCTING = 1, /* Indicates that an object is being or has * been destroyed. */ DESTRUCTOR_CALLED = 2, /* Indicates that evaluation of destructor * script for the object has began */ // OO_UNUSED_4 = 4, /* No longer used. */ ROOT_OBJECT = 0x1000, /* Flag to say that this object is the root of * the class hierarchy and should be treated * specially during teardown. */ 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. */ 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. */ 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). */ FORCE_UNKNOWN = 0x10000, /* States that we are *really* looking up the * unknown method handler at that point. */ 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. */ 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 { |
︙ | ︙ | |||
439 440 441 442 443 444 445 | * [next] command. */ CallChain *callPtr; /* The actual call chain. */ } CallContext; /* * Bits for the 'flags' field of the call chain. */ | | | | | | | < | | > | 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | * [next] command. */ CallChain *callPtr; /* The actual call chain. */ } CallContext; /* * Bits for the 'flags' field of the call chain. */ enum CallChainFlags { PUBLIC_METHOD = 0x01, /* This is a public (exported) method. */ PRIVATE_METHOD = 0x02, /* This is a private (class's direct instances * only) method. Supports itcl. */ 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] */ SCOPE_FLAGS = (PUBLIC_METHOD | PRIVATE_METHOD | TRUE_PRIVATE_METHOD) }; /* * Structure containing definition information about basic class methods. */ typedef struct { const char *name; /* Name of the method in question. */ |
︙ | ︙ | |||
514 515 516 517 518 519 520 | */ MODULE_SCOPE void TclOOAddToInstances(Object *oPtr, Class *clsPtr); 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); | | | | | | | | | | | 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 | */ MODULE_SCOPE void TclOOAddToInstances(Object *oPtr, Class *clsPtr); 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 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, 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, Tcl_Obj *const *objv, Tcl_Size skip, Tcl_Object *objectPtr); MODULE_SCOPE Object * TclNewObjectInstanceCommon(Tcl_Interp *interp, Class *classPtr, |
︙ | ︙ |
Changes to generic/tclPanic.c.
︙ | ︙ | |||
76 77 78 79 80 81 82 | const char *format, ...) { va_list argList; char *arg1, *arg2, *arg3; /* Additional arguments (variable in number) * to pass to fprintf. */ char *arg4, *arg5, *arg6, *arg7, *arg8; | < | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | const char *format, ...) { va_list argList; char *arg1, *arg2, *arg3; /* Additional arguments (variable in number) * to pass to fprintf. */ char *arg4, *arg5, *arg6, *arg7, *arg8; va_start(argList, format); arg1 = va_arg(argList, char *); arg2 = va_arg(argList, char *); arg3 = va_arg(argList, char *); arg4 = va_arg(argList, char *); arg5 = va_arg(argList, char *); |
︙ | ︙ |
Changes to generic/tclParse.h.
1 2 3 4 | /* * Minimal set of shared macro definitions and declarations so that multiple * source files can make use of the parsing table in tclParse.c */ | | | | | | | | | | | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * Minimal set of shared macro definitions and declarations so that multiple * source files can make use of the parsing table in tclParse.c */ enum TclParseTypes { TYPE_NORMAL = 0, TYPE_SPACE = 0x1, TYPE_COMMAND_END = 0x2, TYPE_SUBS = 0x4, TYPE_QUOTE = 0x8, TYPE_CLOSE_PAREN = 0x10, TYPE_CLOSE_BRACK = 0x20, TYPE_BRACE = 0x40, TYPE_OPEN_PAREN = 0x80, TYPE_BAD_ARRAY_INDEX = ( TYPE_OPEN_PAREN | TYPE_CLOSE_PAREN | TYPE_QUOTE | TYPE_BRACE) }; #define CHAR_TYPE(c) tclCharTypeTable[(unsigned char)(c)] MODULE_SCOPE const unsigned char tclCharTypeTable[]; |
Changes to generic/tclPathObj.c.
︙ | ︙ | |||
1514 1515 1516 1517 1518 1519 1520 | Tcl_Obj * Tcl_FSNewNativePath( const Tcl_Filesystem *fromFilesystem, void *clientData) { Tcl_Obj *pathPtr = NULL; FsPath *fsPathPtr; | < | 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 | Tcl_Obj * Tcl_FSNewNativePath( const Tcl_Filesystem *fromFilesystem, void *clientData) { Tcl_Obj *pathPtr = NULL; FsPath *fsPathPtr; if (fromFilesystem->internalToNormalizedProc != NULL) { pathPtr = (*fromFilesystem->internalToNormalizedProc)(clientData); } if (pathPtr == NULL) { return NULL; } |
︙ | ︙ |
Changes to generic/tclProcess.c.
︙ | ︙ | |||
346 347 348 349 350 351 352 | TclNewIntObj(errorStrings[4], resolvedPid); *errorObjPtr = Tcl_NewListObj(5, errorStrings); } return TCL_PROCESS_UNKNOWN_STATUS; } } | < | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | TclNewIntObj(errorStrings[4], resolvedPid); *errorObjPtr = Tcl_NewListObj(5, errorStrings); } return TCL_PROCESS_UNKNOWN_STATUS; } } /* *---------------------------------------------------------------------- * * BuildProcessStatusObj -- * * Build a list object with process status. The first element is always * a standard Tcl return value, which can be either TCL_OK or TCL_ERROR. |
︙ | ︙ | |||
511 512 513 514 515 516 517 | if (objc != 1 && objc != 2) { Tcl_WrongNumArgs(interp, 1, savedobjv, "?switches? ?pids?"); return TCL_ERROR; } if (objc == 1) { /* | | | | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | if (objc != 1 && objc != 2) { Tcl_WrongNumArgs(interp, 1, savedobjv, "?switches? ?pids?"); return TCL_ERROR; } if (objc == 1) { /* * Return a dict with all child process statuses. */ dict = Tcl_NewDictObj(); Tcl_MutexLock(&infoTablesMutex); for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); entry != NULL; entry = Tcl_NextHashEntry(&search)) { info = (ProcessInfo *) Tcl_GetHashValue(entry); RefreshProcessInfo(info, options); |
︙ | ︙ |
Changes to generic/tclScan.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | #include "tclTomMath.h" #include <assert.h> /* * Flag values used by Tcl_ScanObjCmd. */ | > | | | | < | | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include "tclTomMath.h" #include <assert.h> /* * Flag values used by Tcl_ScanObjCmd. */ enum TclScanFlags { SCAN_NOSKIP = 0x1, /* Don't skip blanks. */ SCAN_SUPPRESS = 0x2, /* Suppress assignment. */ SCAN_UNSIGNED = 0x4, /* Read an unsigned value. */ SCAN_WIDTH = 0x8, /* A width value was supplied. */ SCAN_LONGER = 0x400, /* Asked for a wide value. */ SCAN_BIG = 0x800 /* Asked for a bignum value. */ }; /* * The following structure contains the information associated with a * character set. */ typedef struct { |
︙ | ︙ |
Changes to generic/tclStrToD.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | #define copysign _copysign #endif #ifndef PRIx64 # define PRIx64 TCL_LL_MODIFIER "x" #endif | < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #define copysign _copysign #endif #ifndef PRIx64 # define PRIx64 TCL_LL_MODIFIER "x" #endif /* * This code supports (at least hypothetically), IBM, Cray, VAX and IEEE-754 * floating point; of these, only IEEE-754 can represent NaN. IEEE-754 can be * uniquely determined by radix and by the widths of significand and exponent. */ #if (FLT_RADIX == 2) && (DBL_MANT_DIG == 53) && (DBL_MAX_EXP == 1024) |
︙ | ︙ | |||
4226 4227 4228 4229 4230 4231 4232 | * less - unless we're working in F format - because we know that * three groups of digits will always suffice for %#.17e, the * longest format that doesn't introduce empty precision. * * Extract the next group of digits. */ | < | 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 | * less - unless we're working in F format - because we know that * three groups of digits will always suffice for %#.17e, the * longest format that doesn't introduce empty precision. * * Extract the next group of digits. */ if ((err != MP_OKAY) || (mp_div(&b, &S, &dig, &b) != MP_OKAY) || (dig.used > 1)) { Tcl_Panic("wrong digit!"); } digit = dig.dp[0]; for (j = g-1; j >= 0; --j) { int t = itens[j]; |
︙ | ︙ | |||
4843 4844 4845 4846 4847 4848 4849 | const void *big) /* Integer to convert. */ { mp_int b; int bits, shift, i, lsb; double r; mp_err err; const mp_int *a = (const mp_int *)big; | < | 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 | const void *big) /* Integer to convert. */ { mp_int b; int bits, shift, i, lsb; double r; mp_err err; const mp_int *a = (const mp_int *)big; /* * We need a 'mantBits'-bit significand. Determine what shift will * give us that. */ bits = mp_count_bits(a); |
︙ | ︙ |
Changes to generic/tclStringObj.c.
︙ | ︙ | |||
455 456 457 458 459 460 461 | TclGetString(objPtr); numChars = TclNumUtfChars(objPtr->bytes, objPtr->length); } return numChars; } | < | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 | TclGetString(objPtr); numChars = TclNumUtfChars(objPtr->bytes, objPtr->length); } return numChars; } /* *---------------------------------------------------------------------- * * TclCheckEmptyString -- * * Determine whether the string value of an object is or would be the * empty string, without generating a string representation. |
︙ | ︙ | |||
3515 3516 3517 3518 3519 3520 3521 | * * Side effects: * String representations may be generated. Internal representation may * be changed. * *--------------------------------------------------------------------------- */ | < | 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 | * * Side effects: * String representations may be generated. Internal representation may * be changed. * *--------------------------------------------------------------------------- */ static int UniCharNcasememcmp( const void *ucsPtr, /* Unicode string to compare to uct. */ const void *uctPtr, /* Unicode string ucs is compared to. */ size_t numChars) /* Number of Unichars to compare. */ { |
︙ | ︙ |
Changes to generic/tclThread.c.
︙ | ︙ | |||
140 141 142 143 144 145 146 | static void RememberSyncObject( void *objPtr, /* Pointer to sync object */ SyncObjRecord *recPtr) /* Record of sync objects */ { void **newList; int i, j; | < | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | static void RememberSyncObject( void *objPtr, /* Pointer to sync object */ SyncObjRecord *recPtr) /* Record of sync objects */ { void **newList; int i, j; /* * Reuse any free slot in the list. */ for (i=0 ; i < recPtr->num ; ++i) { if (recPtr->list[i] == NULL) { |
︙ | ︙ |
Changes to generic/tclTomMathStubLib.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | #include "tclInt.h" #include "tclTomMath.h" MODULE_SCOPE const TclTomMathStubs *tclTomMathStubsPtr; const TclTomMathStubs *tclTomMathStubsPtr = NULL; | < | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include "tclInt.h" #include "tclTomMath.h" MODULE_SCOPE const TclTomMathStubs *tclTomMathStubsPtr; const TclTomMathStubs *tclTomMathStubsPtr = NULL; /* *---------------------------------------------------------------------- * * TclTomMathInitStubs -- * * Initializes the Stubs table for Tcl's subset of libtommath |
︙ | ︙ |
Changes to generic/tclTrace.c.
︙ | ︙ | |||
78 79 80 81 82 83 84 | * further traces execute. * TCL_TRACE_EXEC_DIRECT - This execution trace is triggered directly * by the command being traced, not because of * an internal trace. * The flag 'TCL_TRACE_DESTROYED' may also be used in command execution traces. */ | > | | | | | > | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | * further traces execute. * TCL_TRACE_EXEC_DIRECT - This execution trace is triggered directly * by the command being traced, not because of * an internal trace. * The flag 'TCL_TRACE_DESTROYED' may also be used in command execution traces. */ enum TraceCommandFlags { TCL_TRACE_ENTER_DURING_EXEC = 4, TCL_TRACE_LEAVE_DURING_EXEC = 8, TCL_TRACE_ANY_EXEC = 15, TCL_TRACE_EXEC_IN_PROGRESS = 0x10, TCL_TRACE_EXEC_DIRECT = 0x20 }; /* * Forward declarations for functions defined in this file: */ enum traceOptionsEnum { TRACE_ADD, TRACE_INFO, TRACE_REMOVE |
︙ | ︙ | |||
1011 1012 1013 1014 1015 1016 1017 | if ((cmdPtr->compileProc != NULL) && !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)){ Interp *iPtr = (Interp *) interp; iPtr->compileEpoch++; } cmdPtr->flags |= CMD_HAS_EXEC_TRACES; } | < | 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 | if ((cmdPtr->compileProc != NULL) && !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)){ Interp *iPtr = (Interp *) interp; iPtr->compileEpoch++; } cmdPtr->flags |= CMD_HAS_EXEC_TRACES; } return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ |
Changes to generic/tclUtil.c.
︙ | ︙ | |||
84 85 86 87 88 89 90 | * in other cases this means an overestimate of the * required size. * * For more details, see the comments on the Tcl*Scan*Element and * Tcl*Convert*Element routines. */ | > | | | | | | > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | * in other cases this means an overestimate of the * required size. * * For more details, see the comments on the Tcl*Scan*Element and * Tcl*Convert*Element routines. */ enum ScanConvertFlags { COMPAT = 1, CONVERT_NONE = 0, CONVERT_BRACE = 2, CONVERT_ESCAPE = 4, CONVERT_MASK = (CONVERT_BRACE | CONVERT_ESCAPE), CONVERT_ANY = 16 }; /* * Prototypes for functions defined later in this file. */ static void ClearHash(Tcl_HashTable *tablePtr); static void FreeProcessGlobalValue(void *clientData); |
︙ | ︙ | |||
2612 2613 2614 2615 2616 2617 2618 | if (length > (TCL_SIZE_MAX - dsPtr->length - 1)) { Tcl_Panic("max size for a Tcl value (%" TCL_SIZE_MODIFIER "d bytes) exceeded", TCL_SIZE_MAX); return NULL; /* NOTREACHED */ } newSize = length + dsPtr->length + 1; | < | 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 | if (length > (TCL_SIZE_MAX - dsPtr->length - 1)) { Tcl_Panic("max size for a Tcl value (%" TCL_SIZE_MODIFIER "d bytes) exceeded", TCL_SIZE_MAX); return NULL; /* NOTREACHED */ } newSize = length + dsPtr->length + 1; if (newSize > dsPtr->spaceAvl) { if (dsPtr->string == dsPtr->staticSpace) { char *newString; newString = (char *) TclAllocEx(newSize, &dsPtr->spaceAvl); memcpy(newString, dsPtr->string, dsPtr->length); dsPtr->string = newString; |
︙ | ︙ |
Changes to generic/tclZipfs.c.
︙ | ︙ | |||
213 214 215 216 217 218 219 | */ typedef struct ZipEntry { char *name; /* The full pathname of the virtual file */ ZipFile *zipFilePtr; /* The ZIP file holding this virtual file */ size_t offset; /* Data offset into memory mapped ZIP file */ int numBytes; /* Uncompressed size of the virtual file. | | | < < < > > > > > > | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | */ typedef struct ZipEntry { char *name; /* The full pathname of the virtual file */ ZipFile *zipFilePtr; /* The ZIP file holding this virtual file */ size_t offset; /* Data offset into memory mapped ZIP file */ int numBytes; /* Uncompressed size of the virtual file. * -1 for zip64 */ int numCompressedBytes; /* Compressed size of the virtual file. * -1 for zip64 */ int compressMethod; /* Compress method */ int isDirectory; /* 0 if file, 1 if directory, -1 if root */ int depth; /* Number of slashes in path. */ int crc32; /* CRC-32 as stored in ZIP */ int timestamp; /* Modification time */ int isEncrypted; /* True if data is encrypted */ int flags; unsigned char *data; /* File data if written */ struct ZipEntry *next; /* Next file in the same archive */ struct ZipEntry *tnext; /* Next top-level dir in archive */ } ZipEntry; enum ZipEntryFlags { ZE_F_CRC_COMPARED = 1, /* The CRC has been compared. */ ZE_F_CRC_CORRECT = 2, /* Only meaningful if ZE_F_CRC_COMPARED is set */ ZE_F_VOLUME = 4 /* Entry corresponds to //zipfs:/ */ }; /* * File channel for file contained in mounted ZIP archive. * * Regarding data buffers: * For READ-ONLY files that are not encrypted and not compressed (zip STORE * method), ubuf points directly to the mapped zip file data in memory. No |
︙ | ︙ |
Changes to generic/tclZlib.c.
︙ | ︙ | |||
126 127 128 129 130 131 132 | Tcl_TimerToken timer; /* Timer used for keeping events fresh. */ Tcl_Obj *compDictObj; /* Byte-array object containing compression * dictionary (not dictObj!) to use if * necessary. */ } ZlibChannelData; /* | | > > | | | | | | | < | < < < < < | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | Tcl_TimerToken timer; /* Timer used for keeping events fresh. */ Tcl_Obj *compDictObj; /* Byte-array object containing compression * dictionary (not dictObj!) to use if * necessary. */ } ZlibChannelData; /* * Value bits for the flags field. */ enum ZlibChannelDataFlags { ASYNC = 0x01, /* This is an asynchronous channel. */ IN_HEADER = 0x02, /* Whether the inHeader field has been * registered with the input compressor. */ OUT_HEADER = 0x04, /* Whether the outputHeader field has been * registered with the output decompressor. */ STREAM_DECOMPRESS = 0x08, /* Signal decompress pending data. */ STREAM_DONE = 0x10 /* Signal stream end up to transform input. */ }; /* * Size of buffers allocated by default, and the range it can be set to. The * same sorts of values apply to streams, except with different limits (they * permit byte-level activity). Channels always use bytes unless told to use * larger buffers. */ |
︙ | ︙ | |||
3868 3869 3870 3871 3872 3873 3874 | char *buf, int toRead, int flush, int *errorCodePtr) { int e, written, resBytes = 0; Tcl_Obj *errObj; | < | 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 | char *buf, int toRead, int flush, int *errorCodePtr) { int e, written, resBytes = 0; Tcl_Obj *errObj; cd->flags &= ~STREAM_DECOMPRESS; cd->inStream.next_out = (Bytef *) buf; cd->inStream.avail_out = toRead; while (cd->inStream.avail_out > 0) { e = inflate(&cd->inStream, flush); |
︙ | ︙ |
Changes to unix/tclSelectNotfy.c.
︙ | ︙ | |||
176 177 178 179 180 181 182 | * terminates. This condition is used to deal with the signal mask, too. */ static pthread_cond_t notifierCV = PTHREAD_COND_INITIALIZER; /* * The pollState bits: | | > | > | < | > | | < | < < | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | * terminates. This condition is used to deal with the signal mask, too. */ static pthread_cond_t notifierCV = PTHREAD_COND_INITIALIZER; /* * The pollState bits: */ enum PollStateBits { POLL_WANT = 0x1, /* Set by each thread before it waits on its * condition variable. Checked by the notifier * before it does select. */ POLL_DONE = 0x2 /* Set by the notifier if it goes into select * after seeing POLL_WANT. The idea is to * ensure it tries a select with the same bits * the initial thread had set. */ }; /* * This is the thread ID of the notifier thread that does select. */ static Tcl_ThreadId notifierThread; |
︙ | ︙ |
Changes to unix/tclUnixFCmd.c.
︙ | ︙ | |||
51 52 53 54 55 56 57 | #endif /* * The following constants specify the type of callback when * TraverseUnixTree() calls the traverseProc() */ | > | | | > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #endif /* * The following constants specify the type of callback when * TraverseUnixTree() calls the traverseProc() */ enum TraverseUnixTreeType { DOTREE_PRED = 1, /* pre-order directory */ DOTREE_POSTD = 2, /* post-order directory */ DOTREE_F = 3 /* regular file */ }; /* * Fallback temporary file location the temporary file generation code. Can be * overridden at compile time for when it is known that temp files can't be * written to /tmp (hello, iOS!). */ |
︙ | ︙ |
Changes to unix/tclUnixSock.c.
︙ | ︙ | |||
82 83 84 85 86 87 88 | }; /* * These bits may be OR'ed together into the "flags" field of a TcpState * structure. */ | > | | | < | | | < | | | > | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | }; /* * These bits may be OR'ed together into the "flags" field of a TcpState * structure. */ enum TcpStateFlags { TCP_NONBLOCKING = 1<<0, /* Socket with non-blocking I/O. */ TCP_ASYNC_CONNECT = 1<<1, /* Async connect in progress. */ TCP_ASYNC_PENDING = 1<<4, /* TcpConnect was called to process an async * connect. This flag indicates that reentry * is still pending. */ TCP_ASYNC_FAILED = 1<<5, /* An async connect finally failed. */ TCP_ASYNC_TEST_MODE = 1<<8 /* Async testing activated. Do not * automatically continue connection * process. */ }; /* * The following defines the maximum length of the listen queue. This is the * number of outstanding yet-to-be-serviced requests for a connection on a * server socket, more than this number of outstanding requests and the * connection request will fail. */ |
︙ | ︙ |
Changes to win/tclWinChan.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | #include "tclWinInt.h" #include "tclIO.h" /* * State flags used in the info structures below. */ | > | | | > > | | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include "tclWinInt.h" #include "tclIO.h" /* * State flags used in the info structures below. */ enum FileInfoFlags { FILE_PENDING = (1<<0), /* Message is pending in the queue. */ FILE_ASYNC = (1<<1), /* Channel is non-blocking. */ FILE_APPEND = (1<<2) /* File is in append mode. */ }; enum TclWinFileType { FILE_TYPE_SERIAL = (FILE_TYPE_PIPE + 1), FILE_TYPE_CONSOLE = (FILE_TYPE_PIPE + 2) }; /* * The following structure contains per-instance data for a file based * channel. */ typedef struct FileInfo { |
︙ | ︙ | |||
104 105 106 107 108 109 110 | /* * This structure describes the channel type structure for file based IO. */ static const Tcl_ChannelType fileChannelType = { "file", /* Type name. */ TCL_CHANNEL_VERSION_5, /* v5 channel */ | | | | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | /* * This structure describes the channel type structure for file based IO. */ static const Tcl_ChannelType fileChannelType = { "file", /* Type name. */ TCL_CHANNEL_VERSION_5, /* v5 channel */ NULL, /* Close proc. */ FileInputProc, /* Input proc. */ FileOutputProc, /* Output proc. */ NULL, NULL, /* Set option proc. */ FileGetOptionProc, /* Get option proc. */ FileWatchProc, /* Set up the notifier to watch the channel. */ FileGetHandleProc, /* Get an OS handle from channel. */ FileCloseProc, /* close2proc. */ FileBlockProc, /* Set blocking or non-blocking mode.*/ NULL, /* flush proc. */ |
︙ | ︙ |
Changes to win/tclWinConsole.c.
︙ | ︙ | |||
141 142 143 144 145 146 147 | DWORD lastError; /* An error caused by the last background * operation. Set to 0 if no error has been * detected. */ int numRefs; /* See comments above */ int permissions; /* TCL_READABLE for input consoles, TCL_WRITABLE * for output. Only one or the other can be set. */ int flags; | > | | > > | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | DWORD lastError; /* An error caused by the last background * operation. Set to 0 if no error has been * detected. */ int numRefs; /* See comments above */ int permissions; /* TCL_READABLE for input consoles, TCL_WRITABLE * for output. Only one or the other can be set. */ int flags; } ConsoleHandleInfo; enum ConsoleHandleInfoFlags { CONSOLE_DATA_AWAITED = 1 /* An interpreter is awaiting data */ }; /* * This structure describes per-instance data for a console based channel. * * Note on locking - this structure has no locks because it is accessed * only from the thread owning channel EXCEPT when a console traverses it * looking for a channel that is watching for events on the console. Even |
︙ | ︙ | |||
186 187 188 189 190 191 192 | int permissions; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, or TCL_EXCEPTION: indicates * which operations are valid on the file. */ int watchMask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, or TCL_EXCEPTION: indicates * which events should be reported. */ int flags; /* State flags */ | > > > | | | < > | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | int permissions; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, or TCL_EXCEPTION: indicates * which operations are valid on the file. */ int watchMask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, or TCL_EXCEPTION: indicates * which events should be reported. */ int flags; /* State flags */ } ConsoleChannelInfo; enum ConsoleChannelInfoFlags { CONSOLE_EVENT_QUEUED = 1, /* Notification event already queued */ CONSOLE_ASYNC = 2, /* Channel is non-blocking. */ CONSOLE_READ_OPS = 4 /* Channel supports read-related ops. */ }; /* * The following structure is what is added to the Tcl event queue when * console events are generated. */ typedef struct { |
︙ | ︙ | |||
275 276 277 278 279 280 281 | * the number of consoles (as opposed to channels) is small (only stdin, * stdout and stderr), and contention low. More finer-grained locking would * likely not only complicate implementation but be slower due to multiple * locks being held. Note console channels also differ from other Tcl * channel types in that the channel<->OS descriptor mapping is not one-to-one. */ SRWLOCK gConsoleLock; | < | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | * the number of consoles (as opposed to channels) is small (only stdin, * stdout and stderr), and contention low. More finer-grained locking would * likely not only complicate implementation but be slower due to multiple * locks being held. Note console channels also differ from other Tcl * channel types in that the channel<->OS descriptor mapping is not one-to-one. */ SRWLOCK gConsoleLock; /* Process-wide list of console handles. Access control through gConsoleLock */ static ConsoleHandleInfo *gConsoleHandleInfoList; /* * Process-wide list of channels that are listening for events. Again access * control through gConsoleLock. Common list for all threads is simplifies |
︙ | ︙ |
Changes to win/tclWinDde.c.
︙ | ︙ | |||
80 81 82 83 84 85 86 | static int ddeIsServer = 0; #define TCL_DDE_VERSION "1.4.5" #define TCL_DDE_PACKAGE_NAME "dde" #define TCL_DDE_SERVICE_NAME L"TclEval" #define TCL_DDE_EXECUTE_RESULT L"$TCLEVAL$EXECUTE$RESULT" | > | | | > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | static int ddeIsServer = 0; #define TCL_DDE_VERSION "1.4.5" #define TCL_DDE_PACKAGE_NAME "dde" #define TCL_DDE_SERVICE_NAME L"TclEval" #define TCL_DDE_EXECUTE_RESULT L"$TCLEVAL$EXECUTE$RESULT" enum TclDdeFlags { DDE_FLAG_ASYNC = 1, DDE_FLAG_BINARY = 2, DDE_FLAG_FORCE = 4 }; TCL_DECLARE_MUTEX(ddeMutex) #if (TCL_MAJOR_VERSION < 9) && defined(TCL_MINOR_VERSION) && (TCL_MINOR_VERSION < 7) # if TCL_UTF_MAX > 3 # define Tcl_WCharToUtfDString(a,b,c) Tcl_WinTCharToUtf((TCHAR *)(a),(b)*sizeof(WCHAR),c) # define Tcl_UtfToWCharDString(a,b,c) (WCHAR *)Tcl_WinUtfToTChar(a,b,c) |
︙ | ︙ |
Changes to win/tclWinFCmd.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | #include "tclWinInt.h" /* * The following constants specify the type of callback when * TraverseWinTree() calls the traverseProc() */ | > | | | | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include "tclWinInt.h" /* * The following constants specify the type of callback when * TraverseWinTree() calls the traverseProc() */ enum TraversalNodeType { DOTREE_PRED = 1, /* pre-order directory */ DOTREE_POSTD = 2, /* post-order directory */ DOTREE_F = 3, /* regular file */ DOTREE_LINK = 4 /* symbolic link */ }; /* * Callbacks for file attributes code. */ static int GetWinFileAttributes(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr); |
︙ | ︙ | |||
46 47 48 49 50 51 52 | WIN_HIDDEN_ATTRIBUTE, WIN_LONGNAME_ATTRIBUTE, WIN_READONLY_ATTRIBUTE, WIN_SHORTNAME_ATTRIBUTE, WIN_SYSTEM_ATTRIBUTE }; | | > < | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | WIN_HIDDEN_ATTRIBUTE, WIN_LONGNAME_ATTRIBUTE, WIN_READONLY_ATTRIBUTE, WIN_SHORTNAME_ATTRIBUTE, WIN_SYSTEM_ATTRIBUTE }; static const int attributeArray[] = { FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_HIDDEN, 0, FILE_ATTRIBUTE_READONLY, 0, FILE_ATTRIBUTE_SYSTEM}; const char *const tclpFileAttrStrings[] = { "-archive", "-hidden", "-longname", "-readonly", "-shortname", "-system", NULL }; const TclFileAttrProcs tclpFileAttrProcs[] = { |
︙ | ︙ |
Changes to win/tclWinInt.h.
︙ | ︙ | |||
71 72 73 74 75 76 77 | typedef struct TclPipeThreadInfo { HANDLE evControl; /* Auto-reset event used by the main thread to * signal when the pipe thread should attempt * to do read/write operation. Additionally * used as signal to stop (state set to -1) */ volatile LONG state; /* Indicates current state of the thread */ | | < | | | | | | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | typedef struct TclPipeThreadInfo { HANDLE evControl; /* Auto-reset event used by the main thread to * signal when the pipe thread should attempt * to do read/write operation. Additionally * used as signal to stop (state set to -1) */ volatile LONG state; /* Indicates current state of the thread */ void *clientData; /* Referenced data of the main thread */ HANDLE evWakeUp; /* Optional wake-up event worker set by shutdown */ } TclPipeThreadInfo; /* If pipe-workers will use some tcl subsystem, we can use Tcl_Alloc without * more overhead for finalize thread (should be executed anyway) * * #define _PTI_USE_CKALLOC 1 */ /* * State of the pipe-worker. * * State PTI_STATE_STOP possible from idle state only, worker owns TI structure. * Otherwise PTI_STATE_END used (main thread hold ownership of the TI). */ enum PipeThreadInfoStates { PTI_STATE_IDLE = 0, /* idle or not yet initialzed */ PTI_STATE_WORK = 1, /* in work */ PTI_STATE_STOP = 2, /* thread should stop work (owns TI structure) */ PTI_STATE_END = 4, /* thread should stop work (worker is busy) */ PTI_STATE_DOWN = 8 /* worker is down */ }; MODULE_SCOPE TclPipeThreadInfo * TclPipeThreadCreateTI(TclPipeThreadInfo **pipeTIPtr, void *clientData, HANDLE wakeEvent); MODULE_SCOPE int TclPipeThreadWaitForSignal(TclPipeThreadInfo **pipeTIPtr); static inline void |
︙ | ︙ |
Changes to win/tclWinPipe.c.
︙ | ︙ | |||
27 28 29 30 31 32 33 | TCL_DECLARE_MUTEX(pipeMutex) /* * The following defines identify the various types of applications that run * under windows. There is special case code for the various types. */ | | | | | | > > | > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | TCL_DECLARE_MUTEX(pipeMutex) /* * The following defines identify the various types of applications that run * under windows. There is special case code for the various types. */ enum TclApplicationTypeIds { APPL_NONE = 0, APPL_DOS = 1, APPL_WIN3X = 2, APPL_WIN32 = 3 }; /* * The following constants and structures are used to encapsulate the state of * various types of files used in a pipeline. This used to have a 1 && 2 that * supported Win32s. */ enum WinFileTypes { WIN_FILE = 3 /* Basic Win32 file. */ }; /* * This structure encapsulates the common state associated with all file types * used in a pipeline. */ typedef struct { |
︙ | ︙ | |||
64 65 66 67 68 69 70 | int dwProcessId; struct ProcInfo *nextPtr; } ProcInfo; static ProcInfo *procList; /* | | > | | | < < < < < | | > | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | int dwProcessId; struct ProcInfo *nextPtr; } ProcInfo; static ProcInfo *procList; /* * Bit masks used in the flags and readFlags fields of the PipeInfo structure * below. */ enum PipeInfoFlags { PIPE_PENDING = (1<<0), /* Message is pending in the queue. */ PIPE_ASYNC = (1<<1), /* Channel is non-blocking. */ PIPE_EOF = (1<<2), /* Pipe has reached EOF. */ PIPE_EXTRABYTE = (1<<3) /* The reader thread has consumed one byte. */ }; /* * TODO: It appears the whole EXTRABYTE machinery is in place to support * outdated Win 95 systems. If this can be confirmed, much code can be * deleted. */ |
︙ | ︙ | |||
109 110 111 112 113 114 115 | Tcl_ThreadId threadId; /* Thread to which events should be reported. * This value is used by the reader/writer * threads. */ TclPipeThreadInfo *writeTI; /* Thread info of writer and reader, this */ TclPipeThreadInfo *readTI; /* structure owned by corresponding thread. */ HANDLE writeThread; /* Handle to writer thread. */ HANDLE readThread; /* Handle to reader thread. */ | < | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | Tcl_ThreadId threadId; /* Thread to which events should be reported. * This value is used by the reader/writer * threads. */ TclPipeThreadInfo *writeTI; /* Thread info of writer and reader, this */ TclPipeThreadInfo *readTI; /* structure owned by corresponding thread. */ HANDLE writeThread; /* Handle to writer thread. */ HANDLE readThread; /* Handle to reader thread. */ HANDLE writable; /* Manual-reset event to signal when the * writer thread has finished waiting for the * current buffer to be written. */ HANDLE readable; /* Manual-reset event to signal when the * reader thread has finished waiting for * input. */ DWORD writeError; /* An error caused by the last background |
︙ | ︙ | |||
199 200 201 202 203 204 205 | * This structure describes the channel type structure for command pipe based * I/O. */ static const Tcl_ChannelType pipeChannelType = { "pipe", /* Type name. */ TCL_CHANNEL_VERSION_5, /* v5 channel */ | | | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | * This structure describes the channel type structure for command pipe based * I/O. */ static const Tcl_ChannelType pipeChannelType = { "pipe", /* Type name. */ TCL_CHANNEL_VERSION_5, /* v5 channel */ NULL, /* Close proc. */ PipeInputProc, /* Input proc. */ PipeOutputProc, /* Output proc. */ NULL, /* Seek proc. */ NULL, /* Set option proc. */ NULL, /* Get option proc. */ PipeWatchProc, /* Set up notifier to watch the channel. */ PipeGetHandleProc, /* Get an OS handle from channel. */ |
︙ | ︙ |
Changes to win/tclWinPort.h.
︙ | ︙ | |||
242 243 244 245 246 247 248 | #ifndef ETXTBSY # define ETXTBSY 139 /* Text file or pseudo-device busy */ #endif #ifndef EWOULDBLOCK # define EWOULDBLOCK 140 /* Operation would block */ #endif | < | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | #ifndef ETXTBSY # define ETXTBSY 139 /* Text file or pseudo-device busy */ #endif #ifndef EWOULDBLOCK # define EWOULDBLOCK 140 /* Operation would block */ #endif /* Visual Studio doesn't have these, so just choose some high numbers */ #ifndef ESOCKTNOSUPPORT # define ESOCKTNOSUPPORT 240 /* Socket type not supported */ #endif #ifndef ESHUTDOWN # define ESHUTDOWN 241 /* Can't send after socket shutdown */ #endif |
︙ | ︙ | |||
411 412 413 414 415 416 417 | # ifdef S_IFLNK # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) # else # define S_ISLNK(m) 0 # endif #endif /* !S_ISLNK */ | < | 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | # ifdef S_IFLNK # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) # else # define S_ISLNK(m) 0 # endif #endif /* !S_ISLNK */ /* * Define MAXPATHLEN in terms of MAXPATH if available */ #ifndef MAXPATH # define MAXPATH MAX_PATH #endif /* MAXPATH */ |
︙ | ︙ | |||
519 520 521 522 523 524 525 | #define TclpSysFree(ptr) (HeapFree(GetProcessHeap(), \ 0, (HGLOBAL)ptr)) #define TclpSysRealloc(ptr, size) ((void*)HeapReAlloc(GetProcessHeap(), \ 0, (LPVOID)ptr, size)) /* This type is not defined in the Windows headers */ #define socklen_t int | < | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 | #define TclpSysFree(ptr) (HeapFree(GetProcessHeap(), \ 0, (HGLOBAL)ptr)) #define TclpSysRealloc(ptr, size) ((void*)HeapReAlloc(GetProcessHeap(), \ 0, (LPVOID)ptr, size)) /* This type is not defined in the Windows headers */ #define socklen_t int /* * The following macros have trivial definitions, allowing generic code to * address platform-specific issues. */ #define TclpReleaseFile(file) Tcl_Free(file) |
︙ | ︙ |
Changes to win/tclWinReg.c.
︙ | ︙ | |||
49 50 51 52 53 54 55 | #define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) /* * The following flag is used in OpenKeys to indicate that the specified key * should be created if it doesn't currently exist. */ | > | > | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) /* * The following flag is used in OpenKeys to indicate that the specified key * should be created if it doesn't currently exist. */ enum TclRegFlags { REG_CREATE = 1 }; /* * The following tables contain the mapping from registry root names to the * system predefined keys. */ static const char *const rootKeyNames[] = { |
︙ | ︙ | |||
382 383 384 385 386 387 388 | HKEY key; /* * Create the key and then close it immediately. */ mode |= KEY_ALL_ACCESS; | | | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | HKEY key; /* * Create the key and then close it immediately. */ mode |= KEY_ALL_ACCESS; if (OpenKey(interp, objv[n], mode, REG_CREATE, &key) != TCL_OK) { return TCL_ERROR; } RegCloseKey(key); return TCL_OK; } else if (argc == 3) { return SetValue(interp, objv[n], objv[n+1], objv[n+2], NULL, mode); |
︙ | ︙ |
Changes to win/tclWinSerial.c.
︙ | ︙ | |||
29 30 31 32 33 34 35 | TCL_DECLARE_MUTEX(serialMutex) /* * Bit masks used in the flags field of the SerialInfo structure below. */ | > | | < < < < < | | | | | | | | > | > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | TCL_DECLARE_MUTEX(serialMutex) /* * Bit masks used in the flags field of the SerialInfo structure below. */ enum SerialInfoFlags { SERIAL_PENDING = (1<<0), /* Message is pending in the queue. */ SERIAL_ASYNC = (1<<1), /* Channel is non-blocking. */ SERIAL_EOF = (1<<2), /* Serial has reached EOF. */ SERIAL_ERROR = (1<<4), /* * Bit masks used for noting whether to drain or discard output on close. * They are disjoint from each other; at most one may be set at a time. */ SERIAL_CLOSE_DRAIN = (1<<6),/* Drain all output on close. */ SERIAL_CLOSE_DISCARD = (1<<7), /* Discard all output on close. */ SERIAL_CLOSE_MASK = (SERIAL_CLOSE_DRAIN | SERIAL_CLOSE_DISCARD) /* Both two bits above. */ }; /* * Default time to block between checking status on the serial port. */ #define SERIAL_DEFAULT_BLOCKTIME 10 /* 10 msec */ |
︙ | ︙ | |||
200 201 202 203 204 205 206 | * This structure describes the channel type structure for command serial * based IO. */ static const Tcl_ChannelType serialChannelType = { "serial", /* Type name. */ TCL_CHANNEL_VERSION_5, /* v5 channel */ | | | | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | * This structure describes the channel type structure for command serial * based IO. */ static const Tcl_ChannelType serialChannelType = { "serial", /* Type name. */ TCL_CHANNEL_VERSION_5, /* v5 channel */ NULL, /* Close proc. */ SerialInputProc, /* Input proc. */ SerialOutputProc, /* Output proc. */ NULL, /* Seek proc. */ SerialSetOptionProc, /* Set option proc. */ SerialGetOptionProc, /* Get option proc. */ SerialWatchProc, /* Set up notifier to watch the channel. */ SerialGetHandleProc, /* Get an OS handle from channel. */ SerialCloseProc, /* close2proc. */ SerialBlockProc, /* Set blocking or non-blocking mode.*/ NULL, /* flush proc. */ NULL, /* handler proc. */ NULL, /* wide seek proc */ SerialThreadActionProc, /* thread action proc */ NULL /* truncate */ }; /* *---------------------------------------------------------------------- * * SerialInit -- * |
︙ | ︙ | |||
608 609 610 611 612 613 614 | int errorCode = 0, result = 0; SerialInfo *infoPtr, **nextPtrPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) { return EINVAL; } | < | 606 607 608 609 610 611 612 613 614 615 616 617 618 619 | int errorCode = 0, result = 0; SerialInfo *infoPtr, **nextPtrPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) { return EINVAL; } if (serialPtr->validMask & TCL_READABLE) { PurgeComm(serialPtr->handle, PURGE_RXABORT | PURGE_RXCLEAR); CloseHandle(serialPtr->osRead.hEvent); } serialPtr->validMask &= ~TCL_READABLE; |
︙ | ︙ | |||
1475 1476 1477 1478 1479 1480 1481 | * Use the pointer to keep the channel names unique, in case the handles * are shared between multiple channels (stdin/stdout). */ TclWinGenerateChannelName(channelName, "file", infoPtr); infoPtr->channel = Tcl_CreateChannel(&serialChannelType, channelName, infoPtr, permissions); | < | 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 | * Use the pointer to keep the channel names unique, in case the handles * are shared between multiple channels (stdin/stdout). */ TclWinGenerateChannelName(channelName, "file", infoPtr); infoPtr->channel = Tcl_CreateChannel(&serialChannelType, channelName, infoPtr, permissions); SetupComm(handle, infoPtr->sysBufRead, infoPtr->sysBufWrite); PurgeComm(handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); /* * Default is blocking. |
︙ | ︙ |
Changes to win/tclWinSock.c.
︙ | ︙ | |||
77 78 79 80 81 82 83 | static const WCHAR className[] = L"TclSocket"; TCL_DECLARE_MUTEX(socketMutex) /* * The following defines declare the messages used on socket windows. */ | > | | | > > > | | > | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | static const WCHAR className[] = L"TclSocket"; TCL_DECLARE_MUTEX(socketMutex) /* * The following defines declare the messages used on socket windows. */ enum TclSocketMessageID { SOCKET_MESSAGE = WM_USER+1, /* There is something waiting. */ SOCKET_SELECT = WM_USER+2, /* Change what we are waiting for. */ SOCKET_TERMINATE = WM_USER+3/* Terminate the worker thread. */ }; enum SocketSelectOp { SELECT = TRUE, UNSELECT = FALSE, }; /* * This is needed to comply with the strict aliasing rules of GCC, but it also * simplifies casting between the different sockaddr types. */ typedef union { |
︙ | ︙ | |||
160 161 162 163 164 165 166 | }; /* * These bits may be OR'ed together into the "flags" field of a TcpState * structure. */ | > | | | < | < | < | | | < | | | > | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | }; /* * These bits may be OR'ed together into the "flags" field of a TcpState * structure. */ enum TcpStateFlags { TCP_NONBLOCKING = (1<<0), /* Socket with non-blocking I/O. */ TCP_ASYNC_CONNECT = (1<<1), /* Async connect in progress. */ SOCKET_EOF = (1<<2), /* A zero read happened on the socket. */ SOCKET_PENDING = (1<<3), /* A message has been sent for this socket */ TCP_ASYNC_PENDING = (1<<4), /* TcpConnect was called to process an async * connect. This flag indicates that reentry * is still pending. */ TCP_ASYNC_FAILED = (1<<5), /* An async connect finally failed. */ TCP_ASYNC_TEST_MODE = (1<<8)/* Async testing activated. Do not * automatically continue connection * process */ }; /* * The following structure is what is added to the Tcl event queue when a * socket event occurs. */ typedef struct { |
︙ | ︙ | |||
197 198 199 200 201 202 203 | /* * This defines the minimum buffersize maintained by the kernel. */ #define TCP_BUFFER_SIZE 4096 | < | < | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | /* * This defines the minimum buffersize maintained by the kernel. */ #define TCP_BUFFER_SIZE 4096 typedef struct { HWND hwnd; /* Handle to window for socket messages. */ HANDLE socketThread; /* Thread handling the window */ Tcl_ThreadId threadId; /* Parent thread. */ HANDLE readyEvent; /* Event indicating that a socket event is * ready. Also used to indicate that the * socketThread has been initialized and has * started. */ HANDLE socketListLock; /* Win32 Event to lock the socketList */ TcpState *pendingTcpState; /* This socket is opened but not jet in the * list. This value is also checked by * the event structure. */ TcpState *socketList; /* Every open socket in this thread has an * entry on this list. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; |
︙ | ︙ | |||
289 290 291 292 293 294 295 | static ProcessGlobalValue hostName = {0, 0, NULL, NULL, InitializeHostName, NULL, NULL}; /* * Simple wrapper round the SendMessage syscall. */ | > | > > > > | | | | 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | static ProcessGlobalValue hostName = {0, 0, NULL, NULL, InitializeHostName, NULL, NULL}; /* * Simple wrapper round the SendMessage syscall. */ static inline void SendSelectMessage( ThreadSpecificData *tsdPtr, enum SocketSelectOp message, TcpState *payload) { SendMessageW(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) message, (LPARAM) payload); } /* * Address print debug functions */ #if 0 void printaddrinfo( |
︙ | ︙ | |||
2837 2838 2839 2840 2841 2842 2843 | * Populate new FD. */ fds->fd = socket; fds->statePtr = statePtr; fds->next = NULL; } | | < | 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 | * Populate new FD. */ fds->fd = socket; fds->statePtr = statePtr; fds->next = NULL; } /* *---------------------------------------------------------------------- * * NewSocketInfo -- * * This function allocates and initializes a new TcpState structure. * |
︙ | ︙ | |||
2893 2894 2895 2896 2897 2898 2899 | * Processes socket events off the system queue. * *---------------------------------------------------------------------- */ static int WaitForSocketEvent( | | | < | 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 | * Processes socket events off the system queue. * *---------------------------------------------------------------------- */ static int WaitForSocketEvent( TcpState *statePtr, /* Information about this socket. */ int events, /* Events to look for. May be one of * FD_READ or FD_WRITE. */ int *errorCodePtr) /* Where to store errors? */ { int result = 1; int oldMode; ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey); /* |
︙ | ︙ | |||
3241 3242 3243 3244 3245 3246 3247 | static void TcpThreadActionProc( void *instanceData, int action) { ThreadSpecificData *tsdPtr; TcpState *statePtr = (TcpState *)instanceData; | | | 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 | static void TcpThreadActionProc( void *instanceData, int action) { ThreadSpecificData *tsdPtr; TcpState *statePtr = (TcpState *)instanceData; enum SocketSelectOp notifyCmd; if (action == TCL_CHANNEL_THREAD_INSERT) { /* * Ensure that socket subsystem is initialized in this thread, or else * sockets will not work. */ |
︙ | ︙ |
Changes to win/tclWinThrd.c.
︙ | ︙ | |||
86 87 88 89 90 91 92 | } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; #endif /* TCL_THREADS */ /* * State bits for the thread. | > > | | | | < | < < < | | | | > | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; #endif /* TCL_THREADS */ /* * State bits for the thread. */ enum ThreadStateFlags { WIN_THREAD_UNINIT = 0x0, /* Uninitialized. Must be zero because of the * way ThreadSpecificData is created. */ WIN_THREAD_RUNNING = 0x1, /* Running, not waiting. */ WIN_THREAD_BLOCKED = 0x2 /* Waiting, or trying to wait. */ }; /* * The per condition queue pointers and the Mutex used to serialize access to * the queue. */ typedef struct { CRITICAL_SECTION condLock; /* Lock to serialize queuing on the * condition. */ ThreadSpecificData *firstPtr; /* Queue pointers */ ThreadSpecificData *lastPtr; } WinCondition; /* * Additions by AOL for specialized thread memory allocator. */ #ifdef USE_THREAD_ALLOC static DWORD tlsKey; typedef struct { Tcl_Mutex tlock; CRITICAL_SECTION wlock; } allocMutex; #endif /* USE_THREAD_ALLOC */ /* * The per thread data passed from TclpThreadCreate * to TclWinThreadStart. */ typedef struct { LPTHREAD_START_ROUTINE lpStartAddress; /* Original startup routine */ LPVOID lpParameter; /* Original startup data */ unsigned int fpControl; /* Floating point control word from the * main thread */ } WinThread; /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
922 923 924 925 926 927 928 | if (winCondPtr != NULL) { DeleteCriticalSection(&winCondPtr->condLock); Tcl_Free(winCondPtr); *condPtr = NULL; } } | < < < | 921 922 923 924 925 926 927 928 929 930 931 932 933 934 | if (winCondPtr != NULL) { DeleteCriticalSection(&winCondPtr->condLock); Tcl_Free(winCondPtr); *condPtr = NULL; } } /* * Additions by AOL for specialized thread memory allocator. */ #ifdef USE_THREAD_ALLOC Tcl_Mutex * TclpNewAllocMutex(void) |
︙ | ︙ | |||
1025 1026 1027 1028 1029 1030 1031 | success = TlsFree(tlsKey); if (!success) { Tcl_Panic("TlsFree failed from TclpFreeAllocCache"); } } } #endif /* USE_THREAD_ALLOC */ | < | 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 | success = TlsFree(tlsKey); if (!success) { Tcl_Panic("TlsFree failed from TclpFreeAllocCache"); } } } #endif /* USE_THREAD_ALLOC */ void * TclpThreadCreateKey(void) { DWORD *key; key = (DWORD *)TclpSysAlloc(sizeof *key); |
︙ | ︙ |
Changes to win/tclWinTime.c.
︙ | ︙ | |||
99 100 101 102 103 104 105 | static struct { int initialized; /* 1 if initialized, 0 otherwise */ int perfCounter; /* 1 if performance counter usable for wide * clicks */ double microsecsScale; /* Denominator scale between clock / microsecs */ } wideClick = {0, 0, 0.0}; | < | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | static struct { int initialized; /* 1 if initialized, 0 otherwise */ int perfCounter; /* 1 if performance counter usable for wide * clicks */ double microsecsScale; /* Denominator scale between clock / microsecs */ } wideClick = {0, 0, 0.0}; /* * Declarations for functions defined later in this file. */ static void StopCalibration(void *clientData); static DWORD WINAPI CalibrationThread(LPVOID arg); static void UpdateTimeEachSecond(void); |
︙ | ︙ | |||
210 211 212 213 214 215 216 | * Try to use high resolution timer. */ if (IsTimeNative() && (usecSincePosixEpoch = NativeGetMicroseconds())) { return (Tcl_WideUInt) usecSincePosixEpoch; } else { /* | | | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | * Try to use high resolution timer. */ if (IsTimeNative() && (usecSincePosixEpoch = NativeGetMicroseconds())) { return (Tcl_WideUInt) usecSincePosixEpoch; } else { /* * Use the Tcl_GetTime abstraction to get the time in microseconds, as * nearly as we can, and return it. */ Tcl_Time now; /* Current Tcl time */ GetTime(&now); return ((unsigned long long)(now.sec)*1000000ULL) + (unsigned long long)(now.usec); } |
︙ | ︙ |