Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch novem-64bit-sizes Excluding Merge-Ins
This is equivalent to a diff from 7ae862fc61 to ec3dfc657f
2013-09-30
| ||
09:44 | merge novem Closed-Leaf check-in: ec3dfc657f user: dkf tags: novem-64bit-sizes | |
09:44 | merge trunk check-in: e25b747b7d user: jan.nijtmans tags: novem | |
08:31 | merge trunk check-in: 7ae862fc61 user: jan.nijtmans tags: novem | |
2013-09-29
| ||
20:46 | merge novem check-in: 2170e066f2 user: dkf tags: novem-64bit-sizes | |
2013-09-28
| ||
22:52 | typo; spotted by stu check-in: 97ba1dcf13 user: dkf tags: trunk | |
2013-09-27
| ||
17:39 | merge trunk check-in: f55df9a649 user: jan.nijtmans tags: novem | |
Changes to generic/regc_locale.c.
︙ | ︙ | |||
744 745 746 747 748 749 750 | NOTE(REG_ULOCALE); /* * Search table. */ Tcl_DStringInit(&ds); | | | 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | NOTE(REG_ULOCALE); /* * Search table. */ Tcl_DStringInit(&ds); np = Tcl_UniCharToUtfDString(startp, (size_t) len, &ds); for (cn=cnames; cn->name!=NULL; cn++) { if (strlen(cn->name)==len && strncmp(cn->name, np, len)==0) { break; /* NOTE BREAK OUT */ } } Tcl_DStringFree(&ds); if (cn->name != NULL) { |
︙ | ︙ | |||
916 917 918 919 920 921 922 | /* * Extract the class name */ len = endp - startp; Tcl_DStringInit(&ds); | | | 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 | /* * Extract the class name */ len = endp - startp; Tcl_DStringInit(&ds); np = Tcl_UniCharToUtfDString(startp, (size_t) len, &ds); /* * Map the name to the corresponding enumerated value. */ index = -1; for (namePtr=classNames,i=0 ; *namePtr!=NULL ; namePtr++,i++) { |
︙ | ︙ |
Changes to generic/tcl.decls.
︙ | ︙ | |||
36 37 38 39 40 41 42 | const char *name, const char *version, int exact, void *clientDataPtr) } declare 2 { void Tcl_Panic(const char *format, ...) } declare 3 { | | | | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | const char *name, const char *version, int exact, void *clientDataPtr) } declare 2 { void Tcl_Panic(const char *format, ...) } declare 3 { char *Tcl_Alloc(size_t size) } declare 4 { void Tcl_Free(char *ptr) } declare 5 { char *Tcl_Realloc(char *ptr, size_t size) } declare 6 { char *Tcl_DbCkalloc(size_t size, const char *file, int line) } declare 7 { void Tcl_DbCkfree(char *ptr, const char *file, int line) } declare 8 { char *Tcl_DbCkrealloc(char *ptr, size_t size, const char *file, int line) } # Tcl_CreateFileHandler and Tcl_DeleteFileHandler are only available on unix, # but they are part of the old generic interface, so we include them here for # compatibility reasons. |
︙ | ︙ | |||
82 83 84 85 86 87 88 | declare 14 { int Tcl_AppendAllObjTypes(Tcl_Interp *interp, Tcl_Obj *objPtr) } declare 15 { void Tcl_AppendStringsToObj(Tcl_Obj *objPtr, ...) } declare 16 { | | | | | | | > | 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 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 154 | declare 14 { int Tcl_AppendAllObjTypes(Tcl_Interp *interp, Tcl_Obj *objPtr) } declare 15 { void Tcl_AppendStringsToObj(Tcl_Obj *objPtr, ...) } declare 16 { void Tcl_AppendToObj(Tcl_Obj *objPtr, const char *bytes, size_t length) } declare 17 { Tcl_Obj *Tcl_ConcatObj(size_t objc, Tcl_Obj *const objv[]) } declare 18 { int Tcl_ConvertToType(Tcl_Interp *interp, Tcl_Obj *objPtr, const Tcl_ObjType *typePtr) } declare 19 { void Tcl_DbDecrRefCount(Tcl_Obj *objPtr, const char *file, int line) } declare 20 { void Tcl_DbIncrRefCount(Tcl_Obj *objPtr, const char *file, int line) } declare 21 { int Tcl_DbIsShared(Tcl_Obj *objPtr, const char *file, int line) } declare 22 { Tcl_Obj *Tcl_DbNewBooleanObj(int boolValue, const char *file, int line) } declare 23 { Tcl_Obj *Tcl_DbNewByteArrayObj(const unsigned char *bytes, size_t length, const char *file, int line) } declare 24 { Tcl_Obj *Tcl_DbNewDoubleObj(double doubleValue, const char *file, int line) } declare 25 { Tcl_Obj *Tcl_DbNewListObj(size_t objc, Tcl_Obj *const *objv, const char *file, int line) } declare 26 { Tcl_Obj *Tcl_DbNewLongObj(long longValue, const char *file, int line) } declare 27 { Tcl_Obj *Tcl_DbNewObj(const char *file, int line) } declare 28 { Tcl_Obj *Tcl_DbNewStringObj(const char *bytes, size_t length, const char *file, int line) } declare 29 { Tcl_Obj *Tcl_DuplicateObj(Tcl_Obj *objPtr) } declare 30 { void TclFreeObj(Tcl_Obj *objPtr) } declare 31 { int Tcl_GetBoolean(Tcl_Interp *interp, const char *src, int *boolPtr) } declare 32 { int Tcl_GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *boolPtr) } declare 33 { unsigned char *Tcl_GetByteArrayFromObj(Tcl_Obj *objPtr, size_t *lengthPtr) } declare 34 { int Tcl_GetDouble(Tcl_Interp *interp, const char *src, double *doublePtr) } declare 35 { int Tcl_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *doublePtr) |
︙ | ︙ | |||
166 167 168 169 170 171 172 | declare 39 { int Tcl_GetLongFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, long *longPtr) } declare 40 { const Tcl_ObjType *Tcl_GetObjType(const char *typeName) } declare 41 { | | | | | | | | | | | | | | | | 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 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 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 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | declare 39 { int Tcl_GetLongFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, long *longPtr) } declare 40 { const Tcl_ObjType *Tcl_GetObjType(const char *typeName) } declare 41 { char *Tcl_GetStringFromObj(Tcl_Obj *objPtr, size_t *lengthPtr) } declare 42 { void Tcl_InvalidateStringRep(Tcl_Obj *objPtr) } declare 43 { int Tcl_ListObjAppendList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *elemListPtr) } declare 44 { int Tcl_ListObjAppendElement(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *objPtr) } declare 45 { int Tcl_ListObjGetElements(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *objcPtr, Tcl_Obj ***objvPtr) } declare 46 { int Tcl_ListObjIndex(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t index, Tcl_Obj **objPtrPtr) } declare 47 { int Tcl_ListObjLength(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *lengthPtr) } declare 48 { int Tcl_ListObjReplace(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t first, size_t count, size_t objc, Tcl_Obj *const objv[]) } declare 49 { Tcl_Obj *Tcl_NewBooleanObj(int boolValue) } declare 50 { Tcl_Obj *Tcl_NewByteArrayObj(const unsigned char *bytes, size_t length) } declare 51 { Tcl_Obj *Tcl_NewDoubleObj(double doubleValue) } declare 52 { Tcl_Obj *Tcl_NewIntObj(int intValue) } declare 53 { Tcl_Obj *Tcl_NewListObj(size_t objc, Tcl_Obj *const objv[]) } declare 54 { Tcl_Obj *Tcl_NewLongObj(long longValue) } declare 55 { Tcl_Obj *Tcl_NewObj(void) } declare 56 { Tcl_Obj *Tcl_NewStringObj(const char *bytes, size_t length) } declare 57 { void Tcl_SetBooleanObj(Tcl_Obj *objPtr, int boolValue) } declare 58 { unsigned char *Tcl_SetByteArrayLength(Tcl_Obj *objPtr, size_t length) } declare 59 { void Tcl_SetByteArrayObj(Tcl_Obj *objPtr, const unsigned char *bytes, size_t length) } declare 60 { void Tcl_SetDoubleObj(Tcl_Obj *objPtr, double doubleValue) } declare 61 { void Tcl_SetIntObj(Tcl_Obj *objPtr, int intValue) } declare 62 { void Tcl_SetListObj(Tcl_Obj *objPtr, size_t objc, Tcl_Obj *const objv[]) } declare 63 { void Tcl_SetLongObj(Tcl_Obj *objPtr, long longValue) } declare 64 { void Tcl_SetObjLength(Tcl_Obj *objPtr, size_t length) } declare 65 { void Tcl_SetStringObj(Tcl_Obj *objPtr, const char *bytes, size_t length) } declare 66 { void Tcl_AddErrorInfo(Tcl_Interp *interp, const char *message) } # Removed in 9.0: #declare 67 { # void Tcl_AddObjErrorInfo(Tcl_Interp *interp, const char *message, |
︙ | ︙ | |||
305 306 307 308 309 310 311 | declare 81 { int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan) } declare 82 { int Tcl_CommandComplete(const char *cmd) } declare 83 { | | | | | | | | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | declare 81 { int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan) } declare 82 { int Tcl_CommandComplete(const char *cmd) } declare 83 { char *Tcl_Concat(size_t argc, const char *const *argv) } declare 84 { size_t Tcl_ConvertElement(const char *src, char *dst, int flags) } declare 85 { size_t Tcl_ConvertCountedElement(const char *src, size_t length, char *dst, int flags) } declare 86 { int Tcl_CreateAlias(Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, size_t argc, const char *const *argv) } declare 87 { int Tcl_CreateAliasObj(Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, size_t objc, Tcl_Obj *const objv[]) } declare 88 { Tcl_Channel Tcl_CreateChannel(const Tcl_ChannelType *typePtr, const char *chanName, ClientData instanceData, int mask) } declare 89 { |
︙ | ︙ | |||
430 431 432 433 434 435 436 | declare 115 { int Tcl_DoOneEvent(int flags) } declare 116 { void Tcl_DoWhenIdle(Tcl_IdleProc *proc, ClientData clientData) } declare 117 { | | > | | 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 460 461 462 463 464 465 466 467 | declare 115 { int Tcl_DoOneEvent(int flags) } declare 116 { void Tcl_DoWhenIdle(Tcl_IdleProc *proc, ClientData clientData) } declare 117 { char *Tcl_DStringAppend(Tcl_DString *dsPtr, const char *bytes, size_t length) } declare 118 { char *Tcl_DStringAppendElement(Tcl_DString *dsPtr, const char *element) } declare 119 { void Tcl_DStringEndSublist(Tcl_DString *dsPtr) } declare 120 { void Tcl_DStringFree(Tcl_DString *dsPtr) } declare 121 { void Tcl_DStringGetResult(Tcl_Interp *interp, Tcl_DString *dsPtr) } declare 122 { void Tcl_DStringInit(Tcl_DString *dsPtr) } declare 123 { void Tcl_DStringResult(Tcl_Interp *interp, Tcl_DString *dsPtr) } declare 124 { void Tcl_DStringSetLength(Tcl_DString *dsPtr, size_t length) } declare 125 { void Tcl_DStringStartSublist(Tcl_DString *dsPtr) } declare 126 { int Tcl_Eof(Tcl_Channel chan) } |
︙ | ︙ | |||
532 533 534 535 536 537 538 | } declare 147 { void Tcl_FreeResult(Tcl_Interp *interp) } declare 148 { int Tcl_GetAlias(Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, const char **targetCmdPtr, | | | | 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 | } declare 147 { void Tcl_FreeResult(Tcl_Interp *interp) } declare 148 { int Tcl_GetAlias(Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, const char **targetCmdPtr, size_t *argcPtr, const char ***argvPtr) } declare 149 { int Tcl_GetAliasObj(Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, const char **targetCmdPtr, size_t *objcPtr, Tcl_Obj ***objv) } declare 150 { ClientData Tcl_GetAssocData(Tcl_Interp *interp, const char *name, Tcl_InterpDeleteProc **procPtr) } declare 151 { Tcl_Channel Tcl_GetChannel(Tcl_Interp *interp, const char *chanName, |
︙ | ︙ | |||
610 611 612 613 614 615 616 | } # Obsolete. Should now use Tcl_FSGetPathType which is objectified # and therefore usually faster. declare 168 { Tcl_PathType Tcl_GetPathType(const char *path) } declare 169 { | | | | 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | } # Obsolete. Should now use Tcl_FSGetPathType which is objectified # and therefore usually faster. declare 168 { Tcl_PathType Tcl_GetPathType(const char *path) } declare 169 { ssize_t Tcl_Gets(Tcl_Channel chan, Tcl_DString *dsPtr) } declare 170 { ssize_t Tcl_GetsObj(Tcl_Channel chan, Tcl_Obj *objPtr) } declare 171 { int Tcl_GetServiceMode(void) } declare 172 { Tcl_Interp *Tcl_GetSlave(Tcl_Interp *interp, const char *slaveName) } |
︙ | ︙ | |||
668 669 670 671 672 673 674 | int Tcl_InterpDeleted(Tcl_Interp *interp) } declare 185 { int Tcl_IsSafe(Tcl_Interp *interp) } # Obsolete, use Tcl_FSJoinPath declare 186 { | | | 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 | int Tcl_InterpDeleted(Tcl_Interp *interp) } declare 185 { int Tcl_IsSafe(Tcl_Interp *interp) } # Obsolete, use Tcl_FSJoinPath declare 186 { char *Tcl_JoinPath(size_t argc, const char *const *argv, Tcl_DString *resultPtr) } declare 187 { int Tcl_LinkVar(Tcl_Interp *interp, const char *varName, char *addr, int type) } |
︙ | ︙ | |||
691 692 693 694 695 696 697 | declare 190 { int Tcl_MakeSafe(Tcl_Interp *interp) } declare 191 { Tcl_Channel Tcl_MakeTcpClientChannel(ClientData tcpSocket) } declare 192 { | | | | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 | declare 190 { int Tcl_MakeSafe(Tcl_Interp *interp) } declare 191 { Tcl_Channel Tcl_MakeTcpClientChannel(ClientData tcpSocket) } declare 192 { char *Tcl_Merge(size_t argc, const char *const *argv) } declare 193 { Tcl_HashEntry *Tcl_NextHashEntry(Tcl_HashSearch *searchPtr) } declare 194 { void Tcl_NotifyChannel(Tcl_Channel channel, int mask) } declare 195 { Tcl_Obj *Tcl_ObjGetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags) } declare 196 { Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags) } declare 197 { Tcl_Channel Tcl_OpenCommandChannel(Tcl_Interp *interp, size_t argc, const char **argv, int flags) } # This is obsolete, use Tcl_FSOpenFileChannel declare 198 { Tcl_Channel Tcl_OpenFileChannel(Tcl_Interp *interp, const char *fileName, const char *modeString, int permissions) } |
︙ | ︙ | |||
741 742 743 744 745 746 747 | declare 204 { const char *Tcl_PosixError(Tcl_Interp *interp) } declare 205 { void Tcl_QueueEvent(Tcl_Event *evPtr, Tcl_QueuePosition position) } declare 206 { | | | 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 | declare 204 { const char *Tcl_PosixError(Tcl_Interp *interp) } declare 205 { void Tcl_QueueEvent(Tcl_Event *evPtr, Tcl_QueuePosition position) } declare 206 { ssize_t Tcl_Read(Tcl_Channel chan, char *bufPtr, size_t toRead) } declare 207 { void Tcl_ReapDetachedProcs(void) } declare 208 { int Tcl_RecordAndEval(Tcl_Interp *interp, const char *cmd, int flags) } |
︙ | ︙ | |||
780 781 782 783 784 785 786 | declare 216 { void Tcl_Release(ClientData clientData) } declare 217 { void Tcl_ResetResult(Tcl_Interp *interp) } declare 218 { | | | | 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | declare 216 { void Tcl_Release(ClientData clientData) } declare 217 { void Tcl_ResetResult(Tcl_Interp *interp) } declare 218 { size_t Tcl_ScanElement(const char *src, int *flagPtr) } declare 219 { size_t Tcl_ScanCountedElement(const char *src, size_t length, int *flagPtr) } # Removed in Tcl 9 #declare 220 { # int Tcl_SeekOld(Tcl_Channel chan, int offset, int mode) #} declare 221 { int Tcl_ServiceAll(void) |
︙ | ︙ | |||
861 862 863 864 865 866 867 | declare 240 { const char *Tcl_SignalMsg(int sig) } declare 241 { void Tcl_SourceRCFile(Tcl_Interp *interp) } declare 242 { | | | | > | 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 | declare 240 { const char *Tcl_SignalMsg(int sig) } declare 241 { void Tcl_SourceRCFile(Tcl_Interp *interp) } declare 242 { int Tcl_SplitList(Tcl_Interp *interp, const char *listStr, size_t *argcPtr, const char ***argvPtr) } # Obsolete, use Tcl_FSSplitPath declare 243 { void Tcl_SplitPath(const char *path, size_t *argcPtr, const char ***argvPtr) } declare 244 { void Tcl_StaticPackage(Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) } declare 245 { int Tcl_StringMatch(const char *str, const char *pattern) |
︙ | ︙ | |||
893 894 895 896 897 898 899 | int flags, Tcl_VarTraceProc *proc, ClientData clientData) } declare 249 { char *Tcl_TranslateFileName(Tcl_Interp *interp, const char *name, Tcl_DString *bufferPtr) } declare 250 { | | | 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 | int flags, Tcl_VarTraceProc *proc, ClientData clientData) } declare 249 { char *Tcl_TranslateFileName(Tcl_Interp *interp, const char *name, Tcl_DString *bufferPtr) } declare 250 { ssize_t Tcl_Ungets(Tcl_Channel chan, const char *str, size_t len, int atHead) } declare 251 { void Tcl_UnlinkVar(Tcl_Interp *interp, const char *varName) } declare 252 { int Tcl_UnregisterChannel(Tcl_Interp *interp, Tcl_Channel chan) } |
︙ | ︙ | |||
946 947 948 949 950 951 952 | #} declare 262 { ClientData Tcl_VarTraceInfo2(Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData) } declare 263 { | | | | 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 | #} declare 262 { ClientData Tcl_VarTraceInfo2(Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData) } declare 263 { ssize_t Tcl_Write(Tcl_Channel chan, const char *s, size_t slen) } declare 264 { void Tcl_WrongNumArgs(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], const char *message) } declare 265 { int Tcl_DumpActiveMemory(const char *fileName) } declare 266 { void Tcl_ValidateAllMemory(const char *file, int line) |
︙ | ︙ | |||
1066 1067 1068 1069 1070 1071 1072 | void Tcl_DeleteThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData) } # Removed in 9.0: #declare 290 { # void Tcl_DiscardResult(Tcl_SavedResult *statePtr) #} declare 291 { | | | | | | | | 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 | void Tcl_DeleteThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData) } # Removed in 9.0: #declare 290 { # void Tcl_DiscardResult(Tcl_SavedResult *statePtr) #} declare 291 { int Tcl_EvalEx(Tcl_Interp *interp, const char *script, size_t numBytes, int flags) } declare 292 { int Tcl_EvalObjv(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags) } declare 293 { int Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags) } declare 294 { void Tcl_ExitThread(int status) } declare 295 { int Tcl_ExternalToUtf(Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, size_t srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, size_t dstLen, size_t *srcReadPtr, size_t *dstWrotePtr, size_t *dstCharsPtr) } declare 296 { char *Tcl_ExternalToUtfDString(Tcl_Encoding encoding, const char *src, size_t srcLen, Tcl_DString *dsPtr) } declare 297 { void Tcl_FinalizeThread(void) } declare 298 { void Tcl_FinalizeNotifier(ClientData clientData) } |
︙ | ︙ | |||
1139 1140 1141 1142 1143 1144 1145 | void Tcl_ConditionNotify(Tcl_Condition *condPtr) } declare 311 { void Tcl_ConditionWait(Tcl_Condition *condPtr, Tcl_Mutex *mutexPtr, const Tcl_Time *timePtr) } declare 312 { | | | | | 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 | void Tcl_ConditionNotify(Tcl_Condition *condPtr) } declare 311 { void Tcl_ConditionWait(Tcl_Condition *condPtr, Tcl_Mutex *mutexPtr, const Tcl_Time *timePtr) } declare 312 { size_t Tcl_NumUtfChars(const char *src, size_t length) } declare 313 { ssize_t Tcl_ReadChars(Tcl_Channel channel, Tcl_Obj *objPtr, size_t charsToRead, int appendFlag) } # Removed in 9.0: #declare 314 { # void Tcl_RestoreResult(Tcl_Interp *interp, Tcl_SavedResult *statePtr) #} # Removed in 9.0: #declare 315 { |
︙ | ︙ | |||
1168 1169 1170 1171 1172 1173 1174 | void Tcl_ThreadAlert(Tcl_ThreadId threadId) } declare 319 { void Tcl_ThreadQueueEvent(Tcl_ThreadId threadId, Tcl_Event *evPtr, Tcl_QueuePosition position) } declare 320 { | | | | | | | | | | | | 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 | void Tcl_ThreadAlert(Tcl_ThreadId threadId) } declare 319 { void Tcl_ThreadQueueEvent(Tcl_ThreadId threadId, Tcl_Event *evPtr, Tcl_QueuePosition position) } declare 320 { Tcl_UniChar Tcl_UniCharAtIndex(const char *src, size_t index) } declare 321 { Tcl_UniChar Tcl_UniCharToLower(int ch) } declare 322 { Tcl_UniChar Tcl_UniCharToTitle(int ch) } declare 323 { Tcl_UniChar Tcl_UniCharToUpper(int ch) } declare 324 { int Tcl_UniCharToUtf(int ch, char *buf) } declare 325 { const char *Tcl_UtfAtIndex(const char *src, size_t index) } declare 326 { int Tcl_UtfCharComplete(const char *src, size_t length) } declare 327 { size_t Tcl_UtfBackslash(const char *src, size_t *readPtr, char *dst) } declare 328 { const char *Tcl_UtfFindFirst(const char *src, int ch) } declare 329 { const char *Tcl_UtfFindLast(const char *src, int ch) } declare 330 { const char *Tcl_UtfNext(const char *src) } declare 331 { const char *Tcl_UtfPrev(const char *src, const char *start) } declare 332 { int Tcl_UtfToExternal(Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, size_t srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, size_t dstLen, size_t *srcReadPtr, size_t *dstWrotePtr, size_t *dstCharsPtr) } declare 333 { char *Tcl_UtfToExternalDString(Tcl_Encoding encoding, const char *src, size_t srcLen, Tcl_DString *dsPtr) } declare 334 { int Tcl_UtfToLower(char *src) } declare 335 { int Tcl_UtfToTitle(char *src) } declare 336 { int Tcl_UtfToUniChar(const char *src, Tcl_UniChar *chPtr) } declare 337 { int Tcl_UtfToUpper(char *src) } declare 338 { ssize_t Tcl_WriteChars(Tcl_Channel chan, const char *src, size_t srcLen) } declare 339 { ssize_t Tcl_WriteObj(Tcl_Channel chan, Tcl_Obj *objPtr) } declare 340 { char *Tcl_GetString(Tcl_Obj *objPtr) } # Removed in 9.0 #declare 341 { # const char *Tcl_GetDefaultEncodingDir(void) |
︙ | ︙ | |||
1278 1279 1280 1281 1282 1283 1284 | } declare 353 { int Tcl_UniCharNcmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, size_t numChars) } declare 354 { char *Tcl_UniCharToUtfDString(const Tcl_UniChar *uniStr, | | | | | | > | | | | | | | 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 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 1337 | } declare 353 { int Tcl_UniCharNcmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, size_t numChars) } declare 354 { char *Tcl_UniCharToUtfDString(const Tcl_UniChar *uniStr, size_t uniLength, Tcl_DString *dsPtr) } declare 355 { Tcl_UniChar *Tcl_UtfToUniCharDString(const char *src, size_t length, Tcl_DString *dsPtr) } declare 356 { Tcl_RegExp Tcl_GetRegExpFromObj(Tcl_Interp *interp, Tcl_Obj *patObj, int flags) } # Removed in 9.0: #declare 357 { # Tcl_Obj *Tcl_EvalTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr, # int count) #} declare 358 { void Tcl_FreeParse(Tcl_Parse *parsePtr) } declare 359 { void Tcl_LogCommandInfo(Tcl_Interp *interp, const char *script, const char *command, size_t length) } declare 360 { int Tcl_ParseBraces(Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr, int append, const char **termPtr) } declare 361 { int Tcl_ParseCommand(Tcl_Interp *interp, const char *start, size_t numBytes, int nested, Tcl_Parse *parsePtr) } declare 362 { int Tcl_ParseExpr(Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr) } declare 363 { int Tcl_ParseQuotedString(Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr, int append, const char **termPtr) } declare 364 { int Tcl_ParseVarName(Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr, int append) } # These 4 functions are obsolete, use Tcl_FSGetCwd, Tcl_FSChdir, # Tcl_FSAccess and Tcl_FSStat declare 365 { char *Tcl_GetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr) } declare 366 { |
︙ | ︙ | |||
1364 1365 1366 1367 1368 1369 1370 | int Tcl_RegExpExecObj(Tcl_Interp *interp, Tcl_RegExp regexp, Tcl_Obj *textObj, int offset, int nmatches, int flags) } declare 377 { void Tcl_RegExpGetInfo(Tcl_RegExp regexp, Tcl_RegExpInfo *infoPtr) } declare 378 { | | | | | | | | | | | | 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 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 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 | int Tcl_RegExpExecObj(Tcl_Interp *interp, Tcl_RegExp regexp, Tcl_Obj *textObj, int offset, int nmatches, int flags) } declare 377 { void Tcl_RegExpGetInfo(Tcl_RegExp regexp, Tcl_RegExpInfo *infoPtr) } declare 378 { Tcl_Obj *Tcl_NewUnicodeObj(const Tcl_UniChar *unicode, size_t numChars) } declare 379 { void Tcl_SetUnicodeObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t numChars) } declare 380 { size_t Tcl_GetCharLength(Tcl_Obj *objPtr) } declare 381 { Tcl_UniChar Tcl_GetUniChar(Tcl_Obj *objPtr, size_t index) } declare 382 { Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj *objPtr) } declare 383 { Tcl_Obj *Tcl_GetRange(Tcl_Obj *objPtr, size_t first, size_t last) } declare 384 { void Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t length) } declare 385 { int Tcl_RegExpMatchObj(Tcl_Interp *interp, Tcl_Obj *textObj, Tcl_Obj *patternObj) } declare 386 { void Tcl_SetNotifier(Tcl_NotifierProcs *notifierProcPtr) } declare 387 { Tcl_Mutex *Tcl_GetAllocMutex(void) } declare 388 { int Tcl_GetChannelNames(Tcl_Interp *interp) } declare 389 { int Tcl_GetChannelNamesEx(Tcl_Interp *interp, const char *pattern) } declare 390 { int Tcl_ProcObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) } declare 391 { void Tcl_ConditionFinalize(Tcl_Condition *condPtr) } declare 392 { void Tcl_MutexFinalize(Tcl_Mutex *mutex) } declare 393 { int Tcl_CreateThread(Tcl_ThreadId *idPtr, Tcl_ThreadCreateProc *proc, ClientData clientData, size_t stackSize, int flags) } # Introduced in 8.3.2 declare 394 { ssize_t Tcl_ReadRaw(Tcl_Channel chan, char *dst, size_t bytesToRead) } declare 395 { ssize_t Tcl_WriteRaw(Tcl_Channel chan, const char *src, size_t srcLen) } declare 396 { Tcl_Channel Tcl_GetTopChannel(Tcl_Channel chan) } declare 397 { int Tcl_ChannelBuffered(Tcl_Channel chan) } |
︙ | ︙ | |||
1544 1545 1546 1547 1548 1549 1550 | Tcl_CommandTraceProc *proc, ClientData clientData) } declare 427 { void Tcl_UntraceCommand(Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, ClientData clientData) } declare 428 { | | | | | | | | 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 | Tcl_CommandTraceProc *proc, ClientData clientData) } declare 427 { void Tcl_UntraceCommand(Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, ClientData clientData) } declare 428 { char *Tcl_AttemptAlloc(size_t size) } declare 429 { char *Tcl_AttemptDbCkalloc(size_t size, const char *file, int line) } declare 430 { char *Tcl_AttemptRealloc(char *ptr, size_t size) } declare 431 { char *Tcl_AttemptDbCkrealloc(char *ptr, size_t size, const char *file, int line) } declare 432 { int Tcl_AttemptSetObjLength(Tcl_Obj *objPtr, size_t length) } # TIP#10 (thread-aware channels) akupries declare 433 { Tcl_ThreadId Tcl_GetChannelThread(Tcl_Channel channel) } # introduced in 8.4a3 declare 434 { Tcl_UniChar *Tcl_GetUnicodeFromObj(Tcl_Obj *objPtr, size_t *lengthPtr) } # TIP#15 (math function introspection) dkf #declare 435 { # int Tcl_GetMathFuncInfo(Tcl_Interp *interp, const char *name, # int *numArgsPtr, Tcl_ValueType **argTypesPtr, # Tcl_MathProc **procPtr, ClientData *clientDataPtr) |
︙ | ︙ | |||
1666 1667 1668 1669 1670 1671 1672 | declare 459 { int Tcl_FSConvertToPathType(Tcl_Interp *interp, Tcl_Obj *pathPtr) } declare 460 { Tcl_Obj *Tcl_FSJoinPath(Tcl_Obj *listObj, int elements) } declare 461 { | | | | 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 | declare 459 { int Tcl_FSConvertToPathType(Tcl_Interp *interp, Tcl_Obj *pathPtr) } declare 460 { Tcl_Obj *Tcl_FSJoinPath(Tcl_Obj *listObj, int elements) } declare 461 { Tcl_Obj *Tcl_FSSplitPath(Tcl_Obj *pathPtr, size_t *lenPtr) } declare 462 { int Tcl_FSEqualPaths(Tcl_Obj *firstPtr, Tcl_Obj *secondPtr) } declare 463 { Tcl_Obj *Tcl_FSGetNormalizedPath(Tcl_Interp *interp, Tcl_Obj *pathPtr) } declare 464 { Tcl_Obj *Tcl_FSJoinToPath(Tcl_Obj *pathPtr, size_t objc, Tcl_Obj *const objv[]) } declare 465 { ClientData Tcl_FSGetInternalRep(Tcl_Obj *pathPtr, const Tcl_Filesystem *fsPtr) } declare 466 { |
︙ | ︙ | |||
1735 1736 1737 1738 1739 1740 1741 | declare 480 { void Tcl_FSMountsChanged(const Tcl_Filesystem *fsPtr) } # TIP#56 (evaluate a parsed script) msofer declare 481 { int Tcl_EvalTokensStandard(Tcl_Interp *interp, Tcl_Token *tokenPtr, | | | 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 | declare 480 { void Tcl_FSMountsChanged(const Tcl_Filesystem *fsPtr) } # TIP#56 (evaluate a parsed script) msofer declare 481 { int Tcl_EvalTokensStandard(Tcl_Interp *interp, Tcl_Token *tokenPtr, size_t count) } # TIP#73 (access to current time) kbk declare 482 { void Tcl_GetTime(Tcl_Time *timeBuf) } |
︙ | ︙ | |||
1805 1806 1807 1808 1809 1810 1811 | Tcl_Obj **valuePtrPtr) } declare 496 { int Tcl_DictObjRemove(Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr) } declare 497 { | | > | | | 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 | Tcl_Obj **valuePtrPtr) } declare 496 { int Tcl_DictObjRemove(Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr) } declare 497 { int Tcl_DictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t *sizePtr) } declare 498 { int Tcl_DictObjFirst(Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr) } declare 499 { void Tcl_DictObjNext(Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr) } declare 500 { void Tcl_DictObjDone(Tcl_DictSearch *searchPtr) } declare 501 { int Tcl_DictObjPutKeyList(Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t keyc, Tcl_Obj *const *keyv, Tcl_Obj *valuePtr) } declare 502 { int Tcl_DictObjRemoveKeyList(Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t keyc, Tcl_Obj *const *keyv) } declare 503 { Tcl_Obj *Tcl_NewDictObj(void) } declare 504 { Tcl_Obj *Tcl_DbNewDictObj(const char *file, int line) } |
︙ | ︙ | |||
2107 2108 2109 2110 2111 2112 2113 | declare 572 { const char *Tcl_GetEncodingNameFromEnvironment(Tcl_DString *bufPtr) } # TIP#268 (extended version numbers and requirements) akupries declare 573 { int Tcl_PkgRequireProc(Tcl_Interp *interp, const char *name, | | | | | | | 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 | declare 572 { const char *Tcl_GetEncodingNameFromEnvironment(Tcl_DString *bufPtr) } # TIP#268 (extended version numbers and requirements) akupries declare 573 { int Tcl_PkgRequireProc(Tcl_Interp *interp, const char *name, size_t objc, Tcl_Obj *const objv[], void *clientDataPtr) } # TIP#270 (utility C routines for string formatting) dgp declare 574 { void Tcl_AppendObjToErrorInfo(Tcl_Interp *interp, Tcl_Obj *objPtr) } declare 575 { void Tcl_AppendLimitedToObj(Tcl_Obj *objPtr, const char *bytes, size_t length, size_t limit, const char *ellipsis) } declare 576 { Tcl_Obj *Tcl_Format(Tcl_Interp *interp, const char *format, size_t objc, Tcl_Obj *const objv[]) } declare 577 { int Tcl_AppendFormatToObj(Tcl_Interp *interp, Tcl_Obj *objPtr, const char *format, size_t objc, Tcl_Obj *const objv[]) } declare 578 { Tcl_Obj *Tcl_ObjPrintf(const char *format, ...) } declare 579 { void Tcl_AppendPrintfToObj(Tcl_Obj *objPtr, const char *format, ...) } |
︙ | ︙ | |||
2161 2162 2163 2164 2165 2166 2167 | Tcl_ObjCmdProc *nreProc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc) } declare 584 { int Tcl_NREvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags) } declare 585 { | | | | | | 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 | Tcl_ObjCmdProc *nreProc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc) } declare 584 { int Tcl_NREvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags) } declare 585 { int Tcl_NREvalObjv(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags) } declare 586 { int Tcl_NRCmdSwap(Tcl_Interp *interp, Tcl_Command cmd, size_t objc, Tcl_Obj *const objv[], int flags) } declare 587 { void Tcl_NRAddCallback(Tcl_Interp *interp, Tcl_NRPostProc *postProcPtr, ClientData data0, ClientData data1, ClientData data2, ClientData data3) } # For use by NR extenders, to have a simple way to also provide a (required!) # classic objProc declare 588 { int Tcl_NRCallObjProc(Tcl_Interp *interp, Tcl_ObjCmdProc *objProc, ClientData clientData, size_t objc, Tcl_Obj *const objv[]) } # TIP#316 (Tcl_StatBuf reader functions) dkf declare 589 { unsigned Tcl_GetFSDeviceFromStat(const Tcl_StatBuf *statPtr) } declare 590 { |
︙ | ︙ | |||
2234 2235 2236 2237 2238 2239 2240 | int Tcl_GetEnsembleParameterList(Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **paramListPtr) } # TIP#265 (option parser) dkf for Sam Bromley declare 604 { int Tcl_ParseArgsObjv(Tcl_Interp *interp, const Tcl_ArgvInfo *argTable, | | | 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 | int Tcl_GetEnsembleParameterList(Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **paramListPtr) } # TIP#265 (option parser) dkf for Sam Bromley declare 604 { int Tcl_ParseArgsObjv(Tcl_Interp *interp, const Tcl_ArgvInfo *argTable, size_t *objcPtr, Tcl_Obj *const *objv, Tcl_Obj ***remObjv) } # TIP#336 (manipulate the error line) dgp declare 605 { int Tcl_GetErrorLine(Tcl_Interp *interp) } declare 606 { |
︙ | ︙ | |||
2272 2273 2274 2275 2276 2277 2278 | } declare 611 { int Tcl_ZlibInflate(Tcl_Interp *interp, int format, Tcl_Obj *data, int buffersize, Tcl_Obj *gzipHeaderDictObj) } declare 612 { unsigned int Tcl_ZlibCRC32(unsigned int crc, const unsigned char *buf, | | | | > | 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 | } declare 611 { int Tcl_ZlibInflate(Tcl_Interp *interp, int format, Tcl_Obj *data, int buffersize, Tcl_Obj *gzipHeaderDictObj) } declare 612 { unsigned int Tcl_ZlibCRC32(unsigned int crc, const unsigned char *buf, size_t len) } declare 613 { unsigned int Tcl_ZlibAdler32(unsigned int adler, const unsigned char *buf, size_t len) } declare 614 { int Tcl_ZlibStreamInit(Tcl_Interp *interp, int mode, int format, int level, Tcl_Obj *dictObj, Tcl_ZlibStream *zshandle) } declare 615 { Tcl_Obj *Tcl_ZlibStreamGetCommandName(Tcl_ZlibStream zshandle) } declare 616 { int Tcl_ZlibStreamEof(Tcl_ZlibStream zshandle) } declare 617 { int Tcl_ZlibStreamChecksum(Tcl_ZlibStream zshandle) } declare 618 { int Tcl_ZlibStreamPut(Tcl_ZlibStream zshandle, Tcl_Obj *data, int flush) } declare 619 { int Tcl_ZlibStreamGet(Tcl_ZlibStream zshandle, Tcl_Obj *data, size_t count) } declare 620 { int Tcl_ZlibStreamClose(Tcl_ZlibStream zshandle) } declare 621 { int Tcl_ZlibStreamReset(Tcl_ZlibStream zshandle) } |
︙ | ︙ | |||
2366 2367 2368 2369 2370 2371 2372 | ################################ # Windows specific functions # Added in Tcl 8.1 declare 0 win { | | | | | | 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 2397 2398 2399 2400 2401 2402 2403 | ################################ # Windows specific functions # Added in Tcl 8.1 declare 0 win { TCHAR *Tcl_WinUtfToTChar(const char *str, size_t len, Tcl_DString *dsPtr) } declare 1 win { char *Tcl_WinTCharToUtf(const TCHAR *str, size_t len, Tcl_DString *dsPtr) } ################################ # Mac OS X specific functions declare 0 macosx { int Tcl_MacOSXOpenBundleResources(Tcl_Interp *interp, const char *bundleName, int hasResourceFile, size_t maxPathLen, char *libraryPath) } declare 1 macosx { int Tcl_MacOSXOpenVersionedBundleResources(Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, size_t maxPathLen, char *libraryPath) } ############################################################################## # Public functions that are not accessible via the stubs table. export { |
︙ | ︙ |
Changes to generic/tcl.h.
︙ | ︙ | |||
118 119 120 121 122 123 124 125 126 127 128 129 130 131 | * Also, many extensions need stdio.h, and they've grown accustomed to tcl.h * providing it for them rather than #include-ing it themselves as they * should, so also for their sake, we keep the #include to be consistent with * prior Tcl releases. */ #include <stdio.h> /* *---------------------------------------------------------------------------- * Support for functions with a variable number of arguments. * * The following TCL_VARARGS* macros are to support old extensions * written for older versions of Tcl where the macros permitted | > > > | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | * Also, many extensions need stdio.h, and they've grown accustomed to tcl.h * providing it for them rather than #include-ing it themselves as they * should, so also for their sake, we keep the #include to be consistent with * prior Tcl releases. */ #include <stdio.h> // TODO: AUTOCONFERY #include <sys/types.h> //#include <stddef.h> /* *---------------------------------------------------------------------------- * Support for functions with a variable number of arguments. * * The following TCL_VARARGS* macros are to support old extensions * written for older versions of Tcl where the macros permitted |
︙ | ︙ | |||
551 552 553 554 555 556 557 | typedef int (Tcl_AppInitProc) (Tcl_Interp *interp); typedef int (Tcl_AsyncProc) (ClientData clientData, Tcl_Interp *interp, int code); typedef void (Tcl_ChannelProc) (ClientData clientData, int mask); typedef void (Tcl_CloseProc) (ClientData data); typedef void (Tcl_CmdDeleteProc) (ClientData clientData); typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp *interp, | | | | | > | | | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 | typedef int (Tcl_AppInitProc) (Tcl_Interp *interp); typedef int (Tcl_AsyncProc) (ClientData clientData, Tcl_Interp *interp, int code); typedef void (Tcl_ChannelProc) (ClientData clientData, int mask); typedef void (Tcl_CloseProc) (ClientData data); typedef void (Tcl_CmdDeleteProc) (ClientData clientData); typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp *interp, size_t argc, const char *argv[]); typedef void (Tcl_CmdTraceProc) (ClientData clientData, Tcl_Interp *interp, int level, char *command, Tcl_CmdProc *proc, ClientData cmdClientData, size_t argc, const char *argv[]); typedef int (Tcl_CmdObjTraceProc) (ClientData clientData, Tcl_Interp *interp, int level, const char *command, Tcl_Command commandInfo, size_t objc, struct Tcl_Obj *const *objv); typedef void (Tcl_CmdObjTraceDeleteProc) (ClientData clientData); typedef void (Tcl_DupInternalRepProc) (struct Tcl_Obj *srcPtr, struct Tcl_Obj *dupPtr); typedef int (Tcl_EncodingConvertProc) (ClientData clientData, const char *src, size_t srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, size_t dstLen, size_t *srcReadPtr, size_t *dstWrotePtr, size_t *dstCharsPtr); typedef void (Tcl_EncodingFreeProc) (ClientData clientData); typedef int (Tcl_EventProc) (Tcl_Event *evPtr, int flags); typedef void (Tcl_EventCheckProc) (ClientData clientData, int flags); typedef int (Tcl_EventDeleteProc) (Tcl_Event *evPtr, ClientData clientData); typedef void (Tcl_EventSetupProc) (ClientData clientData, int flags); typedef void (Tcl_ExitProc) (ClientData clientData); typedef void (Tcl_FileProc) (ClientData clientData, int mask); typedef void (Tcl_FileFreeProc) (ClientData clientData); typedef void (Tcl_FreeInternalRepProc) (struct Tcl_Obj *objPtr); typedef void (Tcl_FreeProc) (char *blockPtr); typedef void (Tcl_IdleProc) (ClientData clientData); typedef void (Tcl_InterpDeleteProc) (ClientData clientData, Tcl_Interp *interp); typedef void (Tcl_NamespaceDeleteProc) (ClientData clientData); typedef int (Tcl_ObjCmdProc) (ClientData clientData, Tcl_Interp *interp, size_t objc, struct Tcl_Obj *const *objv); typedef int (Tcl_PackageInitProc) (Tcl_Interp *interp); typedef int (Tcl_PackageUnloadProc) (Tcl_Interp *interp, int flags); typedef void (Tcl_PanicProc) (const char *format, ...); typedef void (Tcl_TcpAcceptProc) (ClientData callbackData, Tcl_Channel chan, char *address, int port); typedef void (Tcl_TimerProc) (ClientData clientData); typedef int (Tcl_SetFromAnyProc) (Tcl_Interp *interp, struct Tcl_Obj *objPtr); |
︙ | ︙ | |||
645 646 647 648 649 650 651 | * embedded null characters. The array's * storage is allocated by ckalloc. NULL means * the string rep is invalid and must be * regenerated from the internal rep. Clients * should use Tcl_GetStringFromObj or * Tcl_GetString to get a pointer to the byte * array as a readonly value. */ | | | 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 | * embedded null characters. The array's * storage is allocated by ckalloc. NULL means * the string rep is invalid and must be * regenerated from the internal rep. Clients * should use Tcl_GetStringFromObj or * Tcl_GetString to get a pointer to the byte * array as a readonly value. */ size_t length; /* The number of bytes at *bytes, not * including the terminating null. */ const Tcl_ObjType *typePtr; /* Denotes the object's type. Always * corresponds to the type of the object's * internal rep. NULL indicates the object has * no internal rep (has no type). */ union { /* The internal representation: */ long longValue; /* - an long integer value. */ |
︙ | ︙ | |||
672 673 674 675 676 677 678 679 680 681 682 683 684 685 | * off the pointer. */ void *ptr; unsigned long value; } ptrAndLongRep; } internalRep; } Tcl_Obj; /* * Macros to increment and decrement a Tcl_Obj's reference count, and to test * whether an object is shared (i.e. has reference count > 1). Note: clients * should use Tcl_DecrRefCount() when they are finished using an object, and * should never call TclFreeObj() directly. TclFreeObj() is only defined and * made public in tcl.h to support Tcl_DecrRefCount's macro definition. */ | > > > > > > > > | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | * off the pointer. */ void *ptr; unsigned long value; } ptrAndLongRep; } internalRep; } Tcl_Obj; /* * Used in many functions to indicate that the length of the string argument * is not directly known and should be worked out by using strlen() or * equivalent. */ #define TCL_STRLEN ((size_t) -1) /* * Macros to increment and decrement a Tcl_Obj's reference count, and to test * whether an object is shared (i.e. has reference count > 1). Note: clients * should use Tcl_DecrRefCount() when they are finished using an object, and * should never call TclFreeObj() directly. TclFreeObj() is only defined and * made public in tcl.h to support Tcl_DecrRefCount's macro definition. */ |
︙ | ︙ | |||
743 744 745 746 747 748 749 | * WARNING!! The structure definition must be kept consistent with the * CallFrame structure in tclInt.h. If you change one, change the other. */ typedef struct Tcl_CallFrame { Tcl_Namespace *nsPtr; int dummy1; | | | | 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 | * WARNING!! The structure definition must be kept consistent with the * CallFrame structure in tclInt.h. If you change one, change the other. */ typedef struct Tcl_CallFrame { Tcl_Namespace *nsPtr; int dummy1; size_t dummy2; void *dummy3; void *dummy4; void *dummy5; int dummy6; void *dummy7; void *dummy8; size_t dummy9; void *dummy10; void *dummy11; void *dummy12; void *dummy13; } Tcl_CallFrame; /* |
︙ | ︙ | |||
804 805 806 807 808 809 810 | * macros Tcl_DStringValue and Tcl_DStringLength. */ #define TCL_DSTRING_STATIC_SIZE 200 typedef struct Tcl_DString { char *string; /* Points to beginning of string: either * staticSpace below or a malloced array. */ | | | | 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 | * macros Tcl_DStringValue and Tcl_DStringLength. */ #define TCL_DSTRING_STATIC_SIZE 200 typedef struct Tcl_DString { char *string; /* Points to beginning of string: either * staticSpace below or a malloced array. */ size_t length; /* Number of non-NULL characters in the * string. */ size_t spaceAvl; /* Total number of bytes available for the * string and its terminating NULL char. */ char staticSpace[TCL_DSTRING_STATIC_SIZE]; /* Space to use in common case where string is * small. */ } Tcl_DString; #define Tcl_DStringLength(dsPtr) ((dsPtr)->length) |
︙ | ︙ | |||
1086 1087 1088 1089 1090 1091 1092 | 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). */ | | | | | | | | 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 | 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). */ size_t numBuckets; /* Total number of buckets allocated at * **bucketPtr. */ size_t numEntries; /* Total number of entries present in * table. */ size_t rebuildSize; /* Enlarge table when numEntries gets to be * this large. */ size_t downShift; /* Shift count used in hashing function. * Designed to use high-order bits of * randomized keys. */ size_t mask; /* Mask value used in hashing function. */ 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); Tcl_HashEntry *(*createProc) (Tcl_HashTable *tablePtr, const char *key, int *newPtr); const Tcl_HashKeyType *typePtr; /* Type of the keys used in the * Tcl_HashTable. */ }; /* * Structure definition for information used to keep track of searches through * hash tables: */ typedef struct Tcl_HashSearch { Tcl_HashTable *tablePtr; /* Table being searched. */ size_t nextIndex; /* Index of next bucket to be enumerated after * present one. */ Tcl_HashEntry *nextEntryPtr;/* Next entry to be enumerated in the current * bucket. */ } Tcl_HashSearch; /* * Acceptable key types for hash tables: |
︙ | ︙ | |||
1288 1289 1290 1291 1292 1293 1294 | */ typedef int (Tcl_DriverBlockModeProc) (ClientData instanceData, int mode); typedef int (Tcl_DriverCloseProc) (ClientData instanceData, Tcl_Interp *interp); typedef int (Tcl_DriverClose2Proc) (ClientData instanceData, Tcl_Interp *interp, int flags); | | | | | | 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 | */ typedef int (Tcl_DriverBlockModeProc) (ClientData instanceData, int mode); typedef int (Tcl_DriverCloseProc) (ClientData instanceData, Tcl_Interp *interp); typedef int (Tcl_DriverClose2Proc) (ClientData instanceData, Tcl_Interp *interp, int flags); typedef ssize_t (Tcl_DriverInputProc) (ClientData instanceData, char *buf, size_t toRead, int *errorCodePtr); typedef ssize_t (Tcl_DriverOutputProc) (ClientData instanceData, const char *buf, size_t toWrite, int *errorCodePtr); typedef int (Tcl_DriverSeekProc) (ClientData instanceData, long offset, int mode, int *errorCodePtr); typedef int (Tcl_DriverSetOptionProc) (ClientData instanceData, Tcl_Interp *interp, const char *optionName, const char *value); typedef int (Tcl_DriverGetOptionProc) (ClientData instanceData, Tcl_Interp *interp, const char *optionName, |
︙ | ︙ | |||
1724 1725 1726 1727 1728 1729 1730 | * 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. */ | | | | 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 | * 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. */ size_t size; /* Number of bytes in token. */ size_t 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; /* |
︙ | ︙ | |||
1839 1840 1841 1842 1843 1844 1845 | */ #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. */ | | | | | | | 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 | */ #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. */ size_t 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. */ size_t commandSize; /* Number of bytes in command, including first * character of first word, up through the * terminating newline, close bracket, or * semicolon. */ size_t 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 * staticTokens, but may change to point to * malloc-ed space if command exceeds space in * staticTokens. */ size_t numTokens; /* Total number of tokens in command. */ size_t tokensAvailable; /* Total number of tokens available at * *tokenPtr. */ int errorType; /* One of the parsing error types defined * above. */ /* * The fields below are intended only for the private use of the parser. * They should not be used by functions that invoke Tcl_ParseCommand. |
︙ | ︙ | |||
2103 2104 2105 2106 2107 2108 2109 | * Types of callback functions for the TCL_ARGV_FUNC and TCL_ARGV_GENFUNC * argument types: */ typedef int (Tcl_ArgvFuncProc)(ClientData clientData, Tcl_Obj *objPtr, void *dstPtr); typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp, | | | 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 | * Types of callback functions for the TCL_ARGV_FUNC and TCL_ARGV_GENFUNC * argument types: */ typedef int (Tcl_ArgvFuncProc)(ClientData clientData, Tcl_Obj *objPtr, void *dstPtr); typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv, void *dstPtr); /* * Shorthand for commonly used argTable entries. */ #define TCL_ARGV_AUTO_HELP \ {TCL_ARGV_HELP, "-help", NULL, NULL, \ |
︙ | ︙ |
Changes to generic/tclAlloc.c.
︙ | ︙ | |||
690 691 692 693 694 695 696 | * None. * *---------------------------------------------------------------------- */ char * TclpAlloc( | | | 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 | * None. * *---------------------------------------------------------------------- */ char * TclpAlloc( size_t numBytes) /* Number of bytes to allocate. */ { return (char *) malloc(numBytes); } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
738 739 740 741 742 743 744 | * *---------------------------------------------------------------------- */ char * TclpRealloc( char *oldPtr, /* Pointer to alloced block. */ | | | 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 | * *---------------------------------------------------------------------- */ char * TclpRealloc( char *oldPtr, /* Pointer to alloced block. */ size_t numBytes) /* New size of memory. */ { return (char *) realloc(oldPtr, numBytes); } #endif /* !USE_TCLALLOC */ #endif /* !TCL_THREADS */ |
︙ | ︙ |
Changes to generic/tclAssembly.c.
︙ | ︙ | |||
214 215 216 217 218 219 220 | * 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. */ int cmdLine; /* Current line number within the assembly * code */ | | | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | * 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. */ int cmdLine; /* Current line number within the assembly * code */ ssize_t* 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) */ |
︙ | ︙ | |||
275 276 277 278 279 280 281 | Tcl_Obj* jumpTable); static int FindLocalVar(AssemblyEnv* envPtr, Tcl_Token** tokenPtrPtr); static int FinishAssembly(AssemblyEnv*); static void FreeAssembleCodeInternalRep(Tcl_Obj *objPtr); static void FreeAssemblyEnv(AssemblyEnv*); static int GetBooleanOperand(AssemblyEnv*, Tcl_Token**, int*); | | > | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | Tcl_Obj* jumpTable); static int FindLocalVar(AssemblyEnv* envPtr, Tcl_Token** tokenPtrPtr); static int FinishAssembly(AssemblyEnv*); static void FreeAssembleCodeInternalRep(Tcl_Obj *objPtr); static void FreeAssemblyEnv(AssemblyEnv*); static int GetBooleanOperand(AssemblyEnv*, Tcl_Token**, int*); static int GetListIndexOperand(AssemblyEnv*, Tcl_Token**, ssize_t*listIdx); static int GetIntegerOperand(AssemblyEnv*, Tcl_Token**, int*); static int GetNextOperand(AssemblyEnv*, Tcl_Token**, Tcl_Obj**); static void LookForFreshCatches(BasicBlock*, BasicBlock**); static void MoveCodeForJumps(AssemblyEnv*, int); static void MoveExceptionRangesToBasicBlock(AssemblyEnv*, int, int); static AssemblyEnv* NewAssemblyEnv(CompileEnv*, int); |
︙ | ︙ | |||
732 733 734 735 736 737 738 | *----------------------------------------------------------------------------- */ int Tcl_AssembleObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 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 | *----------------------------------------------------------------------------- */ int Tcl_AssembleObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { /* * Boilerplate - make sure that there is an NRE trampoline on the C stack * because there needs to be one in place to execute bytecode. */ return Tcl_NRCallObjProc(interp, TclNRAssembleObjCmd, dummy, objc, objv); } int TclNRAssembleObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { ByteCode *codePtr; /* Pointer to the bytecode to execute */ Tcl_Obj* backtrace; /* Object where extra error information is * constructed. */ if (objc != 2) { |
︙ | ︙ | |||
816 817 818 819 820 821 822 | CompileEnv compEnv; /* Compilation environment structure */ register ByteCode *codePtr = NULL; /* Bytecode resulting from the assembly */ Namespace* namespacePtr; /* Namespace in which variable and command * names in the bytecode resolve */ int status; /* Status return from Tcl_AssembleCode */ const char* source; /* String representation of the source code */ | | | 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 | CompileEnv compEnv; /* Compilation environment structure */ register ByteCode *codePtr = NULL; /* Bytecode resulting from the assembly */ Namespace* namespacePtr; /* Namespace in which variable and command * names in the bytecode resolve */ int status; /* Status return from Tcl_AssembleCode */ const char* source; /* String representation of the source code */ size_t sourceLen; /* Length of the source code in bytes */ /* * Get the expression ByteCode from the object. If it exists, make sure it * is valid in the current context. */ |
︙ | ︙ | |||
952 953 954 955 956 957 958 | */ if (TCL_ERROR == TclAssembleCode(envPtr, tokenPtr[1].start, tokenPtr[1].size, TCL_EVAL_DIRECT)) { Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (\"%.*s\" body, line %d)", | | | 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 | */ if (TCL_ERROR == TclAssembleCode(envPtr, tokenPtr[1].start, tokenPtr[1].size, TCL_EVAL_DIRECT)) { Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (\"%.*s\" body, line %d)", (int) parsePtr->tokenPtr->size, parsePtr->tokenPtr->start, Tcl_GetErrorLine(interp))); envPtr->numCommands = numCommands; envPtr->codeNext = envPtr->codeStart + offset; envPtr->currStackDepth = depth; TclCompileSyntaxError(interp, envPtr); } return TCL_OK; |
︙ | ︙ | |||
1232 1233 1234 1235 1236 1237 1238 | Tcl_Obj* instNameObj; /* Name of the instruction */ int tblIdx; /* Index in TalInstructionTable of the * instruction */ enum TalInstType instType; /* Type of the instruction */ Tcl_Obj* operand1Obj = NULL; /* First operand to the instruction */ const char* operand1; /* String rep of the operand */ | | | 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 | Tcl_Obj* instNameObj; /* Name of the instruction */ int tblIdx; /* Index in TalInstructionTable of the * instruction */ enum TalInstType instType; /* Type of the instruction */ Tcl_Obj* operand1Obj = NULL; /* First operand to the instruction */ const char* operand1; /* String rep of the operand */ size_t operand1Len; /* String length of the operand */ int opnd; /* Integer representation of an operand */ int litIndex; /* Literal pool index of a constant */ int 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 */ |
︙ | ︙ | |||
1552 1553 1554 1555 1556 1557 1558 | BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd); break; case ASSEM_INDEX: if (parsePtr->numWords != 2) { Tcl_WrongNumArgs(interp, 1, &instNameObj, "count"); goto cleanup; | | > | | > > > > > | | 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 | BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd); break; case ASSEM_INDEX: if (parsePtr->numWords != 2) { Tcl_WrongNumArgs(interp, 1, &instNameObj, "count"); goto cleanup; } else { ssize_t idxOpnd; if (GetListIndexOperand(assemEnvPtr, &tokenPtr, &idxOpnd) != TCL_OK) { goto cleanup; } if (idxOpnd < INT_MIN || idxOpnd > INT_MAX) { goto cleanup; } opnd = (int) idxOpnd; } BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd); break; case ASSEM_LSET_FLAT: if (parsePtr->numWords != 2) { Tcl_WrongNumArgs(interp, 1, &instNameObj, "count"); goto cleanup; } if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK) { goto cleanup; } if (opnd < 2) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj("operand must be >=2", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "OPERAND>=2", NULL); } goto cleanup; } BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd); break; |
︙ | ︙ | |||
1919 1920 1921 1922 1923 1924 1925 | */ static int CreateMirrorJumpTable( AssemblyEnv* assemEnvPtr, /* Assembly environment */ Tcl_Obj* jumps) /* List of alternating keywords and labels */ { | | | 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 | */ static int CreateMirrorJumpTable( AssemblyEnv* assemEnvPtr, /* Assembly environment */ Tcl_Obj* jumps) /* List of alternating keywords and labels */ { size_t 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 */ |
︙ | ︙ | |||
1941 1942 1943 1944 1945 1946 1947 | if (Tcl_ListObjGetElements(interp, jumps, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc % 2 != 0) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "jump table must have an even number of list elements", | | | 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 | if (Tcl_ListObjGetElements(interp, jumps, &objc, &objv) != TCL_OK) { return TCL_ERROR; } if (objc % 2 != 0) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "jump table must have an even number of list elements", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADJUMPTABLE", NULL); } return TCL_ERROR; } /* * Allocate the jumptable. |
︙ | ︙ | |||
2053 2054 2055 2056 2057 2058 2059 | Tcl_Interp* interp = (Tcl_Interp*) assemEnvPtr->envPtr->iPtr; Tcl_Obj* operandObj = Tcl_NewObj(); if (!TclWordKnownAtCompileTime(*tokenPtrPtr, operandObj)) { Tcl_DecrRefCount(operandObj); if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 | Tcl_Interp* interp = (Tcl_Interp*) assemEnvPtr->envPtr->iPtr; Tcl_Obj* operandObj = Tcl_NewObj(); if (!TclWordKnownAtCompileTime(*tokenPtrPtr, operandObj)) { Tcl_DecrRefCount(operandObj); if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "assembly code may not contain substitutions", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NOSUBST", NULL); } return TCL_ERROR; } *tokenPtrPtr = TokenAfter(*tokenPtrPtr); Tcl_IncrRefCount(operandObj); *operandObjPtr = operandObj; |
︙ | ︙ | |||
2193 2194 2195 2196 2197 2198 2199 | *----------------------------------------------------------------------------- */ static int GetListIndexOperand( AssemblyEnv* assemEnvPtr, /* Assembly environment */ Tcl_Token** tokenPtrPtr, /* Current token from the parser */ | | | 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 | *----------------------------------------------------------------------------- */ static int GetListIndexOperand( AssemblyEnv* assemEnvPtr, /* Assembly environment */ Tcl_Token** tokenPtrPtr, /* Current token from the parser */ ssize_t* result) /* OUTPUT: Integer extracted from the token */ { CompileEnv* envPtr = assemEnvPtr->envPtr; /* Compilation environment */ Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr; /* Tcl interpreter */ Tcl_Token* tokenPtr = *tokenPtrPtr; /* INOUT: Pointer to the next token in the |
︙ | ︙ | |||
2258 2259 2260 2261 2262 2263 2264 | Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr; /* Tcl interpreter */ Tcl_Token* tokenPtr = *tokenPtrPtr; /* INOUT: Pointer to the next token in the * source code. */ Tcl_Obj* varNameObj; /* Name of the variable */ const char* varNameStr; | | | | 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 | Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr; /* Tcl interpreter */ Tcl_Token* tokenPtr = *tokenPtrPtr; /* INOUT: Pointer to the next token in the * source code. */ Tcl_Obj* varNameObj; /* Name of the variable */ const char* varNameStr; size_t varNameLen; int localVar; /* Index of the variable in the LVT */ if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &varNameObj) != TCL_OK) { return -1; } varNameStr = Tcl_GetStringFromObj(varNameObj, &varNameLen); if (CheckNamespaceQualifiers(interp, varNameStr, varNameLen)) { Tcl_DecrRefCount(varNameObj); return -1; } localVar = TclFindCompiledLocal(varNameStr, varNameLen, 1, envPtr); Tcl_DecrRefCount(varNameObj); if (localVar == -1) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot use this instruction to create a variable" " in a non-proc context", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "LVT", NULL); } return -1; } *tokenPtrPtr = TokenAfter(tokenPtr); return localVar; } |
︙ | ︙ | |||
2345 2346 2347 2348 2349 2350 2351 | CheckOneByte( Tcl_Interp* interp, /* Tcl interpreter for error reporting */ int value) /* Value to check */ { Tcl_Obj* result; /* Error message */ if (value < 0 || value > 0xff) { | | > | 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 | CheckOneByte( Tcl_Interp* interp, /* Tcl interpreter for error reporting */ int value) /* Value to check */ { Tcl_Obj* result; /* Error message */ if (value < 0 || value > 0xff) { result = Tcl_NewStringObj("operand does not fit in one byte", TCL_STRLEN); Tcl_SetObjResult(interp, result); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "1BYTE", NULL); return TCL_ERROR; } return TCL_OK; } |
︙ | ︙ | |||
2380 2381 2382 2383 2384 2385 2386 | CheckSignedOneByte( Tcl_Interp* interp, /* Tcl interpreter for error reporting */ int value) /* Value to check */ { Tcl_Obj* result; /* Error message */ if (value > 0x7f || value < -0x80) { | | > | 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 | CheckSignedOneByte( Tcl_Interp* interp, /* Tcl interpreter for error reporting */ int value) /* Value to check */ { Tcl_Obj* result; /* Error message */ if (value > 0x7f || value < -0x80) { result = Tcl_NewStringObj("operand does not fit in one byte", TCL_STRLEN); Tcl_SetObjResult(interp, result); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "1BYTE", NULL); return TCL_ERROR; } return TCL_OK; } |
︙ | ︙ | |||
2413 2414 2415 2416 2417 2418 2419 | CheckNonNegative( Tcl_Interp* interp, /* Tcl interpreter for error reporting */ int value) /* Value to check */ { Tcl_Obj* result; /* Error message */ if (value < 0) { | | | 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 | CheckNonNegative( Tcl_Interp* interp, /* Tcl interpreter for error reporting */ int value) /* Value to check */ { Tcl_Obj* result; /* Error message */ if (value < 0) { result = Tcl_NewStringObj("operand must be nonnegative", TCL_STRLEN); Tcl_SetObjResult(interp, result); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NONNEGATIVE", NULL); return TCL_ERROR; } return TCL_OK; } |
︙ | ︙ | |||
2446 2447 2448 2449 2450 2451 2452 | CheckStrictlyPositive( Tcl_Interp* interp, /* Tcl interpreter for error reporting */ int value) /* Value to check */ { Tcl_Obj* result; /* Error message */ if (value <= 0) { | | | 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 | CheckStrictlyPositive( Tcl_Interp* interp, /* Tcl interpreter for error reporting */ int value) /* Value to check */ { Tcl_Obj* result; /* Error message */ if (value <= 0) { result = Tcl_NewStringObj("operand must be positive", TCL_STRLEN); Tcl_SetObjResult(interp, result); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "POSITIVE", NULL); return TCL_ERROR; } return TCL_OK; } |
︙ | ︙ | |||
3359 3360 3361 3362 3363 3364 3365 | */ if (blockPtr->initialStackDepth == initialStackDepth) { return TCL_OK; } if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 | */ if (blockPtr->initialStackDepth == initialStackDepth) { return TCL_OK; } if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "inconsistent stack depths on two execution paths", TCL_STRLEN)); /* * TODO - add execution trace of both paths */ Tcl_SetErrorLine(interp, blockPtr->startLine); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACK", NULL); |
︙ | ︙ | |||
3388 3389 3390 3391 3392 3393 3394 | /* * Calculate minimum stack depth, and flag an error if the block * underflows the stack. */ if (initialStackDepth + blockPtr->minStackDepth < 0) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { | | > | > | > | 3399 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 | /* * Calculate minimum stack depth, and flag an error if the block * underflows the stack. */ if (initialStackDepth + blockPtr->minStackDepth < 0) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj("stack underflow", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACK", NULL); AddBasicBlockRangeToErrorInfo(assemEnvPtr, blockPtr); Tcl_SetErrorLine(interp, blockPtr->startLine); } return TCL_ERROR; } /* * Make sure that the block doesn't try to pop below the stack level of an * enclosing catch. */ if (blockPtr->enclosingCatch != 0 && initialStackDepth + blockPtr->minStackDepth < (blockPtr->enclosingCatch->initialStackDepth + blockPtr->enclosingCatch->finalStackDepth)) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "code pops stack below level of enclosing catch", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACKINCATCH", NULL); AddBasicBlockRangeToErrorInfo(assemEnvPtr, blockPtr); Tcl_SetErrorLine(interp, blockPtr->startLine); } return TCL_ERROR; } /* |
︙ | ︙ | |||
3679 3680 3681 3682 3683 3684 3685 | if (bbPtr->catchState == BBCS_UNKNOWN) { bbPtr->enclosingCatch = enclosing; } else if (bbPtr->enclosingCatch != enclosing) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "execution reaches an instruction in inconsistent " | | | 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 | if (bbPtr->catchState == BBCS_UNKNOWN) { bbPtr->enclosingCatch = enclosing; } else if (bbPtr->enclosingCatch != enclosing) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "execution reaches an instruction in inconsistent " "exception contexts", TCL_STRLEN)); Tcl_SetErrorLine(interp, bbPtr->startLine); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADCATCH", NULL); } return TCL_ERROR; } if (state > bbPtr->catchState) { bbPtr->catchState = state; |
︙ | ︙ | |||
3738 3739 3740 3741 3742 3743 3744 | * If the block ends a catch, the state for the successor is whatever * the state was on entry to the catch. */ if (enclosing == NULL) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 | * If the block ends a catch, the state for the successor is whatever * the state was on entry to the catch. */ if (enclosing == NULL) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "endCatch without a corresponding beginCatch", TCL_STRLEN)); Tcl_SetErrorLine(interp, bbPtr->startLine); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADENDCATCH", NULL); } return TCL_ERROR; } fallThruEnclosing = enclosing->enclosingCatch; fallThruState = enclosing->catchState; |
︙ | ︙ | |||
3813 3814 3815 3816 3817 3818 3819 | /* Compilation environment */ Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr; /* Tcl interpreter */ if (assemEnvPtr->curr_bb->catchState >= BBCS_INCATCH) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 | /* Compilation environment */ Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr; /* Tcl interpreter */ if (assemEnvPtr->curr_bb->catchState >= BBCS_INCATCH) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "catch still active on exit from assembly code", TCL_STRLEN)); Tcl_SetErrorLine(interp, assemEnvPtr->curr_bb->enclosingCatch->startLine); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "UNCLOSEDCATCH", NULL); } return TCL_ERROR; } return TCL_OK; |
︙ | ︙ |
Changes to generic/tclBasic.c.
︙ | ︙ | |||
52 53 54 55 56 57 58 | typedef struct { Tcl_Interp *interp; /* Interp this struct belongs to. */ Tcl_AsyncHandler async; /* Async handler token for script * cancellation. */ char *result; /* The script cancellation result or NULL for * a default result. */ | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | typedef struct { Tcl_Interp *interp; /* Interp this struct belongs to. */ Tcl_AsyncHandler async; /* Async handler token for script * cancellation. */ char *result; /* The script cancellation result or NULL for * a default result. */ size_t length; /* Length of the above error message. */ ClientData clientData; /* Ignored */ int flags; /* Additional flags */ } CancelInfo; static Tcl_HashTable cancelTable; static int cancelTableInitialized = 0; /* 0 means not yet initialized. */ TCL_DECLARE_MUTEX(cancelLock) |
︙ | ︙ | |||
111 112 113 114 115 116 117 | static Tcl_ObjCmdProc ExprIsqrtFunc; static Tcl_ObjCmdProc ExprRandFunc; static Tcl_ObjCmdProc ExprRoundFunc; static Tcl_ObjCmdProc ExprSqrtFunc; static Tcl_ObjCmdProc ExprSrandFunc; static Tcl_ObjCmdProc ExprUnaryFunc; static Tcl_ObjCmdProc ExprWideFunc; | | > | | | | | | 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 | static Tcl_ObjCmdProc ExprIsqrtFunc; static Tcl_ObjCmdProc ExprRandFunc; static Tcl_ObjCmdProc ExprRoundFunc; static Tcl_ObjCmdProc ExprSqrtFunc; static Tcl_ObjCmdProc ExprSrandFunc; static Tcl_ObjCmdProc ExprUnaryFunc; static Tcl_ObjCmdProc ExprWideFunc; static void MathFuncWrongNumArgs(Tcl_Interp *interp, size_t expected, size_t actual, Tcl_Obj *const *objv); static Tcl_NRPostProc NRCoroutineCallerCallback; static Tcl_NRPostProc NRCoroutineExitCallback; static int NRCommand(ClientData data[], Tcl_Interp *interp, int result); static void ProcessUnexpectedResult(Tcl_Interp *interp, int returnCode); static int RewindCoroutine(CoroutineData *corPtr, int result); static void TEOV_SwitchVarFrame(Tcl_Interp *interp); static void TEOV_PushExceptionHandlers(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags); static inline Command * TEOV_LookupCmdFromObj(Tcl_Interp *interp, Tcl_Obj *namePtr, Namespace *lookupNsPtr); static int TEOV_NotFound(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], Namespace *lookupNsPtr); static int TEOV_RunEnterTraces(Tcl_Interp *interp, Command **cmdPtrPtr, Tcl_Obj *commandPtr, size_t objc, Tcl_Obj *const objv[]); static Tcl_NRPostProc RewindCoroutineCallback; static Tcl_NRPostProc TailcallCleanup; static Tcl_NRPostProc TEOEx_ByteCodeCallback; static Tcl_NRPostProc TEOEx_ListCallback; static Tcl_NRPostProc TEOV_Error; static Tcl_NRPostProc TEOV_Exception; static Tcl_NRPostProc TEOV_NotFoundCallback; |
︙ | ︙ | |||
1690 1691 1692 1693 1694 1695 1696 | * the source, in order to avoid potential confusion, lets prevent "::" in * the token too. - dl */ if (strstr(hiddenCmdToken, "::") != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot use namespace qualifiers in hidden command" | | | 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 | * the source, in order to avoid potential confusion, lets prevent "::" in * the token too. - dl */ if (strstr(hiddenCmdToken, "::") != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot use namespace qualifiers in hidden command" " token (rename)", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "HIDDENTOKEN", NULL); return TCL_ERROR; } /* * Find the command to hide. An error is returned if cmdName can't be * found. Look up the command only from the global namespace. Full path of |
︙ | ︙ | |||
1714 1715 1716 1717 1718 1719 1720 | /* * Check that the command is really in global namespace */ if (cmdPtr->nsPtr != iPtr->globalNsPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 | /* * Check that the command is really in global namespace */ if (cmdPtr->nsPtr != iPtr->globalNsPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can only hide global namespace commands " "(use rename then hide)", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "HIDE", "NON_GLOBAL", NULL); return TCL_ERROR; } /* * Initialize the hidden command table if necessary. */ |
︙ | ︙ | |||
1844 1845 1846 1847 1848 1849 1850 | * Check that we have a regular name for the command (that the user is not * trying to do an expose and a rename (to another namespace) at the same * time). */ if (strstr(cmdName, "::") != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 | * Check that we have a regular name for the command (that the user is not * trying to do an expose and a rename (to another namespace) at the same * time). */ if (strstr(cmdName, "::") != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot expose to a namespace " "(use expose to toplevel, then rename)", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "EXPOSE", "NON_GLOBAL", NULL); return TCL_ERROR; } /* * Get the command from the hidden command table: */ |
︙ | ︙ | |||
1882 1883 1884 1885 1886 1887 1888 | /* * This case is theoritically impossible, we might rather Tcl_Panic * than 'nicely' erroring out ? */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "trying to expose a non-global command namespace command", | | | 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 | /* * This case is theoritically impossible, we might rather Tcl_Panic * than 'nicely' erroring out ? */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "trying to expose a non-global command namespace command", TCL_STRLEN)); return TCL_ERROR; } /* * This is the global table. */ |
︙ | ︙ | |||
2339 2340 2341 2342 2343 2344 2345 | *---------------------------------------------------------------------- */ int TclInvokeStringCommand( ClientData clientData, /* Points to command's Command structure. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | < | 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 | *---------------------------------------------------------------------- */ int TclInvokeStringCommand( ClientData clientData, /* Points to command's Command structure. */ Tcl_Interp *interp, /* Current interpreter. */ register size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Command *cmdPtr = clientData; int result; size_t i; const char **argv = TclStackAlloc(interp, (objc + 1) * sizeof(char *)); for (i = 0; i < objc; i++) { argv[i] = Tcl_GetString(objv[i]); } argv[objc] = 0; /* |
︙ | ︙ | |||
2387 2388 2389 2390 2391 2392 2393 | *---------------------------------------------------------------------- */ int TclInvokeObjectCommand( ClientData clientData, /* Points to command's Command structure. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | | < | 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 | *---------------------------------------------------------------------- */ int TclInvokeObjectCommand( ClientData clientData, /* Points to command's Command structure. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ register const char **argv) /* Argument strings. */ { Command *cmdPtr = clientData; Tcl_Obj *objPtr; int result; size_t i, length; Tcl_Obj **objv = TclStackAlloc(interp, argc * sizeof(Tcl_Obj *)); for (i = 0; i < argc; i++) { length = strlen(argv[i]); TclNewStringObj(objPtr, argv[i], length); Tcl_IncrRefCount(objPtr); objv[i] = objPtr; } |
︙ | ︙ | |||
2589 2590 2591 2592 2593 2594 2595 | * The trace function needs to get a fully qualified name for old and new * commands [Tcl bug #651271], or else there's no way for the trace * function to get the namespace from which the old command is being * renamed! */ Tcl_DStringInit(&newFullName); | | | | 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 | * The trace function needs to get a fully qualified name for old and new * commands [Tcl bug #651271], or else there's no way for the trace * function to get the namespace from which the old command is being * renamed! */ Tcl_DStringInit(&newFullName); Tcl_DStringAppend(&newFullName, newNsPtr->fullName, TCL_STRLEN); if (newNsPtr != iPtr->globalNsPtr) { TclDStringAppendLiteral(&newFullName, "::"); } Tcl_DStringAppend(&newFullName, newTail, TCL_STRLEN); cmdPtr->refCount++; CallCommandTraces(iPtr, cmdPtr, Tcl_GetString(oldFullName), Tcl_DStringValue(&newFullName), TCL_TRACE_RENAME); Tcl_DStringFree(&newFullName); /* * The new command name is okay, so remove the command from its current |
︙ | ︙ | |||
2882 2883 2884 2885 2886 2887 2888 | /* * Add the full name of the containing namespace, followed by the "::" * separator, and the command name. */ if (cmdPtr != NULL) { if (cmdPtr->nsPtr != NULL) { | | | | 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 | /* * Add the full name of the containing namespace, followed by the "::" * separator, and the command name. */ if (cmdPtr != NULL) { if (cmdPtr->nsPtr != NULL) { Tcl_AppendToObj(objPtr, cmdPtr->nsPtr->fullName, TCL_STRLEN); if (cmdPtr->nsPtr != iPtr->globalNsPtr) { Tcl_AppendToObj(objPtr, "::", 2); } } if (cmdPtr->hPtr != NULL) { name = Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr); Tcl_AppendToObj(objPtr, name, TCL_STRLEN); } } } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3380 3381 3382 3383 3384 3385 3386 | /* * If the interpreter has been deleted, return an error. */ if (iPtr->flags & DELETED) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 | /* * If the interpreter has been deleted, return an error. */ if (iPtr->flags & DELETED) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to call eval in deleted interpreter", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "IDELETE", "attempt to call eval in deleted interpreter", NULL); return TCL_ERROR; } if (iPtr->execEnvPtr->rewind) { return TCL_ERROR; |
︙ | ︙ | |||
3409 3410 3411 3412 3413 3414 3415 | */ if (((iPtr->numLevels) <= iPtr->maxNestingDepth)) { return TCL_OK; } Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 | */ if (((iPtr->numLevels) <= iPtr->maxNestingDepth)) { return TCL_OK; } Tcl_SetObjResult(interp, Tcl_NewStringObj( "too many nested evaluations (infinite loop?)", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LIMIT", "STACK", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3518 3519 3520 3521 3522 3523 3524 | /* * If the TCL_LEAVE_ERR_MSG flags bit is set, place an error in the * interp's result; otherwise, we leave it alone. */ if (flags & TCL_LEAVE_ERR_MSG) { const char *id, *message = NULL; | | | 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 | /* * If the TCL_LEAVE_ERR_MSG flags bit is set, place an error in the * interp's result; otherwise, we leave it alone. */ if (flags & TCL_LEAVE_ERR_MSG) { const char *id, *message = NULL; size_t length; /* * Setup errorCode variables so that we can differentiate between * being canceled and unwound. */ if (iPtr->asyncCancelMsg != NULL) { |
︙ | ︙ | |||
3543 3544 3545 3546 3547 3548 3549 | } else { id = "ICANCEL"; if (length == 0) { message = "eval canceled"; } } | | | 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 | } else { id = "ICANCEL"; if (length == 0) { message = "eval canceled"; } } Tcl_SetObjResult(interp, Tcl_NewStringObj(message, TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "CANCEL", id, message, NULL); } /* * Return TCL_ERROR to the caller (not necessarily just the Tcl core * itself) that indicates further processing of the script or command in * progress should halt gracefully and as soon as possible. |
︙ | ︙ | |||
3689 3690 3691 3692 3693 3694 3695 | *---------------------------------------------------------------------- */ int Tcl_EvalObjv( Tcl_Interp *interp, /* Interpreter in which to evaluate the * command. Also used for error reporting. */ | | | | 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 | *---------------------------------------------------------------------- */ int Tcl_EvalObjv( Tcl_Interp *interp, /* Interpreter in which to evaluate the * command. Also used for error reporting. */ size_t objc, /* Number of words in command. */ Tcl_Obj *const objv[], /* An array of pointers to objects that are * the words that make up the command. */ int flags) /* Collection of OR-ed bits that control the * evaluation of the script. Only * TCL_EVAL_GLOBAL, TCL_EVAL_INVOKE and * TCL_EVAL_NOERR are currently supported. */ { int result; NRE_callback *rootPtr = TOP_CB(interp); result = TclNREvalObjv(interp, objc, objv, flags, NULL); return TclNRRunCallbacks(interp, result, rootPtr); } int TclNREvalObjv( Tcl_Interp *interp, /* Interpreter in which to evaluate the * command. Also used for error reporting. */ size_t objc, /* Number of words in command. */ Tcl_Obj *const objv[], /* An array of pointers to objects that are * the words that make up the command. */ int flags, /* Collection of OR-ed bits that control the * evaluation of the script. Only * TCL_EVAL_GLOBAL, TCL_EVAL_INVOKE and * TCL_EVAL_NOERR are currently supported. */ Command *cmdPtr) /* NULL if the Command is to be looked up |
︙ | ︙ | |||
3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 | /* * Schedule leave traces. Raise the refCount on the resolved * cmdPtr, so that when it passes to the leave traces we know * it's still valid. */ cmdPtr->refCount++; TclNRAddCallback(interp, TEOV_RunLeaveTraces, INT2PTR(objc), commandPtr, cmdPtr, objv); } TclNRAddCallback(interp, Dispatch, cmdPtr->nreProc ? cmdPtr->nreProc : cmdPtr->objProc, cmdPtr->objClientData, INT2PTR(objc), objv); | > | 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 | /* * Schedule leave traces. Raise the refCount on the resolved * cmdPtr, so that when it passes to the leave traces we know * it's still valid. */ cmdPtr->refCount++; // TODO: Check consequences of packing objc into a machine word TclNRAddCallback(interp, TEOV_RunLeaveTraces, INT2PTR(objc), commandPtr, cmdPtr, objv); } TclNRAddCallback(interp, Dispatch, cmdPtr->nreProc ? cmdPtr->nreProc : cmdPtr->objProc, cmdPtr->objClientData, INT2PTR(objc), objv); |
︙ | ︙ | |||
4014 4015 4016 4017 4018 4019 4020 | * *---------------------------------------------------------------------- */ static void TEOV_PushExceptionHandlers( Tcl_Interp *interp, | | | 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 | * *---------------------------------------------------------------------- */ static void TEOV_PushExceptionHandlers( Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags) { Interp *iPtr = (Interp *) interp; /* * If any error processing is necessary, push the appropriate records. |
︙ | ︙ | |||
4109 4110 4111 4112 4113 4114 4115 | ClientData data[], Tcl_Interp *interp, int result) { Interp *iPtr = (Interp *) interp; Tcl_Obj *listPtr; const char *cmdString; | < | | 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 | ClientData data[], Tcl_Interp *interp, int result) { Interp *iPtr = (Interp *) interp; Tcl_Obj *listPtr; const char *cmdString; size_t cmdLen, objc = PTR2INT(data[0]); Tcl_Obj **objv = data[1]; if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)){ /* * If there was an error, a command string will be needed for the * error log: get it out of the itemPtr. The details depend on the * type. |
︙ | ︙ | |||
4132 4133 4134 4135 4136 4137 4138 | iPtr->flags &= ~ERR_ALREADY_LOGGED; return result; } static int TEOV_NotFound( Tcl_Interp *interp, | | | | 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 | iPtr->flags &= ~ERR_ALREADY_LOGGED; return result; } static int TEOV_NotFound( Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], Namespace *lookupNsPtr) { Command * cmdPtr; Interp *iPtr = (Interp *) interp; size_t i, newObjc, handlerObjc; Tcl_Obj **newObjv, **handlerObjv; CallFrame *varFramePtr = iPtr->varFramePtr; Namespace *currNsPtr = NULL;/* Used to check for and invoke any registered * unknown command handler for the current * namespace (TIP 181). */ Namespace *savedNsPtr = NULL; |
︙ | ︙ | |||
4233 4234 4235 4236 4237 4238 4239 | static int TEOV_NotFoundCallback( ClientData data[], Tcl_Interp *interp, int result) { Interp *iPtr = (Interp *) interp; | | < | | 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 | static int TEOV_NotFoundCallback( ClientData data[], Tcl_Interp *interp, int result) { Interp *iPtr = (Interp *) interp; size_t objc = PTR2INT(data[0]); Tcl_Obj **objv = data[1]; Namespace *savedNsPtr = data[2]; size_t i; if (savedNsPtr) { iPtr->varFramePtr->nsPtr = savedNsPtr; } /* * Release any resources we locked and allocated during the handler call. |
︙ | ︙ | |||
4260 4261 4262 4263 4264 4265 4266 | } static int TEOV_RunEnterTraces( Tcl_Interp *interp, Command **cmdPtrPtr, Tcl_Obj *commandPtr, | | > | | 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 | } static int TEOV_RunEnterTraces( Tcl_Interp *interp, Command **cmdPtrPtr, Tcl_Obj *commandPtr, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; Command *cmdPtr = *cmdPtrPtr; int newEpoch, cmdEpoch = cmdPtr->cmdEpoch; size_t length; int traceCode = TCL_OK; const char *command = Tcl_GetStringFromObj(commandPtr, &length); /* * Call trace functions. * Execute any command or execution traces. Note that we bump up the * command's reference count for the duration of the calling of the * traces so that the structure doesn't go away underneath our feet. |
︙ | ︙ | |||
4318 4319 4320 4321 4322 4323 4324 | { Interp *iPtr = (Interp *) interp; int traceCode = TCL_OK; int objc = PTR2INT(data[0]); Tcl_Obj *commandPtr = data[1]; Command *cmdPtr = data[2]; Tcl_Obj **objv = data[3]; | | | 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 | { Interp *iPtr = (Interp *) interp; int traceCode = TCL_OK; int objc = PTR2INT(data[0]); Tcl_Obj *commandPtr = data[1]; Command *cmdPtr = data[2]; Tcl_Obj **objv = data[3]; size_t length; const char *command = Tcl_GetStringFromObj(commandPtr, &length); if (!(cmdPtr->flags & CMD_IS_DELETED)) { if (cmdPtr->flags & CMD_HAS_EXEC_TRACES){ traceCode = TclCheckExecutionTraces(interp, command, length, cmdPtr, result, TCL_TRACE_LEAVE_EXEC, objc, objv); } |
︙ | ︙ | |||
4401 4402 4403 4404 4405 4406 4407 | int Tcl_EvalTokensStandard( Tcl_Interp *interp, /* Interpreter in which to lookup variables, * execute nested commands, and report * errors. */ Tcl_Token *tokenPtr, /* Pointer to first in an array of tokens to * evaluate and concatenate. */ | | | 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 | int Tcl_EvalTokensStandard( Tcl_Interp *interp, /* Interpreter in which to lookup variables, * execute nested commands, and report * errors. */ Tcl_Token *tokenPtr, /* Pointer to first in an array of tokens to * evaluate and concatenate. */ size_t count) /* Number of tokens to consider at tokenPtr. * Must be at least 1. */ { return TclSubstTokens(interp, tokenPtr, count, /* numLeftPtr */ NULL, 1, NULL, NULL); } /* |
︙ | ︙ | |||
4434 4435 4436 4437 4438 4439 4440 | */ int Tcl_EvalEx( Tcl_Interp *interp, /* Interpreter in which to evaluate the * script. Also used for error reporting. */ const char *script, /* First character of script to evaluate. */ | | | | | 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 | */ int Tcl_EvalEx( Tcl_Interp *interp, /* Interpreter in which to evaluate the * script. Also used for error reporting. */ const char *script, /* First character of script to evaluate. */ size_t numBytes, /* Number of bytes in script. If < 0, the * script consists of all bytes up to the * first null character. */ int flags) /* Collection of OR-ed bits that control the * evaluation of the script. Only * TCL_EVAL_GLOBAL is currently supported. */ { return TclEvalEx(interp, script, numBytes, flags, 1, NULL, script); } int TclEvalEx( Tcl_Interp *interp, /* Interpreter in which to evaluate the * script. Also used for error reporting. */ const char *script, /* First character of script to evaluate. */ size_t numBytes, /* Number of bytes in script. If < 0, the * script consists of all bytes up to the * first NUL character. */ int flags, /* Collection of OR-ed bits that control the * evaluation of the script. Only * TCL_EVAL_GLOBAL is currently supported. */ int line, /* The line the script starts on. */ ssize_t *clNextOuter, /* Information about an outer context for */ const char *outerScript) /* continuation line data. This is set only in * TclSubstTokens(), to properly handle * [...]-nested commands. The 'outerScript' * refers to the most-outer script containing * the embedded command, which is refered to * by 'script'. The 'clNextOuter' refers to * the current entry in the table of |
︙ | ︙ | |||
4480 4481 4482 4483 4484 4485 4486 | { Interp *iPtr = (Interp *) interp; const char *p, *next; const unsigned int minObjs = 20; Tcl_Obj **objv, **objvSpace; int *expand, *lines, *lineSpace; Tcl_Token *tokenPtr; | | > | | | 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 | { Interp *iPtr = (Interp *) interp; const char *p, *next; const unsigned int minObjs = 20; Tcl_Obj **objv, **objvSpace; int *expand, *lines, *lineSpace; Tcl_Token *tokenPtr; size_t commandLength, bytesLeft, expandRequested; int code = TCL_OK; CallFrame *savedVarFramePtr;/* Saves old copy of iPtr->varFramePtr in case * TCL_EVAL_GLOBAL was set. */ int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS); int gotParse = 0; unsigned int i, objectsUsed = 0; /* These variables keep track of how much * state has been allocated while evaluating * the script, so that it can be freed * properly if an error occurs. */ Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse)); CmdFrame *eeFramePtr = TclStackAlloc(interp, sizeof(CmdFrame)); Tcl_Obj **stackObjArray = TclStackAlloc(interp, minObjs * sizeof(Tcl_Obj *)); int *expandStack = TclStackAlloc(interp, minObjs * sizeof(int)); int *linesStack = TclStackAlloc(interp, minObjs * sizeof(int)); /* TIP #280 Structures for tracking of command * locations. */ ssize_t *clNext = NULL; /* Pointer for the tracking of invisible * continuation lines. Initialized only if the * caller gave us a table of locations to * track, via scriptCLLocPtr. It always refers * to the table entry holding the location of * the next invisible continuation line to * look for, while parsing the script. */ if (iPtr->scriptCLLocPtr) { if (clNextOuter) { clNext = clNextOuter; } else { clNext = &iPtr->scriptCLLocPtr->loc[0]; } } if (numBytes == TCL_STRLEN) { numBytes = strlen(script); } Tcl_ResetResult(interp); savedVarFramePtr = iPtr->varFramePtr; if (flags & TCL_EVAL_GLOBAL) { iPtr->varFramePtr = iPtr->rootFramePtr; |
︙ | ︙ | |||
4622 4623 4624 4625 4626 4627 4628 | * command. We use a separate pointer into the table of * continuation line locations to not lose our position for the * per-command parsing. */ int wordLine = line; const char *wordStart = parsePtr->commandStart; | | | 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 | * command. We use a separate pointer into the table of * continuation line locations to not lose our position for the * per-command parsing. */ int wordLine = line; const char *wordStart = parsePtr->commandStart; ssize_t *wordCLNext = clNext; unsigned int objectsNeeded = 0; unsigned int numWords = parsePtr->numWords; /* * Generate an array of objects for the words of the command. */ |
︙ | ︙ | |||
4675 4676 4677 4678 4679 4680 4681 | if (code != TCL_OK) { break; } objv[objectsUsed] = Tcl_GetObjResult(interp); Tcl_IncrRefCount(objv[objectsUsed]); if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) { | | | 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 | if (code != TCL_OK) { break; } objv[objectsUsed] = Tcl_GetObjResult(interp); Tcl_IncrRefCount(objv[objectsUsed]); if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) { size_t numElements; code = TclListObjLength(interp, objv[objectsUsed], &numElements); if (code == TCL_ERROR) { /* * Attempt to expand a non-list. */ |
︙ | ︙ | |||
4700 4701 4702 4703 4704 4705 4706 | } else { expand[objectsUsed] = 0; objectsNeeded++; } if (wordCLNext) { TclContinuationsEnterDerived(objv[objectsUsed], | | | 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 | } else { expand[objectsUsed] = 0; objectsNeeded++; } if (wordCLNext) { TclContinuationsEnterDerived(objv[objectsUsed], (size_t) (wordStart - outerScript), wordCLNext); } } /* for loop */ iPtr->cmdFramePtr = eeFramePtr; if (code != TCL_OK) { goto error; } if (expandRequested) { |
︙ | ︙ | |||
4726 4727 4728 4729 4730 4731 4732 | ckalloc(objectsNeeded * sizeof(Tcl_Obj *)); lines = lineSpace = ckalloc(objectsNeeded * sizeof(int)); } objectsUsed = 0; while (wordIdx--) { if (expand[wordIdx]) { | | | 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 | ckalloc(objectsNeeded * sizeof(Tcl_Obj *)); lines = lineSpace = ckalloc(objectsNeeded * sizeof(int)); } objectsUsed = 0; while (wordIdx--) { if (expand[wordIdx]) { size_t numElements; Tcl_Obj **elements, *temp = copy[wordIdx]; Tcl_ListObjGetElements(NULL, temp, &numElements, &elements); objectsUsed += numElements; while (numElements--) { lines[objIdx] = -1; |
︙ | ︙ | |||
4955 4956 4957 4958 4959 4960 4961 | * TIP #280 *---------------------------------------------------------------------- */ void TclAdvanceContinuations( int *line, | | | 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 | * TIP #280 *---------------------------------------------------------------------- */ void TclAdvanceContinuations( int *line, ssize_t **clNextPtrPtr, int loc) { /* * Track the invisible continuation lines embedded in a script, if any. * Here they are just spaces (already). They were removed by * TclSubstTokens via TclParseBackslash. * |
︙ | ︙ | |||
5014 5015 5016 5017 5018 5019 5020 | *---------------------------------------------------------------------- */ void TclArgumentEnter( Tcl_Interp *interp, Tcl_Obj **objv, | | | > | 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 | *---------------------------------------------------------------------- */ void TclArgumentEnter( Tcl_Interp *interp, Tcl_Obj **objv, size_t objc, CmdFrame *cfPtr) { Interp *iPtr = (Interp *) interp; int new; size_t i; Tcl_HashEntry *hPtr; CFWord *cfwPtr; for (i = 1; i < objc; i++) { /* * Ignore argument words without line information (= dynamic). If they * are variables they may have location information associated with |
︙ | ︙ | |||
5082 5083 5084 5085 5086 5087 5088 | *---------------------------------------------------------------------- */ void TclArgumentRelease( Tcl_Interp *interp, Tcl_Obj **objv, | | | | 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 | *---------------------------------------------------------------------- */ void TclArgumentRelease( Tcl_Interp *interp, Tcl_Obj **objv, size_t objc) { Interp *iPtr = (Interp *) interp; size_t i; for (i = 1; i < objc; i++) { CFWord *cfwPtr; Tcl_HashEntry *hPtr = Tcl_FindHashEntry(iPtr->lineLAPtr, (char *) objv[i]); if (!hPtr) { |
︙ | ︙ | |||
5131 5132 5133 5134 5135 5136 5137 | *---------------------------------------------------------------------- */ void TclArgumentBCEnter( Tcl_Interp *interp, Tcl_Obj *objv[], | | | | 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 | *---------------------------------------------------------------------- */ void TclArgumentBCEnter( Tcl_Interp *interp, Tcl_Obj *objv[], size_t objc, void *codePtr, CmdFrame *cfPtr, int cmd, int pc) { ExtCmdLoc *eclPtr; size_t word; ECL *ePtr; CFWordBC *lastPtr = NULL; Interp *iPtr = (Interp *) interp; Tcl_HashEntry *hePtr = Tcl_FindHashEntry(iPtr->lineBCPtr, (char *) codePtr); if (!hePtr) { |
︙ | ︙ | |||
5392 5393 5394 5395 5396 5397 5398 | * a previous call to Tcl_CreateInterp). */ register Tcl_Obj *objPtr, /* Pointer to object containing commands to * execute. */ int flags, /* Collection of OR-ed bits that control the * evaluation of the script. Supported values * are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. */ const CmdFrame *invoker, /* Frame of the command doing the eval. */ | | | | | 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 | * a previous call to Tcl_CreateInterp). */ register Tcl_Obj *objPtr, /* Pointer to object containing commands to * execute. */ int flags, /* Collection of OR-ed bits that control the * evaluation of the script. Supported values * are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. */ const CmdFrame *invoker, /* Frame of the command doing the eval. */ int word) /* Index of the word which is in objPtr. */ { int result = TCL_OK; NRE_callback *rootPtr = TOP_CB(interp); result = TclNREvalObjEx(interp, objPtr, flags, invoker, word); return TclNRRunCallbacks(interp, result, rootPtr); } int TclNREvalObjEx( Tcl_Interp *interp, /* Token for command interpreter (returned by * a previous call to Tcl_CreateInterp). */ register Tcl_Obj *objPtr, /* Pointer to object containing commands to * execute. */ int flags, /* Collection of OR-ed bits that control the * evaluation of the script. Supported values * are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. */ const CmdFrame *invoker, /* Frame of the command doing the eval. */ int word) /* Index of the word which is in objPtr. */ { Interp *iPtr = (Interp *) interp; int result; /* * This function consists of three independent blocks for: direct * evaluation of canonical lists, compilation and bytecode execution and * finally direct evaluation. Precisely one of these blocks will be run. */ if (TclListObjIsCanonical(objPtr)) { CmdFrame *eoFramePtr = NULL; size_t objc; Tcl_Obj *listPtr, **objv; /* * Canonical List Optimization: In this case, we * can safely use Tcl_EvalObjv instead and get an appreciable * improvement in execution speed. This is because it allows us to * avoid a setFromAny step that would just pack everything into a |
︙ | ︙ | |||
5519 5520 5521 5522 5523 5524 5525 | return TCL_ERROR; } if (flags & TCL_EVAL_GLOBAL) { savedVarFramePtr = iPtr->varFramePtr; iPtr->varFramePtr = iPtr->rootFramePtr; } Tcl_IncrRefCount(objPtr); | | | | 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 | return TCL_ERROR; } if (flags & TCL_EVAL_GLOBAL) { savedVarFramePtr = iPtr->varFramePtr; iPtr->varFramePtr = iPtr->rootFramePtr; } Tcl_IncrRefCount(objPtr); codePtr = TclCompileObj(interp, objPtr, invoker, (int) word); TclNRAddCallback(interp, TEOEx_ByteCodeCallback, savedVarFramePtr, objPtr, INT2PTR(allowExceptions), NULL); return TclNRExecuteByteCode(interp, codePtr); } { /* * We're not supposed to use the compiler or byte-code * interpreter. Let Tcl_EvalEx evaluate the command directly (and * probably more slowly). */ const char *script; size_t numSrcBytes; /* * Now we check if we have data about invisible continuation lines for * the script, and make it available to the direct script parser and * evaluator we are about to call, if so. * * It may be possible that the script Tcl_Obj* can be free'd while the |
︙ | ︙ | |||
5588 5589 5590 5591 5592 5593 5594 | if (iPtr->numLevels == 0) { if (result == TCL_RETURN) { result = TclUpdateReturnInfo(iPtr); } if ((result != TCL_OK) && (result != TCL_ERROR) && !allowExceptions) { const char *script; | | | 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 | if (iPtr->numLevels == 0) { if (result == TCL_RETURN) { result = TclUpdateReturnInfo(iPtr); } if ((result != TCL_OK) && (result != TCL_ERROR) && !allowExceptions) { const char *script; size_t numSrcBytes; ProcessUnexpectedResult(interp, result); result = TCL_ERROR; script = Tcl_GetStringFromObj(objPtr, &numSrcBytes); Tcl_LogCommandInfo(interp, script, script, numSrcBytes); } |
︙ | ︙ | |||
5673 5674 5675 5676 5677 5678 5679 | int returnCode) /* The unexpected result code. */ { char buf[TCL_INTEGER_SPACE]; Tcl_ResetResult(interp); if (returnCode == TCL_BREAK) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 | int returnCode) /* The unexpected result code. */ { char buf[TCL_INTEGER_SPACE]; Tcl_ResetResult(interp); if (returnCode == TCL_BREAK) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "invoked \"break\" outside of a loop", TCL_STRLEN)); } else if (returnCode == TCL_CONTINUE) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "invoked \"continue\" outside of a loop", TCL_STRLEN)); } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "command returned bad code: %d", returnCode)); } sprintf(buf, "%d", returnCode); Tcl_SetErrorCode(interp, "TCL", "UNEXPECTED_RESULT_CODE", buf, NULL); } |
︙ | ︙ | |||
5722 5723 5724 5725 5726 5727 5728 | if (*exprstring == '\0') { /* * Legacy compatibility - return 0 for the zero-length string. */ *ptr = 0; } else { | | | 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 | if (*exprstring == '\0') { /* * Legacy compatibility - return 0 for the zero-length string. */ *ptr = 0; } else { exprPtr = Tcl_NewStringObj(exprstring, TCL_STRLEN); Tcl_IncrRefCount(exprPtr); result = Tcl_ExprLongObj(interp, exprPtr, ptr); Tcl_DecrRefCount(exprPtr); } return result; } |
︙ | ︙ | |||
5747 5748 5749 5750 5751 5752 5753 | if (*exprstring == '\0') { /* * Legacy compatibility - return 0 for the zero-length string. */ *ptr = 0.0; } else { | | | 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 | if (*exprstring == '\0') { /* * Legacy compatibility - return 0 for the zero-length string. */ *ptr = 0.0; } else { exprPtr = Tcl_NewStringObj(exprstring, TCL_STRLEN); Tcl_IncrRefCount(exprPtr); result = Tcl_ExprDoubleObj(interp, exprPtr, ptr); Tcl_DecrRefCount(exprPtr); /* Discard the expression object. */ } return result; } |
︙ | ︙ | |||
5772 5773 5774 5775 5776 5777 5778 | * An empty string. Just set the result boolean to 0 (false). */ *ptr = 0; return TCL_OK; } else { int result; | | | 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 | * An empty string. Just set the result boolean to 0 (false). */ *ptr = 0; return TCL_OK; } else { int result; Tcl_Obj *exprPtr = Tcl_NewStringObj(exprstring, TCL_STRLEN); Tcl_IncrRefCount(exprPtr); result = Tcl_ExprBooleanObj(interp, exprPtr, ptr); Tcl_DecrRefCount(exprPtr); return result; } } |
︙ | ︙ | |||
5930 5931 5932 5933 5934 5935 5936 | *---------------------------------------------------------------------- */ int TclObjInvokeNamespace( Tcl_Interp *interp, /* Interpreter in which command is to be * invoked. */ | | | 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 | *---------------------------------------------------------------------- */ int TclObjInvokeNamespace( Tcl_Interp *interp, /* Interpreter in which command is to be * invoked. */ size_t objc, /* Count of arguments. */ Tcl_Obj *const objv[], /* Argument objects; objv[0] points to the * name of the command to invoke. */ Tcl_Namespace *nsPtr, /* The namespace to use. */ int flags) /* Combination of flags controlling the call: * TCL_INVOKE_HIDDEN, TCL_INVOKE_NO_UNKNOWN, * or TCL_INVOKE_NO_TRACEBACK. */ { |
︙ | ︙ | |||
5978 5979 5980 5981 5982 5983 5984 | *---------------------------------------------------------------------- */ int TclObjInvoke( Tcl_Interp *interp, /* Interpreter in which command is to be * invoked. */ | | | | | 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 | *---------------------------------------------------------------------- */ int TclObjInvoke( Tcl_Interp *interp, /* Interpreter in which command is to be * invoked. */ size_t objc, /* Count of arguments. */ Tcl_Obj *const objv[], /* Argument objects; objv[0] points to the * name of the command to invoke. */ int flags) /* Combination of flags controlling the call: * TCL_INVOKE_HIDDEN, TCL_INVOKE_NO_UNKNOWN, * or TCL_INVOKE_NO_TRACEBACK. */ { if (interp == NULL) { return TCL_ERROR; } if ((objc < 1) || (objv == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal argument vector", TCL_STRLEN)); return TCL_ERROR; } if ((flags & TCL_INVOKE_HIDDEN) == 0) { Tcl_Panic("TclObjInvoke: called without TCL_INVOKE_HIDDEN"); } return Tcl_NRCallObjProc(interp, TclNRInvoke, NULL, objc, objv); } int TclNRInvoke( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { register Interp *iPtr = (Interp *) interp; Tcl_HashTable *hTblPtr; /* Table of hidden commands. */ const char *cmdName; /* Name of the command from objv[0]. */ Tcl_HashEntry *hPtr = NULL; Command *cmdPtr; |
︙ | ︙ | |||
6026 6027 6028 6029 6030 6031 6032 | "invalid hidden command name \"%s\"", cmdName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "HIDDENTOKEN", cmdName, NULL); return TCL_ERROR; } cmdPtr = Tcl_GetHashValue(hPtr); | > | > > | > | 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 | "invalid hidden command name \"%s\"", cmdName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "HIDDENTOKEN", cmdName, NULL); return TCL_ERROR; } cmdPtr = Tcl_GetHashValue(hPtr); /* * Avoid the exception-handling brain damage when numLevels == 0. */ iPtr->numLevels++; Tcl_NRAddCallback(interp, NRPostInvoke, NULL, NULL, NULL, NULL); /* * Normal command resolution of objv[0] isn't going to find cmdPtr. * That's the whole point of **hidden** commands. So tell the * Eval core machinery not to even try (and risk finding something wrong). */ return TclNREvalObjv(interp, objc, objv, TCL_EVAL_NORESOLVE, cmdPtr); } static int NRPostInvoke( ClientData clientData[], Tcl_Interp *interp, int result) { Interp *iPtr = (Interp *) interp; iPtr->numLevels--; return result; } /* *--------------------------------------------------------------------------- * |
︙ | ︙ | |||
6085 6086 6087 6088 6089 6090 6091 | if (expr[0] == '\0') { /* * An empty string. Just set the interpreter's result to 0. */ Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); } else { | | | 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 | if (expr[0] == '\0') { /* * An empty string. Just set the interpreter's result to 0. */ Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); } else { Tcl_Obj *resultPtr, *exprObj = Tcl_NewStringObj(expr, TCL_STRLEN); Tcl_IncrRefCount(exprObj); code = Tcl_ExprObj(interp, exprObj, &resultPtr); Tcl_DecrRefCount(exprObj); if (code == TCL_OK) { Tcl_SetObjResult(interp, resultPtr); Tcl_DecrRefCount(resultPtr); |
︙ | ︙ | |||
6152 6153 6154 6155 6156 6157 6158 | void Tcl_AppendObjToErrorInfo( Tcl_Interp *interp, /* Interpreter to which error information * pertains. */ Tcl_Obj *objPtr) /* Message to record. */ { | | | 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 | void Tcl_AppendObjToErrorInfo( Tcl_Interp *interp, /* Interpreter to which error information * pertains. */ Tcl_Obj *objPtr) /* Message to record. */ { size_t length; register Interp *iPtr = (Interp *) interp; const char *message = TclGetStringFromObj(objPtr, &length); Tcl_IncrRefCount(objPtr); /* * If we are just starting to log an error, errorInfo is initialized from |
︙ | ︙ | |||
6310 6311 6312 6313 6314 6315 6316 | */ static int ExprCeilFunc( ClientData clientData, /* Ignored */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 | */ static int ExprCeilFunc( ClientData clientData, /* Ignored */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter list. */ { int code; double d; mp_int big; if (objc != 2) { |
︙ | ︙ | |||
6346 6347 6348 6349 6350 6351 6352 | } static int ExprFloorFunc( ClientData clientData, /* Ignored */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 | } static int ExprFloorFunc( ClientData clientData, /* Ignored */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter list. */ { int code; double d; mp_int big; if (objc != 2) { |
︙ | ︙ | |||
6381 6382 6383 6384 6385 6386 6387 | return TCL_OK; } static int ExprIsqrtFunc( ClientData clientData, /* Ignored */ Tcl_Interp *interp, /* The interpreter in which to execute. */ | | | 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 | return TCL_OK; } static int ExprIsqrtFunc( ClientData clientData, /* Ignored */ Tcl_Interp *interp, /* The interpreter in which to execute. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter list. */ { ClientData ptr; int type; double d; Tcl_WideInt w; mp_int big; |
︙ | ︙ | |||
6471 6472 6473 6474 6475 6476 6477 | mp_clear(&big); Tcl_SetObjResult(interp, Tcl_NewBignumObj(&root)); } return TCL_OK; negarg: Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 | mp_clear(&big); Tcl_SetObjResult(interp, Tcl_NewBignumObj(&root)); } return TCL_OK; negarg: Tcl_SetObjResult(interp, Tcl_NewStringObj( "square root of negative argument", TCL_STRLEN)); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "domain error: argument not in valid range", NULL); return TCL_ERROR; } static int ExprSqrtFunc( ClientData clientData, /* Ignored */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter list. */ { int code; double d; mp_int big; if (objc != 2) { |
︙ | ︙ | |||
6525 6526 6527 6528 6529 6530 6531 | static int ExprUnaryFunc( ClientData clientData, /* Contains the address of a function that * takes one double argument and returns a * double result. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 | static int ExprUnaryFunc( ClientData clientData, /* Contains the address of a function that * takes one double argument and returns a * double result. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count */ Tcl_Obj *const *objv) /* Actual parameter list */ { int code; double d; double (*func)(double) = (double (*)(double)) clientData; if (objc != 2) { |
︙ | ︙ | |||
6585 6586 6587 6588 6589 6590 6591 | static int ExprBinaryFunc( ClientData clientData, /* Contains the address of a function that * takes two double arguments and returns a * double result. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 | static int ExprBinaryFunc( ClientData clientData, /* Contains the address of a function that * takes two double arguments and returns a * double result. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Parameter vector. */ { int code; double d1, d2; double (*func)(double, double) = (double (*)(double, double)) clientData; if (objc != 3) { |
︙ | ︙ | |||
6627 6628 6629 6630 6631 6632 6633 | } static int ExprAbsFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 | } static int ExprAbsFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Parameter vector. */ { ClientData ptr; int type; mp_int big; if (objc != 2) { |
︙ | ︙ | |||
6736 6737 6738 6739 6740 6741 6742 | } static int ExprBoolFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | | 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 | } static int ExprBoolFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter vector. */ { int value; if (objc != 2) { MathFuncWrongNumArgs(interp, 2, objc, objv); return TCL_ERROR; } if (Tcl_GetBooleanFromObj(interp, objv[1], &value) != TCL_OK) { return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value)); return TCL_OK; } static int ExprDoubleFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter vector. */ { double dResult; if (objc != 2) { MathFuncWrongNumArgs(interp, 2, objc, objv); return TCL_ERROR; |
︙ | ︙ | |||
6784 6785 6786 6787 6788 6789 6790 | } static int ExprEntierFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 | } static int ExprEntierFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter vector. */ { double d; int type; ClientData ptr; if (objc != 2) { |
︙ | ︙ | |||
6840 6841 6842 6843 6844 6845 6846 | } static int ExprIntFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 | } static int ExprIntFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter vector. */ { long iResult; Tcl_Obj *objPtr; if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
6872 6873 6874 6875 6876 6877 6878 | } static int ExprWideFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 | } static int ExprWideFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter vector. */ { Tcl_WideInt wResult; Tcl_Obj *objPtr; if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
6905 6906 6907 6908 6909 6910 6911 | } static int ExprRandFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 | } static int ExprRandFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter vector. */ { Interp *iPtr = (Interp *) interp; double dResult; long tmp; /* Algorithm assumes at least 32 bits. Only * long guarantees that. See below. */ Tcl_Obj *oResult; |
︙ | ︙ | |||
6998 6999 7000 7001 7002 7003 7004 | } static int ExprRoundFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 | } static int ExprRoundFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Parameter vector. */ { double d; ClientData ptr; int type; if (objc != 2) { |
︙ | ︙ | |||
7073 7074 7075 7076 7077 7078 7079 | } static int ExprSrandFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ | | | 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 | } static int ExprSrandFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ size_t objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Parameter vector. */ { Interp *iPtr = (Interp *) interp; long i = 0; /* Initialized to avoid compiler warning. */ /* * Convert argument and use it to reset the seed. |
︙ | ︙ | |||
7145 7146 7147 7148 7149 7150 7151 | * *---------------------------------------------------------------------- */ static void MathFuncWrongNumArgs( Tcl_Interp *interp, /* Tcl interpreter */ | | | | 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 | * *---------------------------------------------------------------------- */ static void MathFuncWrongNumArgs( Tcl_Interp *interp, /* Tcl interpreter */ size_t expected, /* Formal parameter count. */ size_t found, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter vector. */ { const char *name = Tcl_GetString(objv[0]); const char *tail = name + strlen(name); while (tail > name+1) { tail--; |
︙ | ︙ | |||
7325 7326 7327 7328 7329 7330 7331 | */ int Tcl_NRCallObjProc( Tcl_Interp *interp, Tcl_ObjCmdProc *objProc, ClientData clientData, | | | 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 | */ int Tcl_NRCallObjProc( Tcl_Interp *interp, Tcl_ObjCmdProc *objProc, ClientData clientData, size_t objc, Tcl_Obj *const objv[]) { NRE_callback *rootPtr = TOP_CB(interp); TclNRAddCallback(interp, Dispatch, objProc, clientData, INT2PTR(objc), objv); return TclNRRunCallbacks(interp, TCL_OK, rootPtr); |
︙ | ︙ | |||
7406 7407 7408 7409 7410 7411 7412 | return TclNREvalObjEx(interp, objPtr, flags, NULL, INT_MIN); } int Tcl_NREvalObjv( Tcl_Interp *interp, /* Interpreter in which to evaluate the * command. Also used for error reporting. */ | | | | 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 | return TclNREvalObjEx(interp, objPtr, flags, NULL, INT_MIN); } int Tcl_NREvalObjv( Tcl_Interp *interp, /* Interpreter in which to evaluate the * command. Also used for error reporting. */ size_t objc, /* Number of words in command. */ Tcl_Obj *const objv[], /* An array of pointers to objects that are * the words that make up the command. */ int flags) /* Collection of OR-ed bits that control the * evaluation of the script. Only * TCL_EVAL_GLOBAL, TCL_EVAL_INVOKE and * TCL_EVAL_NOERR are currently supported. */ { return TclNREvalObjv(interp, objc, objv, flags, NULL); } int Tcl_NRCmdSwap( Tcl_Interp *interp, Tcl_Command cmd, size_t objc, Tcl_Obj *const objv[], int flags) { return TclNREvalObjv(interp, objc, objv, flags|TCL_EVAL_NOERR, (Command *) cmd); } |
︙ | ︙ | |||
7512 7513 7514 7515 7516 7517 7518 | runPtr->data[1] = listPtr; } int TclNRTailcallObjCmd( ClientData clientData, Tcl_Interp *interp, | | | > | 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 | runPtr->data[1] = listPtr; } int TclNRTailcallObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; if (objc < 1) { Tcl_WrongNumArgs(interp, 1, objv, "?command? ?arg ...?"); return TCL_ERROR; } if (!(iPtr->varFramePtr->isProcCallFrame & 1)) { /* or is upleveled */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "tailcall can only be called from a proc or lambda", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL); return TCL_ERROR; } /* * Invocation without args just clears a scheduled tailcall; invocation * with an argument replaces any previously scheduled tailcall. |
︙ | ︙ | |||
7556 7557 7558 7559 7560 7561 7562 | Tcl_Namespace *ns1Ptr; /* The tailcall data is in a Tcl list: the first element is the * namespace, the rest the command to be tailcalled. */ listPtr = Tcl_NewListObj(objc, objv); | | | | 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 | Tcl_Namespace *ns1Ptr; /* The tailcall data is in a Tcl list: the first element is the * namespace, the rest the command to be tailcalled. */ listPtr = Tcl_NewListObj(objc, objv); nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, TCL_STRLEN); if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr)) || (nsPtr != ns1Ptr)) { Tcl_Panic("Tailcall failed to find the proper namespace"); } TclListObjSetElement(interp, listPtr, 0, nsObjPtr); iPtr->varFramePtr->tailcallPtr = listPtr; } return TCL_RETURN; } int TclNRTailcallEval( ClientData data[], Tcl_Interp *interp, int result) { Interp *iPtr = (Interp *) interp; Tcl_Obj *listPtr = data[0], *nsObjPtr; Tcl_Namespace *nsPtr; size_t objc; Tcl_Obj **objv; Tcl_ListObjGetElements(interp, listPtr, &objc, &objv); nsObjPtr = objv[0]; if (result == TCL_OK) { result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr); |
︙ | ︙ | |||
7661 7662 7663 7664 7665 7666 7667 | #define iPtr ((Interp *) interp) int TclNRYieldObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | | | | 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 | #define iPtr ((Interp *) interp) int TclNRYieldObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { CoroutineData *corPtr = iPtr->execEnvPtr->corPtr; if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?returnValue?"); return TCL_ERROR; } if (!corPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "yield can only be called in a coroutine", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL); return TCL_ERROR; } if (objc == 2) { Tcl_SetObjResult(interp, objv[1]); } NRE_ASSERT(!COR_IS_SUSPENDED(corPtr)); TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr, clientData, NULL, NULL); return TCL_OK; } int TclNRYieldToObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { CoroutineData *corPtr = iPtr->execEnvPtr->corPtr; Tcl_Obj *listPtr, *nsObjPtr; Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr; Tcl_Namespace *ns1Ptr; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "command ?arg ...?"); return TCL_ERROR; } if (!corPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "yieldto can only be called in a coroutine", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL); return TCL_ERROR; } /* * Add the tailcall in the caller env, then just yield. * * This is essentially code from TclNRTailcallObjCmd */ /* * Add the tailcall in the caller env, then just yield. * * This is essentially code from TclNRTailcallObjCmd */ listPtr = Tcl_NewListObj(objc, objv); nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, TCL_STRLEN); if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr)) || (nsPtr != ns1Ptr)) { Tcl_Panic("yieldto failed to find the proper namespace"); } TclListObjSetElement(interp, listPtr, 0, nsObjPtr); |
︙ | ︙ | |||
7938 7939 7940 7941 7942 7943 7944 | } else { /* * Coroutine is active: yield */ if (corPtr->stackLevel != stackLevel) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 | } else { /* * Coroutine is active: yield */ if (corPtr->stackLevel != stackLevel) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot yield: C stack busy", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "CANT_YIELD", NULL); return TCL_ERROR; } if (type == CORO_ACTIVATE_YIELD) { corPtr->nargs = COROUTINE_ARGUMENTS_SINGLE_OPTIONAL; |
︙ | ︙ | |||
7978 7979 7980 7981 7982 7983 7984 | *---------------------------------------------------------------------- */ static int NRCoroInjectObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | > | | 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 | *---------------------------------------------------------------------- */ static int NRCoroInjectObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Command *cmdPtr; CoroutineData *corPtr; ExecEnv *savedEEPtr = iPtr->execEnvPtr; /* * Usage more or less like tailcall: * inject coroName cmd ?arg1 arg2 ...? */ if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "coroName cmd ?arg1 arg2 ...?"); return TCL_ERROR; } cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[1]); if ((!cmdPtr) || (cmdPtr->nreProc != TclNRInterpCoroutine)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can only inject a command into a coroutine", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COROUTINE", TclGetString(objv[1]), NULL); return TCL_ERROR; } corPtr = cmdPtr->objClientData; if (!COR_IS_SUSPENDED(corPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can only inject a command into a suspended coroutine", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ACTIVE", NULL); return TCL_ERROR; } /* * Add the callback to the coro's execEnv, so that it is the first thing * to happen when the coro is resumed. */ iPtr->execEnvPtr = corPtr->eePtr; TclNREvalObjEx(interp, Tcl_NewListObj(objc-2, objv+2), 0, NULL, INT_MIN); iPtr->execEnvPtr = savedEEPtr; return TCL_OK; } int TclNRInterpCoroutine( ClientData clientData, Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { CoroutineData *corPtr = clientData; if (!COR_IS_SUSPENDED(corPtr)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "coroutine \"%s\" is already running", |
︙ | ︙ | |||
8057 8058 8059 8060 8061 8062 8063 | Tcl_SetObjResult(interp, objv[1]); } else if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?arg?"); return TCL_ERROR; } break; default: | | | | | | 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 | Tcl_SetObjResult(interp, objv[1]); } else if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?arg?"); return TCL_ERROR; } break; default: if (corPtr->nargs != 1 + (ssize_t) objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "wrong coro nargs; how did we get here? " "not implemented!", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); return TCL_ERROR; } /* fallthrough */ case COROUTINE_ARGUMENTS_ARBITRARY: if (objc > 1) { Tcl_SetObjResult(interp, Tcl_NewListObj(objc-1, objv+1)); |
︙ | ︙ | |||
8092 8093 8094 8095 8096 8097 8098 | *---------------------------------------------------------------------- */ int TclNRCoroutineObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 | *---------------------------------------------------------------------- */ int TclNRCoroutineObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Command *cmdPtr; CoroutineData *corPtr; const char *fullName, *procName; Namespace *nsPtr, *altNsPtr, *cxtNsPtr; Tcl_DString ds; |
︙ | ︙ | |||
8148 8149 8150 8151 8152 8153 8154 | * struct and create the corresponding command. */ corPtr = ckalloc(sizeof(CoroutineData)); Tcl_DStringInit(&ds); if (nsPtr != iPtr->globalNsPtr) { | | | | 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 | * struct and create the corresponding command. */ corPtr = ckalloc(sizeof(CoroutineData)); Tcl_DStringInit(&ds); if (nsPtr != iPtr->globalNsPtr) { Tcl_DStringAppend(&ds, nsPtr->fullName, TCL_STRLEN); TclDStringAppendLiteral(&ds, "::"); } Tcl_DStringAppend(&ds, procName, TCL_STRLEN); cmdPtr = (Command *) Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds), /*objProc*/ NULL, TclNRInterpCoroutine, corPtr, DeleteCoroutine); Tcl_DStringFree(&ds); corPtr->cmdPtr = cmdPtr; cmdPtr->refCount++; |
︙ | ︙ | |||
8242 8243 8244 8245 8246 8247 8248 | * This is used in the [info] ensemble */ int TclInfoCoroutineCmd( ClientData dummy, Tcl_Interp *interp, | | | 8251 8252 8253 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 | * This is used in the [info] ensemble */ int TclInfoCoroutineCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { CoroutineData *corPtr = iPtr->execEnvPtr->corPtr; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; |
︙ | ︙ |
Changes to generic/tclBinary.c.
︙ | ︙ | |||
17 18 19 20 21 22 23 | #include <math.h> /* * The following constants are used by GetFormatSpec to indicate various * special conditions in the parsing of a format specifier. */ | | > | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include <math.h> /* * The following constants are used by GetFormatSpec to indicate various * special conditions in the parsing of a format specifier. */ #define BINARY_ALL ((size_t)-1) /* Use all elements in the argument. */ #define BINARY_NOCOUNT ((size_t)-2) /* No count was specified in format. */ /* * The following flags may be ORed together and returned by GetFormatSpec */ #define BINARY_SIGNED 0 /* Field to be read as signed data */ #define BINARY_UNSIGNED 1 /* Field to be read as unsigned data */ |
︙ | ︙ | |||
56 57 58 59 60 61 62 | static void DupByteArrayInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); static int FormatNumber(Tcl_Interp *interp, int type, Tcl_Obj *src, unsigned char **cursorPtr); static void FreeByteArrayInternalRep(Tcl_Obj *objPtr); static int GetFormatSpec(const char **formatPtr, char *cmdPtr, | | | | < < | < < | < < | < < | < < | < < | < < | < < | 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 | static void DupByteArrayInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); static int FormatNumber(Tcl_Interp *interp, int type, Tcl_Obj *src, unsigned char **cursorPtr); static void FreeByteArrayInternalRep(Tcl_Obj *objPtr); static int GetFormatSpec(const char **formatPtr, char *cmdPtr, size_t *countPtr, int *flagsPtr); static Tcl_Obj * ScanNumber(unsigned char *buffer, int type, int flags, Tcl_HashTable **numberCachePtr); static int SetByteArrayFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static void UpdateStringOfByteArray(Tcl_Obj *listPtr); static void DeleteScanNumberCache(Tcl_HashTable *numberCachePtr); static int NeedReversing(int format); static void CopyNumber(const void *from, void *to, size_t length, int type); /* Binary ensemble commands */ static Tcl_ObjCmdProc BinaryFormatCmd; static Tcl_ObjCmdProc BinaryScanCmd; /* Binary encoding sub-ensemble commands */ static Tcl_ObjCmdProc BinaryEncodeHex; static Tcl_ObjCmdProc BinaryDecodeHex; static Tcl_ObjCmdProc BinaryEncode64; static Tcl_ObjCmdProc BinaryDecode64; static Tcl_ObjCmdProc BinaryEncodeUu; static Tcl_ObjCmdProc BinaryDecodeUu; /* * The following tables are used by the binary encoders */ static const char HexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', |
︙ | ︙ | |||
191 192 193 194 195 196 197 | * The following structure is the internal rep for a ByteArray object. Keeps * track of how much memory has been used and how much has been allocated for * the byte array to enable growing and shrinking of the ByteArray object with * fewer mallocs. */ typedef struct { | | | | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | * The following structure is the internal rep for a ByteArray object. Keeps * track of how much memory has been used and how much has been allocated for * the byte array to enable growing and shrinking of the ByteArray object with * fewer mallocs. */ typedef struct { size_t used; /* The number of bytes used in the byte * array. */ size_t allocated; /* The amount of space actually allocated * minus 1 byte. */ unsigned char bytes[1]; /* The array of bytes. The actual size of this * field depends on the 'allocated' field * above. */ } ByteArray; #define BYTEARRAY_SIZE(len) \ ((size_t) (TclOffset(ByteArray, bytes) + (len))) #define GET_BYTEARRAY(objPtr) \ ((ByteArray *) (objPtr)->internalRep.twoPtrValue.ptr1) #define SET_BYTEARRAY(objPtr, baPtr) \ (objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (baPtr) /* |
︙ | ︙ | |||
232 233 234 235 236 237 238 | #undef Tcl_NewByteArrayObj Tcl_Obj * Tcl_NewByteArrayObj( const unsigned char *bytes, /* The array of bytes used to initialize the * new object. */ | | | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | #undef Tcl_NewByteArrayObj Tcl_Obj * Tcl_NewByteArrayObj( const unsigned char *bytes, /* The array of bytes used to initialize the * new object. */ size_t length) /* Length of the array of bytes, which must be * >= 0. */ { #ifdef TCL_MEM_DEBUG return Tcl_DbNewByteArrayObj(bytes, length, "unknown", 0); #else /* if not TCL_MEM_DEBUG */ Tcl_Obj *objPtr; |
︙ | ︙ | |||
275 276 277 278 279 280 281 | *---------------------------------------------------------------------- */ Tcl_Obj * Tcl_DbNewByteArrayObj( const unsigned char *bytes, /* The array of bytes used to initialize the * new object. */ | | | 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | *---------------------------------------------------------------------- */ Tcl_Obj * Tcl_DbNewByteArrayObj( const unsigned char *bytes, /* The array of bytes used to initialize the * new object. */ size_t length, /* Length of the array of bytes, which must be * >= 0. */ const char *file, /* The name of the source file calling this * procedure; used for debugging. */ int line) /* Line number in the source file; used for * debugging. */ { #ifdef TCL_MEM_DEBUG |
︙ | ︙ | |||
315 316 317 318 319 320 321 | *---------------------------------------------------------------------- */ void Tcl_SetByteArrayObj( Tcl_Obj *objPtr, /* Object to initialize as a ByteArray. */ const unsigned char *bytes, /* The array of bytes to use as the new | | | | < < < | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | *---------------------------------------------------------------------- */ void Tcl_SetByteArrayObj( Tcl_Obj *objPtr, /* Object to initialize as a ByteArray. */ const unsigned char *bytes, /* The array of bytes to use as the new * value. May be NULL even if length > 0. */ size_t length) /* Length of the array of bytes, which must * be >= 0. */ { ByteArray *byteArrayPtr; if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayObj"); } TclFreeIntRep(objPtr); TclInvalidateStringRep(objPtr); byteArrayPtr = ckalloc(BYTEARRAY_SIZE(length)); byteArrayPtr->used = length; byteArrayPtr->allocated = length; if ((bytes != NULL) && (length > 0)) { memcpy(byteArrayPtr->bytes, bytes, length); } objPtr->typePtr = &tclByteArrayType; SET_BYTEARRAY(objPtr, byteArrayPtr); } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
362 363 364 365 366 367 368 | * *---------------------------------------------------------------------- */ unsigned char * Tcl_GetByteArrayFromObj( Tcl_Obj *objPtr, /* The ByteArray object. */ | | | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | * *---------------------------------------------------------------------- */ unsigned char * Tcl_GetByteArrayFromObj( Tcl_Obj *objPtr, /* The ByteArray object. */ size_t *lengthPtr) /* If non-NULL, filled with length of the * array of bytes in the ByteArray object. */ { ByteArray *baPtr; if (objPtr->typePtr != &tclByteArrayType) { SetByteArrayFromAny(NULL, objPtr); } |
︙ | ︙ | |||
403 404 405 406 407 408 409 | * *---------------------------------------------------------------------- */ unsigned char * Tcl_SetByteArrayLength( Tcl_Obj *objPtr, /* The ByteArray object. */ | | | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | * *---------------------------------------------------------------------- */ unsigned char * Tcl_SetByteArrayLength( Tcl_Obj *objPtr, /* The ByteArray object. */ size_t length) /* New length for internal byte array. */ { ByteArray *byteArrayPtr; if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayLength"); } if (objPtr->typePtr != &tclByteArrayType) { |
︙ | ︙ | |||
446 447 448 449 450 451 452 | */ static int SetByteArrayFromAny( Tcl_Interp *interp, /* Not used. */ Tcl_Obj *objPtr) /* The object to convert to type ByteArray. */ { | | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | */ static int SetByteArrayFromAny( Tcl_Interp *interp, /* Not used. */ Tcl_Obj *objPtr) /* The object to convert to type ByteArray. */ { size_t length; const char *src, *srcEnd; unsigned char *dst; ByteArray *byteArrayPtr; Tcl_UniChar ch; if (objPtr->typePtr != &tclByteArrayType) { src = TclGetStringFromObj(objPtr, &length); |
︙ | ︙ | |||
519 520 521 522 523 524 525 | */ static void DupByteArrayInternalRep( Tcl_Obj *srcPtr, /* Object with internal rep to copy. */ Tcl_Obj *copyPtr) /* Object with internal rep to set. */ { | | | | 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | */ static void DupByteArrayInternalRep( Tcl_Obj *srcPtr, /* Object with internal rep to copy. */ Tcl_Obj *copyPtr) /* Object with internal rep to set. */ { size_t length; ByteArray *srcArrayPtr, *copyArrayPtr; srcArrayPtr = GET_BYTEARRAY(srcPtr); length = srcArrayPtr->used; copyArrayPtr = ckalloc(BYTEARRAY_SIZE(length)); copyArrayPtr->used = length; copyArrayPtr->allocated = length; memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, length); SET_BYTEARRAY(copyPtr, copyArrayPtr); copyPtr->typePtr = &tclByteArrayType; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
561 562 563 564 565 566 567 | */ static void UpdateStringOfByteArray( Tcl_Obj *objPtr) /* ByteArray object whose string rep to * update. */ { | | | | | | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 | */ static void UpdateStringOfByteArray( Tcl_Obj *objPtr) /* ByteArray object whose string rep to * update. */ { size_t i, length, size; unsigned char *src; char *dst; ByteArray *byteArrayPtr; byteArrayPtr = GET_BYTEARRAY(objPtr); src = byteArrayPtr->bytes; length = byteArrayPtr->used; /* * How much space will string rep need? */ size = length; for (i = 0; i < length; i++) { if ((src[i] == 0) || (src[i] > 127)) { size++; } } if (size < length) { Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); } dst = ckalloc(size + 1); objPtr->bytes = dst; objPtr->length = size; if (size == length) { memcpy(dst, src, size); dst[size] = '\0'; } else { for (i = 0; i < length; i++) { dst += Tcl_UniCharToUtf(src[i], dst); } *dst = '\0'; } |
︙ | ︙ | |||
624 625 626 627 628 629 630 | *---------------------------------------------------------------------- */ void TclAppendBytesToByteArray( Tcl_Obj *objPtr, const unsigned char *bytes, | | | | | 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 | *---------------------------------------------------------------------- */ void TclAppendBytesToByteArray( Tcl_Obj *objPtr, const unsigned char *bytes, size_t len) { ByteArray *byteArrayPtr; if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray"); } if (len == TCL_STRLEN) { Tcl_Panic("%s must be called with definite number of bytes to append", "TclAppendBytesToByteArray"); } if (objPtr->typePtr != &tclByteArrayType) { SetByteArrayFromAny(NULL, objPtr); } byteArrayPtr = GET_BYTEARRAY(objPtr); /* * If we need to, resize the allocated space in the byte array. */ if (byteArrayPtr->used + len > byteArrayPtr->allocated) { size_t attempt, used = byteArrayPtr->used; ByteArray *tmpByteArrayPtr = NULL; attempt = byteArrayPtr->allocated; if (attempt < 1) { /* * No allocated bytes, so must be none used too. We use this * method to calculate how many bytes to allocate because we can |
︙ | ︙ | |||
744 745 746 747 748 749 750 | *---------------------------------------------------------------------- */ static int BinaryFormatCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | > | | 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 | *---------------------------------------------------------------------- */ static int BinaryFormatCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { size_t arg; /* Index of next argument to consume. */ int value = 0; /* Current integer value to be packed. * Initialized to avoid compiler warning. */ char cmd; /* Current format character. */ size_t count; /* Count associated with current format * character. */ int flags; /* Format field flags */ const char *format; /* Pointer to current position in format * string. */ Tcl_Obj *resultPtr = NULL; /* Object holding result buffer. */ unsigned char *buffer; /* Start of result buffer. */ unsigned char *cursor; /* Current position within result buffer. */ unsigned char *maxPos; /* Greatest position within result buffer that * cursor has visited.*/ const char *errorString; const char *errorValue, *str; int size; size_t length, offset; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "formatString ?arg ...?"); return TCL_ERROR; } /* |
︙ | ︙ | |||
859 860 861 862 863 864 865 | * non-list value. */ if (count == BINARY_NOCOUNT) { arg++; count = 1; } else { | | | | > | 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 | * non-list value. */ if (count == BINARY_NOCOUNT) { arg++; count = 1; } else { size_t listc; Tcl_Obj **listv; /* * The macro evals its args more than once: avoid arg++ */ if (TclListObjGetElements(interp, objv[arg], &listc, &listv) != TCL_OK) { return TCL_ERROR; } arg++; if (count == BINARY_ALL) { count = listc; } else if (count > listc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "number of elements in list does not match count", TCL_STRLEN)); return TCL_ERROR; } } offset += count*size; break; case 'x': if (count == BINARY_ALL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot use \"*\" in format string with \"x\"", TCL_STRLEN)); return TCL_ERROR; } else if (count == BINARY_NOCOUNT) { count = 1; } offset += count; break; case 'X': |
︙ | ︙ | |||
937 938 939 940 941 942 943 | /* * Prepare the result object by preallocating the caclulated number of * bytes and filling with nulls. */ resultPtr = Tcl_NewObj(); buffer = Tcl_SetByteArrayLength(resultPtr, length); | | | 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 | /* * Prepare the result object by preallocating the caclulated number of * bytes and filling with nulls. */ resultPtr = Tcl_NewObj(); buffer = Tcl_SetByteArrayLength(resultPtr, length); memset(buffer, 0, length); /* * Pack the data into the result object. Note that we can skip the * error checking during this pass, since we have already parsed the * string once. */ |
︙ | ︙ | |||
974 975 976 977 978 979 980 | if (count == BINARY_ALL) { count = length; } else if (count == BINARY_NOCOUNT) { count = 1; } if (length >= count) { | | | | | 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 | if (count == BINARY_ALL) { count = length; } else if (count == BINARY_NOCOUNT) { count = 1; } if (length >= count) { memcpy(cursor, bytes, count); } else { memcpy(cursor, bytes, length); memset(cursor + length, pad, (size_t) (count - length)); } cursor += count; break; } case 'b': case 'B': { unsigned char *last; str = Tcl_GetStringFromObj(objv[arg], &length); arg++; if (count == BINARY_ALL) { count = length; } else if (count == BINARY_NOCOUNT) { count = 1; } last = cursor + ((count + 7) / 8); |
︙ | ︙ | |||
1048 1049 1050 1051 1052 1053 1054 | break; } case 'h': case 'H': { unsigned char *last; int c; | | | 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 | break; } case 'h': case 'H': { unsigned char *last; int c; str = Tcl_GetStringFromObj(objv[arg], &length); arg++; if (count == BINARY_ALL) { count = length; } else if (count == BINARY_NOCOUNT) { count = 1; } last = cursor + ((count + 1) / 2); |
︙ | ︙ | |||
1135 1136 1137 1138 1139 1140 1141 | case 'W': case 'r': case 'R': case 'd': case 'q': case 'Q': case 'f': { | | | | > | 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 | case 'W': case 'r': case 'R': case 'd': case 'q': case 'Q': case 'f': { size_t listc, i; Tcl_Obj **listv; if (count == BINARY_NOCOUNT) { /* * Note that we are casting away the const-ness of objv, but * this is safe since we aren't going to modify the array. */ listv = (Tcl_Obj **) (objv + arg); listc = 1; count = 1; } else { TclListObjGetElements(interp, objv[arg], &listc, &listv); if (count == BINARY_ALL) { count = listc; } } arg++; for (i = 0; i < count; i++) { if (FormatNumber(interp, cmd, listv[i], &cursor) != TCL_OK) { Tcl_DecrRefCount(resultPtr); return TCL_ERROR; } } break; } case 'x': if (count == BINARY_NOCOUNT) { count = 1; } memset(cursor, 0, (size_t) count); cursor += count; break; case 'X': if (cursor > maxPos) { maxPos = cursor; } if (count == BINARY_NOCOUNT) { count = 1; } if ((count == BINARY_ALL) || (count > (size_t) (cursor - buffer))) { cursor = buffer; } else { cursor -= count; } break; case '@': if (cursor > maxPos) { |
︙ | ︙ | |||
1225 1226 1227 1228 1229 1230 1231 | buf[Tcl_UniCharToUtf(ch, buf)] = '\0'; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad field specifier \"%s\"", buf)); return TCL_ERROR; } error: | | | 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 | buf[Tcl_UniCharToUtf(ch, buf)] = '\0'; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad field specifier \"%s\"", buf)); return TCL_ERROR; } error: Tcl_SetObjResult(interp, Tcl_NewStringObj(errorString, TCL_STRLEN)); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * BinaryScanCmd -- |
︙ | ︙ | |||
1249 1250 1251 1252 1253 1254 1255 | *---------------------------------------------------------------------- */ int BinaryScanCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | < < | 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 | *---------------------------------------------------------------------- */ int BinaryScanCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { size_t arg; /* Index of next argument to consume. */ int value = 0; /* Current integer value to be packed. * Initialized to avoid compiler warning. */ char cmd; /* Current format character. */ size_t count; /* Count associated with current format * character. */ int flags; /* Format field flags */ const char *format; /* Pointer to current position in format * string. */ Tcl_Obj *resultPtr = NULL; /* Object holding result buffer. */ unsigned char *buffer; /* Start of result buffer. */ const char *errorString; const char *str; size_t length, offset, size, i; Tcl_Obj *valuePtr, *elementPtr; Tcl_HashTable numberCacheHash; Tcl_HashTable *numberCachePtr; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "value formatString ?varName ...?"); |
︙ | ︙ | |||
1569 1570 1571 1572 1573 1574 1575 | } /* * Set the result to the last position of the cursor. */ done: | | | 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 | } /* * Set the result to the last position of the cursor. */ done: Tcl_SetObjResult(interp, Tcl_NewLongObj((long) arg - 3)); DeleteScanNumberCache(numberCachePtr); return TCL_OK; badCount: errorString = "missing count for \"@\" field specifier"; goto error; |
︙ | ︙ | |||
1595 1596 1597 1598 1599 1600 1601 | buf[Tcl_UniCharToUtf(ch, buf)] = '\0'; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad field specifier \"%s\"", buf)); return TCL_ERROR; } error: | | | 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 | buf[Tcl_UniCharToUtf(ch, buf)] = '\0'; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad field specifier \"%s\"", buf)); return TCL_ERROR; } error: Tcl_SetObjResult(interp, Tcl_NewStringObj(errorString, TCL_STRLEN)); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * GetFormatSpec -- |
︙ | ︙ | |||
1624 1625 1626 1627 1628 1629 1630 | *---------------------------------------------------------------------- */ static int GetFormatSpec( const char **formatPtr, /* Pointer to format string. */ char *cmdPtr, /* Pointer to location of command char. */ | | | 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 | *---------------------------------------------------------------------- */ static int GetFormatSpec( const char **formatPtr, /* Pointer to format string. */ char *cmdPtr, /* Pointer to location of command char. */ size_t *countPtr, /* Pointer to repeat count value. */ int *flagsPtr) /* Pointer to field flags */ { /* * Skip any leading blanks. */ while (**formatPtr == ' ') { |
︙ | ︙ | |||
1782 1783 1784 1785 1786 1787 1788 | *---------------------------------------------------------------------- */ static void CopyNumber( const void *from, /* source */ void *to, /* destination */ | | | 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 | *---------------------------------------------------------------------- */ static void CopyNumber( const void *from, /* source */ void *to, /* destination */ size_t length, /* Number of bytes to copy */ int type) /* What type of thing are we copying? */ { switch (NeedReversing(type)) { case 0: memcpy(to, from, length); break; case 1: { |
︙ | ︙ | |||
2305 2306 2307 2308 2309 2310 2311 | *---------------------------------------------------------------------- */ static int BinaryEncodeHex( ClientData clientData, Tcl_Interp *interp, | | | | 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 | *---------------------------------------------------------------------- */ static int BinaryEncodeHex( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *resultObj = NULL; unsigned char *data = NULL; unsigned char *cursor = NULL; size_t offset = 0, count = 0; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "data"); return TCL_ERROR; } TclNewObj(resultObj); |
︙ | ︙ | |||
2349 2350 2351 2352 2353 2354 2355 | *---------------------------------------------------------------------- */ static int BinaryDecodeHex( ClientData clientData, Tcl_Interp *interp, | | > | | 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 | *---------------------------------------------------------------------- */ static int BinaryDecodeHex( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *resultObj = NULL; unsigned char *data, *datastart, *dataend; unsigned char *begin, *cursor, c; int index, value, strict = 0; size_t i, size, count = 0, cut = 0; enum {OPT_STRICT }; static const char *const optStrings[] = { "-strict", NULL }; if (objc < 2 || objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "?options? data"); return TCL_ERROR; } |
︙ | ︙ | |||
2377 2378 2379 2380 2381 2382 2383 | strict = 1; break; } } TclNewObj(resultObj); datastart = data = (unsigned char *) | | | 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 | strict = 1; break; } } TclNewObj(resultObj); datastart = data = (unsigned char *) Tcl_GetStringFromObj(objv[objc-1], &count); dataend = data + count; size = (count + 1) / 2; begin = cursor = Tcl_SetByteArrayLength(resultObj, size); while (data < dataend) { value = 0; for (i=0 ; i<2 ; i++) { if (data >= dataend) { |
︙ | ︙ | |||
2417 2418 2419 2420 2421 2422 2423 | } *cursor++ = UCHAR(value); value = 0; } if (cut > size) { cut = size; } | | | 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 | } *cursor++ = UCHAR(value); value = 0; } if (cut > size) { cut = size; } Tcl_SetByteArrayLength(resultObj, (size_t) (cursor - begin - cut)); Tcl_SetObjResult(interp, resultObj); return TCL_OK; badChar: TclDecrRefCount(resultObj); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid hexadecimal digit \"%c\" at position %d", |
︙ | ︙ | |||
2468 2469 2470 2471 2472 2473 2474 | } \ } while (0) static int BinaryEncode64( ClientData clientData, Tcl_Interp *interp, | | | > < | | > > > > > > | 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 | } \ } while (0) static int BinaryEncode64( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *resultObj; unsigned char *data, *cursor, *limit; size_t maxlen = 0, wrapcharlen = 1, count = 0, outindex = 0; size_t i, size, offset; const char *wrapchar = "\n"; int index, len; enum {OPT_MAXLEN, OPT_WRAPCHAR }; static const char *const optStrings[] = { "-maxlen", "-wrapchar", NULL }; if (objc < 2 || objc%2 != 0) { Tcl_WrongNumArgs(interp, 1, objv, "?-maxlen len? ?-wrapchar char? data"); return TCL_ERROR; } for (i = 1; i < objc-1; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], optStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { return TCL_ERROR; } switch (index) { case OPT_MAXLEN: if (Tcl_GetIntFromObj(interp, objv[i+1], &len) != TCL_OK) { return TCL_ERROR; } if (len < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "maximum length must be non-negative", TCL_STRLEN)); return TCL_ERROR; } if (maxlen < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "line length out of range", -1)); Tcl_SetErrorCode(interp, "TCL", "BINARY", "ENCODE", "LINE_LENGTH", NULL); return TCL_ERROR; } maxlen = (size_t) len; break; case OPT_WRAPCHAR: wrapchar = Tcl_GetStringFromObj(objv[i+1], &wrapcharlen); if (wrapcharlen == 0) { maxlen = 0; } break; |
︙ | ︙ | |||
2574 2575 2576 2577 2578 2579 2580 | *---------------------------------------------------------------------- */ static int BinaryEncodeUu( ClientData clientData, Tcl_Interp *interp, | | | | | | 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 | *---------------------------------------------------------------------- */ static int BinaryEncodeUu( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *resultObj; unsigned char *data, *start, *cursor; int offset, n, i, j, bits, index, lineLength = 61; size_t count, rawLength; const unsigned char SingleNewline[] = { (unsigned char) '\n' }; const unsigned char *wrapchar = SingleNewline; size_t wrapcharlen = sizeof(SingleNewline); enum { OPT_MAXLEN, OPT_WRAPCHAR }; static const char *const optStrings[] = { "-maxlen", "-wrapchar", NULL }; if (objc < 2 || objc%2 != 0) { Tcl_WrongNumArgs(interp, 1, objv, "?-maxlen len? ?-wrapchar char? data"); return TCL_ERROR; |
︙ | ︙ | |||
2690 2691 2692 2693 2694 2695 2696 | *---------------------------------------------------------------------- */ static int BinaryDecodeUu( ClientData clientData, Tcl_Interp *interp, | | | > | | | | | 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 | *---------------------------------------------------------------------- */ static int BinaryDecodeUu( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *resultObj = NULL; unsigned char *data, *datastart, *dataend; unsigned char *begin, *cursor; int index, strict = 0; size_t i, count = 0, size, lineLen; unsigned char c; enum { OPT_STRICT }; static const char *const optStrings[] = { "-strict", NULL }; if (objc < 2 || objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "?options? data"); return TCL_ERROR; } for (i = 1; i < objc-1; ++i) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], optStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { return TCL_ERROR; } switch (index) { case OPT_STRICT: strict = 1; break; } } TclNewObj(resultObj); datastart = data = (unsigned char *) Tcl_GetStringFromObj(objv[objc-1], &count); dataend = data + count; size = ((count + 3) & ~3) * 3 / 4; begin = cursor = Tcl_SetByteArrayLength(resultObj, size); lineLen = TCL_STRLEN; /* * The decoding loop. First, we get the length of line (strictly, the * number of data bytes we expect to generate from the line) we're * processing this time round if it is not already known (i.e., when the * lineLen variable is set to the magic value, -1). */ while (data < dataend) { char d[4] = {0, 0, 0, 0}; if (lineLen == TCL_STRLEN) { c = *data++; if (c < 32 || c > 96) { if (strict || !isspace(c)) { goto badUu; } i--; continue; |
︙ | ︙ | |||
2792 2793 2794 2795 2796 2797 2798 | /* * If we've reached the end of the line, skip until we process a * newline. */ if (lineLen == 0 && data < dataend) { | | | 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 | /* * If we've reached the end of the line, skip until we process a * newline. */ if (lineLen == 0 && data < dataend) { lineLen = TCL_STRLEN; do { c = *data++; if (c == '\n') { break; } else if (c >= 32 && c <= 96) { data--; break; |
︙ | ︙ | |||
2814 2815 2816 2817 2818 2819 2820 | /* * Sanity check, clean up and finish. */ if (lineLen > 0 && strict) { goto shortUu; } | | | 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 | /* * Sanity check, clean up and finish. */ if (lineLen > 0 && strict) { goto shortUu; } Tcl_SetByteArrayLength(resultObj, (size_t)(cursor - begin)); Tcl_SetObjResult(interp, resultObj); return TCL_OK; shortUu: Tcl_SetObjResult(interp, Tcl_ObjPrintf("short uuencode data")); Tcl_SetErrorCode(interp, "TCL", "BINARY", "DECODE", "SHORT", NULL); TclDecrRefCount(resultObj); |
︙ | ︙ | |||
2853 2854 2855 2856 2857 2858 2859 | *---------------------------------------------------------------------- */ static int BinaryDecode64( ClientData clientData, Tcl_Interp *interp, | | | < | | | 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 | *---------------------------------------------------------------------- */ static int BinaryDecode64( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *resultObj = NULL; unsigned char *data, *datastart, *dataend, c = '\0'; unsigned char *begin = NULL, *cursor = NULL; int strict = 0, index; size_t i, count = 0, size, cut = 0; enum { OPT_STRICT }; static const char *const optStrings[] = { "-strict", NULL }; if (objc < 2 || objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "?options? data"); return TCL_ERROR; } |
︙ | ︙ | |||
2883 2884 2885 2886 2887 2888 2889 | strict = 1; break; } } TclNewObj(resultObj); datastart = data = (unsigned char *) | | | 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 | strict = 1; break; } } TclNewObj(resultObj); datastart = data = (unsigned char *) Tcl_GetStringFromObj(objv[objc-1], &count); dataend = data + count; size = ((count + 3) & ~3) * 3 / 4; begin = cursor = Tcl_SetByteArrayLength(resultObj, size); while (data < dataend) { unsigned long value = 0; /* |
︙ | ︙ | |||
2976 2977 2978 2979 2980 2981 2982 | } Tcl_SetByteArrayLength(resultObj, cursor - begin - cut); Tcl_SetObjResult(interp, resultObj); return TCL_OK; bad64: Tcl_SetObjResult(interp, Tcl_ObjPrintf( | | | < | 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 | } Tcl_SetByteArrayLength(resultObj, cursor - begin - cut); Tcl_SetObjResult(interp, resultObj); return TCL_OK; bad64: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid base64 character \"%c\" at position %lu", (char) c, (unsigned long) (data - datastart - 1))); TclDecrRefCount(resultObj); return TCL_ERROR; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclCkalloc.c.
︙ | ︙ | |||
128 129 130 131 132 133 134 | static int ckallocInit = 0; /* * Prototypes for procedures defined in this file: */ static int CheckmemCmd(ClientData clientData, Tcl_Interp *interp, | | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | static int ckallocInit = 0; /* * Prototypes for procedures defined in this file: */ static int CheckmemCmd(ClientData clientData, Tcl_Interp *interp, size_t argc, const char *argv[]); static int MemoryCmd(ClientData clientData, Tcl_Interp *interp, size_t argc, const char *argv[]); static void ValidateMemory(struct mem_header *memHeaderP, const char *file, int line, int nukeGuards); /* *---------------------------------------------------------------------- * * TclInitDbCkalloc -- |
︙ | ︙ | |||
196 197 198 199 200 201 202 | (unsigned long)current_bytes_malloced, maximum_malloc_packets, (unsigned long)maximum_bytes_malloced); if (flags == 0) { fprintf((FILE *)clientData, "%s", buf); } else { /* Assume objPtr to append to */ | | | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | (unsigned long)current_bytes_malloced, maximum_malloc_packets, (unsigned long)maximum_bytes_malloced); if (flags == 0) { fprintf((FILE *)clientData, "%s", buf); } else { /* Assume objPtr to append to */ Tcl_AppendToObj((Tcl_Obj *) clientData, buf, TCL_STRLEN); } return 1; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
390 391 392 393 394 395 396 | * and __LINE__. * *---------------------------------------------------------------------- */ char * Tcl_DbCkalloc( | | | | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | * and __LINE__. * *---------------------------------------------------------------------- */ char * Tcl_DbCkalloc( size_t size, const char *file, int line) { struct mem_header *result = NULL; if (validate_memory) { Tcl_ValidateAllMemory(file, line); } /* Don't let size argument to TclpAlloc overflow */ if (size <= UINT_MAX - HIGH_GUARD_SIZE -sizeof(struct mem_header)) { result = (struct mem_header *) TclpAlloc((unsigned)size + sizeof(struct mem_header) + HIGH_GUARD_SIZE); } if (result == NULL) { fflush(stdout); TclDumpMemoryInfo((ClientData) stderr, 0); Tcl_Panic("unable to alloc %lu bytes, %s line %d", size, file, line); } /* * Fill in guard zones and size. Also initialize the contents of the block * with bogus bytes to detect uses of initialized data. Link into * allocated list. */ |
︙ | ︙ | |||
454 455 456 457 458 459 460 | total_mallocs); fflush(stderr); alloc_tracing = TRUE; trace_on_at_malloc = 0; } if (alloc_tracing) { | | | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 | total_mallocs); fflush(stderr); alloc_tracing = TRUE; trace_on_at_malloc = 0; } if (alloc_tracing) { fprintf(stderr,"ckalloc %lx %lu %s %d\n", (long unsigned int) result->body, size, file, line); } if (break_on_malloc && (total_mallocs >= break_on_malloc)) { break_on_malloc = 0; (void) fflush(stdout); Tcl_Panic("reached malloc break limit (%d)", total_mallocs); |
︙ | ︙ | |||
480 481 482 483 484 485 486 | Tcl_MutexUnlock(ckallocMutexPtr); return result->body; } char * Tcl_AttemptDbCkalloc( | | | 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | Tcl_MutexUnlock(ckallocMutexPtr); return result->body; } char * Tcl_AttemptDbCkalloc( size_t size, const char *file, int line) { struct mem_header *result = NULL; if (validate_memory) { Tcl_ValidateAllMemory(file, line); |
︙ | ︙ | |||
543 544 545 546 547 548 549 | total_mallocs); fflush(stderr); alloc_tracing = TRUE; trace_on_at_malloc = 0; } if (alloc_tracing) { | | | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | total_mallocs); fflush(stderr); alloc_tracing = TRUE; trace_on_at_malloc = 0; } if (alloc_tracing) { fprintf(stderr,"ckalloc %lx %lu %s %d\n", (long unsigned int) result->body, size, file, line); } if (break_on_malloc && (total_mallocs >= break_on_malloc)) { break_on_malloc = 0; (void) fflush(stdout); Tcl_Panic("reached malloc break limit (%d)", total_mallocs); |
︙ | ︙ | |||
666 667 668 669 670 671 672 | * *-------------------------------------------------------------------- */ char * Tcl_DbCkrealloc( char *ptr, | | | 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 | * *-------------------------------------------------------------------- */ char * Tcl_DbCkrealloc( char *ptr, size_t size, const char *file, int line) { char *newPtr; unsigned int copySize; struct mem_header *memp; |
︙ | ︙ | |||
697 698 699 700 701 702 703 | Tcl_DbCkfree(ptr, file, line); return newPtr; } char * Tcl_AttemptDbCkrealloc( char *ptr, | | | 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 | Tcl_DbCkfree(ptr, file, line); return newPtr; } char * Tcl_AttemptDbCkrealloc( char *ptr, size_t size, const char *file, int line) { char *newPtr; unsigned int copySize; struct mem_header *memp; |
︙ | ︙ | |||
748 749 750 751 752 753 754 | * Same as the debug versions. * *---------------------------------------------------------------------- */ char * Tcl_Alloc( | | | | > | | 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 | * Same as the debug versions. * *---------------------------------------------------------------------- */ char * Tcl_Alloc( size_t size) { return Tcl_DbCkalloc(size, "unknown", 0); } char * Tcl_AttemptAlloc( size_t size) { return Tcl_AttemptDbCkalloc(size, "unknown", 0); } void Tcl_Free( char *ptr) { Tcl_DbCkfree(ptr, "unknown", 0); } char * Tcl_Realloc( char *ptr, size_t size) { return Tcl_DbCkrealloc(ptr, size, "unknown", 0); } char * Tcl_AttemptRealloc( char *ptr, size_t size) { return Tcl_AttemptDbCkrealloc(ptr, size, "unknown", 0); } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
809 810 811 812 813 814 815 | *---------------------------------------------------------------------- */ /* ARGSUSED */ static int MemoryCmd( ClientData clientData, Tcl_Interp *interp, | | | 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 | *---------------------------------------------------------------------- */ /* ARGSUSED */ static int MemoryCmd( ClientData clientData, Tcl_Interp *interp, size_t argc, const char *argv[]) { const char *fileName; FILE *fileP; Tcl_DString buffer; int result; size_t len; |
︙ | ︙ | |||
986 987 988 989 990 991 992 | *---------------------------------------------------------------------- */ static int CheckmemCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter for evaluation. */ | | | 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 | *---------------------------------------------------------------------- */ static int CheckmemCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter for evaluation. */ size_t argc, /* Number of arguments. */ const char *argv[]) /* String values of arguments. */ { if (argc != 2) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "wrong # args: should be \"%s fileName\"", argv[0])); return TCL_ERROR; } |
︙ | ︙ | |||
1048 1049 1050 1051 1052 1053 1054 | * that memory was actually allocated. * *---------------------------------------------------------------------- */ char * Tcl_Alloc( | | < < | | | < < | | | | < | | < | < < | | | | | | < | | < | 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 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 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 | * that memory was actually allocated. * *---------------------------------------------------------------------- */ char * Tcl_Alloc( size_t size) { char *result = TclpAlloc(size); /* * Most systems will not alloc(0), instead bumping it to one so that NULL * isn't returned. Some systems (AIX, Tru64) will alloc(0) by returning * NULL, so we have to check that the NULL we get is not in response to * alloc(0). * * The ANSI spec actually says that systems either return NULL *or* a * special pointer on failure, but we only check for NULL */ if ((result == NULL) && size) { Tcl_Panic("unable to alloc %lu bytes", size); } return result; } char * Tcl_DbCkalloc( size_t size, const char *file, int line) { char *result = (char *) TclpAlloc(size); if ((result == NULL) && size) { fflush(stdout); Tcl_Panic("unable to alloc %lu bytes, %s line %d", size, file, line); } return result; } /* *---------------------------------------------------------------------- * * Tcl_AttemptAlloc -- * * Interface to TclpAlloc when TCL_MEM_DEBUG is disabled. It does not * check that memory was actually allocated. * *---------------------------------------------------------------------- */ char * Tcl_AttemptAlloc( size_t size) { char *result = TclpAlloc(size); return result; } char * Tcl_AttemptDbCkalloc( size_t size, const char *file, int line) { char *result = (char *) TclpAlloc(size); return result; } /* *---------------------------------------------------------------------- * * Tcl_Realloc -- * * Interface to TclpRealloc when TCL_MEM_DEBUG is disabled. It does check * that memory was actually allocated. * *---------------------------------------------------------------------- */ char * Tcl_Realloc( char *ptr, size_t size) { char *result = TclpRealloc(ptr, size); if ((result == NULL) && size) { Tcl_Panic("unable to realloc %lu bytes", size); } return result; } char * Tcl_DbCkrealloc( char *ptr, size_t size, const char *file, int line) { char *result; result = (char *) TclpRealloc(ptr, size); if ((result == NULL) && size) { fflush(stdout); Tcl_Panic("unable to realloc %lu bytes, %s line %d", size, file, line); } return result; } /* *---------------------------------------------------------------------- * * Tcl_AttemptRealloc -- * * Interface to TclpRealloc when TCL_MEM_DEBUG is disabled. It does not * check that memory was actually allocated. * *---------------------------------------------------------------------- */ char * Tcl_AttemptRealloc( char *ptr, size_t size) { char *result = TclpRealloc(ptr, size); return result; } char * Tcl_AttemptDbCkrealloc( char *ptr, size_t size, const char *file, int line) { char *result = (char *) TclpRealloc(ptr, size); return result; } /* *---------------------------------------------------------------------- * * Tcl_Free -- |
︙ | ︙ |
Changes to generic/tclClock.c.
︙ | ︙ | |||
138 139 140 141 142 143 144 | /* * Function prototypes for local procedures in this file: */ static int ConvertUTCToLocal(Tcl_Interp *, TclDateFields *, Tcl_Obj *, int); static int ConvertUTCToLocalUsingTable(Tcl_Interp *, | | | | | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | /* * Function prototypes for local procedures in this file: */ static int ConvertUTCToLocal(Tcl_Interp *, TclDateFields *, Tcl_Obj *, int); static int ConvertUTCToLocalUsingTable(Tcl_Interp *, TclDateFields *, size_t, Tcl_Obj *const[]); static int ConvertUTCToLocalUsingC(Tcl_Interp *, TclDateFields *, int); static int ConvertLocalToUTC(Tcl_Interp *, TclDateFields *, Tcl_Obj *, int); static int ConvertLocalToUTCUsingTable(Tcl_Interp *, TclDateFields *, size_t, Tcl_Obj *const[]); static int ConvertLocalToUTCUsingC(Tcl_Interp *, TclDateFields *, int); static Tcl_Obj * LookupLastTransition(Tcl_Interp *, Tcl_WideInt, size_t, Tcl_Obj *const *); static void GetYearWeekDay(TclDateFields *, int); static void GetGregorianEraYearDay(TclDateFields *, int); static void GetMonthDay(TclDateFields *); static void GetJulianDayFromEraYearWeekDay(TclDateFields *, int); static void GetJulianDayFromEraYearMonthDay(TclDateFields *, int); static int IsGregorianLeapYear(TclDateFields *); static int WeekdayOnOrBefore(int, int); static Tcl_ObjCmdProc ClockClicksObjCmd; static Tcl_ObjCmdProc ClockConvertlocaltoutcObjCmd; static Tcl_ObjCmdProc ClockGetdatefieldsObjCmd; static Tcl_ObjCmdProc ClockGetjuliandayfromerayearmonthdayObjCmd; static Tcl_ObjCmdProc ClockGetjuliandayfromerayearweekdayObjCmd; static Tcl_ObjCmdProc ClockGetenvObjCmd; static Tcl_ObjCmdProc ClockMicrosecondsObjCmd; static Tcl_ObjCmdProc ClockMillisecondsObjCmd; static Tcl_ObjCmdProc ClockParseformatargsObjCmd; static Tcl_ObjCmdProc ClockSecondsObjCmd; static struct tm * ThreadSafeLocalTime(const time_t *); static void TzsetIfNecessary(void); static void ClockDeleteCmdProc(ClientData); /* * Structure containing description of "native" clock commands to create. */ |
︙ | ︙ | |||
266 267 268 269 270 271 272 | * Create the client data, which is a refcounted literal pool. */ data = ckalloc(sizeof(ClockClientData)); data->refCount = 0; data->literals = ckalloc(LIT__END * sizeof(Tcl_Obj*)); for (i = 0; i < LIT__END; ++i) { | | | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | * Create the client data, which is a refcounted literal pool. */ data = ckalloc(sizeof(ClockClientData)); data->refCount = 0; data->literals = ckalloc(LIT__END * sizeof(Tcl_Obj*)); for (i = 0; i < LIT__END; ++i) { data->literals[i] = Tcl_NewStringObj(literals[i], TCL_STRLEN); Tcl_IncrRefCount(data->literals[i]); } /* * Install the commands. */ |
︙ | ︙ | |||
315 316 317 318 319 320 321 | *---------------------------------------------------------------------- */ static int ClockConvertlocaltoutcObjCmd( ClientData clientData, /* Client data */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | *---------------------------------------------------------------------- */ static int ClockConvertlocaltoutcObjCmd( ClientData clientData, /* Client data */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj *const *objv) /* Parameter vector */ { ClockClientData *data = clientData; Tcl_Obj *const *literals = data->literals; Tcl_Obj *secondsObj; Tcl_Obj *dict; int changeover; |
︙ | ︙ | |||
342 343 344 345 346 347 348 | dict = objv[1]; if (Tcl_DictObjGet(interp, dict, literals[LIT_LOCALSECONDS], &secondsObj)!= TCL_OK) { return TCL_ERROR; } if (secondsObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("key \"localseconds\" not " | | | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | dict = objv[1]; if (Tcl_DictObjGet(interp, dict, literals[LIT_LOCALSECONDS], &secondsObj)!= TCL_OK) { return TCL_ERROR; } if (secondsObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("key \"localseconds\" not " "found in dictionary", TCL_STRLEN)); return TCL_ERROR; } if ((Tcl_GetWideIntFromObj(interp, secondsObj, &fields.localSeconds) != TCL_OK) || (TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK) || ConvertLocalToUTC(interp, &fields, objv[2], changeover)) { return TCL_ERROR; |
︙ | ︙ | |||
407 408 409 410 411 412 413 | *---------------------------------------------------------------------- */ int ClockGetdatefieldsObjCmd( ClientData clientData, /* Opaque pointer to literal pool, etc. */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | *---------------------------------------------------------------------- */ int ClockGetdatefieldsObjCmd( ClientData clientData, /* Opaque pointer to literal pool, etc. */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj *const *objv) /* Parameter vector */ { TclDateFields fields; Tcl_Obj *dict; ClockClientData *data = clientData; Tcl_Obj *const *literals = data->literals; int changeover; |
︙ | ︙ | |||
521 522 523 524 525 526 527 | *---------------------------------------------------------------------- */ static int ClockGetjuliandayfromerayearmonthdayObjCmd( ClientData clientData, /* Opaque pointer to literal pool, etc. */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 | *---------------------------------------------------------------------- */ static int ClockGetjuliandayfromerayearmonthdayObjCmd( ClientData clientData, /* Opaque pointer to literal pool, etc. */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj *const *objv) /* Parameter vector */ { TclDateFields fields; Tcl_Obj *dict; ClockClientData *data = clientData; Tcl_Obj *const *literals = data->literals; Tcl_Obj *fieldPtr; |
︙ | ︙ | |||
611 612 613 614 615 616 617 | *---------------------------------------------------------------------- */ static int ClockGetjuliandayfromerayearweekdayObjCmd( ClientData clientData, /* Opaque pointer to literal pool, etc. */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | *---------------------------------------------------------------------- */ static int ClockGetjuliandayfromerayearweekdayObjCmd( ClientData clientData, /* Opaque pointer to literal pool, etc. */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj *const *objv) /* Parameter vector */ { TclDateFields fields; Tcl_Obj *dict; ClockClientData *data = clientData; Tcl_Obj *const *literals = data->literals; Tcl_Obj *fieldPtr; |
︙ | ︙ | |||
701 702 703 704 705 706 707 | static int ConvertLocalToUTC( Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Fields of the time */ Tcl_Obj *tzdata, /* Time zone data */ int changeover) /* Julian Day of the Gregorian transition */ { | | | 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 | static int ConvertLocalToUTC( Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Fields of the time */ Tcl_Obj *tzdata, /* Time zone data */ int changeover) /* Julian Day of the Gregorian transition */ { size_t rowc; /* Number of rows in tzdata */ Tcl_Obj **rowv; /* Pointers to the rows */ /* * Unpack the tz data. */ if (TclListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) { |
︙ | ︙ | |||
746 747 748 749 750 751 752 | *---------------------------------------------------------------------- */ static int ConvertLocalToUTCUsingTable( Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Time to convert, with 'seconds' filled in */ | | | | 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 | *---------------------------------------------------------------------- */ static int ConvertLocalToUTCUsingTable( Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Time to convert, with 'seconds' filled in */ size_t rowc, /* Number of points at which time changes */ Tcl_Obj *const rowv[]) /* Points at which time changes */ { Tcl_Obj *row; size_t cellc; Tcl_Obj **cellv; int have[8]; int nHave = 0; int i; int found; /* |
︙ | ︙ | |||
875 876 877 878 879 880 881 | /* * If conversion fails, report an error. */ if (localErrno != 0 || (fields->seconds == -1 && timeVal.tm_yday == -1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 | /* * If conversion fails, report an error. */ if (localErrno != 0 || (fields->seconds == -1 && timeVal.tm_yday == -1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "time value too large/small to represent", TCL_STRLEN)); return TCL_ERROR; } return TCL_OK; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
904 905 906 907 908 909 910 | static int ConvertUTCToLocal( Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Fields of the time */ Tcl_Obj *tzdata, /* Time zone data */ int changeover) /* Julian Day of the Gregorian transition */ { | | | 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 | static int ConvertUTCToLocal( Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Fields of the time */ Tcl_Obj *tzdata, /* Time zone data */ int changeover) /* Julian Day of the Gregorian transition */ { size_t rowc; /* Number of rows in tzdata */ Tcl_Obj **rowv; /* Pointers to the rows */ /* * Unpack the tz data. */ if (TclListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) { |
︙ | ︙ | |||
949 950 951 952 953 954 955 | *---------------------------------------------------------------------- */ static int ConvertUTCToLocalUsingTable( Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Fields of the date */ | | | | 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 | *---------------------------------------------------------------------- */ static int ConvertUTCToLocalUsingTable( Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Fields of the date */ size_t rowc, /* Number of rows in the conversion table * (>= 1) */ Tcl_Obj *const rowv[]) /* Rows of the conversion table */ { Tcl_Obj *row; /* Row containing the current information */ size_t cellc; /* Count of cells in the row (must be 4) */ Tcl_Obj **cellv; /* Pointers to the cells */ /* * Look up the nearest transition time. */ row = LookupLastTransition(interp, fields->seconds, rowc, rowv); |
︙ | ︙ | |||
1015 1016 1017 1018 1019 1020 1021 | /* * Use 'localtime' to determine local year, month, day, time of day. */ tock = (time_t) fields->seconds; if ((Tcl_WideInt) tock != fields->seconds) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | | 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 | /* * Use 'localtime' to determine local year, month, day, time of day. */ tock = (time_t) fields->seconds; if ((Tcl_WideInt) tock != fields->seconds) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "number too large to represent as a Posix time", TCL_STRLEN)); Tcl_SetErrorCode(interp, "CLOCK", "argTooLarge", NULL); return TCL_ERROR; } TzsetIfNecessary(); timeVal = ThreadSafeLocalTime(&tock); if (timeVal == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "localtime failed (clock value may be too " "large/small to represent)", TCL_STRLEN)); Tcl_SetErrorCode(interp, "CLOCK", "localtimeFailed", NULL); return TCL_ERROR; } /* * Fill in the date in 'fields' and use it to derive Julian Day. */ |
︙ | ︙ | |||
1066 1067 1068 1069 1070 1071 1072 | sprintf(buffer+1, "%02d", diff / 3600); diff %= 3600; sprintf(buffer+3, "%02d", diff / 60); diff %= 60; if (diff > 0) { sprintf(buffer+5, "%02d", diff); } | | | 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 | sprintf(buffer+1, "%02d", diff / 3600); diff %= 3600; sprintf(buffer+3, "%02d", diff / 60); diff %= 60; if (diff > 0) { sprintf(buffer+5, "%02d", diff); } fields->tzName = Tcl_NewStringObj(buffer, TCL_STRLEN); Tcl_IncrRefCount(fields->tzName); return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1089 1090 1091 1092 1093 1094 1095 | *---------------------------------------------------------------------- */ static Tcl_Obj * LookupLastTransition( Tcl_Interp *interp, /* Interpreter for error messages */ Tcl_WideInt tick, /* Time from the epoch */ | | | 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 | *---------------------------------------------------------------------- */ static Tcl_Obj * LookupLastTransition( Tcl_Interp *interp, /* Interpreter for error messages */ Tcl_WideInt tick, /* Time from the epoch */ size_t rowc, /* Number of rows of tzdata */ Tcl_Obj *const *rowv) /* Rows in tzdata */ { int l; int u; Tcl_Obj *compObj; Tcl_WideInt compVal; |
︙ | ︙ | |||
1591 1592 1593 1594 1595 1596 1597 | *---------------------------------------------------------------------- */ int ClockGetenvObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 | *---------------------------------------------------------------------- */ int ClockGetenvObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { const char *varName; const char *varValue; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } varName = TclGetString(objv[1]); varValue = getenv(varName); if (varValue == NULL) { varValue = ""; } Tcl_SetObjResult(interp, Tcl_NewStringObj(varValue, TCL_STRLEN)); return TCL_OK; } /* *---------------------------------------------------------------------- * * ThreadSafeLocalTime -- |
︙ | ︙ | |||
1676 1677 1678 1679 1680 1681 1682 | *---------------------------------------------------------------------- */ int ClockClicksObjCmd( ClientData clientData, /* Client data is unused */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 | *---------------------------------------------------------------------- */ int ClockClicksObjCmd( ClientData clientData, /* Client data is unused */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj *const *objv) /* Parameter values */ { static const char *const clicksSwitches[] = { "-milliseconds", "-microseconds", NULL }; enum ClicksSwitch { CLICKS_MILLIS, CLICKS_MICROS, CLICKS_NATIVE |
︙ | ︙ | |||
1747 1748 1749 1750 1751 1752 1753 | *---------------------------------------------------------------------- */ int ClockMillisecondsObjCmd( ClientData clientData, /* Client data is unused */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 | *---------------------------------------------------------------------- */ int ClockMillisecondsObjCmd( ClientData clientData, /* Client data is unused */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj *const *objv) /* Parameter values */ { Tcl_Time now; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; |
︙ | ︙ | |||
1784 1785 1786 1787 1788 1789 1790 | *---------------------------------------------------------------------- */ int ClockMicrosecondsObjCmd( ClientData clientData, /* Client data is unused */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 | *---------------------------------------------------------------------- */ int ClockMicrosecondsObjCmd( ClientData clientData, /* Client data is unused */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj *const *objv) /* Parameter values */ { Tcl_Time now; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; |
︙ | ︙ | |||
1821 1822 1823 1824 1825 1826 1827 | *----------------------------------------------------------------------------- */ static int ClockParseformatargsObjCmd( ClientData clientData, /* Client data containing literal pool */ Tcl_Interp *interp, /* Tcl interpreter */ | | | | 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 | *----------------------------------------------------------------------------- */ static int ClockParseformatargsObjCmd( ClientData clientData, /* Client data containing literal pool */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj *const objv[]) /* Parameter vector */ { ClockClientData *dataPtr = clientData; Tcl_Obj **litPtr = dataPtr->literals; Tcl_Obj *results[3]; /* Format, locale and timezone */ #define formatObj results[0] #define localeObj results[1] #define timezoneObj results[2] int gmtFlag = 0; static const char *const options[] = { /* Command line options expected */ "-format", "-gmt", "-locale", "-timezone", NULL }; enum optionInd { CLOCK_FORMAT_FORMAT, CLOCK_FORMAT_GMT, CLOCK_FORMAT_LOCALE, CLOCK_FORMAT_TIMEZONE }; int optionIndex; /* Index of an option. */ int saw = 0; /* Flag == 1 if option was seen already. */ Tcl_WideInt clockVal; /* Clock value - just used to parse. */ size_t i; /* * Args consist of a time followed by keyword-value pairs. */ if (objc < 2 || (objc % 2) != 0) { Tcl_WrongNumArgs(interp, 0, objv, |
︙ | ︙ | |||
1939 1940 1941 1942 1943 1944 1945 | *---------------------------------------------------------------------- */ int ClockSecondsObjCmd( ClientData clientData, /* Client data is unused */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 | *---------------------------------------------------------------------- */ int ClockSecondsObjCmd( ClientData clientData, /* Client data is unused */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj *const *objv) /* Parameter values */ { Tcl_Time now; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; |
︙ | ︙ |
Changes to generic/tclCmdAH.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | * all its working arrays appended afterwards so they can be allocated and * freed in a single step. */ struct ForeachState { Tcl_Obj *bodyPtr; /* The script body of the command. */ int bodyIdx; /* The argument index of the body. */ | | | | | | < < < | | | | | | | | | | | | | | | > | | | | | | | | | | | | 19 20 21 22 23 24 25 26 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 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 94 95 96 97 98 99 | * all its working arrays appended afterwards so they can be allocated and * freed in a single step. */ struct ForeachState { Tcl_Obj *bodyPtr; /* The script body of the command. */ int bodyIdx; /* The argument index of the body. */ size_t j, maxj; /* Number of loop iterations. */ size_t numLists; /* Count of value lists. */ size_t *index; /* Array of value list indices. */ size_t *varcList; /* # loop variables per list. */ Tcl_Obj ***varvList; /* Array of var name lists. */ Tcl_Obj **vCopyList; /* Copies of var name list arguments. */ size_t *argcList; /* Array of value list sizes. */ Tcl_Obj ***argvList; /* Array of value lists. */ Tcl_Obj **aCopyList; /* Copies of value list arguments. */ Tcl_Obj *resultList; /* List of result values from the loop body, * or NULL if we're not collecting them * ([lmap] vs [foreach]). */ }; /* * Prototypes for local procedures defined in this file: */ static int CheckAccess(Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode); static inline int ForeachAssignments(Tcl_Interp *interp, struct ForeachState *statePtr); static inline void ForeachCleanup(Tcl_Interp *interp, struct ForeachState *statePtr); static int GetStatBuf(Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_FSStatProc *statProc, Tcl_StatBuf *statPtr); static const char * GetTypeFromMode(int mode); static int StoreStatData(Tcl_Interp *interp, Tcl_Obj *varName, Tcl_StatBuf *statPtr); static inline int EachloopCmd(Tcl_Interp *interp, int collect, size_t objc, Tcl_Obj *const objv[]); static Tcl_NRPostProc CatchObjCmdCallback; static Tcl_NRPostProc ExprCallback; static Tcl_NRPostProc ForSetupCallback; static Tcl_NRPostProc ForCondCallback; static Tcl_NRPostProc ForNextCallback; static Tcl_NRPostProc ForPostNextCallback; static Tcl_NRPostProc ForeachLoopStep; static Tcl_NRPostProc EvalCmdErrMsg; static Tcl_ObjCmdProc BadFileSubcommand; static Tcl_ObjCmdProc EncodingDirsObjCmd; static Tcl_ObjCmdProc FileAttrAccessTimeCmd; static Tcl_ObjCmdProc FileAttrIsDirectoryCmd; static Tcl_ObjCmdProc FileAttrIsExecutableCmd; static Tcl_ObjCmdProc FileAttrIsExistingCmd; static Tcl_ObjCmdProc FileAttrIsFileCmd; static Tcl_ObjCmdProc FileAttrIsOwnedCmd; static Tcl_ObjCmdProc FileAttrIsReadableCmd; static Tcl_ObjCmdProc FileAttrIsWritableCmd; static Tcl_ObjCmdProc FileAttrLinkStatCmd; static Tcl_ObjCmdProc FileAttrModifyTimeCmd; static Tcl_ObjCmdProc FileAttrSizeCmd; static Tcl_ObjCmdProc FileAttrStatCmd; static Tcl_ObjCmdProc FileAttrTypeCmd; static Tcl_ObjCmdProc FilesystemSeparatorCmd; static Tcl_ObjCmdProc FilesystemVolumesCmd; static Tcl_ObjCmdProc PathDirNameCmd; static Tcl_ObjCmdProc PathExtensionCmd; static Tcl_ObjCmdProc PathFilesystemCmd; static Tcl_ObjCmdProc PathJoinCmd; static Tcl_ObjCmdProc PathNativeNameCmd; static Tcl_ObjCmdProc PathNormalizeCmd; static Tcl_ObjCmdProc PathRootNameCmd; static Tcl_ObjCmdProc PathSplitCmd; static Tcl_ObjCmdProc PathTailCmd; static Tcl_ObjCmdProc PathTypeCmd; /* *---------------------------------------------------------------------- * * Tcl_BreakObjCmd -- * * This procedure is invoked to process the "break" Tcl command. See the |
︙ | ︙ | |||
115 116 117 118 119 120 121 | */ /* ARGSUSED */ int Tcl_BreakObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | */ /* ARGSUSED */ int Tcl_BreakObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } return TCL_BREAK; |
︙ | ︙ | |||
147 148 149 150 151 152 153 | */ /* ARGSUSED */ int Tcl_CatchObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | */ /* ARGSUSED */ int Tcl_CatchObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRCatchObjCmd, dummy, objc, objv); } int TclNRCatchObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *varNamePtr = NULL; Tcl_Obj *optionVarNamePtr = NULL; Interp *iPtr = (Interp *) interp; if ((objc < 2) || (objc > 4)) { |
︙ | ︙ | |||
253 254 255 256 257 258 259 | */ /* ARGSUSED */ int Tcl_CdObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | */ /* ARGSUSED */ int Tcl_CdObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *dir; int result; if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?dirName?"); |
︙ | ︙ | |||
309 310 311 312 313 314 315 | */ /* ARGSUSED */ int Tcl_ConcatObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | */ /* ARGSUSED */ int Tcl_ConcatObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc >= 2) { Tcl_SetObjResult(interp, Tcl_ConcatObj(objc-1, objv+1)); } return TCL_OK; } |
︙ | ︙ | |||
344 345 346 347 348 349 350 | */ /* ARGSUSED */ int Tcl_ContinueObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | */ /* ARGSUSED */ int Tcl_ContinueObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } return TCL_CONTINUE; |
︙ | ︙ | |||
374 375 376 377 378 379 380 | *---------------------------------------------------------------------- */ int Tcl_EncodingObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | *---------------------------------------------------------------------- */ int Tcl_EncodingObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int index; static const char *const optionStrings[] = { "convertfrom", "convertto", "dirs", "names", "system", NULL |
︙ | ︙ | |||
402 403 404 405 406 407 408 | switch ((enum options) index) { case ENC_CONVERTTO: case ENC_CONVERTFROM: { Tcl_Obj *data; Tcl_DString ds; Tcl_Encoding encoding; | | | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 | switch ((enum options) index) { case ENC_CONVERTTO: case ENC_CONVERTFROM: { Tcl_Obj *data; Tcl_DString ds; Tcl_Encoding encoding; size_t length; const char *stringPtr; if (objc == 3) { encoding = Tcl_GetEncoding(interp, NULL); data = objv[2]; } else if (objc == 4) { if (Tcl_GetEncodingFromObj(interp, objv[2], &encoding) != TCL_OK) { |
︙ | ︙ | |||
464 465 466 467 468 469 470 | case ENC_SYSTEM: if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?encoding?"); return TCL_ERROR; } if (objc == 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | case ENC_SYSTEM: if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?encoding?"); return TCL_ERROR; } if (objc == 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( Tcl_GetEncodingName(NULL), TCL_STRLEN)); } else { return Tcl_SetSystemEncoding(interp, TclGetString(objv[2])); } break; } return TCL_OK; } |
︙ | ︙ | |||
493 494 495 496 497 498 499 | *---------------------------------------------------------------------- */ int EncodingDirsObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | *---------------------------------------------------------------------- */ int EncodingDirsObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *dirListObj; if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?dirList?"); return TCL_ERROR; |
︙ | ︙ | |||
542 543 544 545 546 547 548 | */ /* ARGSUSED */ int Tcl_ErrorObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | */ /* ARGSUSED */ int Tcl_ErrorObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *options, *optName; if ((objc < 2) || (objc > 4)) { Tcl_WrongNumArgs(interp, 1, objv, "message ?errorInfo? ?errorCode?"); return TCL_ERROR; |
︙ | ︙ | |||
605 606 607 608 609 610 611 | return result; } int Tcl_EvalObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 | return result; } int Tcl_EvalObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNREvalObjCmd, dummy, objc, objv); } int TclNREvalObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { register Tcl_Obj *objPtr; Interp *iPtr = (Interp *) interp; CmdFrame *invoker = NULL; int word = 0; |
︙ | ︙ | |||
675 676 677 678 679 680 681 | */ /* ARGSUSED */ int Tcl_ExitObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 | */ /* ARGSUSED */ int Tcl_ExitObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int value; if ((objc != 1) && (objc != 2)) { Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?"); return TCL_ERROR; |
︙ | ︙ | |||
724 725 726 727 728 729 730 | */ /* ARGSUSED */ int Tcl_ExprObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 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 | */ /* ARGSUSED */ int Tcl_ExprObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRExprObjCmd, dummy, objc, objv); } int TclNRExprObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *resultPtr, *objPtr; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?"); return TCL_ERROR; |
︙ | ︙ | |||
921 922 923 924 925 926 927 | Tcl_DStringInit(&newBuf); TclDStringAppendLiteral(&newBuf, "tcl:file:"); for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) { if (unsafeInfo[i].unsafe) { const char *oldName, *newName; Tcl_DStringSetLength(&oldBuf, 13); | | > | > | 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 | Tcl_DStringInit(&newBuf); TclDStringAppendLiteral(&newBuf, "tcl:file:"); for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) { if (unsafeInfo[i].unsafe) { const char *oldName, *newName; Tcl_DStringSetLength(&oldBuf, 13); oldName = Tcl_DStringAppend(&oldBuf, unsafeInfo[i].cmdName, TCL_STRLEN); Tcl_DStringSetLength(&newBuf, 9); newName = Tcl_DStringAppend(&newBuf, unsafeInfo[i].cmdName, TCL_STRLEN); if (TclRenameCommand(interp, oldName, "___tmp") != TCL_OK || Tcl_HideCommand(interp, "___tmp", newName) != TCL_OK) { Tcl_Panic("problem making 'file %s' safe: %s", unsafeInfo[i].cmdName, Tcl_GetString(Tcl_GetObjResult(interp))); } Tcl_CreateObjCommand(interp, oldName, BadFileSubcommand, |
︙ | ︙ | |||
972 973 974 975 976 977 978 | *---------------------------------------------------------------------- */ static int BadFileSubcommand( ClientData clientData, Tcl_Interp *interp, | | | 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 | *---------------------------------------------------------------------- */ static int BadFileSubcommand( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { const char *subcommandName = (const char *) clientData; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "not allowed to invoke subcommand %s of file", subcommandName)); Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL); |
︙ | ︙ | |||
1004 1005 1006 1007 1008 1009 1010 | *---------------------------------------------------------------------- */ static int FileAttrAccessTimeCmd( ClientData clientData, Tcl_Interp *interp, | | | 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 | *---------------------------------------------------------------------- */ static int FileAttrAccessTimeCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_StatBuf buf; struct utimbuf tval; if (objc < 2 || objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "name ?time?"); |
︙ | ︙ | |||
1076 1077 1078 1079 1080 1081 1082 | *---------------------------------------------------------------------- */ static int FileAttrModifyTimeCmd( ClientData clientData, Tcl_Interp *interp, | | | 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 | *---------------------------------------------------------------------- */ static int FileAttrModifyTimeCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_StatBuf buf; struct utimbuf tval; if (objc < 2 || objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "name ?time?"); |
︙ | ︙ | |||
1146 1147 1148 1149 1150 1151 1152 | *---------------------------------------------------------------------- */ static int FileAttrLinkStatCmd( ClientData clientData, Tcl_Interp *interp, | | | 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 | *---------------------------------------------------------------------- */ static int FileAttrLinkStatCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_StatBuf buf; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "name varName"); return TCL_ERROR; |
︙ | ︙ | |||
1182 1183 1184 1185 1186 1187 1188 | *---------------------------------------------------------------------- */ static int FileAttrStatCmd( ClientData clientData, Tcl_Interp *interp, | | | 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 | *---------------------------------------------------------------------- */ static int FileAttrStatCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_StatBuf buf; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "name varName"); return TCL_ERROR; |
︙ | ︙ | |||
1218 1219 1220 1221 1222 1223 1224 | *---------------------------------------------------------------------- */ static int FileAttrTypeCmd( ClientData clientData, Tcl_Interp *interp, | | | | 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 | *---------------------------------------------------------------------- */ static int FileAttrTypeCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_StatBuf buf; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } if (GetStatBuf(interp, objv[1], Tcl_FSLstat, &buf) != TCL_OK) { return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewStringObj( GetTypeFromMode((unsigned short) buf.st_mode), TCL_STRLEN)); return TCL_OK; } /* *---------------------------------------------------------------------- * * FileAttrSizeCmd -- |
︙ | ︙ | |||
1256 1257 1258 1259 1260 1261 1262 | *---------------------------------------------------------------------- */ static int FileAttrSizeCmd( ClientData clientData, Tcl_Interp *interp, | | | 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 | *---------------------------------------------------------------------- */ static int FileAttrSizeCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_StatBuf buf; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; |
︙ | ︙ | |||
1293 1294 1295 1296 1297 1298 1299 | *---------------------------------------------------------------------- */ static int FileAttrIsDirectoryCmd( ClientData clientData, Tcl_Interp *interp, | | | 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 | *---------------------------------------------------------------------- */ static int FileAttrIsDirectoryCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_StatBuf buf; int value = 0; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); |
︙ | ︙ | |||
1331 1332 1333 1334 1335 1336 1337 | *---------------------------------------------------------------------- */ static int FileAttrIsExecutableCmd( ClientData clientData, Tcl_Interp *interp, | | | 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 | *---------------------------------------------------------------------- */ static int FileAttrIsExecutableCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } return CheckAccess(interp, objv[1], X_OK); |
︙ | ︙ | |||
1362 1363 1364 1365 1366 1367 1368 | *---------------------------------------------------------------------- */ static int FileAttrIsExistingCmd( ClientData clientData, Tcl_Interp *interp, | | | 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 | *---------------------------------------------------------------------- */ static int FileAttrIsExistingCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } return CheckAccess(interp, objv[1], F_OK); |
︙ | ︙ | |||
1393 1394 1395 1396 1397 1398 1399 | *---------------------------------------------------------------------- */ static int FileAttrIsFileCmd( ClientData clientData, Tcl_Interp *interp, | | | 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 | *---------------------------------------------------------------------- */ static int FileAttrIsFileCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_StatBuf buf; int value = 0; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); |
︙ | ︙ | |||
1431 1432 1433 1434 1435 1436 1437 | *---------------------------------------------------------------------- */ static int FileAttrIsOwnedCmd( ClientData clientData, Tcl_Interp *interp, | | | 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 | *---------------------------------------------------------------------- */ static int FileAttrIsOwnedCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_StatBuf buf; int value = 0; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); |
︙ | ︙ | |||
1481 1482 1483 1484 1485 1486 1487 | *---------------------------------------------------------------------- */ static int FileAttrIsReadableCmd( ClientData clientData, Tcl_Interp *interp, | | | 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 | *---------------------------------------------------------------------- */ static int FileAttrIsReadableCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } return CheckAccess(interp, objv[1], R_OK); |
︙ | ︙ | |||
1512 1513 1514 1515 1516 1517 1518 | *---------------------------------------------------------------------- */ static int FileAttrIsWritableCmd( ClientData clientData, Tcl_Interp *interp, | | | 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 | *---------------------------------------------------------------------- */ static int FileAttrIsWritableCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } return CheckAccess(interp, objv[1], W_OK); |
︙ | ︙ | |||
1543 1544 1545 1546 1547 1548 1549 | *---------------------------------------------------------------------- */ static int PathDirNameCmd( ClientData clientData, Tcl_Interp *interp, | | | 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 | *---------------------------------------------------------------------- */ static int PathDirNameCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *dirPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; |
︙ | ︙ | |||
1582 1583 1584 1585 1586 1587 1588 | *---------------------------------------------------------------------- */ static int PathExtensionCmd( ClientData clientData, Tcl_Interp *interp, | | | 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 | *---------------------------------------------------------------------- */ static int PathExtensionCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *dirPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; |
︙ | ︙ | |||
1621 1622 1623 1624 1625 1626 1627 | *---------------------------------------------------------------------- */ static int PathRootNameCmd( ClientData clientData, Tcl_Interp *interp, | | | 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 | *---------------------------------------------------------------------- */ static int PathRootNameCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *dirPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; |
︙ | ︙ | |||
1660 1661 1662 1663 1664 1665 1666 | *---------------------------------------------------------------------- */ static int PathTailCmd( ClientData clientData, Tcl_Interp *interp, | | | 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 | *---------------------------------------------------------------------- */ static int PathTailCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *dirPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; |
︙ | ︙ | |||
1699 1700 1701 1702 1703 1704 1705 | *---------------------------------------------------------------------- */ static int PathFilesystemCmd( ClientData clientData, Tcl_Interp *interp, | | | > | 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 | *---------------------------------------------------------------------- */ static int PathFilesystemCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *fsInfo; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } fsInfo = Tcl_FSFileSystemInfo(objv[1]); if (fsInfo == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unrecognised path", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "FILESYSTEM", Tcl_GetString(objv[1]), NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, fsInfo); return TCL_OK; } |
︙ | ︙ | |||
1740 1741 1742 1743 1744 1745 1746 | *---------------------------------------------------------------------- */ static int PathJoinCmd( ClientData clientData, Tcl_Interp *interp, | | | 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 | *---------------------------------------------------------------------- */ static int PathJoinCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?"); return TCL_ERROR; } Tcl_SetObjResult(interp, TclJoinPath(objc - 1, objv + 1)); |
︙ | ︙ | |||
1772 1773 1774 1775 1776 1777 1778 | *---------------------------------------------------------------------- */ static int PathNativeNameCmd( ClientData clientData, Tcl_Interp *interp, | | | 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 | *---------------------------------------------------------------------- */ static int PathNativeNameCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_DString ds; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; |
︙ | ︙ | |||
1809 1810 1811 1812 1813 1814 1815 | *---------------------------------------------------------------------- */ static int PathNormalizeCmd( ClientData clientData, Tcl_Interp *interp, | | | 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 | *---------------------------------------------------------------------- */ static int PathNormalizeCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *fileName; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; |
︙ | ︙ | |||
1847 1848 1849 1850 1851 1852 1853 | *---------------------------------------------------------------------- */ static int PathSplitCmd( ClientData clientData, Tcl_Interp *interp, | | | 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 | *---------------------------------------------------------------------- */ static int PathSplitCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *res; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; |
︙ | ︙ | |||
1890 1891 1892 1893 1894 1895 1896 | *---------------------------------------------------------------------- */ static int PathTypeCmd( ClientData clientData, Tcl_Interp *interp, | | | 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 | *---------------------------------------------------------------------- */ static int PathTypeCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Obj *typeName; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; |
︙ | ︙ | |||
1938 1939 1940 1941 1942 1943 1944 | *---------------------------------------------------------------------- */ static int FilesystemSeparatorCmd( ClientData clientData, Tcl_Interp *interp, | | | 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 | *---------------------------------------------------------------------- */ static int FilesystemSeparatorCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { if (objc < 1 || objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?name?"); return TCL_ERROR; } if (objc == 1) { |
︙ | ︙ | |||
1962 1963 1964 1965 1966 1967 1968 | } Tcl_SetObjResult(interp, Tcl_NewStringObj(separator, 1)); } else { Tcl_Obj *separatorObj = Tcl_FSPathSeparator(objv[1]); if (separatorObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 | } Tcl_SetObjResult(interp, Tcl_NewStringObj(separator, 1)); } else { Tcl_Obj *separatorObj = Tcl_FSPathSeparator(objv[1]); if (separatorObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unrecognised path", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "FILESYSTEM", Tcl_GetString(objv[1]), NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, separatorObj); } return TCL_OK; |
︙ | ︙ | |||
1993 1994 1995 1996 1997 1998 1999 | *---------------------------------------------------------------------- */ static int FilesystemVolumesCmd( ClientData clientData, Tcl_Interp *interp, | | | 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 | *---------------------------------------------------------------------- */ static int FilesystemVolumesCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_FSListVolumes()); |
︙ | ︙ | |||
2160 2161 2162 2163 2164 2165 2166 | STORE_ARY("blksize", Tcl_NewLongObj((long)statPtr->st_blksize)); #endif STORE_ARY("atime", Tcl_NewLongObj((long)statPtr->st_atime)); STORE_ARY("mtime", Tcl_NewLongObj((long)statPtr->st_mtime)); STORE_ARY("ctime", Tcl_NewLongObj((long)statPtr->st_ctime)); mode = (unsigned short) statPtr->st_mode; STORE_ARY("mode", Tcl_NewIntObj(mode)); | | > | 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 | STORE_ARY("blksize", Tcl_NewLongObj((long)statPtr->st_blksize)); #endif STORE_ARY("atime", Tcl_NewLongObj((long)statPtr->st_atime)); STORE_ARY("mtime", Tcl_NewLongObj((long)statPtr->st_mtime)); STORE_ARY("ctime", Tcl_NewLongObj((long)statPtr->st_ctime)); mode = (unsigned short) statPtr->st_mode; STORE_ARY("mode", Tcl_NewIntObj(mode)); STORE_ARY("type", Tcl_NewStringObj(GetTypeFromMode(mode), TCL_STRLEN)); #undef STORE_ARY return TCL_OK; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
2254 2255 2256 2257 2258 2259 2260 | */ /* ARGSUSED */ int Tcl_ForObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 | */ /* ARGSUSED */ int Tcl_ForObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRForObjCmd, dummy, objc, objv); } int TclNRForObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; ForIterData *iterPtr; if (objc != 5) { Tcl_WrongNumArgs(interp, 1, objv, "start test next command"); |
︙ | ︙ | |||
2449 2450 2451 2452 2453 2454 2455 | */ /* ARGSUSED */ int Tcl_ForeachObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | | | | | 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 | */ /* ARGSUSED */ int Tcl_ForeachObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRForeachCmd, dummy, objc, objv); } int TclNRForeachCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { return EachloopCmd(interp, TCL_EACH_KEEP_NONE, objc, objv); } int Tcl_LmapObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRLmapCmd, dummy, objc, objv); } int TclNRLmapCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { return EachloopCmd(interp, TCL_EACH_COLLECT, objc, objv); } static inline int EachloopCmd( Tcl_Interp *interp, /* Our context for variables and script * evaluation. */ int collect, /* Select collecting or accumulating mode * (TCL_EACH_*) */ size_t objc, /* The arguments being passed in... */ Tcl_Obj *const objv[]) { size_t numLists = (objc-2) / 2, i, j; register struct ForeachState *statePtr; int result; if (objc < 4 || (objc%2 != 0)) { Tcl_WrongNumArgs(interp, 1, objv, "varList list ?varList list ...? command"); return TCL_ERROR; } |
︙ | ︙ | |||
2520 2521 2522 2523 2524 2525 2526 | * * The setting up of all of these pointers is moderately messy, but allows * the rest of this code to be simple and for us to use a single memory * allocation for better performance. */ statePtr = TclStackAlloc(interp, | | | | | | 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 | * * The setting up of all of these pointers is moderately messy, but allows * the rest of this code to be simple and for us to use a single memory * allocation for better performance. */ statePtr = TclStackAlloc(interp, sizeof(struct ForeachState) + 3 * numLists * sizeof(size_t) + 2 * numLists * (sizeof(Tcl_Obj **) + sizeof(Tcl_Obj *))); memset(statePtr, 0, sizeof(struct ForeachState) + 3 * numLists * sizeof(size_t) + 2 * numLists * (sizeof(Tcl_Obj **) + sizeof(Tcl_Obj *))); statePtr->varvList = (Tcl_Obj ***) (statePtr + 1); statePtr->argvList = statePtr->varvList + numLists; statePtr->vCopyList = (Tcl_Obj **) (statePtr->argvList + numLists); statePtr->aCopyList = statePtr->vCopyList + numLists; statePtr->index = (size_t *) (statePtr->aCopyList + numLists); statePtr->varcList = statePtr->index + numLists; statePtr->argcList = statePtr->varcList + numLists; statePtr->numLists = numLists; statePtr->bodyPtr = objv[objc - 1]; statePtr->bodyIdx = (int) objc - 1; if (collect == TCL_EACH_COLLECT) { statePtr->resultList = Tcl_NewListObj(0, NULL); } else { statePtr->resultList = NULL; } |
︙ | ︙ | |||
2596 2597 2598 2599 2600 2601 2602 | result = ForeachAssignments(interp, statePtr); if (result == TCL_ERROR) { goto done; } TclNRAddCallback(interp, ForeachLoopStep, statePtr, NULL, NULL, NULL); return TclNREvalObjEx(interp, objv[objc-1], 0, | | | 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 | result = ForeachAssignments(interp, statePtr); if (result == TCL_ERROR) { goto done; } TclNRAddCallback(interp, ForeachLoopStep, statePtr, NULL, NULL, NULL); return TclNREvalObjEx(interp, objv[objc-1], 0, ((Interp *) interp)->cmdFramePtr, (int) objc-1); } /* * This cleanup stage is only used when an error occurs during setup or if * there is no work to do. */ |
︙ | ︙ | |||
2691 2692 2693 2694 2695 2696 2697 | */ static inline int ForeachAssignments( Tcl_Interp *interp, struct ForeachState *statePtr) { | | | 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 | */ static inline int ForeachAssignments( Tcl_Interp *interp, struct ForeachState *statePtr) { size_t i, v, k; Tcl_Obj *valuePtr, *varValuePtr; for (i=0 ; i<statePtr->numLists ; i++) { for (v=0 ; v<statePtr->varcList[i] ; v++) { k = statePtr->index[i]++; if (k < statePtr->argcList[i]) { |
︙ | ︙ | |||
2729 2730 2731 2732 2733 2734 2735 | */ static inline void ForeachCleanup( Tcl_Interp *interp, struct ForeachState *statePtr) { | | | 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 | */ static inline void ForeachCleanup( Tcl_Interp *interp, struct ForeachState *statePtr) { size_t i; for (i=0 ; i<statePtr->numLists ; i++) { if (statePtr->vCopyList[i]) { TclDecrRefCount(statePtr->vCopyList[i]); } if (statePtr->aCopyList[i]) { TclDecrRefCount(statePtr->aCopyList[i]); |
︙ | ︙ | |||
2767 2768 2769 2770 2771 2772 2773 | */ /* ARGSUSED */ int Tcl_FormatObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 | */ /* ARGSUSED */ int Tcl_FormatObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *resultPtr; /* Where result is stored finally. */ if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "formatString ?arg ...?"); return TCL_ERROR; |
︙ | ︙ |
Changes to generic/tclCmdIL.c.
︙ | ︙ | |||
59 60 61 62 63 64 65 | typedef struct { int isIncreasing; /* Nonzero means sort in increasing order. */ int sortMode; /* The sort mode. One of SORTMODE_* values * defined below. */ Tcl_Obj *compareCmdPtr; /* The Tcl comparison command when sortMode is * SORTMODE_COMMAND. Pre-initialized to hold * base of command. */ | | | | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | typedef struct { int isIncreasing; /* Nonzero means sort in increasing order. */ int sortMode; /* The sort mode. One of SORTMODE_* values * defined below. */ Tcl_Obj *compareCmdPtr; /* The Tcl comparison command when sortMode is * SORTMODE_COMMAND. Pre-initialized to hold * base of command. */ ssize_t *indexv; /* If the -index option was specified, this * holds the indexes contained in the list * supplied as an argument to that option. * NULL if no indexes supplied, and points to * singleIndex field when only one * supplied. */ size_t indexc; /* Number of indexes in indexv array. */ ssize_t singleIndex; /* Static space for common index case. */ int unique; size_t numElements; Tcl_Interp *interp; /* The interpreter in which the sort is being * done. */ int resultCode; /* Completion code for the lsort command. If * an error occurs during the sort this is * changed from TCL_OK to TCL_ERROR. */ } SortInfo; |
︙ | ︙ | |||
103 104 105 106 107 108 109 | /* * Forward declarations for procedures defined in this file: */ static int DictionaryCompare(const char *left, const char *right); static int IfConditionCallback(ClientData data[], Tcl_Interp *interp, int result); | | < | < | < | < | < | < < | < < | < | < | < | < | < | < | < < | < | < | < | < | < | 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 | /* * Forward declarations for procedures defined in this file: */ static int DictionaryCompare(const char *left, const char *right); static int IfConditionCallback(ClientData data[], Tcl_Interp *interp, int result); static Tcl_ObjCmdProc InfoArgsCmd; static Tcl_ObjCmdProc InfoBodyCmd; static Tcl_ObjCmdProc InfoCmdCountCmd; static Tcl_ObjCmdProc InfoCommandsCmd; static Tcl_ObjCmdProc InfoCompleteCmd; static Tcl_ObjCmdProc InfoDefaultCmd; static Tcl_ObjCmdProc InfoErrorStackCmd; static Tcl_ObjCmdProc InfoFrameCmd; static Tcl_ObjCmdProc InfoFunctionsCmd; static Tcl_ObjCmdProc InfoHostnameCmd; static Tcl_ObjCmdProc InfoLevelCmd; static Tcl_ObjCmdProc InfoLibraryCmd; static Tcl_ObjCmdProc InfoLoadedCmd; static Tcl_ObjCmdProc InfoNameOfExecutableCmd; static Tcl_ObjCmdProc InfoPatchLevelCmd; static Tcl_ObjCmdProc InfoProcsCmd; static Tcl_ObjCmdProc InfoScriptCmd; static Tcl_ObjCmdProc InfoSharedlibCmd; static Tcl_ObjCmdProc InfoTclVersionCmd; static SortElement * MergeLists(SortElement *leftPtr, SortElement *rightPtr, SortInfo *infoPtr); static int SortCompare(SortElement *firstPtr, SortElement *second, SortInfo *infoPtr); static Tcl_Obj * SelectObjFromSublist(Tcl_Obj *firstPtr, SortInfo *infoPtr); |
︙ | ︙ | |||
209 210 211 212 213 214 215 | *---------------------------------------------------------------------- */ int Tcl_IfObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | *---------------------------------------------------------------------- */ int Tcl_IfObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRIfObjCmd, dummy, objc, objv); } int TclNRIfObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *boolObj; if (objc <= 1) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "wrong # args: no expression after \"%s\" argument", |
︙ | ︙ | |||
345 346 347 348 349 350 351 | if (i >= objc) { goto missingScript; } } if (i < objc - 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "wrong # args: extra words after \"else\" clause in \"if\" command", | | | 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | if (i >= objc) { goto missingScript; } } if (i < objc - 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "wrong # args: extra words after \"else\" clause in \"if\" command", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); return TCL_ERROR; } if (thenScriptIndex) { /* * TIP #280. Make invoking context available to branch/else. */ |
︙ | ︙ | |||
392 393 394 395 396 397 398 | *---------------------------------------------------------------------- */ int Tcl_IncrObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | *---------------------------------------------------------------------- */ int Tcl_IncrObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *newValuePtr, *incrPtr; if ((objc != 2) && (objc != 3)) { Tcl_WrongNumArgs(interp, 1, objv, "varName ?increment?"); return TCL_ERROR; |
︙ | ︙ | |||
473 474 475 476 477 478 479 | *---------------------------------------------------------------------- */ static int InfoArgsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | *---------------------------------------------------------------------- */ static int InfoArgsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { register Interp *iPtr = (Interp *) interp; const char *name; Proc *procPtr; CompiledLocal *localPtr; Tcl_Obj *listObjPtr; |
︙ | ︙ | |||
505 506 507 508 509 510 511 | */ listObjPtr = Tcl_NewListObj(0, NULL); for (localPtr = procPtr->firstLocalPtr; localPtr != NULL; localPtr = localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_ListObjAppendElement(interp, listObjPtr, | | | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 | */ listObjPtr = Tcl_NewListObj(0, NULL); for (localPtr = procPtr->firstLocalPtr; localPtr != NULL; localPtr = localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(localPtr->name, TCL_STRLEN)); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* |
︙ | ︙ | |||
536 537 538 539 540 541 542 | *---------------------------------------------------------------------- */ static int InfoBodyCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | *---------------------------------------------------------------------- */ static int InfoBodyCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { register Interp *iPtr = (Interp *) interp; const char *name; Proc *procPtr; Tcl_Obj *bodyPtr, *resultPtr; |
︙ | ︙ | |||
607 608 609 610 611 612 613 | *---------------------------------------------------------------------- */ static int InfoCmdCountCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | *---------------------------------------------------------------------- */ static int InfoCmdCountCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; |
︙ | ︙ | |||
649 650 651 652 653 654 655 | *---------------------------------------------------------------------- */ static int InfoCommandsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 | *---------------------------------------------------------------------- */ static int InfoCommandsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *cmdName, *pattern; const char *simplePattern; register Tcl_HashEntry *entryPtr; Tcl_HashSearch search; Namespace *nsPtr; Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp); Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp); Tcl_Obj *listPtr, *elemObjPtr; int specificNsInPattern = 0;/* Init. to avoid compiler warning. */ Tcl_Command cmd; size_t i; /* * Get the pattern and find the "effective namespace" in which to list * commands. */ if (objc == 1) { |
︙ | ︙ | |||
727 728 729 730 731 732 733 | if (entryPtr != NULL) { if (specificNsInPattern) { cmd = Tcl_GetHashValue(entryPtr); elemObjPtr = Tcl_NewObj(); Tcl_GetCommandFullName(interp, cmd, elemObjPtr); } else { cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); | | | 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 | if (entryPtr != NULL) { if (specificNsInPattern) { cmd = Tcl_GetHashValue(entryPtr); elemObjPtr = Tcl_NewObj(); Tcl_GetCommandFullName(interp, cmd, elemObjPtr); } else { cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); elemObjPtr = Tcl_NewStringObj(cmdName, TCL_STRLEN); } Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr); Tcl_SetObjResult(interp, listPtr); return TCL_OK; } if ((nsPtr != globalNsPtr) && !specificNsInPattern) { Tcl_HashTable *tablePtr = NULL; /* Quell warning. */ |
︙ | ︙ | |||
755 756 757 758 759 760 761 | if (entryPtr == NULL) { tablePtr = &globalNsPtr->cmdTable; entryPtr = Tcl_FindHashEntry(tablePtr, simplePattern); } if (entryPtr != NULL) { cmdName = Tcl_GetHashKey(tablePtr, entryPtr); Tcl_ListObjAppendElement(interp, listPtr, | | | 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 | if (entryPtr == NULL) { tablePtr = &globalNsPtr->cmdTable; entryPtr = Tcl_FindHashEntry(tablePtr, simplePattern); } if (entryPtr != NULL) { cmdName = Tcl_GetHashKey(tablePtr, entryPtr); Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(cmdName, TCL_STRLEN)); Tcl_SetObjResult(interp, listPtr); return TCL_OK; } } } else if (nsPtr->commandPathLength == 0 || specificNsInPattern) { /* * The pattern is non-trivial, but either there is no explicit path or |
︙ | ︙ | |||
777 778 779 780 781 782 783 | if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { if (specificNsInPattern) { cmd = Tcl_GetHashValue(entryPtr); elemObjPtr = Tcl_NewObj(); Tcl_GetCommandFullName(interp, cmd, elemObjPtr); } else { | | | 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 | if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { if (specificNsInPattern) { cmd = Tcl_GetHashValue(entryPtr); elemObjPtr = Tcl_NewObj(); Tcl_GetCommandFullName(interp, cmd, elemObjPtr); } else { elemObjPtr = Tcl_NewStringObj(cmdName, TCL_STRLEN); } Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr); } entryPtr = Tcl_NextHashEntry(&search); } /* |
︙ | ︙ | |||
800 801 802 803 804 805 806 | entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search); while (entryPtr != NULL) { cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { if (Tcl_FindHashEntry(&nsPtr->cmdTable,cmdName) == NULL) { Tcl_ListObjAppendElement(interp, listPtr, | | | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search); while (entryPtr != NULL) { cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { if (Tcl_FindHashEntry(&nsPtr->cmdTable,cmdName) == NULL) { Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(cmdName, TCL_STRLEN)); } } entryPtr = Tcl_NextHashEntry(&search); } } } else { /* |
︙ | ︙ | |||
829 830 831 832 833 834 835 | Tcl_InitObjHashTable(&addedCommandsTable); entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); while (entryPtr != NULL) { cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { | | | 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 | Tcl_InitObjHashTable(&addedCommandsTable); entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); while (entryPtr != NULL) { cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { elemObjPtr = Tcl_NewStringObj(cmdName, TCL_STRLEN); Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr); (void) Tcl_CreateHashEntry(&addedCommandsTable, elemObjPtr, &isNew); } entryPtr = Tcl_NextHashEntry(&search); } |
︙ | ︙ | |||
855 856 857 858 859 860 861 | foundGlobal = 1; } entryPtr = Tcl_FirstHashEntry(&pathNsPtr->cmdTable, &search); while (entryPtr != NULL) { cmdName = Tcl_GetHashKey(&pathNsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { | | | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 | foundGlobal = 1; } entryPtr = Tcl_FirstHashEntry(&pathNsPtr->cmdTable, &search); while (entryPtr != NULL) { cmdName = Tcl_GetHashKey(&pathNsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { elemObjPtr = Tcl_NewStringObj(cmdName, TCL_STRLEN); (void) Tcl_CreateHashEntry(&addedCommandsTable, elemObjPtr, &isNew); if (isNew) { Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr); } else { TclDecrRefCount(elemObjPtr); } |
︙ | ︙ | |||
882 883 884 885 886 887 888 | if (!foundGlobal) { entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search); while (entryPtr != NULL) { cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { | | | 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 | if (!foundGlobal) { entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search); while (entryPtr != NULL) { cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { elemObjPtr = Tcl_NewStringObj(cmdName, TCL_STRLEN); if (Tcl_FindHashEntry(&addedCommandsTable, (char *) elemObjPtr) == NULL) { Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr); } else { TclDecrRefCount(elemObjPtr); } } |
︙ | ︙ | |||
926 927 928 929 930 931 932 | *---------------------------------------------------------------------- */ static int InfoCompleteCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 | *---------------------------------------------------------------------- */ static int InfoCompleteCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "command"); return TCL_ERROR; } |
︙ | ︙ | |||
963 964 965 966 967 968 969 | *---------------------------------------------------------------------- */ static int InfoDefaultCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 | *---------------------------------------------------------------------- */ static int InfoDefaultCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; const char *procName, *argName; Proc *procPtr; CompiledLocal *localPtr; Tcl_Obj *valueObjPtr; |
︙ | ︙ | |||
1045 1046 1047 1048 1049 1050 1051 | *---------------------------------------------------------------------- */ static int InfoErrorStackCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 | *---------------------------------------------------------------------- */ static int InfoErrorStackCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Interp *target; Interp *iPtr; if ((objc != 1) && (objc != 2)) { Tcl_WrongNumArgs(interp, 1, objv, "?interp?"); |
︙ | ︙ | |||
1094 1095 1096 1097 1098 1099 1100 | *---------------------------------------------------------------------- */ int TclInfoExistsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 | *---------------------------------------------------------------------- */ int TclInfoExistsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *varName; Var *varPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "varName"); |
︙ | ︙ | |||
1139 1140 1141 1142 1143 1144 1145 | *---------------------------------------------------------------------- */ static int InfoFrameCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 | *---------------------------------------------------------------------- */ static int InfoFrameCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; int level, topLevel, code = TCL_OK; CmdFrame *runPtr, *framePtr; CoroutineData *corPtr = iPtr->execEnvPtr->corPtr; |
︙ | ︙ | |||
1270 1271 1272 1273 1274 1275 1276 | Tcl_Interp *interp, /* Current interpreter. */ CmdFrame *framePtr) /* Frame to get info for. */ { Interp *iPtr = (Interp *) interp; Tcl_Obj *tmpObj; Tcl_Obj *lv[20]; /* Keep uptodate when more keys are added to * the dict. */ | | | 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 | Tcl_Interp *interp, /* Current interpreter. */ CmdFrame *framePtr) /* Frame to get info for. */ { Interp *iPtr = (Interp *) interp; Tcl_Obj *tmpObj; Tcl_Obj *lv[20]; /* Keep uptodate when more keys are added to * the dict. */ size_t lc = 0; /* * This array is indexed by the TCL_LOCATION_... values, except * for _LAST. */ static const char *const typeString[TCL_LOCATION_LAST] = { "eval", "eval", "eval", "precompiled", "source", "proc" }; |
︙ | ︙ | |||
1297 1298 1299 1300 1301 1302 1303 | switch (framePtr->type) { case TCL_LOCATION_EVAL: /* * Evaluation, dynamic script. Type, line, cmd, the latter through * str. */ | | > | > | 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 | switch (framePtr->type) { case TCL_LOCATION_EVAL: /* * Evaluation, dynamic script. Type, line, cmd, the latter through * str. */ ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], TCL_STRLEN)); if (framePtr->line) { ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0])); } else { ADD_PAIR("line", Tcl_NewIntObj(1)); } ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL)); break; case TCL_LOCATION_PREBC: /* * Precompiled. Result contains the type as signal, nothing else. */ ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], TCL_STRLEN)); break; case TCL_LOCATION_BC: { /* * Execution of bytecode. Talk to the BC engine to fill out the frame. */ |
︙ | ︙ | |||
1336 1337 1338 1339 1340 1341 1342 | TclGetSrcInfoForPc(fPtr); /* * Now filled: cmd.str.(cmd,len), line * Possibly modified: type, path! */ | | > | 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 | TclGetSrcInfoForPc(fPtr); /* * Now filled: cmd.str.(cmd,len), line * Possibly modified: type, path! */ ADD_PAIR("type", Tcl_NewStringObj(typeString[fPtr->type], TCL_STRLEN)); if (fPtr->line) { ADD_PAIR("line", Tcl_NewIntObj(fPtr->line[0])); } if (fPtr->type == TCL_LOCATION_SOURCE) { ADD_PAIR("file", fPtr->data.eval.path); |
︙ | ︙ | |||
1361 1362 1363 1364 1365 1366 1367 | } case TCL_LOCATION_SOURCE: /* * Evaluation of a script file. */ | | > | 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 | } case TCL_LOCATION_SOURCE: /* * Evaluation of a script file. */ ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], TCL_STRLEN)); ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0])); ADD_PAIR("file", framePtr->data.eval.path); /* * Refcount framePtr->data.eval.path goes up when lv is converted into * the result list object. */ |
︙ | ︙ | |||
1399 1400 1401 1402 1403 1404 1405 | TclNewObj(procNameObj); Tcl_GetCommandFullName(interp, (Tcl_Command) procPtr->cmdPtr, procNameObj); ADD_PAIR("proc", procNameObj); } else if (procPtr->cmdPtr->clientData) { ExtraFrameInfo *efiPtr = procPtr->cmdPtr->clientData; | | | > | 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 | TclNewObj(procNameObj); Tcl_GetCommandFullName(interp, (Tcl_Command) procPtr->cmdPtr, procNameObj); ADD_PAIR("proc", procNameObj); } else if (procPtr->cmdPtr->clientData) { ExtraFrameInfo *efiPtr = procPtr->cmdPtr->clientData; size_t i; /* * This is a non-standard command. Luckily, it's told us how to * render extra information about its frame. */ for (i=0 ; i<efiPtr->length ; i++) { lv[lc++] = Tcl_NewStringObj(efiPtr->fields[i].name, TCL_STRLEN); if (efiPtr->fields[i].proc) { lv[lc++] = efiPtr->fields[i].proc(efiPtr->fields[i].clientData); } else { lv[lc++] = efiPtr->fields[i].clientData; } } |
︙ | ︙ | |||
1467 1468 1469 1470 1471 1472 1473 | *---------------------------------------------------------------------- */ static int InfoFunctionsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 | *---------------------------------------------------------------------- */ static int InfoFunctionsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *script; int code; if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?pattern?"); |
︙ | ︙ | |||
1491 1492 1493 1494 1495 1496 1497 | " ::foreach cmd [::info commands tcl::mathfunc::$pattern] {\n" " ::set cmd [::namespace tail $cmd]\n" " ::if {$cmd ni $cmds} {\n" " ::lappend cmds $cmd\n" " }\n" " }\n" " ::return $cmds\n" | | | 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 | " ::foreach cmd [::info commands tcl::mathfunc::$pattern] {\n" " ::set cmd [::namespace tail $cmd]\n" " ::if {$cmd ni $cmds} {\n" " ::lappend cmds $cmd\n" " }\n" " }\n" " ::return $cmds\n" " } [::namespace current]] ", TCL_STRLEN); if (objc == 2) { Tcl_Obj *arg = Tcl_NewListObj(1, &(objv[1])); Tcl_AppendObjToObj(script, arg); Tcl_DecrRefCount(arg); } |
︙ | ︙ | |||
1532 1533 1534 1535 1536 1537 1538 | *---------------------------------------------------------------------- */ static int InfoHostnameCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 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 | *---------------------------------------------------------------------- */ static int InfoHostnameCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *name; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } name = Tcl_GetHostName(); if (name) { Tcl_SetObjResult(interp, Tcl_NewStringObj(name, TCL_STRLEN)); return TCL_OK; } Tcl_SetObjResult(interp, Tcl_NewStringObj( "unable to determine name of host", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "HOSTNAME", "UNKNOWN", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1578 1579 1580 1581 1582 1583 1584 | *---------------------------------------------------------------------- */ static int InfoLevelCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 | *---------------------------------------------------------------------- */ static int InfoLevelCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; if (objc == 1) { /* Just "info level" */ Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->varFramePtr->level)); return TCL_OK; |
︙ | ︙ | |||
1652 1653 1654 1655 1656 1657 1658 | *---------------------------------------------------------------------- */ static int InfoLibraryCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 | *---------------------------------------------------------------------- */ static int InfoLibraryCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *libDirName; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } libDirName = Tcl_GetVar(interp, "tcl_library", TCL_GLOBAL_ONLY); if (libDirName != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(libDirName, TCL_STRLEN)); return TCL_OK; } Tcl_SetObjResult(interp, Tcl_NewStringObj( "no library has been specified for Tcl", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", "tcl_library",NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1699 1700 1701 1702 1703 1704 1705 | *---------------------------------------------------------------------- */ static int InfoLoadedCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 | *---------------------------------------------------------------------- */ static int InfoLoadedCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *interpName; if ((objc != 1) && (objc != 2)) { Tcl_WrongNumArgs(interp, 1, objv, "?interp?"); return TCL_ERROR; |
︙ | ︙ | |||
1742 1743 1744 1745 1746 1747 1748 | *---------------------------------------------------------------------- */ static int InfoNameOfExecutableCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 | *---------------------------------------------------------------------- */ static int InfoNameOfExecutableCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, TclGetObjNameOfExecutable()); |
︙ | ︙ | |||
1778 1779 1780 1781 1782 1783 1784 | *---------------------------------------------------------------------- */ static int InfoPatchLevelCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 | *---------------------------------------------------------------------- */ static int InfoPatchLevelCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *patchlevel; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } patchlevel = Tcl_GetVar(interp, "tcl_patchLevel", (TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)); if (patchlevel != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(patchlevel, TCL_STRLEN)); return TCL_OK; } return TCL_ERROR; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1825 1826 1827 1828 1829 1830 1831 | *---------------------------------------------------------------------- */ static int InfoProcsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 | *---------------------------------------------------------------------- */ static int InfoProcsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *cmdName, *pattern; const char *simplePattern; Namespace *nsPtr; #ifdef INFO_PROCS_SEARCH_GLOBAL_NS Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp); |
︙ | ︙ | |||
1904 1905 1906 1907 1908 1909 1910 | } else { simpleProcOK: if (specificNsInPattern) { elemObjPtr = Tcl_NewObj(); Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, elemObjPtr); } else { | | | 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 | } else { simpleProcOK: if (specificNsInPattern) { elemObjPtr = Tcl_NewObj(); Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, elemObjPtr); } else { elemObjPtr = Tcl_NewStringObj(simplePattern, TCL_STRLEN); } Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr); } } } else #endif /* !INFO_PROCS_SEARCH_GLOBAL_NS */ { |
︙ | ︙ | |||
1932 1933 1934 1935 1936 1937 1938 | } else { procOK: if (specificNsInPattern) { elemObjPtr = Tcl_NewObj(); Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, elemObjPtr); } else { | | | 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 | } else { procOK: if (specificNsInPattern) { elemObjPtr = Tcl_NewObj(); Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, elemObjPtr); } else { elemObjPtr = Tcl_NewStringObj(cmdName, TCL_STRLEN); } Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr); } } entryPtr = Tcl_NextHashEntry(&search); } |
︙ | ︙ | |||
1971 1972 1973 1974 1975 1976 1977 | cmdPtr = Tcl_GetHashValue(entryPtr); realCmdPtr = (Command *) TclGetOriginalCommand( (Tcl_Command) cmdPtr); if (TclIsProc(cmdPtr) || ((realCmdPtr != NULL) && TclIsProc(realCmdPtr))) { Tcl_ListObjAppendElement(interp, listPtr, | | | 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 | cmdPtr = Tcl_GetHashValue(entryPtr); realCmdPtr = (Command *) TclGetOriginalCommand( (Tcl_Command) cmdPtr); if (TclIsProc(cmdPtr) || ((realCmdPtr != NULL) && TclIsProc(realCmdPtr))) { Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(cmdName, TCL_STRLEN)); } } } entryPtr = Tcl_NextHashEntry(&search); } } #endif |
︙ | ︙ | |||
2012 2013 2014 2015 2016 2017 2018 | *---------------------------------------------------------------------- */ static int InfoScriptCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 | *---------------------------------------------------------------------- */ static int InfoScriptCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; if ((objc != 1) && (objc != 2)) { Tcl_WrongNumArgs(interp, 1, objv, "?filename?"); return TCL_ERROR; } |
︙ | ︙ | |||
2059 2060 2061 2062 2063 2064 2065 | *---------------------------------------------------------------------- */ static int InfoSharedlibCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 | *---------------------------------------------------------------------- */ static int InfoSharedlibCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } #ifdef TCL_SHLIB_EXT Tcl_SetObjResult(interp, Tcl_NewStringObj(TCL_SHLIB_EXT, TCL_STRLEN)); #endif return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
2097 2098 2099 2100 2101 2102 2103 | *---------------------------------------------------------------------- */ static int InfoTclVersionCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 | *---------------------------------------------------------------------- */ static int InfoTclVersionCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *version; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; |
︙ | ︙ | |||
2137 2138 2139 2140 2141 2142 2143 | *---------------------------------------------------------------------- */ int Tcl_JoinObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 | *---------------------------------------------------------------------- */ int Tcl_JoinObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { size_t listLen, i; Tcl_Obj *resObjPtr, *joinObjPtr, **elemPtrs; if ((objc < 2) || (objc > 3)) { Tcl_WrongNumArgs(interp, 1, objv, "list ?joinString?"); return TCL_ERROR; } |
︙ | ︙ | |||
2194 2195 2196 2197 2198 2199 2200 | *---------------------------------------------------------------------- */ int Tcl_LassignObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 | *---------------------------------------------------------------------- */ int Tcl_LassignObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *listCopyPtr; Tcl_Obj **listObjv; /* The contents of the list. */ size_t listObjc; /* The length of the list. */ int code = TCL_OK; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "list ?varName ...?"); return TCL_ERROR; } |
︙ | ︙ | |||
2268 2269 2270 2271 2272 2273 2274 | *---------------------------------------------------------------------- */ int Tcl_LindexObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 | *---------------------------------------------------------------------- */ int Tcl_LindexObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *elemPtr; /* Pointer to the element being extracted. */ if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "list ?index ...?"); |
︙ | ︙ | |||
2327 2328 2329 2330 2331 2332 2333 | *---------------------------------------------------------------------- */ int Tcl_LinsertObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | | | | | | > | 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 | *---------------------------------------------------------------------- */ int Tcl_LinsertObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *listPtr; ssize_t index; size_t len, result; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "list index ?element ...?"); return TCL_ERROR; } result = TclListObjLength(interp, objv[1], &len); if (result != TCL_OK) { return result; } /* * Get the index. "end" is interpreted to be the index after the last * element, such that using it will cause any inserted elements to be * appended to the list. */ result = TclGetIntForIndexM(interp, objv[2], (int) len, &index); if (result != TCL_OK) { return result; } if (index > (ssize_t) len) { index = (ssize_t) len; } /* * If the list object is unshared we can modify it directly. Otherwise we * create a copy to modify: this is "copy on write". */ listPtr = objv[1]; if (Tcl_IsShared(listPtr)) { listPtr = TclListObjCopy(NULL, listPtr); } if ((objc == 4) && (index == (ssize_t) len)) { /* * Special case: insert one element at the end of the list. */ Tcl_ListObjAppendElement(NULL, listPtr, objv[3]); } else { Tcl_ListObjReplace(NULL, listPtr, (size_t) index, 0, objc-3, &(objv[3])); } /* * Set the interpreter's object result. */ Tcl_SetObjResult(interp, listPtr); |
︙ | ︙ | |||
2406 2407 2408 2409 2410 2411 2412 | *---------------------------------------------------------------------- */ int Tcl_ListObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | < | | 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 | *---------------------------------------------------------------------- */ int Tcl_ListObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { /* * If there are no list elements, the result is an empty object. * Otherwise set the interpreter's result object to be a list object. */ if (objc > 1) { |
︙ | ︙ | |||
2442 2443 2444 2445 2446 2447 2448 | *---------------------------------------------------------------------- */ int Tcl_LlengthObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | < | | > | > | 2426 2427 2428 2429 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 2456 2457 2458 2459 2460 2461 2462 | *---------------------------------------------------------------------- */ int Tcl_LlengthObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { size_t listLen; int result; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "list"); return TCL_ERROR; } result = TclListObjLength(interp, objv[1], &listLen); if (result != TCL_OK) { return result; } /* * Set the interpreter's object result to an integer object holding the * length. */ Tcl_SetObjResult(interp, Tcl_NewWideIntObj( (Tcl_WideInt) ((Tcl_WideUInt) listLen))); return TCL_OK; } /* *---------------------------------------------------------------------- * * Tcl_LrangeObjCmd -- |
︙ | ︙ | |||
2488 2489 2490 2491 2492 2493 2494 | *---------------------------------------------------------------------- */ int Tcl_LrangeObjCmd( ClientData notUsed, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | < | > | > | < | < | | < | | | | | | 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 2548 2549 2550 2551 2552 | *---------------------------------------------------------------------- */ int Tcl_LrangeObjCmd( ClientData notUsed, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj **elemPtrs; size_t listLen; ssize_t first, last; int result; if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "list first last"); return TCL_ERROR; } result = TclListObjLength(interp, objv[1], &listLen); if (result != TCL_OK) { return result; } result = TclGetIntForIndexM(interp, objv[2], (int) listLen - 1, &first); if (result != TCL_OK) { return result; } if (first < 0) { first = 0; } result = TclGetIntForIndexM(interp, objv[3], (int) listLen - 1, &last); if (result != TCL_OK) { return result; } if (last >= (ssize_t) listLen && last >= 0) { last = listLen - 1; } if (first > last) { /* * Returning an empty list is easy. */ return TCL_OK; } result = TclListObjGetElements(interp, objv[1], &listLen, &elemPtrs); if (result != TCL_OK) { return result; } if (Tcl_IsShared(objv[1]) || ListRepPtr(objv[1])->refCount > 1) { Tcl_SetObjResult(interp, Tcl_NewListObj((size_t)(last - first + 1), &elemPtrs[first])); } else { /* * In-place is possible. */ if (last + 1 < (ssize_t) listLen) { Tcl_ListObjReplace(interp, objv[1], (size_t) last + 1, (size_t) (listLen - 1 - last), 0, NULL); } /* * This one is not conditioned on (first > 0) in order to preserve the * string-canonizing effect of [lrange 0 end]. */ Tcl_ListObjReplace(interp, objv[1], 0, (size_t) first, 0, NULL); Tcl_SetObjResult(interp, objv[1]); } return TCL_OK; } /* |
︙ | ︙ | |||
2583 2584 2585 2586 2587 2588 2589 | *---------------------------------------------------------------------- */ int Tcl_LrepeatObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | < | | > | 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 | *---------------------------------------------------------------------- */ int Tcl_LrepeatObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { int elementCount, i; size_t totalElems; Tcl_Obj *listPtr, **dataArray = NULL; /* * Check arguments for legality: * lrepeat count ?value ...? */ |
︙ | ︙ | |||
2619 2620 2621 2622 2623 2624 2625 | */ objc -= 2; objv += 2; /* Final sanity check. Do not exceed limits on max list length. */ | | | 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 | */ objc -= 2; objv += 2; /* Final sanity check. Do not exceed limits on max list length. */ if (elementCount && objc > (size_t) (LIST_MAX/elementCount)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "max length of a Tcl list (%d elements) exceeded", LIST_MAX)); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); return TCL_ERROR; } totalElems = objc * elementCount; |
︙ | ︙ | |||
2656 2657 2658 2659 2660 2661 2662 | register Tcl_Obj *tmpPtr = objv[0]; tmpPtr->refCount += elementCount; for (i=0 ; i<elementCount ; i++) { dataArray[i] = tmpPtr; } } else { | | | 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 | register Tcl_Obj *tmpPtr = objv[0]; tmpPtr->refCount += elementCount; for (i=0 ; i<elementCount ; i++) { dataArray[i] = tmpPtr; } } else { size_t j, k = 0; for (i=0 ; i<elementCount ; i++) { for (j=0 ; j<objc ; j++) { Tcl_IncrRefCount(objv[j]); dataArray[k++] = objv[j]; } } |
︙ | ︙ | |||
2692 2693 2694 2695 2696 2697 2698 | *---------------------------------------------------------------------- */ int Tcl_LreplaceObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | > | 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 | *---------------------------------------------------------------------- */ int Tcl_LreplaceObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { register Tcl_Obj *listPtr; ssize_t first, last; size_t listLen, numToDelete; int result; if (objc < 4) { Tcl_WrongNumArgs(interp, 1, objv, "list first last ?element ...?"); return TCL_ERROR; } |
︙ | ︙ | |||
2743 2744 2745 2746 2747 2748 2749 | if ((first >= listLen) && (listLen > 0)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "list doesn't contain element %s", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPLACE", "BADIDX", NULL); return TCL_ERROR; } | | | 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 | if ((first >= listLen) && (listLen > 0)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "list doesn't contain element %s", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPLACE", "BADIDX", NULL); return TCL_ERROR; } if (last >= listLen && (last > 0)) { last = listLen - 1; } if (first <= last) { numToDelete = last - first + 1; } else { numToDelete = 0; } |
︙ | ︙ | |||
2801 2802 2803 2804 2805 2806 2807 | *---------------------------------------------------------------------- */ int Tcl_LreverseObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 | *---------------------------------------------------------------------- */ int Tcl_LreverseObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument values. */ { Tcl_Obj **elemv; size_t elemc, i, j; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "list"); return TCL_ERROR; } if (TclListObjGetElements(interp, objv[1], &elemc, &elemv) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
2880 2881 2882 2883 2884 2885 2886 | *---------------------------------------------------------------------- */ int Tcl_LsearchObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | > > | 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 | *---------------------------------------------------------------------- */ int Tcl_LsearchObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument values. */ { const char *bytes, *patternBytes; int i, match, index, result, bisect; int dataType, isIncreasing, lower, upper, patInt, objInt; int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase; size_t listc, length, elemLen; ssize_t offset; double patDouble, objDouble; SortInfo sortInfo; Tcl_Obj *patObj, **listv, *listPtr, *startPtr, *itemPtr; SortStrCmpFn_t strCmpFn = strcmp; Tcl_RegExp regexp = NULL; static const char *const options[] = { "-all", "-ascii", "-bisect", "-decreasing", "-dictionary", |
︙ | ︙ | |||
3010 3011 3012 3013 3014 3015 3016 | * If there was a previous -start option, release its saved index * because it will either be replaced or there will be an error. */ if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } | | | | 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 | * If there was a previous -start option, release its saved index * because it will either be replaced or there will be an error. */ if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } if (i+4 > objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing starting index", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); result = TCL_ERROR; goto done; } i++; if (objv[i] == objv[objc - 2]) { /* |
︙ | ︙ | |||
3039 3040 3041 3042 3043 3044 3045 | case LSEARCH_INDEX: { /* -index */ Tcl_Obj **indices; int j; if (sortInfo.indexc > 1) { TclStackFree(interp, sortInfo.indexv); } | | | | 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 | case LSEARCH_INDEX: { /* -index */ Tcl_Obj **indices; int j; if (sortInfo.indexc > 1) { TclStackFree(interp, sortInfo.indexv); } if (i+4 > objc) { if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-index\" option must be followed by list index", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); return TCL_ERROR; } /* * Store the extracted indices for processing by sublist * extraction. Note that we don't do this using objects because |
︙ | ︙ | |||
3073 3074 3075 3076 3077 3078 3079 | sortInfo.indexv = NULL; break; case 1: sortInfo.indexv = &sortInfo.singleIndex; break; default: sortInfo.indexv = | | | 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 | sortInfo.indexv = NULL; break; case 1: sortInfo.indexv = &sortInfo.singleIndex; break; default: sortInfo.indexv = TclStackAlloc(interp, sizeof(ssize_t) * sortInfo.indexc); } /* * Fill the array by parsing each index. We don't know whether * their scale is sensible yet, but we at least perform the * syntactic check here. */ |
︙ | ︙ | |||
3105 3106 3107 3108 3109 3110 3111 | */ if (returnSubindices && sortInfo.indexc==0) { if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | | 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 | */ if (returnSubindices && sortInfo.indexc==0) { if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } Tcl_SetObjResult(interp, Tcl_NewStringObj( "-subindices cannot be used without -index option", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH", "BAD_OPTION_MIX", NULL); return TCL_ERROR; } if (bisect && (allMatches || negatedMatch)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "-bisect is not compatible with -all or -not", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH", "BAD_OPTION_MIX", NULL); return TCL_ERROR; } if (mode == REGEXP) { /* |
︙ | ︙ | |||
3460 3461 3462 3463 3464 3465 3466 | } else { itemPtr = listv[i]; } Tcl_ListObjAppendElement(interp, listPtr, itemPtr); } else if (returnSubindices) { int j; | | | | | | | 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 | } else { itemPtr = listv[i]; } Tcl_ListObjAppendElement(interp, listPtr, itemPtr); } else if (returnSubindices) { int j; itemPtr = Tcl_NewWideIntObj(i); for (j=0 ; j<sortInfo.indexc ; j++) { Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewWideIntObj(sortInfo.indexv[j])); } Tcl_ListObjAppendElement(interp, listPtr, itemPtr); } else { Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(i)); } } } /* * Return everything or a single value. */ if (allMatches) { Tcl_SetObjResult(interp, listPtr); } else if (!inlineReturn) { if (returnSubindices) { int j; itemPtr = Tcl_NewWideIntObj(index); for (j=0 ; j<sortInfo.indexc ; j++) { Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewWideIntObj(sortInfo.indexv[j])); } Tcl_SetObjResult(interp, itemPtr); } else { Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index)); } } else if (index < 0) { /* * Is this superfluous? The result should be a blank object by * default... */ |
︙ | ︙ | |||
3535 3536 3537 3538 3539 3540 3541 | *---------------------------------------------------------------------- */ int Tcl_LsetObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 | *---------------------------------------------------------------------- */ int Tcl_LsetObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument values. */ { Tcl_Obj *listPtr; /* Pointer to the list being altered. */ Tcl_Obj *finalValuePtr; /* Value finally assigned to the variable. */ /* * Check parameter count. |
︙ | ︙ | |||
3620 3621 3622 3623 3624 3625 3626 | *---------------------------------------------------------------------- */ int Tcl_LsortObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | < | > | 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 | *---------------------------------------------------------------------- */ int Tcl_LsortObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument values. */ { int index, indices, nocase = 0, sortMode = SORTMODE_ASCII; size_t i, j, length, indexc; int group, groupSize, groupOffset, idx, allocatedIndexVector = 0; Tcl_Obj *resultPtr, *cmdPtr, **listObjPtrs, *listObj, *indexPtr; SortElement *elementArray, *elementPtr; SortInfo sortInfo; /* Information about this sort that needs to * be passed to the comparison function. */ # define NUM_LISTS 30 SortElement *subList[NUM_LISTS+1]; |
︙ | ︙ | |||
3683 3684 3685 3686 3687 3688 3689 | case LSORT_ASCII: sortInfo.sortMode = SORTMODE_ASCII; break; case LSORT_COMMAND: if (i == objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-command\" option must be followed " | | | | | 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 | case LSORT_ASCII: sortInfo.sortMode = SORTMODE_ASCII; break; case LSORT_COMMAND: if (i == objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-command\" option must be followed " "by comparison command", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); sortInfo.resultCode = TCL_ERROR; goto done2; } sortInfo.sortMode = SORTMODE_COMMAND; cmdPtr = objv[i+1]; i++; break; case LSORT_DECREASING: sortInfo.isIncreasing = 0; break; case LSORT_DICTIONARY: sortInfo.sortMode = SORTMODE_DICTIONARY; break; case LSORT_INCREASING: sortInfo.isIncreasing = 1; break; case LSORT_INDEX: { ssize_t dummy; Tcl_Obj **indexv; if (i == objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-index\" option must be followed by list index", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); sortInfo.resultCode = TCL_ERROR; goto done2; } if (TclListObjGetElements(interp, objv[i+1], &indexc, &indexv) != TCL_OK) { sortInfo.resultCode = TCL_ERROR; |
︙ | ︙ | |||
3731 3732 3733 3734 3735 3736 3737 | * options is done. */ for (j=0 ; j<indexc ; j++) { if (TclGetIntForIndexM(interp, indexv[j], SORTIDX_END, &dummy) != TCL_OK) { Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( | | | 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 | * options is done. */ for (j=0 ; j<indexc ; j++) { if (TclGetIntForIndexM(interp, indexv[j], SORTIDX_END, &dummy) != TCL_OK) { Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (-index option item number %lu)", j)); sortInfo.resultCode = TCL_ERROR; goto done2; } } indexPtr = objv[i+1]; i++; break; |
︙ | ︙ | |||
3759 3760 3761 3762 3763 3764 3765 | case LSORT_INDICES: indices = 1; break; case LSORT_STRIDE: if (i == objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-stride\" option must be " | | | | 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 | case LSORT_INDICES: indices = 1; break; case LSORT_STRIDE: if (i == objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-stride\" option must be " "followed by stride length", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); sortInfo.resultCode = TCL_ERROR; goto done2; } if (Tcl_GetIntFromObj(interp, objv[i+1], &groupSize) != TCL_OK) { sortInfo.resultCode = TCL_ERROR; goto done2; } if (groupSize < 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "stride length must be at least 2", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADSTRIDE", NULL); sortInfo.resultCode = TCL_ERROR; goto done2; } group = 1; i++; |
︙ | ︙ | |||
3804 3805 3806 3807 3808 3809 3810 | sortInfo.indexv = NULL; break; case 1: sortInfo.indexv = &sortInfo.singleIndex; break; default: sortInfo.indexv = | | | 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 | sortInfo.indexv = NULL; break; case 1: sortInfo.indexv = &sortInfo.singleIndex; break; default: sortInfo.indexv = TclStackAlloc(interp, sizeof(ssize_t) * sortInfo.indexc); allocatedIndexVector = 1; /* Cannot use indexc field, as it * might be decreased by 1 later. */ } for (j=0 ; j<sortInfo.indexc ; j++) { TclGetIntForIndexM(interp, indexv[j], SORTIDX_END, &sortInfo.indexv[j]); } |
︙ | ︙ | |||
3868 3869 3870 3871 3872 3873 3874 | * because of the -stride option. [TIP #326] */ if (group) { if (length % groupSize) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "list size must be a multiple of the stride length", | | | | 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 | * because of the -stride option. [TIP #326] */ if (group) { if (length % groupSize) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "list size must be a multiple of the stride length", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADSTRIDE", NULL); sortInfo.resultCode = TCL_ERROR; goto done; } length = length / groupSize; if (sortInfo.indexc > 0) { /* * Use the first value in the list supplied to -index as the * offset of the element within each group by which to sort. */ groupOffset = sortInfo.indexv[0]; if (groupOffset <= SORTIDX_END) { groupOffset = (groupOffset - SORTIDX_END) + groupSize - 1; } if (groupOffset < 0 || groupOffset >= groupSize) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "when used with \"-stride\", the leading \"-index\"" " value must be within the group", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADINDEX", NULL); sortInfo.resultCode = TCL_ERROR; goto done; } if (sortInfo.indexc == 1) { sortInfo.indexc = 0; |
︙ | ︙ | |||
4036 4037 4038 4039 4040 4041 4042 | listRepPtr = ListRepPtr(resultPtr); newArray = &listRepPtr->elements; if (group) { for (i=0; elementPtr!=NULL ; elementPtr=elementPtr->nextPtr) { idx = elementPtr->payload.index; for (j = 0; j < groupSize; j++) { if (indices) { | | | | 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 | listRepPtr = ListRepPtr(resultPtr); newArray = &listRepPtr->elements; if (group) { for (i=0; elementPtr!=NULL ; elementPtr=elementPtr->nextPtr) { idx = elementPtr->payload.index; for (j = 0; j < groupSize; j++) { if (indices) { objPtr = Tcl_NewWideIntObj(idx + j - groupOffset); newArray[i++] = objPtr; Tcl_IncrRefCount(objPtr); } else { objPtr = listObjPtrs[idx + j - groupOffset]; newArray[i++] = objPtr; Tcl_IncrRefCount(objPtr); } } } } else if (indices) { for (i=0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr) { objPtr = Tcl_NewWideIntObj(elementPtr->payload.index); newArray[i++] = objPtr; Tcl_IncrRefCount(objPtr); } } else { for (i=0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr) { objPtr = elementPtr->payload.objPtr; newArray[i++] = objPtr; |
︙ | ︙ | |||
4231 4232 4233 4234 4235 4236 4237 | double a, b; a = elemPtr1->collationKey.doubleValue; b = elemPtr2->collationKey.doubleValue; order = ((a >= b) - (a <= b)); } else { Tcl_Obj **objv, *paramObjv[2]; | | | 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 | double a, b; a = elemPtr1->collationKey.doubleValue; b = elemPtr2->collationKey.doubleValue; order = ((a >= b) - (a <= b)); } else { Tcl_Obj **objv, *paramObjv[2]; size_t objc; Tcl_Obj *objPtr1, *objPtr2; if (infoPtr->resultCode != TCL_OK) { /* * Once an error has occurred, skip any future comparisons so as * to preserve the error message in sortInterp->result. */ |
︙ | ︙ | |||
4275 4276 4277 4278 4279 4280 4281 | /* * Parse the result of the command. */ if (TclGetIntFromObj(infoPtr->interp, Tcl_GetObjResult(infoPtr->interp), &order) != TCL_OK) { Tcl_SetObjResult(infoPtr->interp, Tcl_NewStringObj( | | > | 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 | /* * Parse the result of the command. */ if (TclGetIntFromObj(infoPtr->interp, Tcl_GetObjResult(infoPtr->interp), &order) != TCL_OK) { Tcl_SetObjResult(infoPtr->interp, Tcl_NewStringObj( "-compare command returned non-integer result", TCL_STRLEN)); Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT", "COMPARISONFAILED", NULL); infoPtr->resultCode = TCL_ERROR; return 0; } } if (!infoPtr->isIncreasing) { |
︙ | ︙ | |||
4449 4450 4451 4452 4453 4454 4455 | static Tcl_Obj * SelectObjFromSublist( Tcl_Obj *objPtr, /* Obj to select sublist from. */ SortInfo *infoPtr) /* Information passed from the top-level * "lsearch" or "lsort" command. */ { | | | > | | | 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 | static Tcl_Obj * SelectObjFromSublist( Tcl_Obj *objPtr, /* Obj to select sublist from. */ SortInfo *infoPtr) /* Information passed from the top-level * "lsearch" or "lsort" command. */ { size_t i; /* * Quick check for case when no "-index" option is there. */ if (infoPtr->indexc == 0) { return objPtr; } /* * Iterate over the indices, traversing through the nested sublists as we * go. */ for (i=0 ; i<infoPtr->indexc ; i++) { size_t listLen; ssize_t index; Tcl_Obj *currentObj; if (TclListObjLength(infoPtr->interp, objPtr, &listLen) != TCL_OK) { infoPtr->resultCode = TCL_ERROR; return NULL; } index = infoPtr->indexv[i]; /* * Adjust for end-based indexing. */ if (index < SORTIDX_NONE) { index += listLen + 1; } if (Tcl_ListObjIndex(infoPtr->interp, objPtr, (size_t) index, ¤tObj) != TCL_OK) { infoPtr->resultCode = TCL_ERROR; return NULL; } if (currentObj == NULL) { Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf( "element %lu missing from sublist \"%s\"", index, TclGetString(objPtr))); Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT", "INDEXFAILED", NULL); infoPtr->resultCode = TCL_ERROR; return NULL; } objPtr = currentObj; |
︙ | ︙ |
Changes to generic/tclCmdMZ.c.
︙ | ︙ | |||
81 82 83 84 85 86 87 | *---------------------------------------------------------------------- */ int Tcl_PwdObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | *---------------------------------------------------------------------- */ int Tcl_PwdObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *retVal; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; |
︙ | ︙ | |||
121 122 123 124 125 126 127 | *---------------------------------------------------------------------- */ int Tcl_RegexpObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | > > | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | *---------------------------------------------------------------------- */ int Tcl_RegexpObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int i, indices, match, about, all, doinline, numMatchesSaved; int cflags, eflags, matchLength; size_t stringLength; ssize_t offset; Tcl_RegExp regExpr; Tcl_Obj *objPtr, *startIndex = NULL, *resultPtr = NULL; Tcl_RegExpInfo info; static const char *const options[] = { "-all", "-about", "-indices", "-inline", "-expanded", "-line", "-linestop", "-lineanchor", "-nocase", "-start", "--", NULL |
︙ | ︙ | |||
188 189 190 191 192 193 194 | case REGEXP_LINESTOP: cflags |= TCL_REG_NLSTOP; break; case REGEXP_LINEANCHOR: cflags |= TCL_REG_NLANCH; break; case REGEXP_START: { | | > | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | case REGEXP_LINESTOP: cflags |= TCL_REG_NLSTOP; break; case REGEXP_LINEANCHOR: cflags |= TCL_REG_NLANCH; break; case REGEXP_START: { ssize_t temp; if (++i >= objc) { goto endOfForLoop; } if (TclGetIntForIndexM(interp, objv[i], 0, &temp) != TCL_OK) { goto optionError; } if (startIndex) { |
︙ | ︙ | |||
224 225 226 227 228 229 230 | /* * Check if the user requested -inline, but specified match variables; a * no-no. */ if (doinline && ((objc - 2) != 0)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | /* * Check if the user requested -inline, but specified match variables; a * no-no. */ if (doinline && ((objc - 2) != 0)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "regexp match variables not allowed when using -inline", TCL_STRLEN)); goto optionError; } /* * Handle the odd about case separately. */ |
︙ | ︙ | |||
453 454 455 456 457 458 459 | * if -all wasn't specified, otherwise it's all-1 (the number of times * through the while - 1). */ if (doinline) { Tcl_SetObjResult(interp, resultPtr); } else { | | | 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 | * if -all wasn't specified, otherwise it's all-1 (the number of times * through the while - 1). */ if (doinline) { Tcl_SetObjResult(interp, resultPtr); } else { Tcl_SetObjResult(interp, Tcl_NewWideIntObj(all ? all-1 : 1)); } return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
479 480 481 482 483 484 485 | *---------------------------------------------------------------------- */ int Tcl_RegsubObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > > | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 | *---------------------------------------------------------------------- */ int Tcl_RegsubObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int idx, result, cflags, all, numMatches; int start, end, subStart, subEnd, match; ssize_t offset; size_t wlen, wsublen; Tcl_RegExp regExpr; Tcl_RegExpInfo info; Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL; Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend; static const char *const options[] = { "-all", "-nocase", "-expanded", |
︙ | ︙ | |||
537 538 539 540 541 542 543 | case REGSUB_LINESTOP: cflags |= TCL_REG_NLSTOP; break; case REGSUB_LINEANCHOR: cflags |= TCL_REG_NLANCH; break; case REGSUB_START: { | | > | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 | case REGSUB_LINESTOP: cflags |= TCL_REG_NLSTOP; break; case REGSUB_LINEANCHOR: cflags |= TCL_REG_NLANCH; break; case REGSUB_START: { ssize_t temp; if (++idx >= objc) { goto endOfForLoop; } if (TclGetIntForIndexM(interp, objv[idx], 0, &temp) != TCL_OK) { goto optionError; } if (startIndex) { |
︙ | ︙ | |||
572 573 574 575 576 577 578 | return TCL_ERROR; } objc -= idx; objv += idx; if (startIndex) { | | | | 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 | return TCL_ERROR; } objc -= idx; objv += idx; if (startIndex) { size_t stringLength = Tcl_GetCharLength(objv[1]); TclGetIntForIndexM(NULL, startIndex, stringLength, &offset); Tcl_DecrRefCount(startIndex); if (offset < 0) { offset = 0; } } if (all && (offset == 0) && (strpbrk(TclGetString(objv[2]), "&\\") == NULL) && (strpbrk(TclGetString(objv[0]), "*+?{}()[].\\|^$") == NULL)) { /* * This is a simple one pair string map situation. We make use of a * slightly modified version of the one pair STR_MAP code. */ size_t slen, nocase; int (*strCmpFn)(const Tcl_UniChar*,const Tcl_UniChar*,size_t); Tcl_UniChar *p, wsrclc; numMatches = 0; nocase = (cflags & TCL_REG_NOCASE); strCmpFn = nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp; |
︙ | ︙ | |||
624 625 626 627 628 629 630 | wlen = 0; } } else { wsrclc = Tcl_UniCharToLower(*wsrc); for (p = wfirstChar = wstring; wstring < wend; wstring++) { if ((*wstring == *wsrc || (nocase && Tcl_UniCharToLower(*wstring)==wsrclc)) && | | < | 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 | wlen = 0; } } else { wsrclc = Tcl_UniCharToLower(*wsrc); for (p = wfirstChar = wstring; wstring < wend; wstring++) { if ((*wstring == *wsrc || (nocase && Tcl_UniCharToLower(*wstring)==wsrclc)) && (slen==1 || (strCmpFn(wstring, wsrc, slen) == 0))) { if (numMatches == 0) { resultPtr = Tcl_NewUnicodeObj(wstring, 0); Tcl_IncrRefCount(resultPtr); } if (p != wstring) { Tcl_AppendUnicodeToObj(resultPtr, p, wstring - p); p = wstring + slen; |
︙ | ︙ | |||
887 888 889 890 891 892 893 | *---------------------------------------------------------------------- */ int Tcl_RenameObjCmd( ClientData dummy, /* Arbitrary value passed to the command. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 | *---------------------------------------------------------------------- */ int Tcl_RenameObjCmd( ClientData dummy, /* Arbitrary value passed to the command. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *oldName, *newName; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "oldName newName"); return TCL_ERROR; |
︙ | ︙ | |||
923 924 925 926 927 928 929 | *---------------------------------------------------------------------- */ int Tcl_ReturnObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 | *---------------------------------------------------------------------- */ int Tcl_ReturnObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int code, level; Tcl_Obj *returnOpts; /* * General syntax: [return ?-option value ...? ?result?] |
︙ | ︙ | |||
970 971 972 973 974 975 976 | *---------------------------------------------------------------------- */ int Tcl_SourceObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 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 | *---------------------------------------------------------------------- */ int Tcl_SourceObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRSourceObjCmd, dummy, objc, objv); } int TclNRSourceObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *encodingName = NULL; Tcl_Obj *fileName; if (objc != 2 && objc !=4) { Tcl_WrongNumArgs(interp, 1, objv, "?-encoding name? fileName"); |
︙ | ︙ | |||
1030 1031 1032 1033 1034 1035 1036 | *---------------------------------------------------------------------- */ int Tcl_SplitObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 | *---------------------------------------------------------------------- */ int Tcl_SplitObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_UniChar ch; int len; const char *splitChars; const char *stringPtr; const char *end; size_t splitCharLen, stringLen; Tcl_Obj *listPtr, *objPtr; if (objc == 2) { splitChars = " \n\t\r"; splitCharLen = 4; } else if (objc == 3) { splitChars = TclGetStringFromObj(objv[2], &splitCharLen); |
︙ | ︙ | |||
1169 1170 1171 1172 1173 1174 1175 | *---------------------------------------------------------------------- */ static int StringFirstCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 | *---------------------------------------------------------------------- */ static int StringFirstCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_UniChar *needleStr, *haystackStr; size_t needleLen, haystackLen; ssize_t match, start; if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "needleString haystackString ?startIndex?"); return TCL_ERROR; } |
︙ | ︙ | |||
1210 1211 1212 1213 1214 1215 1216 | /* * Reread to prevent shimmering problems. */ needleStr = Tcl_GetUnicodeFromObj(objv[1], &needleLen); haystackStr = Tcl_GetUnicodeFromObj(objv[2], &haystackLen); | < < < < < | > > > > > | | | 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 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 | /* * Reread to prevent shimmering problems. */ needleStr = Tcl_GetUnicodeFromObj(objv[1], &needleLen); haystackStr = Tcl_GetUnicodeFromObj(objv[2], &haystackLen); if (start < 0) { /* * Invalid start index mapped to string start; Bug #423581 */ start = 0; } else if (start >= haystackLen) { goto str_first_done; } else if (start > 0) { haystackStr += start; haystackLen -= start; } } /* * If the length of the needle is more than the length of the haystack, it * cannot be contained in there so we can avoid searching. [Bug 2960021] */ if (needleLen > 0 && needleLen <= haystackLen) { register Tcl_UniChar *p, *end; end = haystackStr + haystackLen - needleLen + 1; for (p = haystackStr; p < end; p++) { /* * Scan forward to find the first character. */ if ((*p == *needleStr) && (TclUniCharNcmp(needleStr, p, needleLen) == 0)) { match = p - haystackStr; break; } } } /* * Compute the character index of the matching string by counting the * number of characters before the match. */ if ((match != -1) && (objc == 4)) { match += start; } str_first_done: Tcl_SetObjResult(interp, Tcl_NewWideIntObj(match)); return TCL_OK; } /* *---------------------------------------------------------------------- * * StringLastCmd -- |
︙ | ︙ | |||
1282 1283 1284 1285 1286 1287 1288 | *---------------------------------------------------------------------- */ static int StringLastCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | | 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 | *---------------------------------------------------------------------- */ static int StringLastCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_UniChar *needleStr, *haystackStr, *p; ssize_t match, start; size_t needleLen, haystackLen; if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "needleString haystackString ?startIndex?"); return TCL_ERROR; } |
︙ | ︙ | |||
1354 1355 1356 1357 1358 1359 1360 | match = p - haystackStr; break; } } } str_last_done: | | | 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 | match = p - haystackStr; break; } } } str_last_done: Tcl_SetObjResult(interp, Tcl_NewWideIntObj(match)); return TCL_OK; } /* *---------------------------------------------------------------------- * * StringIndexCmd -- |
︙ | ︙ | |||
1380 1381 1382 1383 1384 1385 1386 | *---------------------------------------------------------------------- */ static int StringIndexCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 | *---------------------------------------------------------------------- */ static int StringIndexCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { size_t length; ssize_t index; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string charIndex"); return TCL_ERROR; } /* |
︙ | ︙ | |||
1443 1444 1445 1446 1447 1448 1449 | *---------------------------------------------------------------------- */ static int StringIsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 | *---------------------------------------------------------------------- */ static int StringIsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *string1, *end, *stop; Tcl_UniChar ch; int (*chcomp)(int) = NULL; /* The UniChar comparison function. */ int i, failat = 0, result = 1, strict = 0, index; size_t length1, length2; Tcl_Obj *objPtr, *failVarObj = NULL; Tcl_WideInt w; static const char *const isClasses[] = { "alnum", "alpha", "ascii", "control", "boolean", "digit", "double", "entier", "false", "graph", "integer", "list", |
︙ | ︙ | |||
1575 1576 1577 1578 1579 1580 1581 | if (length1 == 0) { if (strict) { result = 0; } goto str_is_done; } end = string1 + length1; | | | 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 | if (length1 == 0) { if (strict) { result = 0; } goto str_is_done; } end = string1 + length1; if (TclParseNumber(NULL, objPtr, NULL, NULL, TCL_STRLEN, (const char **) &stop, 0) != TCL_OK) { result = 0; failat = 0; } else { failat = stop - string1; if (stop < end) { result = 0; |
︙ | ︙ | |||
1612 1613 1614 1615 1616 1617 1618 | if (length1 == 0) { if (strict) { result = 0; } goto str_is_done; } end = string1 + length1; | | | 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 | if (length1 == 0) { if (strict) { result = 0; } goto str_is_done; } end = string1 + length1; if (TclParseNumber(NULL, objPtr, NULL, NULL, TCL_STRLEN, (const char **) &stop, TCL_PARSE_INTEGER_ONLY) == TCL_OK) { if (stop == end) { /* * Entire string parses as an integer. */ break; |
︙ | ︙ | |||
1664 1665 1666 1667 1668 1669 1670 | * Don't bother computing the failure point if we're not going to * return it. */ break; } end = string1 + length1; | | | 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 | * Don't bother computing the failure point if we're not going to * return it. */ break; } end = string1 + length1; if (TclParseNumber(NULL, objPtr, NULL, NULL, TCL_STRLEN, (const char **) &stop, TCL_PARSE_INTEGER_ONLY) == TCL_OK) { if (stop == end) { /* * Entire string parses as an integer, but rejected by * Tcl_Get(Wide)IntFromObj() so we must have overflowed the * target type, and our convention is to return failure at * index -1 in that situation. |
︙ | ︙ | |||
1712 1713 1714 1715 1716 1717 1718 | /* * Need to figure out where the list parsing failed, which is * fairly expensive. This is adapted from the core of * SetListFromAny(). */ const char *elemStart, *nextElem; | | | 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 | /* * Need to figure out where the list parsing failed, which is * fairly expensive. This is adapted from the core of * SetListFromAny(). */ const char *elemStart, *nextElem; size_t lenRemain, elemSize; register const char *p; string1 = TclGetStringFromObj(objPtr, &length1); end = string1 + length1; failat = -1; for (p=string1, lenRemain=length1; lenRemain > 0; p=nextElem, lenRemain=end-nextElem) { |
︙ | ︙ | |||
1794 1795 1796 1797 1798 1799 1800 | /* * Only set the failVarObj when we will return 0 and we have indicated a * valid fail index (>= 0). */ str_is_done: if ((result == 0) && (failVarObj != NULL) && | | | 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 | /* * Only set the failVarObj when we will return 0 and we have indicated a * valid fail index (>= 0). */ str_is_done: if ((result == 0) && (failVarObj != NULL) && Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewWideIntObj(failat), TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewLongObj(result!=0)); return TCL_OK; } |
︙ | ︙ | |||
1838 1839 1840 1841 1842 1843 1844 | *---------------------------------------------------------------------- */ static int StringMapCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 | *---------------------------------------------------------------------- */ static int StringMapCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { size_t length1, length2, mapElemc, index; int nocase = 0, mapWithDict = 0, copySource = 0; Tcl_Obj **mapElemv, *sourceObj, *resultPtr; Tcl_UniChar *ustring1, *ustring2, *p, *end; int (*strCmpFn)(const Tcl_UniChar*, const Tcl_UniChar*, size_t); if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "?-nocase? charMap string"); |
︙ | ︙ | |||
1924 1925 1926 1927 1928 1929 1930 | return TCL_OK; } else if (mapElemc & 1) { /* * The charMap must be an even number of key/value items. */ Tcl_SetObjResult(interp, | | | 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 | return TCL_OK; } else if (mapElemc & 1) { /* * The charMap must be an even number of key/value items. */ Tcl_SetObjResult(interp, Tcl_NewStringObj("char map list unbalanced", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "MAP", "UNBALANCED", NULL); return TCL_ERROR; } } /* |
︙ | ︙ | |||
1968 1969 1970 1971 1972 1973 1974 | /* * Special case for one map pair which avoids the extra for loop and * extra calls to get Unicode data. The algorithm is otherwise * identical to the multi-pair case. This will be >30% faster on * larger strings. */ | | | | | | | 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 | /* * Special case for one map pair which avoids the extra for loop and * extra calls to get Unicode data. The algorithm is otherwise * identical to the multi-pair case. This will be >30% faster on * larger strings. */ size_t mapLen; Tcl_UniChar *mapString, u2lc; ustring2 = Tcl_GetUnicodeFromObj(mapElemv[0], &length2); p = ustring1; if ((length2 > length1) || (length2 == 0)) { /* * Match string is either longer than input or empty. */ ustring1 = end; } else { mapString = Tcl_GetUnicodeFromObj(mapElemv[1], &mapLen); u2lc = (nocase ? Tcl_UniCharToLower(*ustring2) : 0); for (; ustring1 < end; ustring1++) { if (((*ustring1 == *ustring2) || (nocase && Tcl_UniCharToLower(*ustring1)==u2lc)) && (length2==1 || strCmpFn(ustring1, ustring2, length2) == 0)) { if (p != ustring1) { Tcl_AppendUnicodeToObj(resultPtr, p, ustring1-p); p = ustring1 + length2; } else { p += length2; } ustring1 = p - 1; Tcl_AppendUnicodeToObj(resultPtr, mapString, mapLen); } } } } else { Tcl_UniChar **mapStrings, *u2lc = NULL; size_t *mapLens; /* * Precompute pointers to the unicode string and length. This saves us * repeated function calls later, significantly speeding up the * algorithm. We only need the lowercase first char in the nocase * case. */ mapStrings = TclStackAlloc(interp, mapElemc*2*sizeof(Tcl_UniChar *)); mapLens = TclStackAlloc(interp, mapElemc * 2 * sizeof(size_t)); if (nocase) { u2lc = TclStackAlloc(interp, mapElemc * sizeof(Tcl_UniChar)); } for (index = 0; index < mapElemc; index++) { mapStrings[index] = Tcl_GetUnicodeFromObj(mapElemv[index], mapLens+index); if (nocase && ((index % 2) == 0)) { |
︙ | ︙ | |||
2034 2035 2036 2037 2038 2039 2040 | ustring2 = mapStrings[index]; length2 = mapLens[index]; if ((length2 > 0) && ((*ustring1 == *ustring2) || (nocase && (Tcl_UniCharToLower(*ustring1) == u2lc[index/2]))) && /* Restrict max compare length. */ (end-ustring1 >= length2) && ((length2 == 1) || | | | 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 | ustring2 = mapStrings[index]; length2 = mapLens[index]; if ((length2 > 0) && ((*ustring1 == *ustring2) || (nocase && (Tcl_UniCharToLower(*ustring1) == u2lc[index/2]))) && /* Restrict max compare length. */ (end-ustring1 >= length2) && ((length2 == 1) || strCmpFn(ustring2, ustring1, length2) == 0)) { if (p != ustring1) { /* * Put the skipped chars onto the result first. */ Tcl_AppendUnicodeToObj(resultPtr, p, ustring1-p); p = ustring1 + length2; |
︙ | ︙ | |||
2108 2109 2110 2111 2112 2113 2114 | *---------------------------------------------------------------------- */ static int StringMatchCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 | *---------------------------------------------------------------------- */ static int StringMatchCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int nocase = 0; if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "?-nocase? pattern string"); return TCL_ERROR; } if (objc == 4) { size_t length; const char *string = TclGetStringFromObj(objv[1], &length); if ((length > 1) && strncmp(string, "-nocase", (size_t) length) == 0) { nocase = TCL_MATCH_NOCASE; } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( |
︙ | ︙ | |||
2160 2161 2162 2163 2164 2165 2166 | *---------------------------------------------------------------------- */ static int StringRangeCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | | 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 | *---------------------------------------------------------------------- */ static int StringRangeCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { size_t length; ssize_t first, last; if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "string first last"); return TCL_ERROR; } /* |
︙ | ︙ | |||
2185 2186 2187 2188 2189 2190 2191 | TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK) { return TCL_ERROR; } if (first < 0) { first = 0; } | | | 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 | TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK) { return TCL_ERROR; } if (first < 0) { first = 0; } if (last >= length && last > 0) { last = length; } if (last >= first) { Tcl_SetObjResult(interp, Tcl_GetRange(objv[1], first, last)); } return TCL_OK; } |
︙ | ︙ | |||
2216 2217 2218 2219 2220 2221 2222 | *---------------------------------------------------------------------- */ static int StringReptCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | | 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 | *---------------------------------------------------------------------- */ static int StringReptCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *string1; char *string2; int count; size_t index, length1, length2; Tcl_Obj *resultPtr; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string count"); return TCL_ERROR; } |
︙ | ︙ | |||
2271 2272 2273 2274 2275 2276 2277 | } length2 = length1 * count; /* * Include space for the NUL. */ | | | | 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 | } length2 = length1 * count; /* * Include space for the NUL. */ string2 = attemptckalloc(length2 + 1); if (string2 == NULL) { /* * Alloc failed. Note that in this case we try to do an error message * since this is a case that's most likely when the alloc is large and * that's easy to do with this API. Note that if we fail allocating a * short string, this will likely keel over too (and fatally). */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "string size overflow, out of memory allocating %lu bytes", length2 + 1)); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); return TCL_ERROR; } for (index = 0; index < count; index++) { memcpy(string2 + (length1 * index), string1, (size_t) length1); } |
︙ | ︙ | |||
2328 2329 2330 2331 2332 2333 2334 | *---------------------------------------------------------------------- */ static int StringRplcCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > > > > > < < < < | 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 | *---------------------------------------------------------------------- */ static int StringRplcCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_UniChar *ustring; ssize_t first, last; size_t length; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 1, objv, "string first last ?string?"); return TCL_ERROR; } ustring = Tcl_GetUnicodeFromObj(objv[1], &length); length--; if (TclGetIntForIndexM(interp, objv[2], length, &first) != TCL_OK || TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK){ return TCL_ERROR; } if (first < 0) { first = 0; } if ((last < first) || (last < 0) || (first > length)) { Tcl_SetObjResult(interp, objv[1]); } else { Tcl_Obj *resultPtr; ustring = Tcl_GetUnicodeFromObj(objv[1], &length); length--; resultPtr = Tcl_NewUnicodeObj(ustring, first); if (objc == 5) { Tcl_AppendObjToObj(resultPtr, objv[4]); } if (last < length) { Tcl_AppendUnicodeToObj(resultPtr, ustring + last + 1, length - last); |
︙ | ︙ | |||
2394 2395 2396 2397 2398 2399 2400 | *---------------------------------------------------------------------- */ static int StringRevCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 | *---------------------------------------------------------------------- */ static int StringRevCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "string"); return TCL_ERROR; } |
︙ | ︙ | |||
2429 2430 2431 2432 2433 2434 2435 | *---------------------------------------------------------------------- */ static int StringStartCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | | | | 2442 2443 2444 2445 2446 2447 2448 2449 2450 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 | *---------------------------------------------------------------------- */ static int StringStartCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_UniChar ch; const char *p, *string; size_t cur, length, numChars; ssize_t index; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string index"); return TCL_ERROR; } string = TclGetStringFromObj(objv[1], &length); numChars = Tcl_NumUtfChars(string, length); if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) { return TCL_ERROR; } string = TclGetStringFromObj(objv[1], &length); if (index >= numChars && index >= 0) { index = numChars - 1; } cur = 0; if (index > 0) { p = Tcl_UtfAtIndex(string, index); for (cur = index+1; cur --> 0 ;) { TclUtfToUniChar(p, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } p = Tcl_UtfPrev(p, string); } if (cur != index) { cur += 1; } } Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur)); return TCL_OK; } /* *---------------------------------------------------------------------- * * StringEndCmd -- |
︙ | ︙ | |||
2490 2491 2492 2493 2494 2495 2496 | *---------------------------------------------------------------------- */ static int StringEndCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 | *---------------------------------------------------------------------- */ static int StringEndCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_UniChar ch; const char *p, *end, *string; size_t cur, length, numChars; ssize_t index; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string index"); return TCL_ERROR; } string = TclGetStringFromObj(objv[1], &length); |
︙ | ︙ | |||
2552 2553 2554 2555 2556 2557 2558 | *---------------------------------------------------------------------- */ static int StringEqualCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | 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 | *---------------------------------------------------------------------- */ static int StringEqualCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { /* * Remember to keep code here in some sync with the byte-compiled versions * in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as * the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...). */ const char *string1, *string2; size_t length1, length2, i, match, length; int nocase = 0, reqlength = -1; typedef int (*strCmpFn_t)(const char *, const char *, size_t); strCmpFn_t strCmpFn; if (objc < 3 || objc > 6) { str_cmp_args: Tcl_WrongNumArgs(interp, 1, objv, "?-nocase? ?-length int? string1 string2"); |
︙ | ︙ | |||
2670 2671 2672 2673 2674 2675 2676 | * The requested length is negative, so we ignore it by setting it * to length + 1 so we correct the match var. */ reqlength = length + 1; } | | | 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 | * The requested length is negative, so we ignore it by setting it * to length + 1 so we correct the match var. */ reqlength = length + 1; } match = strCmpFn(string1, string2, length); if ((match == 0) && (reqlength > length)) { match = length1 - length2; } } Tcl_SetObjResult(interp, Tcl_NewLongObj(match==0)); return TCL_OK; |
︙ | ︙ | |||
2702 2703 2704 2705 2706 2707 2708 | *---------------------------------------------------------------------- */ static int StringCmpCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | | 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 | *---------------------------------------------------------------------- */ static int StringCmpCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { /* * Remember to keep code here in some sync with the byte-compiled versions * in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as * the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...). */ const char *string1, *string2; size_t length1, length2, i, length; int nocase = 0, reqlength = -1, match; typedef int (*strCmpFn_t)(const char *, const char *, size_t); strCmpFn_t strCmpFn; if (objc < 3 || objc > 6) { str_cmp_args: Tcl_WrongNumArgs(interp, 1, objv, "?-nocase? ?-length int? string1 string2"); |
︙ | ︙ | |||
2817 2818 2819 2820 2821 2822 2823 | * The requested length is negative, so we ignore it by setting it to * length + 1 so we correct the match var. */ reqlength = length + 1; } | | | 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 | * The requested length is negative, so we ignore it by setting it to * length + 1 so we correct the match var. */ reqlength = length + 1; } match = strCmpFn(string1, string2, length); if ((match == 0) && (reqlength > length)) { match = length1 - length2; } Tcl_SetObjResult(interp, Tcl_NewLongObj((match > 0) ? 1 : (match < 0) ? -1 : 0)); return TCL_OK; |
︙ | ︙ | |||
2850 2851 2852 2853 2854 2855 2856 | *---------------------------------------------------------------------- */ static int StringBytesCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 | *---------------------------------------------------------------------- */ static int StringBytesCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { size_t length; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "string"); return TCL_ERROR; } (void) TclGetStringFromObj(objv[1], &length); Tcl_SetObjResult(interp, Tcl_NewWideIntObj(length)); return TCL_OK; } /* *---------------------------------------------------------------------- * * StringLenCmd -- |
︙ | ︙ | |||
2887 2888 2889 2890 2891 2892 2893 | *---------------------------------------------------------------------- */ static int StringLenCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 | *---------------------------------------------------------------------- */ static int StringLenCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "string"); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tcl_GetCharLength(objv[1]))); return TCL_OK; } /* *---------------------------------------------------------------------- * * StringLowerCmd -- |
︙ | ︙ | |||
2921 2922 2923 2924 2925 2926 2927 | *---------------------------------------------------------------------- */ static int StringLowerCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 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 | *---------------------------------------------------------------------- */ static int StringLowerCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { size_t length1, length2; const char *string1; char *string2; if (objc < 2 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "string ?first? ?last?"); return TCL_ERROR; } string1 = TclGetStringFromObj(objv[1], &length1); if (objc == 2) { Tcl_Obj *resultPtr = Tcl_NewStringObj(string1, length1); length1 = Tcl_UtfToLower(TclGetString(resultPtr)); Tcl_SetObjLength(resultPtr, length1); Tcl_SetObjResult(interp, resultPtr); } else { ssize_t first, last; const char *start, *end; Tcl_Obj *resultPtr; length1 = Tcl_NumUtfChars(string1, length1) - 1; if (TclGetIntForIndexM(interp,objv[2],length1, &first) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
2977 2978 2979 2980 2981 2982 2983 | end = Tcl_UtfAtIndex(start, last - first + 1); resultPtr = Tcl_NewStringObj(string1, end - string1); string2 = TclGetString(resultPtr) + (start - string1); length2 = Tcl_UtfToLower(string2); Tcl_SetObjLength(resultPtr, length2 + (start - string1)); | | | 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 | end = Tcl_UtfAtIndex(start, last - first + 1); resultPtr = Tcl_NewStringObj(string1, end - string1); string2 = TclGetString(resultPtr) + (start - string1); length2 = Tcl_UtfToLower(string2); Tcl_SetObjLength(resultPtr, length2 + (start - string1)); Tcl_AppendToObj(resultPtr, end, TCL_STRLEN); Tcl_SetObjResult(interp, resultPtr); } return TCL_OK; } /* |
︙ | ︙ | |||
3006 3007 3008 3009 3010 3011 3012 | *---------------------------------------------------------------------- */ static int StringUpperCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 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 | *---------------------------------------------------------------------- */ static int StringUpperCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { size_t length1, length2; const char *string1; char *string2; if (objc < 2 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "string ?first? ?last?"); return TCL_ERROR; } string1 = TclGetStringFromObj(objv[1], &length1); if (objc == 2) { Tcl_Obj *resultPtr = Tcl_NewStringObj(string1, length1); length1 = Tcl_UtfToUpper(TclGetString(resultPtr)); Tcl_SetObjLength(resultPtr, length1); Tcl_SetObjResult(interp, resultPtr); } else { ssize_t first, last; const char *start, *end; Tcl_Obj *resultPtr; length1 = Tcl_NumUtfChars(string1, length1) - 1; if (TclGetIntForIndexM(interp,objv[2],length1, &first) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
3062 3063 3064 3065 3066 3067 3068 | end = Tcl_UtfAtIndex(start, last - first + 1); resultPtr = Tcl_NewStringObj(string1, end - string1); string2 = TclGetString(resultPtr) + (start - string1); length2 = Tcl_UtfToUpper(string2); Tcl_SetObjLength(resultPtr, length2 + (start - string1)); | | | 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 | end = Tcl_UtfAtIndex(start, last - first + 1); resultPtr = Tcl_NewStringObj(string1, end - string1); string2 = TclGetString(resultPtr) + (start - string1); length2 = Tcl_UtfToUpper(string2); Tcl_SetObjLength(resultPtr, length2 + (start - string1)); Tcl_AppendToObj(resultPtr, end, TCL_STRLEN); Tcl_SetObjResult(interp, resultPtr); } return TCL_OK; } /* |
︙ | ︙ | |||
3091 3092 3093 3094 3095 3096 3097 | *---------------------------------------------------------------------- */ static int StringTitleCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 | *---------------------------------------------------------------------- */ static int StringTitleCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { size_t length1, length2; const char *string1; char *string2; if (objc < 2 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "string ?first? ?last?"); return TCL_ERROR; } string1 = TclGetStringFromObj(objv[1], &length1); if (objc == 2) { Tcl_Obj *resultPtr = Tcl_NewStringObj(string1, length1); length1 = Tcl_UtfToTitle(TclGetString(resultPtr)); Tcl_SetObjLength(resultPtr, length1); Tcl_SetObjResult(interp, resultPtr); } else { ssize_t first, last; const char *start, *end; Tcl_Obj *resultPtr; length1 = Tcl_NumUtfChars(string1, length1) - 1; if (TclGetIntForIndexM(interp,objv[2],length1, &first) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
3147 3148 3149 3150 3151 3152 3153 | end = Tcl_UtfAtIndex(start, last - first + 1); resultPtr = Tcl_NewStringObj(string1, end - string1); string2 = TclGetString(resultPtr) + (start - string1); length2 = Tcl_UtfToTitle(string2); Tcl_SetObjLength(resultPtr, length2 + (start - string1)); | | | 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 | end = Tcl_UtfAtIndex(start, last - first + 1); resultPtr = Tcl_NewStringObj(string1, end - string1); string2 = TclGetString(resultPtr) + (start - string1); length2 = Tcl_UtfToTitle(string2); Tcl_SetObjLength(resultPtr, length2 + (start - string1)); Tcl_AppendToObj(resultPtr, end, TCL_STRLEN); Tcl_SetObjResult(interp, resultPtr); } return TCL_OK; } /* |
︙ | ︙ | |||
3176 3177 3178 3179 3180 3181 3182 | *---------------------------------------------------------------------- */ static int StringTrimCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 | *---------------------------------------------------------------------- */ static int StringTrimCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *string1, *string2; size_t triml, trimr, length1, length2; if (objc == 3) { string2 = TclGetStringFromObj(objv[2], &length2); } else if (objc == 2) { string2 = DEFAULT_TRIM_SET; length2 = strlen(DEFAULT_TRIM_SET); } else { |
︙ | ︙ | |||
3224 3225 3226 3227 3228 3229 3230 | *---------------------------------------------------------------------- */ static int StringTrimLCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 | *---------------------------------------------------------------------- */ static int StringTrimLCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *string1, *string2; size_t trim, length1, length2; if (objc == 3) { string2 = TclGetStringFromObj(objv[2], &length2); } else if (objc == 2) { string2 = DEFAULT_TRIM_SET; length2 = strlen(DEFAULT_TRIM_SET); } else { |
︙ | ︙ | |||
3270 3271 3272 3273 3274 3275 3276 | *---------------------------------------------------------------------- */ static int StringTrimRCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 | *---------------------------------------------------------------------- */ static int StringTrimRCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *string1, *string2; size_t trim, length1, length2; if (objc == 3) { string2 = TclGetStringFromObj(objv[2], &length2); } else if (objc == 2) { string2 = DEFAULT_TRIM_SET; length2 = strlen(DEFAULT_TRIM_SET); } else { |
︙ | ︙ | |||
3370 3371 3372 3373 3374 3375 3376 | * *---------------------------------------------------------------------- */ int TclSubstOptions( Tcl_Interp *interp, | | | 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 | * *---------------------------------------------------------------------- */ int TclSubstOptions( Tcl_Interp *interp, size_t numOpts, Tcl_Obj *const opts[], int *flagPtr) { static const char *const substOptions[] = { "-nobackslashes", "-nocommands", "-novariables", NULL }; enum { |
︙ | ︙ | |||
3411 3412 3413 3414 3415 3416 3417 | return TCL_OK; } int Tcl_SubstObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 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 | return TCL_OK; } int Tcl_SubstObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRSubstObjCmd, dummy, objc, objv); } int TclNRSubstObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int flags; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "?-nobackslashes? ?-nocommands? ?-novariables? string"); |
︙ | ︙ | |||
3459 3460 3461 3462 3463 3464 3465 | *---------------------------------------------------------------------- */ int Tcl_SwitchObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | | | | 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 | *---------------------------------------------------------------------- */ int Tcl_SwitchObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRSwitchObjCmd, dummy, objc, objv); } int TclNRSwitchObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int i,j, index, mode, foundmode, splitObjs, numMatchesSaved, noCase; size_t patternLength; const char *pattern; Tcl_Obj *stringObj, *indexVarObj, *matchVarObj; Tcl_Obj *const *savedObjv = objv; Tcl_RegExp regExpr = NULL; Interp *iPtr = (Interp *) interp; int pc = 0; int bidx = 0; /* Index of body argument. */ |
︙ | ︙ | |||
3506 3507 3508 3509 3510 3511 3512 | mode = OPT_EXACT; foundmode = 0; indexVarObj = NULL; matchVarObj = NULL; numMatchesSaved = 0; noCase = 0; | | | 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 | mode = OPT_EXACT; foundmode = 0; indexVarObj = NULL; matchVarObj = NULL; numMatchesSaved = 0; noCase = 0; for (i = 1; i+2 < objc; i++) { if (TclGetString(objv[i])[0] != '-') { break; } if (Tcl_GetIndexFromObjStruct(interp, objv[i], options, sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
3647 3648 3649 3650 3651 3652 3653 | * Complain if there is an odd number of words in the list of patterns and * bodies. */ if (objc % 2) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 | * Complain if there is an odd number of words in the list of patterns and * bodies. */ if (objc % 2) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_NewStringObj( "extra switch pattern with no body", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "BADARM", NULL); /* * Check if this can be due to a badly placed comment in the switch * block. * * The following is an heuristic to detect the infamous "comment in * switch" error: just check if a pattern begins with '#'. */ if (splitObjs) { for (i=0 ; i<objc ; i+=2) { if (TclGetString(objv[i])[0] == '#') { Tcl_AppendToObj(Tcl_GetObjResult(interp), ", this may be due to a comment incorrectly" " placed outside of a switch body - see the" " \"switch\" documentation", TCL_STRLEN); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "BADARM", "COMMENT?", NULL); break; } } } |
︙ | ︙ | |||
3992 3993 3994 3995 3996 3997 3998 | */ /* ARGSUSED */ int Tcl_ThrowObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 | */ /* ARGSUSED */ int Tcl_ThrowObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *options; size_t len; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "type message"); return TCL_ERROR; } /* * The type must be a list of at least length 1. */ if (Tcl_ListObjLength(interp, objv[1], &len) != TCL_OK) { return TCL_ERROR; } else if (len < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "type must be non-empty list", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "THROW", "BADEXCEPTION", NULL); return TCL_ERROR; } /* * Now prepare the result options dictionary. We use the list API as it is |
︙ | ︙ | |||
4054 4055 4056 4057 4058 4059 4060 | *---------------------------------------------------------------------- */ int Tcl_TimeObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 | *---------------------------------------------------------------------- */ int Tcl_TimeObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { register Tcl_Obj *objPtr; Tcl_Obj *objs[4]; register int i, result; int count; double totalMicroSec; |
︙ | ︙ | |||
4146 4147 4148 4149 4150 4151 4152 | *---------------------------------------------------------------------- */ int Tcl_TryObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | > | 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 | *---------------------------------------------------------------------- */ int Tcl_TryObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRTryObjCmd, dummy, objc, objv); } int TclNRTryObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *bodyObj, *handlersObj, *finallyObj = NULL; int i, bodyShared, haveHandlers, code; size_t dummy; static const char *const handlerNames[] = { "finally", "on", "trap", NULL }; enum Handlers { TryFinally, TryOn, TryTrap }; |
︙ | ︙ | |||
4194 4195 4196 4197 4198 4199 4200 | if (Tcl_GetIndexFromObjStruct(interp, objv[i], handlerNames, sizeof(char *), "handler type", 0, &type) != TCL_OK) { Tcl_DecrRefCount(handlersObj); return TCL_ERROR; } switch ((enum Handlers) type) { case TryFinally: /* finally script */ | | | | | | | | | | 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 | if (Tcl_GetIndexFromObjStruct(interp, objv[i], handlerNames, sizeof(char *), "handler type", 0, &type) != TCL_OK) { Tcl_DecrRefCount(handlersObj); return TCL_ERROR; } switch ((enum Handlers) type) { case TryFinally: /* finally script */ if (i+2 < objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "finally clause must be last", TCL_STRLEN)); Tcl_DecrRefCount(handlersObj); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "FINALLY", "NONTERMINAL", NULL); return TCL_ERROR; } else if (i+1 == objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "wrong # args to finally clause: must be" " \"... finally script\"", TCL_STRLEN)); Tcl_DecrRefCount(handlersObj); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "FINALLY", "ARGUMENT", NULL); return TCL_ERROR; } finallyObj = objv[++i]; break; case TryOn: /* on code variableList script */ if (i+4 > objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "wrong # args to on clause: must be \"... on code" " variableList script\"", TCL_STRLEN)); Tcl_DecrRefCount(handlersObj); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "ON", "ARGUMENT", NULL); return TCL_ERROR; } if (TclGetCompletionCodeFromObj(interp, objv[i+1], &code) != TCL_OK) { Tcl_DecrRefCount(handlersObj); return TCL_ERROR; } info[2] = NULL; goto commonHandler; case TryTrap: /* trap pattern variableList script */ if (i+4 > objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "wrong # args to trap clause: " "must be \"... trap pattern variableList script\"", TCL_STRLEN)); Tcl_DecrRefCount(handlersObj); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "TRAP", "ARGUMENT", NULL); return TCL_ERROR; } code = 1; if (Tcl_ListObjLength(NULL, objv[i+1], &dummy) != TCL_OK) { |
︙ | ︙ | |||
4278 4279 4280 4281 4282 4283 4284 | haveHandlers = 1; i += 3; break; } } if (bodyShared) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 | haveHandlers = 1; i += 3; break; } } if (bodyShared) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "last non-finally clause must not have a body of \"-\"", TCL_STRLEN)); Tcl_DecrRefCount(handlersObj); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "BADFALLTHROUGH", NULL); return TCL_ERROR; } if (!haveHandlers) { Tcl_DecrRefCount(handlersObj); |
︙ | ︙ | |||
4357 4358 4359 4360 4361 4362 4363 | static int TryPostBody( ClientData data[], Tcl_Interp *interp, int result) { Tcl_Obj *resultObj, *options, *handlersObj, *finallyObj, *cmdObj, **objv; | | | | 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 | static int TryPostBody( ClientData data[], Tcl_Interp *interp, int result) { Tcl_Obj *resultObj, *options, *handlersObj, *finallyObj, *cmdObj, **objv; int i, code, objc; size_t dummy, numHandlers = 0; handlersObj = data[0]; finallyObj = data[1]; objv = data[2]; objc = PTR2INT(data[3]); cmdObj = objv[0]; |
︙ | ︙ | |||
4425 4426 4427 4428 4429 4430 4431 | * matching of the errorcode list. However, if this was an * 'on' handler, the list that we are matching against will be * empty. */ if (code == TCL_ERROR) { Tcl_Obj *errorCodeName, *errcode, **bits1, **bits2; | | | 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 | * matching of the errorcode list. However, if this was an * 'on' handler, the list that we are matching against will be * empty. */ if (code == TCL_ERROR) { Tcl_Obj *errorCodeName, *errcode, **bits1, **bits2; size_t len1, len2, j; TclNewLiteralStringObj(errorCodeName, "-errorcode"); Tcl_DictObjGet(NULL, options, errorCodeName, &errcode); Tcl_DecrRefCount(errorCodeName); Tcl_ListObjGetElements(NULL, info[2], &len1, &bits1); if (Tcl_ListObjGetElements(NULL, errcode, &len2, &bits2) != TCL_OK) { |
︙ | ︙ | |||
4722 4723 4724 4725 4726 4727 4728 | *---------------------------------------------------------------------- */ int Tcl_WhileObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 | *---------------------------------------------------------------------- */ int Tcl_WhileObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRWhileObjCmd, dummy, objc, objv); } int TclNRWhileObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { ForIterData *iterPtr; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "test command"); return TCL_ERROR; |
︙ | ︙ | |||
4763 4764 4765 4766 4767 4768 4769 | } /* *---------------------------------------------------------------------- * * TclListLines -- * | | > | | | | | 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 | } /* *---------------------------------------------------------------------- * * TclListLines -- * * Compute line information for sub-subelements. Used in some types of * [switch]es and in the processing of lambdas by [apply]. * * Results: * Filled in array of line numbers? * * Side effects: * None. * *---------------------------------------------------------------------- */ void TclListLines( Tcl_Obj *listObj, /* Pointer to obj holding a string with list * structure. Assumed to be valid. Assumed to * contain n elements. */ int line, /* Line the list as a whole starts on. */ size_t numLines, /* #elements in lines */ int *lines, /* Array of line numbers, to fill. */ Tcl_Obj *const *elems) /* The list elems as Tcl_Obj*, in need of * derived continuation data */ { const char *listStr = Tcl_GetString(listObj); const char *listHead = listStr; size_t i, length = strlen(listStr); const char *element = NULL, *next = NULL; ContLineLoc *clLocPtr = TclContinuationsGet(listObj); ssize_t *clNext = (clLocPtr ? &clLocPtr->loc[0] : NULL); for (i = 0; i < numLines; i++) { TclFindElement(NULL, listStr, length, &element, &next, NULL, NULL); TclAdvanceLines(&line, listStr, element); /* Leading whitespace */ TclAdvanceContinuations(&line, &clNext, element - listHead); if (elems && clNext) { TclContinuationsEnterDerived(elems[i], element-listHead, clNext); |
︙ | ︙ |
Changes to generic/tclCompCmds.c.
︙ | ︙ | |||
240 241 242 243 244 245 246 | Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *varTokenPtr, *dataTokenPtr; int isScalar, localIndex, code = TCL_OK; | | > | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *varTokenPtr, *dataTokenPtr; int isScalar, localIndex, code = TCL_OK; int isDataLiteral, isDataValid, isDataEven; int dataVar, iterVar, keyVar, valVar, infoIndex; int back, fwd, offsetBack, offsetFwd; size_t len; Tcl_Obj *literalObj; ForeachInfo *infoPtr; if (parsePtr->numWords != 3) { return TCL_ERROR; } |
︙ | ︙ | |||
908 909 910 911 912 913 914 | /* * Parse the increment amount, if present. */ if (parsePtr->numWords == 4) { const char *word; | | > | 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 | /* * Parse the increment amount, if present. */ if (parsePtr->numWords == 4) { const char *word; size_t numBytes; int code; Tcl_Token *incrTokenPtr; Tcl_Obj *intObj; incrTokenPtr = TokenAfter(keyTokenPtr); if (incrTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { return TclCompileBasic2Or3ArgCmd(interp, parsePtr,cmdPtr, envPtr); } |
︙ | ︙ | |||
1092 1093 1094 1095 1096 1097 1098 | CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ int worker; /* Temp var for building the value in. */ Tcl_Token *tokenPtr; Tcl_Obj *keyObj, *valueObj, *dictObj; const char *bytes; | | > | 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 | CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ int worker; /* Temp var for building the value in. */ Tcl_Token *tokenPtr; Tcl_Obj *keyObj, *valueObj, *dictObj; const char *bytes; int i; size_t len; if ((parsePtr->numWords & 1) == 0) { return TCL_ERROR; } /* * See if we can build the value at compile time... |
︙ | ︙ | |||
1327 1328 1329 1330 1331 1332 1333 | * construct a new dictionary with the loop * body result. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *varsTokenPtr, *dictTokenPtr, *bodyTokenPtr; int keyVarIndex, valueVarIndex, nameChars, loopRange, catchRange; int infoIndex, jumpDisplacement, bodyTargetOffset, emptyTargetOffset; | | > | 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 | * construct a new dictionary with the loop * body result. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *varsTokenPtr, *dictTokenPtr, *bodyTokenPtr; int keyVarIndex, valueVarIndex, nameChars, loopRange, catchRange; int infoIndex, jumpDisplacement, bodyTargetOffset, emptyTargetOffset; int endTargetOffset; size_t numVars; int collectVar = -1; /* Index of temp var holding the result * dict. */ const char **argv; Tcl_DString buffer; /* * There must be three arguments after the command. |
︙ | ︙ | |||
2096 2097 2098 2099 2100 2101 2102 | unsigned int pcOffset) { DictUpdateInfo *duiPtr = clientData; int i; for (i=0 ; i<duiPtr->length ; i++) { if (i) { | | | 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 | unsigned int pcOffset) { DictUpdateInfo *duiPtr = clientData; int i; for (i=0 ; i<duiPtr->length ; i++) { if (i) { Tcl_AppendToObj(appendObj, ", ", TCL_STRLEN); } Tcl_AppendPrintfToObj(appendObj, "%%v%u", duiPtr->varIndices[i]); } } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
2456 2457 2458 2459 2460 2461 2462 | /* * We parse the variable list argument words and create two arrays: * varcList[i] is number of variables in i-th var list. * varvList[i] points to array of var names in i-th var list. */ | | | 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 | /* * We parse the variable list argument words and create two arrays: * varcList[i] is number of variables in i-th var list. * varvList[i] points to array of var names in i-th var list. */ size_t *varcList; const char ***varvList; /* * If the foreach command isn't in a procedure, don't compile it inline: * the payoff is too small. */ |
︙ | ︙ | |||
2491 2492 2493 2494 2495 2496 2497 | } /* * Allocate storage for the varcList and varvList arrays if necessary. */ numLists = (numWords - 2)/2; | | | | 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 | } /* * Allocate storage for the varcList and varvList arrays if necessary. */ numLists = (numWords - 2)/2; varcList = TclStackAlloc(interp, numLists * sizeof(size_t)); memset(varcList, 0, numLists * sizeof(size_t)); varvList = (const char ***) TclStackAlloc(interp, numLists * sizeof(const char **)); memset((char*) varvList, 0, numLists * sizeof(const char **)); /* * Break up each var list and set the varcList and varvList arrays. Don't * compile the foreach inline if any var name needs substitutions or isn't |
︙ | ︙ | |||
2859 2860 2861 2862 2863 2864 2865 | ByteCode *codePtr, unsigned int pcOffset) { register ForeachInfo *infoPtr = clientData; register ForeachVarList *varsPtr; int i, j; | | | | | | | 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 | ByteCode *codePtr, unsigned int pcOffset) { register ForeachInfo *infoPtr = clientData; register ForeachVarList *varsPtr; int i, j; Tcl_AppendToObj(appendObj, "data=[", TCL_STRLEN); for (i=0 ; i<infoPtr->numLists ; i++) { if (i) { Tcl_AppendToObj(appendObj, ", ", TCL_STRLEN); } Tcl_AppendPrintfToObj(appendObj, "%%v%u", (unsigned) (infoPtr->firstValueTemp + i)); } Tcl_AppendPrintfToObj(appendObj, "], loop=%%v%u", (unsigned) infoPtr->loopCtTemp); for (i=0 ; i<infoPtr->numLists ; i++) { if (i) { Tcl_AppendToObj(appendObj, ",", TCL_STRLEN); } Tcl_AppendPrintfToObj(appendObj, "\n\t\t it%%v%u\t[", (unsigned) (infoPtr->firstValueTemp + i)); varsPtr = infoPtr->varLists[i]; for (j=0 ; j<varsPtr->numVars ; j++) { if (j) { Tcl_AppendToObj(appendObj, ", ", TCL_STRLEN); } Tcl_AppendPrintfToObj(appendObj, "%%v%u", (unsigned) varsPtr->varIndexes[j]); } Tcl_AppendToObj(appendObj, "]", TCL_STRLEN); } } /* *---------------------------------------------------------------------- * * TclCompileFormatCmd -- |
︙ | ︙ | |||
2920 2921 2922 2923 2924 2925 2926 | * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = parsePtr->tokenPtr; Tcl_Obj **objv, *formatObj, *tmpObj; char *bytes, *start; | | | 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 | * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr = parsePtr->tokenPtr; Tcl_Obj **objv, *formatObj, *tmpObj; char *bytes, *start; size_t i, j, len; /* * Don't handle any guaranteed-error cases. */ if (parsePtr->numWords < 2) { return TCL_ERROR; |
︙ | ︙ | |||
2960 2961 2962 2963 2964 2965 2966 | /* * Everything is a literal, so the result is constant too (or an error if * the format is broken). Do the format now. */ tmpObj = Tcl_Format(interp, Tcl_GetString(formatObj), parsePtr->numWords-2, objv); | | | 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 | /* * Everything is a literal, so the result is constant too (or an error if * the format is broken). Do the format now. */ tmpObj = Tcl_Format(interp, Tcl_GetString(formatObj), parsePtr->numWords-2, objv); while (i --> 0) { Tcl_DecrRefCount(objv[i]); } ckfree(objv); Tcl_DecrRefCount(formatObj); if (tmpObj == NULL) { TclCompileSyntaxError(interp, envPtr); return TCL_OK; |
︙ | ︙ | |||
2990 2991 2992 2993 2994 2995 2996 | * requires that all the % sequences be %s or %%, as everything else is * sufficiently complex that we don't bother. * * First, get the state of the system relatively sensible (cleaning up * after our attempt to spot a literal). */ | | | 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 | * requires that all the % sequences be %s or %%, as everything else is * sufficiently complex that we don't bother. * * First, get the state of the system relatively sensible (cleaning up * after our attempt to spot a literal). */ for (; i --> 0 ;) { Tcl_DecrRefCount(objv[i]); } ckfree(objv); tokenPtr = TokenAfter(parsePtr->tokenPtr); tokenPtr = TokenAfter(tokenPtr); i = 0; |
︙ | ︙ |
Changes to generic/tclCompCmdsGR.c.
︙ | ︙ | |||
23 24 25 26 27 28 29 | */ static void CompileReturnInternal(CompileEnv *envPtr, unsigned char op, int code, int level, Tcl_Obj *returnOpts); static int IndexTailVarIfKnown(Tcl_Interp *interp, Tcl_Token *varTokenPtr, CompileEnv *envPtr); | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 23 24 25 26 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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | */ static void CompileReturnInternal(CompileEnv *envPtr, unsigned char op, int code, int level, Tcl_Obj *returnOpts); static int IndexTailVarIfKnown(Tcl_Interp *interp, Tcl_Token *varTokenPtr, CompileEnv *envPtr); /* * Simple parser for list indices. */ static inline int ParseIndex( Tcl_Token *tokenPtr, int *indexPtr) { Tcl_Obj *tmpObj = Tcl_NewStringObj(tokenPtr[1].start, tokenPtr[1].size); int result, idx; ssize_t bigidx; result = TclGetIntFromObj(NULL, tmpObj, &idx); if (result == TCL_OK) { if (idx < 0) { result = TCL_ERROR; } else { *indexPtr = idx; } } else { result = TclGetIntForIndexM(NULL, tmpObj, -2, &bigidx); if (result == TCL_OK) { if (bigidx > -2 || bigidx < INT_MIN) { result = TCL_ERROR; } else { *indexPtr = (int) bigidx; } } } TclDecrRefCount(tmpObj); return result; } /* *---------------------------------------------------------------------- * * TclCompileGlobalCmd -- * * Procedure called to compile the "global" command. |
︙ | ︙ | |||
1075 1076 1077 1078 1079 1080 1081 | valTokenPtr = TokenAfter(parsePtr->tokenPtr); if (numWords != 3) { goto emitComplexLindex; } idxTokenPtr = TokenAfter(valTokenPtr); if (idxTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) { | < | < < | < < < < < < < < < < < < | 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 | valTokenPtr = TokenAfter(parsePtr->tokenPtr); if (numWords != 3) { goto emitComplexLindex; } idxTokenPtr = TokenAfter(valTokenPtr); if (idxTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) { int idx; if (ParseIndex(idxTokenPtr, &idx) == TCL_OK) { /* * All checks have been completed, and we have exactly one of * these constructs: * lindex <arbitraryValue> <posInt> * lindex <arbitraryValue> end-<posInt> * This is best compiled as a push of the arbitrary value followed * by an "immediate lindex" which is the most efficient variety. |
︙ | ︙ | |||
1198 1199 1200 1201 1202 1203 1204 | Tcl_DecrRefCount(objPtr); Tcl_DecrRefCount(listObj); listObj = NULL; } valueTokenPtr = TokenAfter(valueTokenPtr); } if (listObj != NULL) { | | | 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 | Tcl_DecrRefCount(objPtr); Tcl_DecrRefCount(listObj); listObj = NULL; } valueTokenPtr = TokenAfter(valueTokenPtr); } if (listObj != NULL) { size_t len; const char *bytes = Tcl_GetStringFromObj(listObj, &len); PushLiteral(envPtr, bytes, len); Tcl_DecrRefCount(listObj); if (len > 0) { /* * Force list interpretation! |
︙ | ︙ | |||
1326 1327 1328 1329 1330 1331 1332 | * command. */ Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds the resulting instructions. */ { Tcl_Token *tokenPtr, *listTokenPtr; DefineLineInformation; /* TIP #280 */ | < | < < < < < < < < < < < < < | < < < < < < < < < < < < < | | 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 | * command. */ Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds the resulting instructions. */ { Tcl_Token *tokenPtr, *listTokenPtr; DefineLineInformation; /* TIP #280 */ int idx1, idx2; if (parsePtr->numWords != 4) { return TCL_ERROR; } listTokenPtr = TokenAfter(parsePtr->tokenPtr); /* * Parse the first index. Will only compile if it is constant and not an * _integer_ less than zero (since we reserve negative indices here for * end-relative indexing). */ tokenPtr = TokenAfter(listTokenPtr); if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { return TCL_ERROR; } if (ParseIndex(tokenPtr, &idx1) != TCL_OK) { return TCL_ERROR; } /* * Parse the second index. Will only compile if it is constant and not an * _integer_ less than zero (since we reserve negative indices here for * end-relative indexing). */ tokenPtr = TokenAfter(tokenPtr); if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { return TCL_ERROR; } if (ParseIndex(tokenPtr, &idx2) != TCL_OK) { return TCL_ERROR; } /* * Issue instructions. It's not safe to skip doing the LIST_RANGE, as * we've not proved that the 'list' argument is really a list. Not that it * is worth trying to do that given current knowledge. |
︙ | ︙ | |||
1425 1426 1427 1428 1429 1430 1431 | * command. */ Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds the resulting instructions. */ { Tcl_Token *tokenPtr, *listTokenPtr; DefineLineInformation; /* TIP #280 */ | < | < < < < < < < < < < < < < | < < < < < < < < < < < < < | | 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 | * command. */ Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds the resulting instructions. */ { Tcl_Token *tokenPtr, *listTokenPtr; DefineLineInformation; /* TIP #280 */ int idx1, idx2, guaranteedDropAll = 0; if (parsePtr->numWords != 4) { return TCL_ERROR; } listTokenPtr = TokenAfter(parsePtr->tokenPtr); /* * Parse the first index. Will only compile if it is constant and not an * _integer_ less than zero (since we reserve negative indices here for * end-relative indexing). */ tokenPtr = TokenAfter(listTokenPtr); if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { return TCL_ERROR; } if (ParseIndex(tokenPtr, &idx1) != TCL_OK) { return TCL_ERROR; } /* * Parse the second index. Will only compile if it is constant and not an * _integer_ less than zero (since we reserve negative indices here for * end-relative indexing). */ tokenPtr = TokenAfter(tokenPtr); if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { return TCL_ERROR; } if (ParseIndex(tokenPtr, &idx2) != TCL_OK) { return TCL_ERROR; } /* * Sanity check: can only issue when we're removing a range at one or * other end of the list. If we're at one end or the other, convert the * indices into the equivalent for an [lrange]. |
︙ | ︙ | |||
2185 2186 2187 2188 2189 2190 2191 | */ DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr, *stringTokenPtr; Tcl_Obj *patternObj = NULL, *replacementObj = NULL; Tcl_DString pattern; const char *bytes; | > | | 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 | */ DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr, *stringTokenPtr; Tcl_Obj *patternObj = NULL, *replacementObj = NULL; Tcl_DString pattern; const char *bytes; size_t len; int exact, result = TCL_ERROR; if (parsePtr->numWords < 5 || parsePtr->numWords > 6) { return TCL_ERROR; } /* * Parse the "-all", which must be the first argument (other options not |
︙ | ︙ | |||
2338 2339 2340 2341 2342 2343 2344 | * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { /* * General syntax: [return ?-option value ...? ?result?] * An even number of words means an explicit result argument is present. */ | | | | 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 | * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { /* * General syntax: [return ?-option value ...? ?result?] * An even number of words means an explicit result argument is present. */ int level, code, objc, status = TCL_OK, numWords = parsePtr->numWords; size_t size; int explicitResult = (0 == (numWords % 2)); int numOptionWords = numWords - 1 - explicitResult; Tcl_Obj *returnOpts, **objv; Tcl_Token *wordTokenPtr = TokenAfter(parsePtr->tokenPtr); DefineLineInformation; /* TIP #280 */ /* |
︙ | ︙ | |||
2528 2529 2530 2531 2532 2533 2534 | void TclCompileSyntaxError( Tcl_Interp *interp, CompileEnv *envPtr) { Tcl_Obj *msg = Tcl_GetObjResult(interp); | | | 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 | void TclCompileSyntaxError( Tcl_Interp *interp, CompileEnv *envPtr) { Tcl_Obj *msg = Tcl_GetObjResult(interp); size_t numBytes; const char *bytes = TclGetStringFromObj(msg, &numBytes); TclErrorStackResetIf(interp, bytes, numBytes); TclEmitPush(TclRegisterNewLiteral(envPtr, bytes, numBytes), envPtr); CompileReturnInternal(envPtr, INST_SYNTAX, TCL_ERROR, 0, TclNoErrorStack(interp, Tcl_GetReturnOptions(interp, TCL_ERROR))); Tcl_ResetResult(interp); |
︙ | ︙ | |||
2758 2759 2760 2761 2762 2763 2764 | IndexTailVarIfKnown( Tcl_Interp *interp, Tcl_Token *varTokenPtr, /* Token representing the variable name */ CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Obj *tailPtr; const char *tailName, *p; | | | | 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 | IndexTailVarIfKnown( Tcl_Interp *interp, Tcl_Token *varTokenPtr, /* Token representing the variable name */ CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Obj *tailPtr; const char *tailName, *p; size_t len; Tcl_Token *lastTokenPtr; int full, localIndex, n = varTokenPtr->numComponents; /* * Determine if the tail is (a) known at compile time, and (b) not an * array element. Should any of these fail, return an error so that the * non-compiled command will be called at runtime. * * In order for the tail to be known at compile time, the last token in |
︙ | ︙ |
Changes to generic/tclCompCmdsSZ.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | static int CompileUnaryOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, int instruction, CompileEnv *envPtr); static void IssueSwitchChainedTests(Tcl_Interp *interp, CompileEnv *envPtr, int mode, int noCase, int valueIndex, int numWords, Tcl_Token **bodyToken, int *bodyLines, | | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | static int CompileUnaryOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, int instruction, CompileEnv *envPtr); static void IssueSwitchChainedTests(Tcl_Interp *interp, CompileEnv *envPtr, int mode, int noCase, int valueIndex, int numWords, Tcl_Token **bodyToken, int *bodyLines, ssize_t **bodyContLines); static void IssueSwitchJumpTable(Tcl_Interp *interp, CompileEnv *envPtr, int valueIndex, int numWords, Tcl_Token **bodyToken, int *bodyLines, ssize_t **bodyContLines); static int IssueTryClausesInstructions(Tcl_Interp *interp, CompileEnv *envPtr, Tcl_Token *bodyToken, int numHandlers, int *matchCodes, Tcl_Obj **matchClauses, int *resultVarIndices, int *optionVarIndices, Tcl_Token **handlerTokens); static int IssueTryClausesFinallyInstructions(Tcl_Interp *interp, CompileEnv *envPtr, Tcl_Token *bodyToken, |
︙ | ︙ | |||
375 376 377 378 379 380 381 | * created by Tcl_ParseCommand. */ Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; | | > | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | * created by Tcl_ParseCommand. */ Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; int i, exactMatch = 0, nocase = 0; const char *str; size_t length; if (parsePtr->numWords < 3 || parsePtr->numWords > 4) { return TCL_ERROR; } tokenPtr = TokenAfter(parsePtr->tokenPtr); /* |
︙ | ︙ | |||
498 499 500 501 502 503 504 | * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *mapTokenPtr, *stringTokenPtr; Tcl_Obj *mapObj, **objv; char *bytes; | | | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *mapTokenPtr, *stringTokenPtr; Tcl_Obj *mapObj, **objv; char *bytes; size_t len; /* * We only handle the case: * * string map {foo bar} $thing * * That is, a literal two-element list (doesn't need to be brace-quoted, |
︙ | ︙ | |||
560 561 562 563 564 565 566 | Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *stringTokenPtr, *fromTokenPtr, *toTokenPtr; Tcl_Obj *tmpObj; | | > | | > | | | > | | 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 | Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ Tcl_Token *stringTokenPtr, *fromTokenPtr, *toTokenPtr; Tcl_Obj *tmpObj; ssize_t idx1, idx2; int intIdx1, intIdx2, result; if (parsePtr->numWords != 4) { return TCL_ERROR; } stringTokenPtr = TokenAfter(parsePtr->tokenPtr); fromTokenPtr = TokenAfter(stringTokenPtr); toTokenPtr = TokenAfter(fromTokenPtr); /* * Parse the first index. Will only compile if it is constant and not an * _integer_ less than zero (since we reserve negative indices here for * end-relative indexing). */ tmpObj = Tcl_NewObj(); result = TCL_ERROR; if (TclWordKnownAtCompileTime(fromTokenPtr, tmpObj)) { if (TclGetIntFromObj(NULL, tmpObj, &intIdx1) == TCL_OK) { if (intIdx1 >= 0) { result = TCL_OK; } idx1 = (ssize_t) intIdx1; } else if (TclGetIntForIndexM(NULL, tmpObj, -2, &idx1) == TCL_OK) { if (idx1 <= -2) { result = TCL_OK; } } } TclDecrRefCount(tmpObj); if (result != TCL_OK || idx1 < INT_MIN || idx1 > INT_MAX) { goto nonConstantIndices; } /* * Parse the second index. Will only compile if it is constant and not an * _integer_ less than zero (since we reserve negative indices here for * end-relative indexing). */ tmpObj = Tcl_NewObj(); result = TCL_ERROR; if (TclWordKnownAtCompileTime(toTokenPtr, tmpObj)) { if (TclGetIntFromObj(NULL, tmpObj, &intIdx2) == TCL_OK) { if (intIdx2 >= 0) { result = TCL_OK; } idx2 = (ssize_t) intIdx2; } else if (TclGetIntForIndexM(NULL, tmpObj, -2, &idx2) == TCL_OK) { if (idx2 <= -2) { result = TCL_OK; } } } TclDecrRefCount(tmpObj); if (result != TCL_OK || idx2 < INT_MIN || idx2 > INT_MAX) { goto nonConstantIndices; } /* * Push the operand onto the stack and then the substring operation. */ |
︙ | ︙ | |||
708 709 710 711 712 713 714 | * stored in Tcl_Tokens to point back to the same original string. */ if (wordTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) { code = TclSubstOptions(NULL, numOpts, objv, &flags); } cleanup: | | | | 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 | * stored in Tcl_Tokens to point back to the same original string. */ if (wordTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) { code = TclSubstOptions(NULL, numOpts, objv, &flags); } cleanup: while (objc --> 0) { TclDecrRefCount(objv[objc]); } TclStackFree(interp, objv); if (/*toSubst == NULL*/ code != TCL_OK) { return TCL_ERROR; } SetLineInformation(numArgs); TclSubstCompile(interp, wordTokenPtr[1].start, wordTokenPtr[1].size, flags, mapPtr->loc[eclIndex].line[numArgs], envPtr); /* TclDecrRefCount(toSubst);*/ return TCL_OK; } void TclSubstCompile( Tcl_Interp *interp, const char *bytes, size_t numBytes, int flags, int line, CompileEnv *envPtr) { Tcl_Token *endTokenPtr, *tokenPtr; int breakOffset = 0, count = 0, bline = line; Tcl_Parse parse; |
︙ | ︙ | |||
1010 1011 1012 1013 1014 1015 1016 | enum {Switch_Exact, Switch_Glob, Switch_Regexp} mode; /* What kind of switch are we doing? */ Tcl_Token *bodyTokenArray; /* Array of real pattern list items. */ Tcl_Token **bodyToken; /* Array of pointers to pattern list items. */ int *bodyLines; /* Array of line numbers for body list * items. */ | | | | 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 | enum {Switch_Exact, Switch_Glob, Switch_Regexp} mode; /* What kind of switch are we doing? */ Tcl_Token *bodyTokenArray; /* Array of real pattern list items. */ Tcl_Token **bodyToken; /* Array of pointers to pattern list items. */ int *bodyLines; /* Array of line numbers for body list * items. */ ssize_t **bodyContLines; /* Array of continuation line info. */ int noCase; /* Has the -nocase flag been given? */ int foundMode = 0; /* Have we seen a mode flag yet? */ int i, valueIndex; int result = TCL_ERROR; DefineLineInformation; /* TIP #280 */ ssize_t *clNext = envPtr->clNext; /* * Only handle the following versions: * switch ?--? word {pattern body ...} * switch -exact ?--? word {pattern body ...} * switch -glob ?--? word {pattern body ...} * switch -regexp ?--? word {pattern body ...} |
︙ | ︙ | |||
1174 1175 1176 1177 1178 1179 1180 | maxLen = TclMaxListLength(bytes, numBytes, NULL); if (maxLen < 2) { return TCL_ERROR; } bodyTokenArray = ckalloc(sizeof(Tcl_Token) * maxLen); bodyToken = ckalloc(sizeof(Tcl_Token *) * maxLen); bodyLines = ckalloc(sizeof(int) * maxLen); | | | 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 | maxLen = TclMaxListLength(bytes, numBytes, NULL); if (maxLen < 2) { return TCL_ERROR; } bodyTokenArray = ckalloc(sizeof(Tcl_Token) * maxLen); bodyToken = ckalloc(sizeof(Tcl_Token *) * maxLen); bodyLines = ckalloc(sizeof(int) * maxLen); bodyContLines = ckalloc(sizeof(ssize_t*) * maxLen); bline = mapPtr->loc[eclIndex].line[valueIndex+1]; numWords = 0; while (numBytes > 0) { const char *prevBytes = bytes; int literal; |
︙ | ︙ | |||
1332 1333 1334 1335 1336 1337 1338 | int valueIndex, /* The value to match against. */ int numBodyTokens, /* Number of tokens describing things the * switch can match against and bodies to * execute when the match succeeds. */ Tcl_Token **bodyToken, /* Array of pointers to pattern list items. */ int *bodyLines, /* Array of line numbers for body list * items. */ | | | 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 | int valueIndex, /* The value to match against. */ int numBodyTokens, /* Number of tokens describing things the * switch can match against and bodies to * execute when the match succeeds. */ Tcl_Token **bodyToken, /* Array of pointers to pattern list items. */ int *bodyLines, /* Array of line numbers for body list * items. */ ssize_t **bodyContLines) /* Array of continuation line info. */ { enum {Switch_Exact, Switch_Glob, Switch_Regexp}; int foundDefault; /* Flag to indicate whether a "default" clause * is present. */ JumpFixup *fixupArray; /* Array of forward-jump fixup records. */ int *fixupTargetArray; /* Array of places for fixups to point at. */ int fixupCount; /* Number of places to fix up. */ |
︙ | ︙ | |||
1581 1582 1583 1584 1585 1586 1587 | int valueIndex, /* The value to match against. */ int numBodyTokens, /* Number of tokens describing things the * switch can match against and bodies to * execute when the match succeeds. */ Tcl_Token **bodyToken, /* Array of pointers to pattern list items. */ int *bodyLines, /* Array of line numbers for body list * items. */ | | | 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 | int valueIndex, /* The value to match against. */ int numBodyTokens, /* Number of tokens describing things the * switch can match against and bodies to * execute when the match succeeds. */ Tcl_Token **bodyToken, /* Array of pointers to pattern list items. */ int *bodyLines, /* Array of line numbers for body list * items. */ ssize_t **bodyContLines) /* Array of continuation line info. */ { JumptableInfo *jtPtr; int infoIndex, isNew, *finalFixups, numRealBodies = 0, jumpLocation; int mustGenerate, foundDefault, jumpToDefault, i; Tcl_DString buffer; Tcl_HashEntry *hPtr; |
︙ | ︙ | |||
1813 1814 1815 1816 1817 1818 1819 | hPtr = Tcl_FirstHashEntry(&jtPtr->hashTable, &search); for (; hPtr ; hPtr = Tcl_NextHashEntry(&search)) { keyPtr = Tcl_GetHashKey(&jtPtr->hashTable, hPtr); offset = PTR2INT(Tcl_GetHashValue(hPtr)); if (i++) { | | | | 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 | hPtr = Tcl_FirstHashEntry(&jtPtr->hashTable, &search); for (; hPtr ; hPtr = Tcl_NextHashEntry(&search)) { keyPtr = Tcl_GetHashKey(&jtPtr->hashTable, hPtr); offset = PTR2INT(Tcl_GetHashValue(hPtr)); if (i++) { Tcl_AppendToObj(appendObj, ", ", TCL_STRLEN); if (i%4==0) { Tcl_AppendToObj(appendObj, "\n\t\t", TCL_STRLEN); } } Tcl_AppendPrintfToObj(appendObj, "\"%s\"->pc %d", keyPtr, pcOffset + offset); } } |
︙ | ︙ | |||
1898 1899 1900 1901 1902 1903 1904 | Tcl_Parse *parsePtr, /* Points to a parse structure for the command * created by Tcl_ParseCommand. */ Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ | | | | 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 | Tcl_Parse *parsePtr, /* Points to a parse structure for the command * created by Tcl_ParseCommand. */ Command *cmdPtr, /* Points to defintion of command being * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ int codeKnown, codeIsList, codeIsValid, numWords = parsePtr->numWords; Tcl_Token *codeToken, *msgToken; Tcl_Obj *objPtr; size_t len; if (numWords != 3) { return TCL_ERROR; } codeToken = TokenAfter(parsePtr->tokenPtr); msgToken = TokenAfter(codeToken); |
︙ | ︙ | |||
2043 2044 2045 2046 2047 2048 2049 | memset(matchClauses, 0, sizeof(Tcl_Obj *) * numHandlers); matchCodes = TclStackAlloc(interp, sizeof(int) * numHandlers); resultVarIndices = TclStackAlloc(interp, sizeof(int) * numHandlers); optionVarIndices = TclStackAlloc(interp, sizeof(int) * numHandlers); for (i=0 ; i<numHandlers ; i++) { Tcl_Obj *tmpObj, **objv; | | | 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 | memset(matchClauses, 0, sizeof(Tcl_Obj *) * numHandlers); matchCodes = TclStackAlloc(interp, sizeof(int) * numHandlers); resultVarIndices = TclStackAlloc(interp, sizeof(int) * numHandlers); optionVarIndices = TclStackAlloc(interp, sizeof(int) * numHandlers); for (i=0 ; i<numHandlers ; i++) { Tcl_Obj *tmpObj, **objv; size_t objc; if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { goto failedToCompile; } if (tokenPtr[1].size == 4 && !strncmp(tokenPtr[1].start, "trap", 4)) { /* |
︙ | ︙ | |||
2108 2109 2110 2111 2112 2113 2114 | } if (Tcl_ListObjGetElements(NULL, tmpObj, &objc, &objv) != TCL_OK || (objc > 2)) { TclDecrRefCount(tmpObj); goto failedToCompile; } if (objc > 0) { | | | | 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 | } if (Tcl_ListObjGetElements(NULL, tmpObj, &objc, &objv) != TCL_OK || (objc > 2)) { TclDecrRefCount(tmpObj); goto failedToCompile; } if (objc > 0) { size_t len; const char *varname = Tcl_GetStringFromObj(objv[0], &len); resultVarIndices[i] = LocalScalar(varname, len, envPtr); if (resultVarIndices[i] < 0) { TclDecrRefCount(tmpObj); goto failedToCompile; } } else { resultVarIndices[i] = -1; } if (objc == 2) { size_t len; const char *varname = Tcl_GetStringFromObj(objv[1], &len); optionVarIndices[i] = LocalScalar(varname, len, envPtr); if (optionVarIndices[i] < 0) { TclDecrRefCount(tmpObj); goto failedToCompile; } |
︙ | ︙ | |||
2238 2239 2240 2241 2242 2243 2244 | Tcl_Obj **matchClauses, int *resultVars, int *optionVars, Tcl_Token **handlerTokens) { DefineLineInformation; /* TIP #280 */ int range, resultVar, optionsVar; | | > | 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 | Tcl_Obj **matchClauses, int *resultVars, int *optionVars, Tcl_Token **handlerTokens) { DefineLineInformation; /* TIP #280 */ int range, resultVar, optionsVar; int i, j, forwardsNeedFixing = 0, trapZero = 0, afterBody = 0; int *addrsToFix, *forwardsToFix, notCodeJumpSource, notECJumpSource; int *noError; char buf[TCL_INTEGER_SPACE]; size_t len; resultVar = AnonymousLocal(envPtr); optionsVar = AnonymousLocal(envPtr); if (resultVar < 0 || optionsVar < 0) { return TCL_ERROR; } |
︙ | ︙ | |||
2447 2448 2449 2450 2451 2452 2453 | Tcl_Obj **matchClauses, int *resultVars, int *optionVars, Tcl_Token **handlerTokens, Tcl_Token *finallyToken) /* Not NULL */ { DefineLineInformation; /* TIP #280 */ | | > | 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 | Tcl_Obj **matchClauses, int *resultVars, int *optionVars, Tcl_Token **handlerTokens, Tcl_Token *finallyToken) /* Not NULL */ { DefineLineInformation; /* TIP #280 */ int range, resultVar, optionsVar, i, j, forwardsNeedFixing = 0; int trapZero = 0, afterBody = 0, finalOK, finalError, noFinalError; int *addrsToFix, *forwardsToFix, notCodeJumpSource, notECJumpSource; char buf[TCL_INTEGER_SPACE]; size_t len; resultVar = AnonymousLocal(envPtr); optionsVar = AnonymousLocal(envPtr); if (resultVar < 0 || optionsVar < 0) { return TCL_ERROR; } |
︙ | ︙ | |||
2860 2861 2862 2863 2864 2865 2866 | continue; } } return TCL_ERROR; } if (i == 1) { const char *bytes; | | | 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 | continue; } } return TCL_ERROR; } if (i == 1) { const char *bytes; size_t len; bytes = Tcl_GetStringFromObj(leadingWord, &len); if (len == 11 && !strncmp("-nocomplain", bytes, 11)) { flags = 0; haveFlags = 1; } else if (len == 2 && !strncmp("--", bytes, 2)) { haveFlags = 1; |
︙ | ︙ | |||
3219 3220 3221 3222 3223 3224 3225 | /* TODO: Consider support for compiling expanded args. */ for (words=1 ; words<parsePtr->numWords ; words++) { tokenPtr = TokenAfter(tokenPtr); CompileWord(envPtr, tokenPtr, interp, words); } if (parsePtr->numWords <= 2) { | | | 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 | /* TODO: Consider support for compiling expanded args. */ for (words=1 ; words<parsePtr->numWords ; words++) { tokenPtr = TokenAfter(tokenPtr); CompileWord(envPtr, tokenPtr, interp, words); } if (parsePtr->numWords <= 2) { PushLiteral(envPtr, identity, strlen(identity)); words++; } if (words > 3) { /* * Reverse order of arguments to get precise agreement with [expr] in * calcuations, including roundoff errors. */ |
︙ | ︙ |
Changes to generic/tclCompExpr.c.
︙ | ︙ | |||
751 752 753 754 755 756 757 | TclParseNumber(NULL, NULL, NULL, start, scanned, &stop, TCL_PARSE_NO_WHITESPACE); if (isdigit(UCHAR(*stop)) || (stop == start + 1)) { switch (start[1]) { case 'b': Tcl_AppendToObj(post, | | > | > | > | 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 | TclParseNumber(NULL, NULL, NULL, start, scanned, &stop, TCL_PARSE_NO_WHITESPACE); if (isdigit(UCHAR(*stop)) || (stop == start + 1)) { switch (start[1]) { case 'b': Tcl_AppendToObj(post, " (invalid binary number?)", TCL_STRLEN); parsePtr->errorType = TCL_PARSE_BAD_NUMBER; errCode = "BADNUMBER"; subErrCode = "BINARY"; break; case 'o': Tcl_AppendToObj(post, " (invalid octal number?)", TCL_STRLEN); parsePtr->errorType = TCL_PARSE_BAD_NUMBER; errCode = "BADNUMBER"; subErrCode = "OCTAL"; break; default: if (isdigit(UCHAR(start[1]))) { Tcl_AppendToObj(post, " (invalid octal number?)", TCL_STRLEN); parsePtr->errorType = TCL_PARSE_BAD_NUMBER; errCode = "BADNUMBER"; subErrCode = "OCTAL"; } break; } } |
︙ | ︙ | |||
1415 1416 1417 1418 1419 1420 1421 | (start + scanned + limit > parsePtr->end) ? "" : "..."); /* * Next, append any postscript message. */ if (post != NULL) { | | | 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 | (start + scanned + limit > parsePtr->end) ? "" : "..."); /* * Next, append any postscript message. */ if (post != NULL) { Tcl_AppendToObj(msg, ";\n", TCL_STRLEN); Tcl_AppendObjToObj(msg, post); Tcl_DecrRefCount(post); } Tcl_SetObjResult(interp, msg); /* * Finally, place context information in the errorInfo. |
︙ | ︙ | |||
1813 1814 1815 1816 1817 1818 1819 | *---------------------------------------------------------------------- */ int Tcl_ParseExpr( Tcl_Interp *interp, /* Used for error reporting. */ const char *start, /* Start of source string to parse. */ | | | | | 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 | *---------------------------------------------------------------------- */ int Tcl_ParseExpr( Tcl_Interp *interp, /* Used for error reporting. */ const char *start, /* Start of source string to parse. */ size_t numBytes, /* Number of bytes in string. If ==TCL_STRLEN, * the string consists of all bytes up to the * first null character. */ Tcl_Parse *parsePtr) /* Structure to fill with information about * the parsed expression; any previous * information in the structure is ignored. */ { int code; OpNode *opTree = NULL; /* Will point to the tree of operators. */ Tcl_Obj *litList = Tcl_NewObj(); /* List to hold the literals. */ Tcl_Obj *funcList = Tcl_NewObj(); /* List to hold the functon names. */ Tcl_Parse *exprParsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse)); /* Holds the Tcl_Tokens of substitutions. */ if (numBytes == TCL_STRLEN) { numBytes = (start ? strlen(start) : 0); } code = ParseExpr(interp, start, numBytes, &opTree, litList, funcList, exprParsePtr, 1 /* parseOnly */); Tcl_DecrRefCount(funcList); Tcl_DecrRefCount(litList); |
︙ | ︙ | |||
2109 2110 2111 2112 2113 2114 2115 | *---------------------------------------------------------------------- */ void TclCompileExpr( Tcl_Interp *interp, /* Used for error reporting. */ const char *script, /* The source script to compile. */ | | | | 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 | *---------------------------------------------------------------------- */ void TclCompileExpr( Tcl_Interp *interp, /* Used for error reporting. */ const char *script, /* The source script to compile. */ size_t numBytes, /* Number of bytes in script. */ CompileEnv *envPtr, /* Holds resulting instructions. */ int optimize) /* 0 for one-off expressions. */ { OpNode *opTree = NULL; /* Will point to the tree of operators */ Tcl_Obj *litList = Tcl_NewObj(); /* List to hold the literals */ Tcl_Obj *funcList = Tcl_NewObj(); /* List to hold the functon names*/ Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse)); /* Holds the Tcl_Tokens of substitutions */ int code = ParseExpr(interp, script, numBytes, &opTree, litList, funcList, parsePtr, 0 /* parseOnly */); if (code == TCL_OK) { /* * Valid parse; compile the tree. */ size_t objc; Tcl_Obj *const *litObjv; Tcl_Obj **funcObjv; /* TIP #280 : Track Lines within the expression */ TclAdvanceLines(&envPtr->line, script, script + TclParseAllWhiteSpace(script, numBytes)); |
︙ | ︙ | |||
2260 2261 2262 2263 2264 2265 2266 | } else if (nodePtr->mark == MARK_RIGHT) { next = nodePtr->right; switch (nodePtr->lexeme) { case FUNCTION: { Tcl_DString cmdName; const char *p; | | | 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 | } else if (nodePtr->mark == MARK_RIGHT) { next = nodePtr->right; switch (nodePtr->lexeme) { case FUNCTION: { Tcl_DString cmdName; const char *p; size_t length; Tcl_DStringInit(&cmdName); TclDStringAppendLiteral(&cmdName, "tcl::mathfunc::"); p = TclGetStringFromObj(*funcObjv, &length); funcObjv++; Tcl_DStringAppend(&cmdName, p, length); TclEmitPush(TclRegisterNewCmdLiteral(envPtr, |
︙ | ︙ | |||
2419 2420 2421 2422 2423 2424 2425 | numWords = 1; /* No arguments, so just the command */ break; case OT_LITERAL: { Tcl_Obj *const *litObjv = *litObjvPtr; Tcl_Obj *literal = *litObjv; if (optimize) { | | | 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 | numWords = 1; /* No arguments, so just the command */ break; case OT_LITERAL: { Tcl_Obj *const *litObjv = *litObjvPtr; Tcl_Obj *literal = *litObjv; if (optimize) { size_t length; const char *bytes = TclGetStringFromObj(literal, &length); int index = TclRegisterNewLiteral(envPtr, bytes, length); Tcl_Obj *objPtr = TclFetchLiteral(envPtr, index); if ((objPtr->typePtr == NULL) && (literal->typePtr != NULL)) { /* * Would like to do this: |
︙ | ︙ | |||
2531 2532 2533 2534 2535 2536 2537 | *---------------------------------------------------------------------- */ int TclSingleOpCmd( ClientData clientData, Tcl_Interp *interp, | | | 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 | *---------------------------------------------------------------------- */ int TclSingleOpCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { TclOpCmdClientData *occdPtr = clientData; unsigned char lexeme; OpNode nodes[2]; Tcl_Obj *const *litObjv = objv + 1; |
︙ | ︙ | |||
2584 2585 2586 2587 2588 2589 2590 | *---------------------------------------------------------------------- */ int TclSortingOpCmd( ClientData clientData, Tcl_Interp *interp, | | | 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 | *---------------------------------------------------------------------- */ int TclSortingOpCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { int code = TCL_OK; if (objc < 3) { Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1)); } else { |
︙ | ︙ | |||
2664 2665 2666 2667 2668 2669 2670 | *---------------------------------------------------------------------- */ int TclVariadicOpCmd( ClientData clientData, Tcl_Interp *interp, | | | 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 | *---------------------------------------------------------------------- */ int TclVariadicOpCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { TclOpCmdClientData *occdPtr = clientData; unsigned char lexeme; int code; if (objc < 2) { |
︙ | ︙ | |||
2783 2784 2785 2786 2787 2788 2789 | *---------------------------------------------------------------------- */ int TclNoIdentOpCmd( ClientData clientData, Tcl_Interp *interp, | | | 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 | *---------------------------------------------------------------------- */ int TclNoIdentOpCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { TclOpCmdClientData *occdPtr = clientData; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, occdPtr->expected); return TCL_ERROR; |
︙ | ︙ |
Changes to generic/tclCompile.c.
︙ | ︙ | |||
582 583 584 585 586 587 588 | /* * TIP #280: Helper for building the per-word line information of all compiled * commands. */ static void EnterCmdWordData(ExtCmdLoc *eclPtr, int srcOffset, Tcl_Token *tokenPtr, const char *cmd, int len, | | | | 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 | /* * TIP #280: Helper for building the per-word line information of all compiled * commands. */ static void EnterCmdWordData(ExtCmdLoc *eclPtr, int srcOffset, Tcl_Token *tokenPtr, const char *cmd, int len, int numWords, int line, ssize_t *clNext, int **lines, CompileEnv *envPtr); static void ReleaseCmdWordData(ExtCmdLoc *eclPtr); /* * The structure below defines the bytecode Tcl object type by means of * procedures that can be invoked by generic object code. */ |
︙ | ︙ | |||
669 670 671 672 673 674 675 | Tcl_Obj *objPtr, /* The object to make a ByteCode object. */ CompileHookProc *hookProc, /* Procedure to invoke after compilation. */ ClientData clientData) /* Hook procedure private data. */ { Interp *iPtr = (Interp *) interp; CompileEnv compEnv; /* Compilation environment structure allocated * in frame. */ | > | | 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 | Tcl_Obj *objPtr, /* The object to make a ByteCode object. */ CompileHookProc *hookProc, /* Procedure to invoke after compilation. */ ClientData clientData) /* Hook procedure private data. */ { Interp *iPtr = (Interp *) interp; CompileEnv compEnv; /* Compilation environment structure allocated * in frame. */ size_t length; int result = TCL_OK; const char *stringPtr; Proc *procPtr = iPtr->compiledProcPtr; ContLineLoc *clLocPtr; #ifdef TCL_COMPILE_DEBUG if (!traceInitialized) { if (Tcl_LinkVar(interp, "tcl_traceCompile", |
︙ | ︙ | |||
1202 1203 1204 1205 1206 1207 1208 | || (codePtr->localCachePtr != iPtr->varFramePtr->localCachePtr)) { FreeSubstCodeInternalRep(objPtr); } } if (objPtr->typePtr != &substCodeType) { CompileEnv compEnv; | | | 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 | || (codePtr->localCachePtr != iPtr->varFramePtr->localCachePtr)) { FreeSubstCodeInternalRep(objPtr); } } if (objPtr->typePtr != &substCodeType) { CompileEnv compEnv; size_t numBytes; const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes); /* TODO: Check for more TIP 280 */ TclInitCompileEnv(interp, &compEnv, bytes, numBytes, NULL, 0); TclSubstCompile(interp, bytes, numBytes, flags, 1, &compEnv); |
︙ | ︙ | |||
1309 1310 1311 1312 1313 1314 1315 | void TclInitCompileEnv( Tcl_Interp *interp, /* The interpreter for which a CompileEnv * structure is initialized. */ register CompileEnv *envPtr,/* Points to the CompileEnv structure to * initialize. */ const char *stringPtr, /* The source string to be compiled. */ | | | 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 | void TclInitCompileEnv( Tcl_Interp *interp, /* The interpreter for which a CompileEnv * structure is initialized. */ register CompileEnv *envPtr,/* Points to the CompileEnv structure to * initialize. */ const char *stringPtr, /* The source string to be compiled. */ size_t numBytes, /* Number of bytes in source string. */ const CmdFrame *invoker, /* Location context invoking the bcc */ int word) /* Index of the word in that context getting * compiled */ { Interp *iPtr = (Interp *) interp; assert(tclInstructionTable[LAST_INST_OPCODE+1].name == NULL); |
︙ | ︙ | |||
1686 1687 1688 1689 1690 1691 1692 | static void CompileCmdLiteral( Tcl_Interp *interp, Tcl_Obj *cmdObj, CompileEnv *envPtr) { | | | 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 | static void CompileCmdLiteral( Tcl_Interp *interp, Tcl_Obj *cmdObj, CompileEnv *envPtr) { size_t numBytes; const char *bytes = Tcl_GetStringFromObj(cmdObj, &numBytes); int cmdLitIdx = TclRegisterNewCmdLiteral(envPtr, bytes, numBytes); Command *cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, cmdObj); if (cmdPtr) { TclSetCmdNameObj(interp, TclFetchLiteral(envPtr, cmdLitIdx), cmdPtr); } |
︙ | ︙ | |||
1897 1898 1899 1900 1901 1902 1903 | ExtCmdLoc *eclPtr = envPtr->extCmdMapPtr; Tcl_Obj *cmdObj = Tcl_NewObj(); Command *cmdPtr = NULL; int code = TCL_ERROR; int cmdKnown, expand = -1; int *wlines, wlineat; int cmdLine = envPtr->line; | | | 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 | ExtCmdLoc *eclPtr = envPtr->extCmdMapPtr; Tcl_Obj *cmdObj = Tcl_NewObj(); Command *cmdPtr = NULL; int code = TCL_ERROR; int cmdKnown, expand = -1; int *wlines, wlineat; int cmdLine = envPtr->line; ssize_t *clNext = envPtr->clNext; int cmdIdx = envPtr->numCommands; int startCodeOffset = envPtr->codeNext - envPtr->codeStart; assert (parsePtr->numWords > 0); /* Pre-Compile */ |
︙ | ︙ | |||
2001 2002 2003 2004 2005 2006 2007 | void TclCompileScript( Tcl_Interp *interp, /* Used for error and status reporting. Also * serves as context for finding and compiling * commands. May not be NULL. */ const char *script, /* The source script to compile. */ | | | | | 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 | void TclCompileScript( Tcl_Interp *interp, /* Used for error and status reporting. Also * serves as context for finding and compiling * commands. May not be NULL. */ const char *script, /* The source script to compile. */ size_t numBytes, /* Number of bytes in script. If this is equal * to TCL_STRLEN, the script consists of all * bytes up to the first null character. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { int lastCmdIdx = -1; /* Index into envPtr->cmdMapPtr of the last * command this routine compiles into bytecode. * Initial value of -1 indicates this routine * has not yet generated any bytecode. */ const char *p = script; /* Where we are in our compile. */ |
︙ | ︙ | |||
2229 2230 2231 2232 2233 2234 2235 | Tcl_DString textBuffer; /* Holds concatenated chars from adjacent * TCL_TOKEN_TEXT, TCL_TOKEN_BS tokens. */ char buffer[TCL_UTF_MAX]; int i, numObjsToConcat, length, adjust; unsigned char *entryCodeNext = envPtr->codeNext; #define NUM_STATIC_POS 20 int isLiteral, maxNumCL, numCL; | | | 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 | Tcl_DString textBuffer; /* Holds concatenated chars from adjacent * TCL_TOKEN_TEXT, TCL_TOKEN_BS tokens. */ char buffer[TCL_UTF_MAX]; int i, numObjsToConcat, length, adjust; unsigned char *entryCodeNext = envPtr->codeNext; #define NUM_STATIC_POS 20 int isLiteral, maxNumCL, numCL; ssize_t *clPosition = NULL; /* * For the handling of continuation lines in literals we first check if * this is actually a literal. For if not we can forego the additional * processing. Otherwise we pre-allocate a small table to store the * locations of all continuation lines we find in this literal, if any. * The table is extended if needed. |
︙ | ︙ | |||
2259 2260 2261 2262 2263 2264 2265 | isLiteral = 0; break; } } if (isLiteral) { maxNumCL = NUM_STATIC_POS; | | | 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 | isLiteral = 0; break; } } if (isLiteral) { maxNumCL = NUM_STATIC_POS; clPosition = ckalloc(maxNumCL * sizeof(ssize_t)); } adjust = 0; Tcl_DStringInit(&textBuffer); numObjsToConcat = 0; for ( ; count > 0; count--, tokenPtr++) { switch (tokenPtr->type) { |
︙ | ︙ | |||
2294 2295 2296 2297 2298 2299 2300 | * where the adjustment we are tracking here is taken into * account. The good thing is that we do not need a table of * everything, just the number of lines we have to add as * correction. */ if ((length == 1) && (buffer[0] == ' ') && | | | | | < | 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 | * where the adjustment we are tracking here is taken into * account. The good thing is that we do not need a table of * everything, just the number of lines we have to add as * correction. */ if ((length == 1) && (buffer[0] == ' ') && (tokenPtr->start[1] == '\n')) { if (isLiteral) { ssize_t clPos = (ssize_t) Tcl_DStringLength(&textBuffer); if (numCL >= maxNumCL) { maxNumCL *= 2; clPosition = ckrealloc(clPosition, maxNumCL * sizeof(ssize_t)); } clPosition[numCL++] = clPos; } adjust++; } break; case TCL_TOKEN_COMMAND: /* |
︙ | ︙ | |||
2358 2359 2360 2361 2362 2363 2364 | numObjsToConcat++; count -= tokenPtr->numComponents; tokenPtr += tokenPtr->numComponents; break; default: Tcl_Panic("Unexpected token type in TclCompileTokens: %d; %.*s", | | | 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 | numObjsToConcat++; count -= tokenPtr->numComponents; tokenPtr += tokenPtr->numComponents; break; default: Tcl_Panic("Unexpected token type in TclCompileTokens: %d; %.*s", tokenPtr->type, (int) tokenPtr->size, tokenPtr->start); } } /* * Push any accumulated characters appearing at the end. */ |
︙ | ︙ | |||
2680 2681 2682 2683 2684 2685 2686 | p += TCL_ALIGN(codeBytes); /* align object array */ codePtr->objArrayPtr = (Tcl_Obj **) p; for (i = 0; i < numLitObjects; i++) { Tcl_Obj *fetched = TclFetchLiteral(envPtr, i); if (objPtr == fetched) { /* | | | | | > | | 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 | p += TCL_ALIGN(codeBytes); /* align object array */ codePtr->objArrayPtr = (Tcl_Obj **) p; for (i = 0; i < numLitObjects; i++) { Tcl_Obj *fetched = TclFetchLiteral(envPtr, i); if (objPtr == fetched) { /* * Prevent circular reference where the bytecode intrep of a value * contains a literal which is that same value. If this is allowed * to happen, refcount decrements may not reach zero, and memory * may leak. Bugs 467523, 3357771 * * NOTE: [Bugs 3392070, 3389764] We make a copy based completely * on the string value, and do not call Tcl_DuplicateObj() so we * can be sure we do not have any lingering cycles hiding in * the intrep. */ size_t numBytes; const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes); codePtr->objArrayPtr[i] = Tcl_NewStringObj(bytes, numBytes); Tcl_IncrRefCount(codePtr->objArrayPtr[i]); TclReleaseLiteral((Tcl_Interp *)iPtr, objPtr); } else { codePtr->objArrayPtr[i] = fetched; |
︙ | ︙ | |||
2794 2795 2796 2797 2798 2799 2800 | */ int TclFindCompiledLocal( register const char *name, /* Points to first character of the name of a * scalar or array variable. If NULL, a * temporary var should be created. */ | | | 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 | */ int TclFindCompiledLocal( register const char *name, /* Points to first character of the name of a * scalar or array variable. If NULL, a * temporary var should be created. */ size_t nameBytes, /* Number of bytes in the name. */ int create, /* If 1, allocate a local frame entry for the * variable if it is new. */ CompileEnv *envPtr) /* Points to the current compile environment*/ { register CompiledLocal *localPtr; int localVar = -1; register int i; |
︙ | ︙ | |||
2820 2821 2822 2823 2824 2825 2826 | * Compiling a non-body script: give it read access to the LVT in the * current localCache */ LocalCache *cachePtr = envPtr->iPtr->varFramePtr->localCachePtr; const char *localName; Tcl_Obj **varNamePtr; | | | 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 | * Compiling a non-body script: give it read access to the LVT in the * current localCache */ LocalCache *cachePtr = envPtr->iPtr->varFramePtr->localCachePtr; const char *localName; Tcl_Obj **varNamePtr; size_t len; if (!cachePtr || !name) { return -1; } varNamePtr = &cachePtr->varName0; for (i=0; i < cachePtr->numVars; varNamePtr++, i++) { |
︙ | ︙ | |||
3099 3100 3101 3102 3103 3104 3105 | * information. */ int srcOffset, /* Offset of first char of the command. */ Tcl_Token *tokenPtr, const char *cmd, int len, int numWords, int line, | | | > | 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 | * information. */ int srcOffset, /* Offset of first char of the command. */ Tcl_Token *tokenPtr, const char *cmd, int len, int numWords, int line, ssize_t *clNext, int **wlines, CompileEnv *envPtr) { ECL *ePtr; const char *last; int wordIdx, wordLine, *wwlines; ssize_t *wordNext; if (eclPtr->nuloc >= eclPtr->nloc) { /* * Expand the ECL array by allocating more storage from the heap. The * currently allocated ECL entries are stored from eclPtr->loc[0] up * to eclPtr->loc[eclPtr->nuloc-1] (inclusive). */ |
︙ | ︙ | |||
4448 4449 4450 4451 4452 4453 4454 | sprintf(ptrBuf1, "%p", codePtr); sprintf(ptrBuf2, "%p", iPtr); Tcl_AppendPrintfToObj(bufferObj, "ByteCode 0x%s, refCt %u, epoch %u, interp 0x%s (epoch %u)\n", ptrBuf1, codePtr->refCount, codePtr->compileEpoch, ptrBuf2, iPtr->compileEpoch); | | | 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 | sprintf(ptrBuf1, "%p", codePtr); sprintf(ptrBuf2, "%p", iPtr); Tcl_AppendPrintfToObj(bufferObj, "ByteCode 0x%s, refCt %u, epoch %u, interp 0x%s (epoch %u)\n", ptrBuf1, codePtr->refCount, codePtr->compileEpoch, ptrBuf2, iPtr->compileEpoch); Tcl_AppendToObj(bufferObj, " Source ", TCL_STRLEN); PrintSourceToObj(bufferObj, codePtr->source, TclMin(codePtr->numSrcBytes, 55)); Tcl_AppendPrintfToObj(bufferObj, "\n Cmds %d, src %d, inst %d, litObjs %u, aux %d, stkDepth %u, code/src %.2f\n", numCmds, codePtr->numSrcBytes, codePtr->numCodeBytes, codePtr->numLitObjects, codePtr->numAuxDataItems, codePtr->maxStackDepth, |
︙ | ︙ | |||
4486 4487 4488 4489 4490 4491 4492 | if (codePtr->procPtr != NULL) { Proc *procPtr = codePtr->procPtr; int numCompiledLocals = procPtr->numCompiledLocals; sprintf(ptrBuf1, "%p", procPtr); Tcl_AppendPrintfToObj(bufferObj, | | | | 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 | if (codePtr->procPtr != NULL) { Proc *procPtr = codePtr->procPtr; int numCompiledLocals = procPtr->numCompiledLocals; sprintf(ptrBuf1, "%p", procPtr); Tcl_AppendPrintfToObj(bufferObj, " Proc 0x%s, refCt %d, args %lu, compiled locals %d\n", ptrBuf1, procPtr->refCount, procPtr->numArgs, numCompiledLocals); if (numCompiledLocals > 0) { CompiledLocal *localPtr = procPtr->firstLocalPtr; for (i = 0; i < numCompiledLocals; i++) { Tcl_AppendPrintfToObj(bufferObj, " slot %d%s%s%s%s%s%s", i, (localPtr->flags & (VAR_ARRAY|VAR_LINK)) ? "" : ", scalar", (localPtr->flags & VAR_ARRAY) ? ", array" : "", (localPtr->flags & VAR_LINK) ? ", link" : "", (localPtr->flags & VAR_ARGUMENT) ? ", arg" : "", (localPtr->flags & VAR_TEMPORARY) ? ", temp" : "", (localPtr->flags & VAR_RESOLVED) ? ", resolved" : ""); if (TclIsVarTemporary(localPtr)) { Tcl_AppendToObj(bufferObj, "\n", TCL_STRLEN); } else { Tcl_AppendPrintfToObj(bufferObj, ", \"%s\"\n", localPtr->name); } localPtr = localPtr->nextPtr; } } |
︙ | ︙ | |||
4552 4553 4554 4555 4556 4557 4558 | * If there were no commands (e.g., an expression or an empty string was * compiled), just print all instructions and return. */ if (numCmds == 0) { pc = codeStart; while (pc < codeLimit) { | | | 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 | * If there were no commands (e.g., an expression or an empty string was * compiled), just print all instructions and return. */ if (numCmds == 0) { pc = codeStart; while (pc < codeLimit) { Tcl_AppendToObj(bufferObj, " ", TCL_STRLEN); pc += FormatInstruction(codePtr, pc, bufferObj); } return bufferObj; } /* * Print table showing the code offset, source offset, and source length |
︙ | ︙ | |||
4614 4615 4616 4617 4618 4619 4620 | Tcl_AppendPrintfToObj(bufferObj, "%s%4d: pc %d-%d, src %d-%d", ((i % 2)? " " : "\n "), (i+1), codeOffset, (codeOffset + codeLen - 1), srcOffset, (srcOffset + srcLen - 1)); } if (numCmds > 0) { | | | 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 | Tcl_AppendPrintfToObj(bufferObj, "%s%4d: pc %d-%d, src %d-%d", ((i % 2)? " " : "\n "), (i+1), codeOffset, (codeOffset + codeLen - 1), srcOffset, (srcOffset + srcLen - 1)); } if (numCmds > 0) { Tcl_AppendToObj(bufferObj, "\n", TCL_STRLEN); } /* * Print each instruction. If the instruction corresponds to the start of * a command, print the command's source. Note that we don't need the code * length here. */ |
︙ | ︙ | |||
4663 4664 4665 4666 4667 4668 4669 | } /* * Print instructions before command i. */ while ((pc-codeStart) < codeOffset) { | | | | | 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 | } /* * Print instructions before command i. */ while ((pc-codeStart) < codeOffset) { Tcl_AppendToObj(bufferObj, " ", TCL_STRLEN); pc += FormatInstruction(codePtr, pc, bufferObj); } Tcl_AppendPrintfToObj(bufferObj, " Command %d: ", i+1); PrintSourceToObj(bufferObj, (codePtr->source + srcOffset), TclMin(srcLen, 55)); Tcl_AppendToObj(bufferObj, "\n", TCL_STRLEN); } if (pc < codeLimit) { /* * Print instructions after the last command. */ while (pc < codeLimit) { Tcl_AppendToObj(bufferObj, " ", TCL_STRLEN); pc += FormatInstruction(codePtr, pc, bufferObj); } } return bufferObj; } /* |
︙ | ︙ | |||
4800 4801 4802 4803 4804 4805 4806 | case OPERAND_NONE: default: break; } } if (suffixObj) { const char *bytes; | | | | | | | 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 | case OPERAND_NONE: default: break; } } if (suffixObj) { const char *bytes; size_t length; Tcl_AppendToObj(bufferObj, "\t# ", TCL_STRLEN); bytes = Tcl_GetStringFromObj(codePtr->objArrayPtr[opnd], &length); PrintSourceToObj(bufferObj, bytes, TclMin(length, 40)); } else if (suffixBuffer[0]) { Tcl_AppendPrintfToObj(bufferObj, "\t# %s", suffixBuffer); if (suffixSrc) { PrintSourceToObj(bufferObj, suffixSrc, 40); } } Tcl_AppendToObj(bufferObj, "\n", TCL_STRLEN); if (auxPtr && auxPtr->type->printProc) { Tcl_AppendToObj(bufferObj, "\t\t[", TCL_STRLEN); auxPtr->type->printProc(auxPtr->clientData, bufferObj, codePtr, pcOffset); Tcl_AppendToObj(bufferObj, "]\n", TCL_STRLEN); } return numBytes; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
4907 4908 4909 4910 4911 4912 4913 | result = iPtr->innerContext; if (Tcl_IsShared(result)) { Tcl_DecrRefCount(result); iPtr->innerContext = result = Tcl_NewListObj(objc + 1, NULL); Tcl_IncrRefCount(result); } else { | | | 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 | result = iPtr->innerContext; if (Tcl_IsShared(result)) { Tcl_DecrRefCount(result); iPtr->innerContext = result = Tcl_NewListObj(objc + 1, NULL); Tcl_IncrRefCount(result); } else { size_t len; /* * Reset while keeping the list intrep as much as possible. */ Tcl_ListObjLength(interp, result, &len); Tcl_ListObjReplace(interp, result, 0, len, 0, NULL); |
︙ | ︙ | |||
5012 5013 5014 5015 5016 5017 5018 | const char *stringPtr, /* The string to print. */ int maxChars) /* Maximum number of chars to print. */ { register const char *p; register int i = 0; if (stringPtr == NULL) { | | | | | | | | | | | 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 | const char *stringPtr, /* The string to print. */ int maxChars) /* Maximum number of chars to print. */ { register const char *p; register int i = 0; if (stringPtr == NULL) { Tcl_AppendToObj(appendObj, "\"\"", TCL_STRLEN); return; } Tcl_AppendToObj(appendObj, "\"", TCL_STRLEN); p = stringPtr; for (; (*p != '\0') && (i < maxChars); p++, i++) { switch (*p) { case '"': Tcl_AppendToObj(appendObj, "\\\"", TCL_STRLEN); continue; case '\f': Tcl_AppendToObj(appendObj, "\\f", TCL_STRLEN); continue; case '\n': Tcl_AppendToObj(appendObj, "\\n", TCL_STRLEN); continue; case '\r': Tcl_AppendToObj(appendObj, "\\r", TCL_STRLEN); continue; case '\t': Tcl_AppendToObj(appendObj, "\\t", TCL_STRLEN); continue; case '\v': Tcl_AppendToObj(appendObj, "\\v", TCL_STRLEN); continue; default: Tcl_AppendPrintfToObj(appendObj, "%c", *p); continue; } } Tcl_AppendToObj(appendObj, "\"", TCL_STRLEN); } #ifdef TCL_COMPILE_STATS /* *---------------------------------------------------------------------- * * RecordByteCodeStats -- |
︙ | ︙ |
Changes to generic/tclCompile.h.
︙ | ︙ | |||
171 172 173 174 175 176 177 | * through the 'lineBCPtr' HashTable in Interp, keyed by the address of BC. * Also recorded is information coming from the context, i.e. type of the * frame and associated information, like the path of a sourced file. */ typedef struct { int srcOffset; /* Command location to find the entry. */ | | | | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | * through the 'lineBCPtr' HashTable in Interp, keyed by the address of BC. * Also recorded is information coming from the context, i.e. type of the * frame and associated information, like the path of a sourced file. */ typedef struct { int srcOffset; /* Command location to find the entry. */ size_t nline; /* Number of words in the command */ int *line; /* Line information for all words in the * command. */ ssize_t **next; /* Transient information used by the compiler * for tracking of hidden continuation * lines. */ } ECL; typedef struct { int type; /* Context type. */ int start; /* Starting line for compiled script. Needed |
︙ | ︙ | |||
361 362 363 364 365 366 367 | * inefficient. If set to 2, that instruction * should not be issued at all (by the generic * part of the command compiler). */ int expandCount; /* Number of INST_EXPAND_START instructions * encountered that have not yet been paired * with a corresponding * INST_INVOKE_EXPANDED. */ | | | 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | * inefficient. If set to 2, that instruction * should not be issued at all (by the generic * part of the command compiler). */ int expandCount; /* Number of INST_EXPAND_START instructions * encountered that have not yet been paired * with a corresponding * INST_INVOKE_EXPANDED. */ ssize_t *clNext; /* If not NULL, it refers to the next slot in * clLoc to check for an invisible * continuation line. */ } CompileEnv; /* * The structure defining the bytecode instructions resulting from compiling a * Tcl script. Note that this structure is variable length: a single heap |
︙ | ︙ | |||
986 987 988 989 990 991 992 | MODULE_SCOPE void TclCleanupByteCode(ByteCode *codePtr); MODULE_SCOPE void TclCleanupStackForBreakContinue(CompileEnv *envPtr, ExceptionAux *auxPtr); MODULE_SCOPE void TclCompileCmdWord(Tcl_Interp *interp, Tcl_Token *tokenPtr, int count, CompileEnv *envPtr); MODULE_SCOPE void TclCompileExpr(Tcl_Interp *interp, const char *script, | | | | | | > | 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 1011 1012 1013 1014 1015 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 1046 1047 1048 1049 1050 1051 | MODULE_SCOPE void TclCleanupByteCode(ByteCode *codePtr); MODULE_SCOPE void TclCleanupStackForBreakContinue(CompileEnv *envPtr, ExceptionAux *auxPtr); MODULE_SCOPE void TclCompileCmdWord(Tcl_Interp *interp, Tcl_Token *tokenPtr, int count, CompileEnv *envPtr); MODULE_SCOPE void TclCompileExpr(Tcl_Interp *interp, const char *script, size_t numBytes, CompileEnv *envPtr, int optimize); MODULE_SCOPE void TclCompileExprWords(Tcl_Interp *interp, Tcl_Token *tokenPtr, int numWords, CompileEnv *envPtr); MODULE_SCOPE void TclCompileInvocation(Tcl_Interp *interp, Tcl_Token *tokenPtr, Tcl_Obj *cmdObj, int numWords, CompileEnv *envPtr); MODULE_SCOPE void TclCompileScript(Tcl_Interp *interp, const char *script, size_t numBytes, CompileEnv *envPtr); MODULE_SCOPE void TclCompileSyntaxError(Tcl_Interp *interp, CompileEnv *envPtr); MODULE_SCOPE void TclCompileTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr, int count, CompileEnv *envPtr); MODULE_SCOPE void TclCompileVarSubst(Tcl_Interp *interp, Tcl_Token *tokenPtr, CompileEnv *envPtr); MODULE_SCOPE int TclCreateAuxData(ClientData clientData, const AuxDataType *typePtr, CompileEnv *envPtr); MODULE_SCOPE int TclCreateExceptRange(ExceptionRangeType type, CompileEnv *envPtr); MODULE_SCOPE ExecEnv * TclCreateExecEnv(Tcl_Interp *interp, int size); MODULE_SCOPE Tcl_Obj * TclCreateLiteral(Interp *iPtr, char *bytes, size_t length, unsigned int hash, int *newPtr, Namespace *nsPtr, int flags, LiteralEntry **globalPtrPtr); MODULE_SCOPE void TclDeleteExecEnv(ExecEnv *eePtr); MODULE_SCOPE void TclDeleteLiteralTable(Tcl_Interp *interp, LiteralTable *tablePtr); MODULE_SCOPE void TclEmitForwardJump(CompileEnv *envPtr, TclJumpType jumpType, JumpFixup *jumpFixupPtr); MODULE_SCOPE ExceptionRange * TclGetExceptionRangeForPc(unsigned char *pc, int catchOnly, ByteCode *codePtr); MODULE_SCOPE void TclExpandJumpFixupArray(JumpFixupArray *fixupArrayPtr); MODULE_SCOPE int TclNRExecuteByteCode(Tcl_Interp *interp, ByteCode *codePtr); MODULE_SCOPE Tcl_Obj * TclFetchLiteral(CompileEnv *envPtr, unsigned int index); MODULE_SCOPE void TclFinalizeAuxDataTypeTable(void); MODULE_SCOPE int TclFindCompiledLocal(const char *name, size_t nameChars, int create, CompileEnv *envPtr); MODULE_SCOPE int TclFixupForwardJump(CompileEnv *envPtr, JumpFixup *jumpFixupPtr, int jumpDist, int distThreshold); MODULE_SCOPE void TclFreeCompileEnv(CompileEnv *envPtr); MODULE_SCOPE void TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr); MODULE_SCOPE void TclInitAuxDataTypeTable(void); MODULE_SCOPE void TclInitByteCodeObj(Tcl_Obj *objPtr, CompileEnv *envPtr); MODULE_SCOPE void TclInitCompileEnv(Tcl_Interp *interp, CompileEnv *envPtr, const char *string, size_t numBytes, const CmdFrame *invoker, int word); MODULE_SCOPE void TclInitJumpFixupArray(JumpFixupArray *fixupArrayPtr); MODULE_SCOPE void TclInitLiteralTable(LiteralTable *tablePtr); MODULE_SCOPE ExceptionRange *TclGetInnermostExceptionRange(CompileEnv *envPtr, int returnCode, ExceptionAux **auxPtrPtr); MODULE_SCOPE void TclAddLoopBreakFixup(CompileEnv *envPtr, ExceptionAux *auxPtr); MODULE_SCOPE void TclAddLoopContinueFixup(CompileEnv *envPtr, |
︙ | ︙ | |||
1071 1072 1073 1074 1075 1076 1077 | int flags, int *localIndexPtr, int *isScalarPtr); MODULE_SCOPE int TclRegisterLiteral(CompileEnv *envPtr, char *bytes, int length, int flags); MODULE_SCOPE void TclReleaseLiteral(Tcl_Interp *interp, Tcl_Obj *objPtr); MODULE_SCOPE void TclInvalidateCmdLiteral(Tcl_Interp *interp, const char *name, Namespace *nsPtr); | | < < | < < | < < | < < | | | | 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 | int flags, int *localIndexPtr, int *isScalarPtr); MODULE_SCOPE int TclRegisterLiteral(CompileEnv *envPtr, char *bytes, int length, int flags); MODULE_SCOPE void TclReleaseLiteral(Tcl_Interp *interp, Tcl_Obj *objPtr); MODULE_SCOPE void TclInvalidateCmdLiteral(Tcl_Interp *interp, const char *name, Namespace *nsPtr); MODULE_SCOPE Tcl_ObjCmdProc TclSingleOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclSortingOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclVariadicOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNoIdentOpCmd; #ifdef TCL_COMPILE_DEBUG MODULE_SCOPE void TclVerifyGlobalLiteralTable(Interp *iPtr); MODULE_SCOPE void TclVerifyLocalLiteralTable(CompileEnv *envPtr); #endif MODULE_SCOPE int TclWordKnownAtCompileTime(Tcl_Token *tokenPtr, Tcl_Obj *valuePtr); MODULE_SCOPE void TclLogCommandInfo(Tcl_Interp *interp, const char *script, const char *command, size_t length, const unsigned char *pc, Tcl_Obj **tosPtr); MODULE_SCOPE Tcl_Obj *TclGetInnerContext(Tcl_Interp *interp, const unsigned char *pc, Tcl_Obj **tosPtr); MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst); /* *---------------------------------------------------------------- |
︙ | ︙ | |||
1122 1123 1124 1125 1126 1127 1128 | #define LITERAL_CMD_NAME 0x02 /* * Form of TclRegisterLiteral with flags == 0. In that case, it is safe to * cast away constness, and it is cleanest to do that here, all in one place. * * int TclRegisterNewLiteral(CompileEnv *envPtr, const char *bytes, | | | | 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 | #define LITERAL_CMD_NAME 0x02 /* * Form of TclRegisterLiteral with flags == 0. In that case, it is safe to * cast away constness, and it is cleanest to do that here, all in one place. * * int TclRegisterNewLiteral(CompileEnv *envPtr, const char *bytes, * size_t length); */ #define TclRegisterNewLiteral(envPtr, bytes, length) \ TclRegisterLiteral(envPtr, (char *)(bytes), length, /*flags*/ 0) /* * Form of TclRegisterLiteral with flags == LITERAL_CMD_NAME. In that case, it * is safe to cast away constness, and it is cleanest to do that here, all in * one place. * * int TclRegisterNewNSLiteral(CompileEnv *envPtr, const char *bytes, * size_t length); */ #define TclRegisterNewCmdLiteral(envPtr, bytes, length) \ TclRegisterLiteral(envPtr, (char *)(bytes), length, LITERAL_CMD_NAME) /* * Macro used to manually adjust the stack requirements; used in cases where |
︙ | ︙ |
Changes to generic/tclConfig.c.
︙ | ︙ | |||
37 38 39 40 41 42 43 | char *encoding; } QCCD; /* * Static functions in this file: */ | | < < | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | char *encoding; } QCCD; /* * Static functions in this file: */ static Tcl_ObjCmdProc QueryConfigObjCmd; static void QueryConfigDelete(ClientData clientData); static Tcl_Obj * GetConfigDict(Tcl_Interp *interp); static void ConfigDictDeleteProc(ClientData clientData, Tcl_Interp *interp); /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
84 85 86 87 88 89 90 | cdPtr->interp = interp; if (valEncoding) { cdPtr->encoding = ckalloc(strlen(valEncoding)+1); strcpy(cdPtr->encoding, valEncoding); } else { cdPtr->encoding = NULL; } | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | cdPtr->interp = interp; if (valEncoding) { cdPtr->encoding = ckalloc(strlen(valEncoding)+1); strcpy(cdPtr->encoding, valEncoding); } else { cdPtr->encoding = NULL; } cdPtr->pkg = Tcl_NewStringObj(pkgName, TCL_STRLEN); /* * Phase I: Adding the provided information to the internal database of * package meta data. * * Phase II: Create a command for querying this database, specific to the * package registering its configuration. This is the approved interface |
︙ | ︙ | |||
121 122 123 124 125 126 127 | pkgDict = Tcl_NewDictObj(); } else if (Tcl_IsShared(pkgDict)) { pkgDict = Tcl_DuplicateObj(pkgDict); } /* * Extend the package configuration... | | | | | > | | 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 154 155 156 | pkgDict = Tcl_NewDictObj(); } else if (Tcl_IsShared(pkgDict)) { pkgDict = Tcl_DuplicateObj(pkgDict); } /* * Extend the package configuration... * We cannot assume that the encodings are initialized, therefore store * the value as-is in a byte array. See Bug [9b2e636361]. */ for (cfg=configuration ; cfg->key!=NULL && cfg->key[0]!='\0' ; cfg++) { Tcl_DictObjPut(interp, pkgDict, Tcl_NewStringObj(cfg->key,TCL_STRLEN), Tcl_NewByteArrayObj((unsigned char *) cfg->value, strlen(cfg->value))); } /* * Write the changes back into the overall database. */ Tcl_DictObjPut(interp, pDB, cdPtr->pkg, pkgDict); /* * Now create the interface command for retrieval of the package * information. */ Tcl_DStringInit(&cmdName); TclDStringAppendLiteral(&cmdName, "::"); Tcl_DStringAppend(&cmdName, pkgName, TCL_STRLEN); /* * The incomplete command name is the name of the namespace to place it * in. */ if (Tcl_FindNamespace(interp, Tcl_DStringValue(&cmdName), NULL, |
︙ | ︙ | |||
192 193 194 195 196 197 198 | *---------------------------------------------------------------------- */ static int QueryConfigObjCmd( ClientData clientData, Tcl_Interp *interp, | | | > | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | *---------------------------------------------------------------------- */ static int QueryConfigObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, struct Tcl_Obj *const *objv) { QCCD *cdPtr = clientData; Tcl_Obj *pkgName = cdPtr->pkg; Tcl_Obj *pDB, *pkgDict, *val, *listPtr; int index; size_t n; static const char *const subcmdStrings[] = { "get", "list", NULL }; enum subcmds { CFG_GET, CFG_LIST }; Tcl_DString conv; |
︙ | ︙ | |||
226 227 228 229 230 231 232 | if (Tcl_DictObjGet(interp, pDB, pkgName, &pkgDict) != TCL_OK || pkgDict == NULL) { /* * Maybe a Tcl_Panic is better, because the package data has to be * present. */ | | > | > > > | | 226 227 228 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 293 | if (Tcl_DictObjGet(interp, pDB, pkgName, &pkgDict) != TCL_OK || pkgDict == NULL) { /* * Maybe a Tcl_Panic is better, because the package data has to be * present. */ Tcl_SetObjResult(interp, Tcl_NewStringObj("package not known", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "FATAL", "PKGCFG_BASE", Tcl_GetString(pkgName), NULL); return TCL_ERROR; } switch ((enum subcmds) index) { case CFG_GET: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "key"); return TCL_ERROR; } if (Tcl_DictObjGet(interp, pkgDict, objv[2], &val) != TCL_OK || val == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("key not known", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CONFIG", Tcl_GetString(objv[2]), NULL); return TCL_ERROR; } if (cdPtr->encoding) { venc = Tcl_GetEncoding(interp, cdPtr->encoding); if (!venc) { return TCL_ERROR; } } /* * Value is stored as-is in a byte array, see Bug [9b2e636361], * so we have to decode it first. */ value = (const char *) Tcl_GetByteArrayFromObj(val, &n); value = Tcl_ExternalToUtfDString(venc, value, n, &conv); Tcl_SetObjResult(interp, Tcl_NewStringObj(value, Tcl_DStringLength(&conv))); Tcl_DStringFree(&conv); return TCL_OK; case CFG_LIST: if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); return TCL_ERROR; } Tcl_DictObjSize(interp, pkgDict, &n); listPtr = Tcl_NewListObj(n, NULL); if (!listPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "insufficient memory to create list", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); return TCL_ERROR; } if (n) { Tcl_DictSearch s; Tcl_Obj *key; |
︙ | ︙ |
Changes to generic/tclDate.c.
︙ | ︙ | |||
2499 2500 2501 2502 2503 2504 2505 | static void TclDateerror( YYLTYPE* location, DateInfo* infoPtr, const char *s) { Tcl_Obj* t; | | | | | | | 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 | static void TclDateerror( YYLTYPE* location, DateInfo* infoPtr, const char *s) { Tcl_Obj* t; Tcl_AppendToObj(infoPtr->messages, infoPtr->separatrix, TCL_STRLEN); Tcl_AppendToObj(infoPtr->messages, s, TCL_STRLEN); Tcl_AppendToObj(infoPtr->messages, " (characters ", TCL_STRLEN); t = Tcl_NewIntObj(location->first_column); Tcl_IncrRefCount(t); Tcl_AppendObjToObj(infoPtr->messages, t); Tcl_DecrRefCount(t); Tcl_AppendToObj(infoPtr->messages, "-", TCL_STRLEN); t = Tcl_NewIntObj(location->last_column); Tcl_IncrRefCount(t); Tcl_AppendObjToObj(infoPtr->messages, t); Tcl_DecrRefCount(t); Tcl_AppendToObj(infoPtr->messages, ")", TCL_STRLEN); infoPtr->separatrix = "\n"; } static time_t ToSeconds( time_t Hours, time_t Minutes, |
︙ | ︙ | |||
2747 2748 2749 2750 2751 2752 2753 | } } int TclClockOldscanObjCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 | } } int TclClockOldscanObjCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Count of parameters */ Tcl_Obj *const *objv) /* Parameters */ { Tcl_Obj *result, *resultElement; int yr, mo, da; DateInfo dateInfo; DateInfo* info = &dateInfo; int status; |
︙ | ︙ | |||
2799 2800 2801 2802 2803 2804 2805 | status = yyparse(&dateInfo); if (status == 1) { Tcl_SetObjResult(interp, dateInfo.messages); Tcl_DecrRefCount(dateInfo.messages); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "PARSE", NULL); return TCL_ERROR; } else if (status == 2) { | | > | | | < | | | | | | | | | | | 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 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 | status = yyparse(&dateInfo); if (status == 1) { Tcl_SetObjResult(interp, dateInfo.messages); Tcl_DecrRefCount(dateInfo.messages); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "PARSE", NULL); return TCL_ERROR; } else if (status == 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj("memory exhausted", TCL_STRLEN)); Tcl_DecrRefCount(dateInfo.messages); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); return TCL_ERROR; } else if (status != 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unknown status returned from date parser. Please " "report this error as a bug in Tcl.", TCL_STRLEN)); Tcl_DecrRefCount(dateInfo.messages); Tcl_SetErrorCode(interp, "TCL", "BUG", NULL); return TCL_ERROR; } Tcl_DecrRefCount(dateInfo.messages); if (yyHaveDate > 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "more than one date in string", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL); return TCL_ERROR; } if (yyHaveTime > 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "more than one time of day in string", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL); return TCL_ERROR; } if (yyHaveZone > 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "more than one time zone in string", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL); return TCL_ERROR; } if (yyHaveDay > 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "more than one weekday in string", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL); return TCL_ERROR; } if (yyHaveOrdinalMonth > 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "more than one ordinal month in string", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL); return TCL_ERROR; } result = Tcl_NewObj(); resultElement = Tcl_NewObj(); if (yyHaveDate) { |
︙ | ︙ |
Changes to generic/tclDecls.h.
︙ | ︙ | |||
31 32 33 34 35 36 37 | /* 1 */ TCLAPI const char * Tcl_PkgRequireEx(Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 2 */ TCLAPI void Tcl_Panic(const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 3 */ | | | | | | 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 | /* 1 */ TCLAPI const char * Tcl_PkgRequireEx(Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 2 */ TCLAPI void Tcl_Panic(const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 3 */ TCLAPI char * Tcl_Alloc(size_t size); /* 4 */ TCLAPI void Tcl_Free(char *ptr); /* 5 */ TCLAPI char * Tcl_Realloc(char *ptr, size_t size); /* 6 */ TCLAPI char * Tcl_DbCkalloc(size_t size, const char *file, int line); /* 7 */ TCLAPI void Tcl_DbCkfree(char *ptr, const char *file, int line); /* 8 */ TCLAPI char * Tcl_DbCkrealloc(char *ptr, size_t size, const char *file, int line); #if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */ /* 9 */ TCLAPI void Tcl_CreateFileHandler(int fd, int mask, Tcl_FileProc *proc, ClientData clientData); #endif /* UNIX */ #ifdef MAC_OSX_TCL /* MACOSX */ |
︙ | ︙ | |||
75 76 77 78 79 80 81 | /* 14 */ TCLAPI int Tcl_AppendAllObjTypes(Tcl_Interp *interp, Tcl_Obj *objPtr); /* 15 */ TCLAPI void Tcl_AppendStringsToObj(Tcl_Obj *objPtr, ...); /* 16 */ TCLAPI void Tcl_AppendToObj(Tcl_Obj *objPtr, const char *bytes, | | | | | | | | > | | | | | | | | | > | | | | | 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 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 154 155 156 157 158 159 160 161 162 163 164 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 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 217 218 219 | /* 14 */ TCLAPI int Tcl_AppendAllObjTypes(Tcl_Interp *interp, Tcl_Obj *objPtr); /* 15 */ TCLAPI void Tcl_AppendStringsToObj(Tcl_Obj *objPtr, ...); /* 16 */ TCLAPI void Tcl_AppendToObj(Tcl_Obj *objPtr, const char *bytes, size_t length); /* 17 */ TCLAPI Tcl_Obj * Tcl_ConcatObj(size_t objc, Tcl_Obj *const objv[]); /* 18 */ TCLAPI int Tcl_ConvertToType(Tcl_Interp *interp, Tcl_Obj *objPtr, const Tcl_ObjType *typePtr); /* 19 */ TCLAPI void Tcl_DbDecrRefCount(Tcl_Obj *objPtr, const char *file, int line); /* 20 */ TCLAPI void Tcl_DbIncrRefCount(Tcl_Obj *objPtr, const char *file, int line); /* 21 */ TCLAPI int Tcl_DbIsShared(Tcl_Obj *objPtr, const char *file, int line); /* 22 */ TCLAPI Tcl_Obj * Tcl_DbNewBooleanObj(int boolValue, const char *file, int line); /* 23 */ TCLAPI Tcl_Obj * Tcl_DbNewByteArrayObj(const unsigned char *bytes, size_t length, const char *file, int line); /* 24 */ TCLAPI Tcl_Obj * Tcl_DbNewDoubleObj(double doubleValue, const char *file, int line); /* 25 */ TCLAPI Tcl_Obj * Tcl_DbNewListObj(size_t objc, Tcl_Obj *const *objv, const char *file, int line); /* 26 */ TCLAPI Tcl_Obj * Tcl_DbNewLongObj(long longValue, const char *file, int line); /* 27 */ TCLAPI Tcl_Obj * Tcl_DbNewObj(const char *file, int line); /* 28 */ TCLAPI Tcl_Obj * Tcl_DbNewStringObj(const char *bytes, size_t length, const char *file, int line); /* 29 */ TCLAPI Tcl_Obj * Tcl_DuplicateObj(Tcl_Obj *objPtr); /* 30 */ TCLAPI void TclFreeObj(Tcl_Obj *objPtr); /* 31 */ TCLAPI int Tcl_GetBoolean(Tcl_Interp *interp, const char *src, int *boolPtr); /* 32 */ TCLAPI int Tcl_GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *boolPtr); /* 33 */ TCLAPI unsigned char * Tcl_GetByteArrayFromObj(Tcl_Obj *objPtr, size_t *lengthPtr); /* 34 */ TCLAPI int Tcl_GetDouble(Tcl_Interp *interp, const char *src, double *doublePtr); /* 35 */ TCLAPI int Tcl_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *doublePtr); /* Slot 36 is reserved */ /* 37 */ TCLAPI int Tcl_GetInt(Tcl_Interp *interp, const char *src, int *intPtr); /* 38 */ TCLAPI int Tcl_GetIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *intPtr); /* 39 */ TCLAPI int Tcl_GetLongFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, long *longPtr); /* 40 */ TCLAPI const Tcl_ObjType * Tcl_GetObjType(const char *typeName); /* 41 */ TCLAPI char * Tcl_GetStringFromObj(Tcl_Obj *objPtr, size_t *lengthPtr); /* 42 */ TCLAPI void Tcl_InvalidateStringRep(Tcl_Obj *objPtr); /* 43 */ TCLAPI int Tcl_ListObjAppendList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *elemListPtr); /* 44 */ TCLAPI int Tcl_ListObjAppendElement(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *objPtr); /* 45 */ TCLAPI int Tcl_ListObjGetElements(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *objcPtr, Tcl_Obj ***objvPtr); /* 46 */ TCLAPI int Tcl_ListObjIndex(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t index, Tcl_Obj **objPtrPtr); /* 47 */ TCLAPI int Tcl_ListObjLength(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *lengthPtr); /* 48 */ TCLAPI int Tcl_ListObjReplace(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t first, size_t count, size_t objc, Tcl_Obj *const objv[]); /* 49 */ TCLAPI Tcl_Obj * Tcl_NewBooleanObj(int boolValue); /* 50 */ TCLAPI Tcl_Obj * Tcl_NewByteArrayObj(const unsigned char *bytes, size_t length); /* 51 */ TCLAPI Tcl_Obj * Tcl_NewDoubleObj(double doubleValue); /* 52 */ TCLAPI Tcl_Obj * Tcl_NewIntObj(int intValue); /* 53 */ TCLAPI Tcl_Obj * Tcl_NewListObj(size_t objc, Tcl_Obj *const objv[]); /* 54 */ TCLAPI Tcl_Obj * Tcl_NewLongObj(long longValue); /* 55 */ TCLAPI Tcl_Obj * Tcl_NewObj(void); /* 56 */ TCLAPI Tcl_Obj * Tcl_NewStringObj(const char *bytes, size_t length); /* 57 */ TCLAPI void Tcl_SetBooleanObj(Tcl_Obj *objPtr, int boolValue); /* 58 */ TCLAPI unsigned char * Tcl_SetByteArrayLength(Tcl_Obj *objPtr, size_t length); /* 59 */ TCLAPI void Tcl_SetByteArrayObj(Tcl_Obj *objPtr, const unsigned char *bytes, size_t length); /* 60 */ TCLAPI void Tcl_SetDoubleObj(Tcl_Obj *objPtr, double doubleValue); /* 61 */ TCLAPI void Tcl_SetIntObj(Tcl_Obj *objPtr, int intValue); /* 62 */ TCLAPI void Tcl_SetListObj(Tcl_Obj *objPtr, size_t objc, Tcl_Obj *const objv[]); /* 63 */ TCLAPI void Tcl_SetLongObj(Tcl_Obj *objPtr, long longValue); /* 64 */ TCLAPI void Tcl_SetObjLength(Tcl_Obj *objPtr, size_t length); /* 65 */ TCLAPI void Tcl_SetStringObj(Tcl_Obj *objPtr, const char *bytes, size_t length); /* 66 */ TCLAPI void Tcl_AddErrorInfo(Tcl_Interp *interp, const char *message); /* Slot 67 is reserved */ /* 68 */ TCLAPI void Tcl_AllowExceptions(Tcl_Interp *interp); /* 69 */ |
︙ | ︙ | |||
245 246 247 248 249 250 251 | TCLAPI void Tcl_CancelIdleCall(Tcl_IdleProc *idleProc, ClientData clientData); /* 81 */ TCLAPI int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan); /* 82 */ TCLAPI int Tcl_CommandComplete(const char *cmd); /* 83 */ | | | | | | | | 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 | TCLAPI void Tcl_CancelIdleCall(Tcl_IdleProc *idleProc, ClientData clientData); /* 81 */ TCLAPI int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan); /* 82 */ TCLAPI int Tcl_CommandComplete(const char *cmd); /* 83 */ TCLAPI char * Tcl_Concat(size_t argc, const char *const *argv); /* 84 */ TCLAPI size_t Tcl_ConvertElement(const char *src, char *dst, int flags); /* 85 */ TCLAPI size_t Tcl_ConvertCountedElement(const char *src, size_t length, char *dst, int flags); /* 86 */ TCLAPI int Tcl_CreateAlias(Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, size_t argc, const char *const *argv); /* 87 */ TCLAPI int Tcl_CreateAliasObj(Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, size_t objc, Tcl_Obj *const objv[]); /* 88 */ TCLAPI Tcl_Channel Tcl_CreateChannel(const Tcl_ChannelType *typePtr, const char *chanName, ClientData instanceData, int mask); /* 89 */ TCLAPI void Tcl_CreateChannelHandler(Tcl_Channel chan, int mask, |
︙ | ︙ | |||
350 351 352 353 354 355 356 | /* 115 */ TCLAPI int Tcl_DoOneEvent(int flags); /* 116 */ TCLAPI void Tcl_DoWhenIdle(Tcl_IdleProc *proc, ClientData clientData); /* 117 */ TCLAPI char * Tcl_DStringAppend(Tcl_DString *dsPtr, | | | > | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | /* 115 */ TCLAPI int Tcl_DoOneEvent(int flags); /* 116 */ TCLAPI void Tcl_DoWhenIdle(Tcl_IdleProc *proc, ClientData clientData); /* 117 */ TCLAPI char * Tcl_DStringAppend(Tcl_DString *dsPtr, const char *bytes, size_t length); /* 118 */ TCLAPI char * Tcl_DStringAppendElement(Tcl_DString *dsPtr, const char *element); /* 119 */ TCLAPI void Tcl_DStringEndSublist(Tcl_DString *dsPtr); /* 120 */ TCLAPI void Tcl_DStringFree(Tcl_DString *dsPtr); /* 121 */ TCLAPI void Tcl_DStringGetResult(Tcl_Interp *interp, Tcl_DString *dsPtr); /* 122 */ TCLAPI void Tcl_DStringInit(Tcl_DString *dsPtr); /* 123 */ TCLAPI void Tcl_DStringResult(Tcl_Interp *interp, Tcl_DString *dsPtr); /* 124 */ TCLAPI void Tcl_DStringSetLength(Tcl_DString *dsPtr, size_t length); /* 125 */ TCLAPI void Tcl_DStringStartSublist(Tcl_DString *dsPtr); /* 126 */ TCLAPI int Tcl_Eof(Tcl_Channel chan); /* 127 */ TCLAPI const char * Tcl_ErrnoId(void); /* 128 */ |
︙ | ︙ | |||
425 426 427 428 429 430 431 | TCLAPI int Tcl_Flush(Tcl_Channel chan); /* 147 */ TCLAPI void Tcl_FreeResult(Tcl_Interp *interp); /* 148 */ TCLAPI int Tcl_GetAlias(Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, | | | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 | TCLAPI int Tcl_Flush(Tcl_Channel chan); /* 147 */ TCLAPI void Tcl_FreeResult(Tcl_Interp *interp); /* 148 */ TCLAPI int Tcl_GetAlias(Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, const char **targetCmdPtr, size_t *argcPtr, const char ***argvPtr); /* 149 */ TCLAPI int Tcl_GetAliasObj(Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, const char **targetCmdPtr, size_t *objcPtr, Tcl_Obj ***objv); /* 150 */ TCLAPI ClientData Tcl_GetAssocData(Tcl_Interp *interp, const char *name, Tcl_InterpDeleteProc **procPtr); /* 151 */ TCLAPI Tcl_Channel Tcl_GetChannel(Tcl_Interp *interp, |
︙ | ︙ | |||
491 492 493 494 495 496 497 | TCLAPI int Tcl_GetOpenFile(Tcl_Interp *interp, const char *chanID, int forWriting, int checkUsage, ClientData *filePtr); #endif /* MACOSX */ /* 168 */ TCLAPI Tcl_PathType Tcl_GetPathType(const char *path); /* 169 */ | | | | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 | TCLAPI int Tcl_GetOpenFile(Tcl_Interp *interp, const char *chanID, int forWriting, int checkUsage, ClientData *filePtr); #endif /* MACOSX */ /* 168 */ TCLAPI Tcl_PathType Tcl_GetPathType(const char *path); /* 169 */ TCLAPI ssize_t Tcl_Gets(Tcl_Channel chan, Tcl_DString *dsPtr); /* 170 */ TCLAPI ssize_t Tcl_GetsObj(Tcl_Channel chan, Tcl_Obj *objPtr); /* 171 */ TCLAPI int Tcl_GetServiceMode(void); /* 172 */ TCLAPI Tcl_Interp * Tcl_GetSlave(Tcl_Interp *interp, const char *slaveName); /* 173 */ TCLAPI Tcl_Channel Tcl_GetStdChannel(int type); |
︙ | ︙ | |||
527 528 529 530 531 532 533 | /* 183 */ TCLAPI int Tcl_InputBuffered(Tcl_Channel chan); /* 184 */ TCLAPI int Tcl_InterpDeleted(Tcl_Interp *interp); /* 185 */ TCLAPI int Tcl_IsSafe(Tcl_Interp *interp); /* 186 */ | | | | | | 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 567 568 569 570 571 | /* 183 */ TCLAPI int Tcl_InputBuffered(Tcl_Channel chan); /* 184 */ TCLAPI int Tcl_InterpDeleted(Tcl_Interp *interp); /* 185 */ TCLAPI int Tcl_IsSafe(Tcl_Interp *interp); /* 186 */ TCLAPI char * Tcl_JoinPath(size_t argc, const char *const *argv, Tcl_DString *resultPtr); /* 187 */ TCLAPI int Tcl_LinkVar(Tcl_Interp *interp, const char *varName, char *addr, int type); /* Slot 188 is reserved */ /* 189 */ TCLAPI Tcl_Channel Tcl_MakeFileChannel(ClientData handle, int mode); /* 190 */ TCLAPI int Tcl_MakeSafe(Tcl_Interp *interp); /* 191 */ TCLAPI Tcl_Channel Tcl_MakeTcpClientChannel(ClientData tcpSocket); /* 192 */ TCLAPI char * Tcl_Merge(size_t argc, const char *const *argv); /* 193 */ TCLAPI Tcl_HashEntry * Tcl_NextHashEntry(Tcl_HashSearch *searchPtr); /* 194 */ TCLAPI void Tcl_NotifyChannel(Tcl_Channel channel, int mask); /* 195 */ TCLAPI Tcl_Obj * Tcl_ObjGetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags); /* 196 */ TCLAPI Tcl_Obj * Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); /* 197 */ TCLAPI Tcl_Channel Tcl_OpenCommandChannel(Tcl_Interp *interp, size_t argc, const char **argv, int flags); /* 198 */ TCLAPI Tcl_Channel Tcl_OpenFileChannel(Tcl_Interp *interp, const char *fileName, const char *modeString, int permissions); /* 199 */ TCLAPI Tcl_Channel Tcl_OpenTcpClient(Tcl_Interp *interp, int port, const char *address, const char *myaddr, |
︙ | ︙ | |||
581 582 583 584 585 586 587 | TCLAPI int Tcl_PutEnv(const char *assignment); /* 204 */ TCLAPI const char * Tcl_PosixError(Tcl_Interp *interp); /* 205 */ TCLAPI void Tcl_QueueEvent(Tcl_Event *evPtr, Tcl_QueuePosition position); /* 206 */ | | > | 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | TCLAPI int Tcl_PutEnv(const char *assignment); /* 204 */ TCLAPI const char * Tcl_PosixError(Tcl_Interp *interp); /* 205 */ TCLAPI void Tcl_QueueEvent(Tcl_Event *evPtr, Tcl_QueuePosition position); /* 206 */ TCLAPI ssize_t Tcl_Read(Tcl_Channel chan, char *bufPtr, size_t toRead); /* 207 */ TCLAPI void Tcl_ReapDetachedProcs(void); /* 208 */ TCLAPI int Tcl_RecordAndEval(Tcl_Interp *interp, const char *cmd, int flags); /* 209 */ TCLAPI int Tcl_RecordAndEvalObj(Tcl_Interp *interp, |
︙ | ︙ | |||
612 613 614 615 616 617 618 | TCLAPI void Tcl_RegExpRange(Tcl_RegExp regexp, int index, const char **startPtr, const char **endPtr); /* 216 */ TCLAPI void Tcl_Release(ClientData clientData); /* 217 */ TCLAPI void Tcl_ResetResult(Tcl_Interp *interp); /* 218 */ | | | | | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 | TCLAPI void Tcl_RegExpRange(Tcl_RegExp regexp, int index, const char **startPtr, const char **endPtr); /* 216 */ TCLAPI void Tcl_Release(ClientData clientData); /* 217 */ TCLAPI void Tcl_ResetResult(Tcl_Interp *interp); /* 218 */ TCLAPI size_t Tcl_ScanElement(const char *src, int *flagPtr); /* 219 */ TCLAPI size_t Tcl_ScanCountedElement(const char *src, size_t length, int *flagPtr); /* Slot 220 is reserved */ /* 221 */ TCLAPI int Tcl_ServiceAll(void); /* 222 */ TCLAPI int Tcl_ServiceEvent(int flags); /* 223 */ TCLAPI void Tcl_SetAssocData(Tcl_Interp *interp, |
︙ | ︙ | |||
670 671 672 673 674 675 676 | TCLAPI const char * Tcl_SignalId(int sig); /* 240 */ TCLAPI const char * Tcl_SignalMsg(int sig); /* 241 */ TCLAPI void Tcl_SourceRCFile(Tcl_Interp *interp); /* 242 */ TCLAPI int Tcl_SplitList(Tcl_Interp *interp, | | | | | | 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 | TCLAPI const char * Tcl_SignalId(int sig); /* 240 */ TCLAPI const char * Tcl_SignalMsg(int sig); /* 241 */ TCLAPI void Tcl_SourceRCFile(Tcl_Interp *interp); /* 242 */ TCLAPI int Tcl_SplitList(Tcl_Interp *interp, const char *listStr, size_t *argcPtr, const char ***argvPtr); /* 243 */ TCLAPI void Tcl_SplitPath(const char *path, size_t *argcPtr, const char ***argvPtr); /* 244 */ TCLAPI void Tcl_StaticPackage(Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 245 */ TCLAPI int Tcl_StringMatch(const char *str, const char *pattern); /* Slot 246 is reserved */ /* Slot 247 is reserved */ /* 248 */ TCLAPI int Tcl_TraceVar2(Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 249 */ TCLAPI char * Tcl_TranslateFileName(Tcl_Interp *interp, const char *name, Tcl_DString *bufferPtr); /* 250 */ TCLAPI ssize_t Tcl_Ungets(Tcl_Channel chan, const char *str, size_t len, int atHead); /* 251 */ TCLAPI void Tcl_UnlinkVar(Tcl_Interp *interp, const char *varName); /* 252 */ TCLAPI int Tcl_UnregisterChannel(Tcl_Interp *interp, Tcl_Channel chan); /* Slot 253 is reserved */ |
︙ | ︙ | |||
727 728 729 730 731 732 733 | /* Slot 261 is reserved */ /* 262 */ TCLAPI ClientData Tcl_VarTraceInfo2(Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData); /* 263 */ | | > | | 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 | /* Slot 261 is reserved */ /* 262 */ TCLAPI ClientData Tcl_VarTraceInfo2(Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData); /* 263 */ TCLAPI ssize_t Tcl_Write(Tcl_Channel chan, const char *s, size_t slen); /* 264 */ TCLAPI void Tcl_WrongNumArgs(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], const char *message); /* 265 */ TCLAPI int Tcl_DumpActiveMemory(const char *fileName); /* 266 */ TCLAPI void Tcl_ValidateAllMemory(const char *file, int line); /* 267 */ TCLAPI void Tcl_AppendResultVA(Tcl_Interp *interp, |
︙ | ︙ | |||
795 796 797 798 799 800 801 | ClientData clientData); /* 289 */ TCLAPI void Tcl_DeleteThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData); /* Slot 290 is reserved */ /* 291 */ TCLAPI int Tcl_EvalEx(Tcl_Interp *interp, const char *script, | | | | | | | | 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 | ClientData clientData); /* 289 */ TCLAPI void Tcl_DeleteThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData); /* Slot 290 is reserved */ /* 291 */ TCLAPI int Tcl_EvalEx(Tcl_Interp *interp, const char *script, size_t numBytes, int flags); /* 292 */ TCLAPI int Tcl_EvalObjv(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags); /* 293 */ TCLAPI int Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 294 */ TCLAPI void Tcl_ExitThread(int status); /* 295 */ TCLAPI int Tcl_ExternalToUtf(Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, size_t srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, size_t dstLen, size_t *srcReadPtr, size_t *dstWrotePtr, size_t *dstCharsPtr); /* 296 */ TCLAPI char * Tcl_ExternalToUtfDString(Tcl_Encoding encoding, const char *src, size_t srcLen, Tcl_DString *dsPtr); /* 297 */ TCLAPI void Tcl_FinalizeThread(void); /* 298 */ TCLAPI void Tcl_FinalizeNotifier(ClientData clientData); /* 299 */ TCLAPI void Tcl_FreeEncoding(Tcl_Encoding encoding); |
︙ | ︙ | |||
852 853 854 855 856 857 858 | TCLAPI void Tcl_MutexUnlock(Tcl_Mutex *mutexPtr); /* 310 */ TCLAPI void Tcl_ConditionNotify(Tcl_Condition *condPtr); /* 311 */ TCLAPI void Tcl_ConditionWait(Tcl_Condition *condPtr, Tcl_Mutex *mutexPtr, const Tcl_Time *timePtr); /* 312 */ | | | | | | | | | | | | | | | | 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 | TCLAPI void Tcl_MutexUnlock(Tcl_Mutex *mutexPtr); /* 310 */ TCLAPI void Tcl_ConditionNotify(Tcl_Condition *condPtr); /* 311 */ TCLAPI void Tcl_ConditionWait(Tcl_Condition *condPtr, Tcl_Mutex *mutexPtr, const Tcl_Time *timePtr); /* 312 */ TCLAPI size_t Tcl_NumUtfChars(const char *src, size_t length); /* 313 */ TCLAPI ssize_t Tcl_ReadChars(Tcl_Channel channel, Tcl_Obj *objPtr, size_t charsToRead, int appendFlag); /* Slot 314 is reserved */ /* Slot 315 is reserved */ /* 316 */ TCLAPI int Tcl_SetSystemEncoding(Tcl_Interp *interp, const char *name); /* 317 */ TCLAPI Tcl_Obj * Tcl_SetVar2Ex(Tcl_Interp *interp, const char *part1, const char *part2, Tcl_Obj *newValuePtr, int flags); /* 318 */ TCLAPI void Tcl_ThreadAlert(Tcl_ThreadId threadId); /* 319 */ TCLAPI void Tcl_ThreadQueueEvent(Tcl_ThreadId threadId, Tcl_Event *evPtr, Tcl_QueuePosition position); /* 320 */ TCLAPI Tcl_UniChar Tcl_UniCharAtIndex(const char *src, size_t index); /* 321 */ TCLAPI Tcl_UniChar Tcl_UniCharToLower(int ch); /* 322 */ TCLAPI Tcl_UniChar Tcl_UniCharToTitle(int ch); /* 323 */ TCLAPI Tcl_UniChar Tcl_UniCharToUpper(int ch); /* 324 */ TCLAPI int Tcl_UniCharToUtf(int ch, char *buf); /* 325 */ TCLAPI const char * Tcl_UtfAtIndex(const char *src, size_t index); /* 326 */ TCLAPI int Tcl_UtfCharComplete(const char *src, size_t length); /* 327 */ TCLAPI size_t Tcl_UtfBackslash(const char *src, size_t *readPtr, char *dst); /* 328 */ TCLAPI const char * Tcl_UtfFindFirst(const char *src, int ch); /* 329 */ TCLAPI const char * Tcl_UtfFindLast(const char *src, int ch); /* 330 */ TCLAPI const char * Tcl_UtfNext(const char *src); /* 331 */ TCLAPI const char * Tcl_UtfPrev(const char *src, const char *start); /* 332 */ TCLAPI int Tcl_UtfToExternal(Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, size_t srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, size_t dstLen, size_t *srcReadPtr, size_t *dstWrotePtr, size_t *dstCharsPtr); /* 333 */ TCLAPI char * Tcl_UtfToExternalDString(Tcl_Encoding encoding, const char *src, size_t srcLen, Tcl_DString *dsPtr); /* 334 */ TCLAPI int Tcl_UtfToLower(char *src); /* 335 */ TCLAPI int Tcl_UtfToTitle(char *src); /* 336 */ TCLAPI int Tcl_UtfToUniChar(const char *src, Tcl_UniChar *chPtr); /* 337 */ TCLAPI int Tcl_UtfToUpper(char *src); /* 338 */ TCLAPI ssize_t Tcl_WriteChars(Tcl_Channel chan, const char *src, size_t srcLen); /* 339 */ TCLAPI ssize_t Tcl_WriteObj(Tcl_Channel chan, Tcl_Obj *objPtr); /* 340 */ TCLAPI char * Tcl_GetString(Tcl_Obj *objPtr); /* Slot 341 is reserved */ /* Slot 342 is reserved */ /* 343 */ TCLAPI void Tcl_AlertNotifier(ClientData clientData); /* 344 */ |
︙ | ︙ | |||
948 949 950 951 952 953 954 | /* 352 */ TCLAPI int Tcl_UniCharLen(const Tcl_UniChar *uniStr); /* 353 */ TCLAPI int Tcl_UniCharNcmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, size_t numChars); /* 354 */ TCLAPI char * Tcl_UniCharToUtfDString(const Tcl_UniChar *uniStr, | | | | | | | | | | | | 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 990 991 992 993 994 995 996 997 998 999 1000 | /* 352 */ TCLAPI int Tcl_UniCharLen(const Tcl_UniChar *uniStr); /* 353 */ TCLAPI int Tcl_UniCharNcmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, size_t numChars); /* 354 */ TCLAPI char * Tcl_UniCharToUtfDString(const Tcl_UniChar *uniStr, size_t uniLength, Tcl_DString *dsPtr); /* 355 */ TCLAPI Tcl_UniChar * Tcl_UtfToUniCharDString(const char *src, size_t length, Tcl_DString *dsPtr); /* 356 */ TCLAPI Tcl_RegExp Tcl_GetRegExpFromObj(Tcl_Interp *interp, Tcl_Obj *patObj, int flags); /* Slot 357 is reserved */ /* 358 */ TCLAPI void Tcl_FreeParse(Tcl_Parse *parsePtr); /* 359 */ TCLAPI void Tcl_LogCommandInfo(Tcl_Interp *interp, const char *script, const char *command, size_t length); /* 360 */ TCLAPI int Tcl_ParseBraces(Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr, int append, const char **termPtr); /* 361 */ TCLAPI int Tcl_ParseCommand(Tcl_Interp *interp, const char *start, size_t numBytes, int nested, Tcl_Parse *parsePtr); /* 362 */ TCLAPI int Tcl_ParseExpr(Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr); /* 363 */ TCLAPI int Tcl_ParseQuotedString(Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr, int append, const char **termPtr); /* 364 */ TCLAPI int Tcl_ParseVarName(Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr, int append); /* 365 */ TCLAPI char * Tcl_GetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr); /* 366 */ TCLAPI int Tcl_Chdir(const char *dirName); /* 367 */ TCLAPI int Tcl_Access(const char *path, int mode); |
︙ | ︙ | |||
1016 1017 1018 1019 1020 1021 1022 | Tcl_RegExp regexp, Tcl_Obj *textObj, int offset, int nmatches, int flags); /* 377 */ TCLAPI void Tcl_RegExpGetInfo(Tcl_RegExp regexp, Tcl_RegExpInfo *infoPtr); /* 378 */ TCLAPI Tcl_Obj * Tcl_NewUnicodeObj(const Tcl_UniChar *unicode, | | | | | | > | | | | | | | | 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 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 1081 | Tcl_RegExp regexp, Tcl_Obj *textObj, int offset, int nmatches, int flags); /* 377 */ TCLAPI void Tcl_RegExpGetInfo(Tcl_RegExp regexp, Tcl_RegExpInfo *infoPtr); /* 378 */ TCLAPI Tcl_Obj * Tcl_NewUnicodeObj(const Tcl_UniChar *unicode, size_t numChars); /* 379 */ TCLAPI void Tcl_SetUnicodeObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t numChars); /* 380 */ TCLAPI size_t Tcl_GetCharLength(Tcl_Obj *objPtr); /* 381 */ TCLAPI Tcl_UniChar Tcl_GetUniChar(Tcl_Obj *objPtr, size_t index); /* 382 */ TCLAPI Tcl_UniChar * Tcl_GetUnicode(Tcl_Obj *objPtr); /* 383 */ TCLAPI Tcl_Obj * Tcl_GetRange(Tcl_Obj *objPtr, size_t first, size_t last); /* 384 */ TCLAPI void Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t length); /* 385 */ TCLAPI int Tcl_RegExpMatchObj(Tcl_Interp *interp, Tcl_Obj *textObj, Tcl_Obj *patternObj); /* 386 */ TCLAPI void Tcl_SetNotifier(Tcl_NotifierProcs *notifierProcPtr); /* 387 */ TCLAPI Tcl_Mutex * Tcl_GetAllocMutex(void); /* 388 */ TCLAPI int Tcl_GetChannelNames(Tcl_Interp *interp); /* 389 */ TCLAPI int Tcl_GetChannelNamesEx(Tcl_Interp *interp, const char *pattern); /* 390 */ TCLAPI int Tcl_ProcObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* 391 */ TCLAPI void Tcl_ConditionFinalize(Tcl_Condition *condPtr); /* 392 */ TCLAPI void Tcl_MutexFinalize(Tcl_Mutex *mutex); /* 393 */ TCLAPI int Tcl_CreateThread(Tcl_ThreadId *idPtr, Tcl_ThreadCreateProc *proc, ClientData clientData, size_t stackSize, int flags); /* 394 */ TCLAPI ssize_t Tcl_ReadRaw(Tcl_Channel chan, char *dst, size_t bytesToRead); /* 395 */ TCLAPI ssize_t Tcl_WriteRaw(Tcl_Channel chan, const char *src, size_t srcLen); /* 396 */ TCLAPI Tcl_Channel Tcl_GetTopChannel(Tcl_Channel chan); /* 397 */ TCLAPI int Tcl_ChannelBuffered(Tcl_Channel chan); /* 398 */ TCLAPI const char * Tcl_ChannelName(const Tcl_ChannelType *chanTypePtr); /* 399 */ |
︙ | ︙ | |||
1155 1156 1157 1158 1159 1160 1161 | ClientData clientData); /* 427 */ TCLAPI void Tcl_UntraceCommand(Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, ClientData clientData); /* 428 */ | | | | | | | > | | 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 | ClientData clientData); /* 427 */ TCLAPI void Tcl_UntraceCommand(Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, ClientData clientData); /* 428 */ TCLAPI char * Tcl_AttemptAlloc(size_t size); /* 429 */ TCLAPI char * Tcl_AttemptDbCkalloc(size_t size, const char *file, int line); /* 430 */ TCLAPI char * Tcl_AttemptRealloc(char *ptr, size_t size); /* 431 */ TCLAPI char * Tcl_AttemptDbCkrealloc(char *ptr, size_t size, const char *file, int line); /* 432 */ TCLAPI int Tcl_AttemptSetObjLength(Tcl_Obj *objPtr, size_t length); /* 433 */ TCLAPI Tcl_ThreadId Tcl_GetChannelThread(Tcl_Channel channel); /* 434 */ TCLAPI Tcl_UniChar * Tcl_GetUnicodeFromObj(Tcl_Obj *objPtr, size_t *lengthPtr); /* Slot 435 is reserved */ /* Slot 436 is reserved */ /* 437 */ TCLAPI Tcl_Obj * Tcl_SubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 438 */ TCLAPI int Tcl_DetachChannel(Tcl_Interp *interp, |
︙ | ︙ | |||
1242 1243 1244 1245 1246 1247 1248 | TCLAPI int Tcl_FSChdir(Tcl_Obj *pathPtr); /* 459 */ TCLAPI int Tcl_FSConvertToPathType(Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 460 */ TCLAPI Tcl_Obj * Tcl_FSJoinPath(Tcl_Obj *listObj, int elements); /* 461 */ | | | | 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 | TCLAPI int Tcl_FSChdir(Tcl_Obj *pathPtr); /* 459 */ TCLAPI int Tcl_FSConvertToPathType(Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 460 */ TCLAPI Tcl_Obj * Tcl_FSJoinPath(Tcl_Obj *listObj, int elements); /* 461 */ TCLAPI Tcl_Obj * Tcl_FSSplitPath(Tcl_Obj *pathPtr, size_t *lenPtr); /* 462 */ TCLAPI int Tcl_FSEqualPaths(Tcl_Obj *firstPtr, Tcl_Obj *secondPtr); /* 463 */ TCLAPI Tcl_Obj * Tcl_FSGetNormalizedPath(Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 464 */ TCLAPI Tcl_Obj * Tcl_FSJoinToPath(Tcl_Obj *pathPtr, size_t objc, Tcl_Obj *const objv[]); /* 465 */ TCLAPI ClientData Tcl_FSGetInternalRep(Tcl_Obj *pathPtr, const Tcl_Filesystem *fsPtr); /* 466 */ TCLAPI Tcl_Obj * Tcl_FSGetTranslatedPath(Tcl_Interp *interp, Tcl_Obj *pathPtr); |
︙ | ︙ | |||
1292 1293 1294 1295 1296 1297 1298 | TCLAPI Tcl_PathType Tcl_FSGetPathType(Tcl_Obj *pathPtr); /* 479 */ TCLAPI int Tcl_OutputBuffered(Tcl_Channel chan); /* 480 */ TCLAPI void Tcl_FSMountsChanged(const Tcl_Filesystem *fsPtr); /* 481 */ TCLAPI int Tcl_EvalTokensStandard(Tcl_Interp *interp, | | | 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 | TCLAPI Tcl_PathType Tcl_FSGetPathType(Tcl_Obj *pathPtr); /* 479 */ TCLAPI int Tcl_OutputBuffered(Tcl_Channel chan); /* 480 */ TCLAPI void Tcl_FSMountsChanged(const Tcl_Filesystem *fsPtr); /* 481 */ TCLAPI int Tcl_EvalTokensStandard(Tcl_Interp *interp, Tcl_Token *tokenPtr, size_t count); /* 482 */ TCLAPI void Tcl_GetTime(Tcl_Time *timeBuf); /* 483 */ TCLAPI Tcl_Trace Tcl_CreateObjTrace(Tcl_Interp *interp, int level, int flags, Tcl_CmdObjTraceProc *objProc, ClientData clientData, Tcl_CmdObjTraceDeleteProc *delProc); |
︙ | ︙ | |||
1338 1339 1340 1341 1342 1343 1344 | TCLAPI int Tcl_DictObjGet(Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr, Tcl_Obj **valuePtrPtr); /* 496 */ TCLAPI int Tcl_DictObjRemove(Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr); /* 497 */ TCLAPI int Tcl_DictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr, | | | | | 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 1370 1371 1372 1373 1374 1375 1376 1377 | TCLAPI int Tcl_DictObjGet(Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr, Tcl_Obj **valuePtrPtr); /* 496 */ TCLAPI int Tcl_DictObjRemove(Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr); /* 497 */ TCLAPI int Tcl_DictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t *sizePtr); /* 498 */ TCLAPI int Tcl_DictObjFirst(Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr); /* 499 */ TCLAPI void Tcl_DictObjNext(Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr); /* 500 */ TCLAPI void Tcl_DictObjDone(Tcl_DictSearch *searchPtr); /* 501 */ TCLAPI int Tcl_DictObjPutKeyList(Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t keyc, Tcl_Obj *const *keyv, Tcl_Obj *valuePtr); /* 502 */ TCLAPI int Tcl_DictObjRemoveKeyList(Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t keyc, Tcl_Obj *const *keyv); /* 503 */ TCLAPI Tcl_Obj * Tcl_NewDictObj(void); /* 504 */ TCLAPI Tcl_Obj * Tcl_DbNewDictObj(const char *file, int line); /* 505 */ TCLAPI void Tcl_RegisterConfig(Tcl_Interp *interp, |
︙ | ︙ | |||
1556 1557 1558 1559 1560 1561 1562 | /* 571 */ TCLAPI int Tcl_SetEncodingSearchPath(Tcl_Obj *searchPath); /* 572 */ TCLAPI const char * Tcl_GetEncodingNameFromEnvironment( Tcl_DString *bufPtr); /* 573 */ TCLAPI int Tcl_PkgRequireProc(Tcl_Interp *interp, | | | | | | | 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 | /* 571 */ TCLAPI int Tcl_SetEncodingSearchPath(Tcl_Obj *searchPath); /* 572 */ TCLAPI const char * Tcl_GetEncodingNameFromEnvironment( Tcl_DString *bufPtr); /* 573 */ TCLAPI int Tcl_PkgRequireProc(Tcl_Interp *interp, const char *name, size_t objc, Tcl_Obj *const objv[], void *clientDataPtr); /* 574 */ TCLAPI void Tcl_AppendObjToErrorInfo(Tcl_Interp *interp, Tcl_Obj *objPtr); /* 575 */ TCLAPI void Tcl_AppendLimitedToObj(Tcl_Obj *objPtr, const char *bytes, size_t length, size_t limit, const char *ellipsis); /* 576 */ TCLAPI Tcl_Obj * Tcl_Format(Tcl_Interp *interp, const char *format, size_t objc, Tcl_Obj *const objv[]); /* 577 */ TCLAPI int Tcl_AppendFormatToObj(Tcl_Interp *interp, Tcl_Obj *objPtr, const char *format, size_t objc, Tcl_Obj *const objv[]); /* 578 */ TCLAPI Tcl_Obj * Tcl_ObjPrintf(const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 579 */ TCLAPI void Tcl_AppendPrintfToObj(Tcl_Obj *objPtr, const char *format, ...) TCL_FORMAT_PRINTF(2, 3); /* 580 */ TCLAPI int Tcl_CancelEval(Tcl_Interp *interp, |
︙ | ︙ | |||
1597 1598 1599 1600 1601 1602 1603 | Tcl_ObjCmdProc *nreProc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); /* 584 */ TCLAPI int Tcl_NREvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 585 */ | | | > | | 1604 1605 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 | Tcl_ObjCmdProc *nreProc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); /* 584 */ TCLAPI int Tcl_NREvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 585 */ TCLAPI int Tcl_NREvalObjv(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags); /* 586 */ TCLAPI int Tcl_NRCmdSwap(Tcl_Interp *interp, Tcl_Command cmd, size_t objc, Tcl_Obj *const objv[], int flags); /* 587 */ TCLAPI void Tcl_NRAddCallback(Tcl_Interp *interp, Tcl_NRPostProc *postProcPtr, ClientData data0, ClientData data1, ClientData data2, ClientData data3); /* 588 */ TCLAPI int Tcl_NRCallObjProc(Tcl_Interp *interp, Tcl_ObjCmdProc *objProc, ClientData clientData, size_t objc, Tcl_Obj *const objv[]); /* 589 */ TCLAPI unsigned Tcl_GetFSDeviceFromStat(const Tcl_StatBuf *statPtr); /* 590 */ TCLAPI unsigned Tcl_GetFSInodeFromStat(const Tcl_StatBuf *statPtr); /* 591 */ TCLAPI unsigned Tcl_GetModeFromStat(const Tcl_StatBuf *statPtr); |
︙ | ︙ | |||
1647 1648 1649 1650 1651 1652 1653 | TCLAPI int Tcl_SetEnsembleParameterList(Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *paramList); /* 603 */ TCLAPI int Tcl_GetEnsembleParameterList(Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **paramListPtr); /* 604 */ TCLAPI int Tcl_ParseArgsObjv(Tcl_Interp *interp, | | > | | 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 | TCLAPI int Tcl_SetEnsembleParameterList(Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *paramList); /* 603 */ TCLAPI int Tcl_GetEnsembleParameterList(Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **paramListPtr); /* 604 */ TCLAPI int Tcl_ParseArgsObjv(Tcl_Interp *interp, const Tcl_ArgvInfo *argTable, size_t *objcPtr, Tcl_Obj *const *objv, Tcl_Obj ***remObjv); /* 605 */ TCLAPI int Tcl_GetErrorLine(Tcl_Interp *interp); /* 606 */ TCLAPI void Tcl_SetErrorLine(Tcl_Interp *interp, int lineNum); /* 607 */ TCLAPI void Tcl_TransferResult(Tcl_Interp *sourceInterp, int result, Tcl_Interp *targetInterp); |
︙ | ︙ | |||
1670 1671 1672 1673 1674 1675 1676 | Tcl_Obj *gzipHeaderDictObj); /* 611 */ TCLAPI int Tcl_ZlibInflate(Tcl_Interp *interp, int format, Tcl_Obj *data, int buffersize, Tcl_Obj *gzipHeaderDictObj); /* 612 */ TCLAPI unsigned int Tcl_ZlibCRC32(unsigned int crc, | | | | | 1679 1680 1681 1682 1683 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 1709 1710 1711 1712 | Tcl_Obj *gzipHeaderDictObj); /* 611 */ TCLAPI int Tcl_ZlibInflate(Tcl_Interp *interp, int format, Tcl_Obj *data, int buffersize, Tcl_Obj *gzipHeaderDictObj); /* 612 */ TCLAPI unsigned int Tcl_ZlibCRC32(unsigned int crc, const unsigned char *buf, size_t len); /* 613 */ TCLAPI unsigned int Tcl_ZlibAdler32(unsigned int adler, const unsigned char *buf, size_t len); /* 614 */ TCLAPI int Tcl_ZlibStreamInit(Tcl_Interp *interp, int mode, int format, int level, Tcl_Obj *dictObj, Tcl_ZlibStream *zshandle); /* 615 */ TCLAPI Tcl_Obj * Tcl_ZlibStreamGetCommandName(Tcl_ZlibStream zshandle); /* 616 */ TCLAPI int Tcl_ZlibStreamEof(Tcl_ZlibStream zshandle); /* 617 */ TCLAPI int Tcl_ZlibStreamChecksum(Tcl_ZlibStream zshandle); /* 618 */ TCLAPI int Tcl_ZlibStreamPut(Tcl_ZlibStream zshandle, Tcl_Obj *data, int flush); /* 619 */ TCLAPI int Tcl_ZlibStreamGet(Tcl_ZlibStream zshandle, Tcl_Obj *data, size_t count); /* 620 */ TCLAPI int Tcl_ZlibStreamClose(Tcl_ZlibStream zshandle); /* 621 */ TCLAPI int Tcl_ZlibStreamReset(Tcl_ZlibStream zshandle); /* 622 */ TCLAPI void Tcl_SetStartupScript(Tcl_Obj *path, const char *encoding); |
︙ | ︙ | |||
1736 1737 1738 1739 1740 1741 1742 | typedef struct TclStubs { int magic; const TclStubHooks *hooks; int (*tcl_PkgProvideEx) (Tcl_Interp *interp, const char *name, const char *version, const void *clientData); /* 0 */ const char * (*tcl_PkgRequireEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 1 */ void (*tcl_Panic) (const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 2 */ | | | | | | 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 | typedef struct TclStubs { int magic; const TclStubHooks *hooks; int (*tcl_PkgProvideEx) (Tcl_Interp *interp, const char *name, const char *version, const void *clientData); /* 0 */ const char * (*tcl_PkgRequireEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 1 */ void (*tcl_Panic) (const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 2 */ char * (*tcl_Alloc) (size_t size); /* 3 */ void (*tcl_Free) (char *ptr); /* 4 */ char * (*tcl_Realloc) (char *ptr, size_t size); /* 5 */ char * (*tcl_DbCkalloc) (size_t size, const char *file, int line); /* 6 */ void (*tcl_DbCkfree) (char *ptr, const char *file, int line); /* 7 */ char * (*tcl_DbCkrealloc) (char *ptr, size_t size, const char *file, int line); /* 8 */ #if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */ void (*tcl_CreateFileHandler) (int fd, int mask, Tcl_FileProc *proc, ClientData clientData); /* 9 */ #endif /* UNIX */ #if defined(__WIN32__) /* WIN */ void (*reserved9)(void); #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ |
︙ | ︙ | |||
1765 1766 1767 1768 1769 1770 1771 | void (*tcl_DeleteFileHandler) (int fd); /* 10 */ #endif /* MACOSX */ void (*tcl_SetTimer) (const Tcl_Time *timePtr); /* 11 */ void (*tcl_Sleep) (int ms); /* 12 */ int (*tcl_WaitForEvent) (const Tcl_Time *timePtr); /* 13 */ int (*tcl_AppendAllObjTypes) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 14 */ void (*tcl_AppendStringsToObj) (Tcl_Obj *objPtr, ...); /* 15 */ | | | | | | | | | | | | | | | | | | | | | | | | | | 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 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 | void (*tcl_DeleteFileHandler) (int fd); /* 10 */ #endif /* MACOSX */ void (*tcl_SetTimer) (const Tcl_Time *timePtr); /* 11 */ void (*tcl_Sleep) (int ms); /* 12 */ int (*tcl_WaitForEvent) (const Tcl_Time *timePtr); /* 13 */ int (*tcl_AppendAllObjTypes) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 14 */ void (*tcl_AppendStringsToObj) (Tcl_Obj *objPtr, ...); /* 15 */ void (*tcl_AppendToObj) (Tcl_Obj *objPtr, const char *bytes, size_t length); /* 16 */ Tcl_Obj * (*tcl_ConcatObj) (size_t objc, Tcl_Obj *const objv[]); /* 17 */ int (*tcl_ConvertToType) (Tcl_Interp *interp, Tcl_Obj *objPtr, const Tcl_ObjType *typePtr); /* 18 */ void (*tcl_DbDecrRefCount) (Tcl_Obj *objPtr, const char *file, int line); /* 19 */ void (*tcl_DbIncrRefCount) (Tcl_Obj *objPtr, const char *file, int line); /* 20 */ int (*tcl_DbIsShared) (Tcl_Obj *objPtr, const char *file, int line); /* 21 */ Tcl_Obj * (*tcl_DbNewBooleanObj) (int boolValue, const char *file, int line); /* 22 */ Tcl_Obj * (*tcl_DbNewByteArrayObj) (const unsigned char *bytes, size_t length, const char *file, int line); /* 23 */ Tcl_Obj * (*tcl_DbNewDoubleObj) (double doubleValue, const char *file, int line); /* 24 */ Tcl_Obj * (*tcl_DbNewListObj) (size_t objc, Tcl_Obj *const *objv, const char *file, int line); /* 25 */ Tcl_Obj * (*tcl_DbNewLongObj) (long longValue, const char *file, int line); /* 26 */ Tcl_Obj * (*tcl_DbNewObj) (const char *file, int line); /* 27 */ Tcl_Obj * (*tcl_DbNewStringObj) (const char *bytes, size_t length, const char *file, int line); /* 28 */ Tcl_Obj * (*tcl_DuplicateObj) (Tcl_Obj *objPtr); /* 29 */ void (*tclFreeObj) (Tcl_Obj *objPtr); /* 30 */ int (*tcl_GetBoolean) (Tcl_Interp *interp, const char *src, int *boolPtr); /* 31 */ int (*tcl_GetBooleanFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *boolPtr); /* 32 */ unsigned char * (*tcl_GetByteArrayFromObj) (Tcl_Obj *objPtr, size_t *lengthPtr); /* 33 */ int (*tcl_GetDouble) (Tcl_Interp *interp, const char *src, double *doublePtr); /* 34 */ int (*tcl_GetDoubleFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, double *doublePtr); /* 35 */ void (*reserved36)(void); int (*tcl_GetInt) (Tcl_Interp *interp, const char *src, int *intPtr); /* 37 */ int (*tcl_GetIntFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *intPtr); /* 38 */ int (*tcl_GetLongFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, long *longPtr); /* 39 */ const Tcl_ObjType * (*tcl_GetObjType) (const char *typeName); /* 40 */ char * (*tcl_GetStringFromObj) (Tcl_Obj *objPtr, size_t *lengthPtr); /* 41 */ void (*tcl_InvalidateStringRep) (Tcl_Obj *objPtr); /* 42 */ int (*tcl_ListObjAppendList) (Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *elemListPtr); /* 43 */ int (*tcl_ListObjAppendElement) (Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *objPtr); /* 44 */ int (*tcl_ListObjGetElements) (Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *objcPtr, Tcl_Obj ***objvPtr); /* 45 */ int (*tcl_ListObjIndex) (Tcl_Interp *interp, Tcl_Obj *listPtr, size_t index, Tcl_Obj **objPtrPtr); /* 46 */ int (*tcl_ListObjLength) (Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *lengthPtr); /* 47 */ int (*tcl_ListObjReplace) (Tcl_Interp *interp, Tcl_Obj *listPtr, size_t first, size_t count, size_t objc, Tcl_Obj *const objv[]); /* 48 */ Tcl_Obj * (*tcl_NewBooleanObj) (int boolValue); /* 49 */ Tcl_Obj * (*tcl_NewByteArrayObj) (const unsigned char *bytes, size_t length); /* 50 */ Tcl_Obj * (*tcl_NewDoubleObj) (double doubleValue); /* 51 */ Tcl_Obj * (*tcl_NewIntObj) (int intValue); /* 52 */ Tcl_Obj * (*tcl_NewListObj) (size_t objc, Tcl_Obj *const objv[]); /* 53 */ Tcl_Obj * (*tcl_NewLongObj) (long longValue); /* 54 */ Tcl_Obj * (*tcl_NewObj) (void); /* 55 */ Tcl_Obj * (*tcl_NewStringObj) (const char *bytes, size_t length); /* 56 */ void (*tcl_SetBooleanObj) (Tcl_Obj *objPtr, int boolValue); /* 57 */ unsigned char * (*tcl_SetByteArrayLength) (Tcl_Obj *objPtr, size_t length); /* 58 */ void (*tcl_SetByteArrayObj) (Tcl_Obj *objPtr, const unsigned char *bytes, size_t length); /* 59 */ void (*tcl_SetDoubleObj) (Tcl_Obj *objPtr, double doubleValue); /* 60 */ void (*tcl_SetIntObj) (Tcl_Obj *objPtr, int intValue); /* 61 */ void (*tcl_SetListObj) (Tcl_Obj *objPtr, size_t objc, Tcl_Obj *const objv[]); /* 62 */ void (*tcl_SetLongObj) (Tcl_Obj *objPtr, long longValue); /* 63 */ void (*tcl_SetObjLength) (Tcl_Obj *objPtr, size_t length); /* 64 */ void (*tcl_SetStringObj) (Tcl_Obj *objPtr, const char *bytes, size_t length); /* 65 */ void (*tcl_AddErrorInfo) (Tcl_Interp *interp, const char *message); /* 66 */ void (*reserved67)(void); void (*tcl_AllowExceptions) (Tcl_Interp *interp); /* 68 */ void (*tcl_AppendElement) (Tcl_Interp *interp, const char *element); /* 69 */ void (*tcl_AppendResult) (Tcl_Interp *interp, ...); /* 70 */ Tcl_AsyncHandler (*tcl_AsyncCreate) (Tcl_AsyncProc *proc, ClientData clientData); /* 71 */ void (*tcl_AsyncDelete) (Tcl_AsyncHandler async); /* 72 */ int (*tcl_AsyncInvoke) (Tcl_Interp *interp, int code); /* 73 */ void (*tcl_AsyncMark) (Tcl_AsyncHandler async); /* 74 */ int (*tcl_AsyncReady) (void); /* 75 */ void (*tcl_BackgroundError) (Tcl_Interp *interp); /* 76 */ void (*reserved77)(void); int (*tcl_BadChannelOption) (Tcl_Interp *interp, const char *optionName, const char *optionList); /* 78 */ void (*tcl_CallWhenDeleted) (Tcl_Interp *interp, Tcl_InterpDeleteProc *proc, ClientData clientData); /* 79 */ void (*tcl_CancelIdleCall) (Tcl_IdleProc *idleProc, ClientData clientData); /* 80 */ int (*tcl_Close) (Tcl_Interp *interp, Tcl_Channel chan); /* 81 */ int (*tcl_CommandComplete) (const char *cmd); /* 82 */ char * (*tcl_Concat) (size_t argc, const char *const *argv); /* 83 */ size_t (*tcl_ConvertElement) (const char *src, char *dst, int flags); /* 84 */ size_t (*tcl_ConvertCountedElement) (const char *src, size_t length, char *dst, int flags); /* 85 */ int (*tcl_CreateAlias) (Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, size_t argc, const char *const *argv); /* 86 */ int (*tcl_CreateAliasObj) (Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, size_t objc, Tcl_Obj *const objv[]); /* 87 */ Tcl_Channel (*tcl_CreateChannel) (const Tcl_ChannelType *typePtr, const char *chanName, ClientData instanceData, int mask); /* 88 */ void (*tcl_CreateChannelHandler) (Tcl_Channel chan, int mask, Tcl_ChannelProc *proc, ClientData clientData); /* 89 */ void (*tcl_CreateCloseHandler) (Tcl_Channel chan, Tcl_CloseProc *proc, ClientData clientData); /* 90 */ Tcl_Command (*tcl_CreateCommand) (Tcl_Interp *interp, const char *cmdName, Tcl_CmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); /* 91 */ void (*tcl_CreateEventSource) (Tcl_EventSetupProc *setupProc, Tcl_EventCheckProc *checkProc, ClientData clientData); /* 92 */ void (*tcl_CreateExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 93 */ Tcl_Interp * (*tcl_CreateInterp) (void); /* 94 */ |
︙ | ︙ | |||
1866 1867 1868 1869 1870 1871 1872 | void (*tcl_DeleteInterp) (Tcl_Interp *interp); /* 110 */ void (*tcl_DetachPids) (int numPids, Tcl_Pid *pidPtr); /* 111 */ void (*tcl_DeleteTimerHandler) (Tcl_TimerToken token); /* 112 */ void (*tcl_DeleteTrace) (Tcl_Interp *interp, Tcl_Trace trace); /* 113 */ void (*tcl_DontCallWhenDeleted) (Tcl_Interp *interp, Tcl_InterpDeleteProc *proc, ClientData clientData); /* 114 */ int (*tcl_DoOneEvent) (int flags); /* 115 */ void (*tcl_DoWhenIdle) (Tcl_IdleProc *proc, ClientData clientData); /* 116 */ | | | | 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 | void (*tcl_DeleteInterp) (Tcl_Interp *interp); /* 110 */ void (*tcl_DetachPids) (int numPids, Tcl_Pid *pidPtr); /* 111 */ void (*tcl_DeleteTimerHandler) (Tcl_TimerToken token); /* 112 */ void (*tcl_DeleteTrace) (Tcl_Interp *interp, Tcl_Trace trace); /* 113 */ void (*tcl_DontCallWhenDeleted) (Tcl_Interp *interp, Tcl_InterpDeleteProc *proc, ClientData clientData); /* 114 */ int (*tcl_DoOneEvent) (int flags); /* 115 */ void (*tcl_DoWhenIdle) (Tcl_IdleProc *proc, ClientData clientData); /* 116 */ char * (*tcl_DStringAppend) (Tcl_DString *dsPtr, const char *bytes, size_t length); /* 117 */ char * (*tcl_DStringAppendElement) (Tcl_DString *dsPtr, const char *element); /* 118 */ void (*tcl_DStringEndSublist) (Tcl_DString *dsPtr); /* 119 */ void (*tcl_DStringFree) (Tcl_DString *dsPtr); /* 120 */ void (*tcl_DStringGetResult) (Tcl_Interp *interp, Tcl_DString *dsPtr); /* 121 */ void (*tcl_DStringInit) (Tcl_DString *dsPtr); /* 122 */ void (*tcl_DStringResult) (Tcl_Interp *interp, Tcl_DString *dsPtr); /* 123 */ void (*tcl_DStringSetLength) (Tcl_DString *dsPtr, size_t length); /* 124 */ void (*tcl_DStringStartSublist) (Tcl_DString *dsPtr); /* 125 */ int (*tcl_Eof) (Tcl_Channel chan); /* 126 */ const char * (*tcl_ErrnoId) (void); /* 127 */ const char * (*tcl_ErrnoMsg) (int err); /* 128 */ void (*reserved129)(void); void (*reserved130)(void); void (*reserved131)(void); |
︙ | ︙ | |||
1897 1898 1899 1900 1901 1902 1903 | int (*tcl_ExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj **resultPtrPtr); /* 141 */ int (*tcl_ExprString) (Tcl_Interp *interp, const char *expr); /* 142 */ void (*tcl_Finalize) (void); /* 143 */ void (*reserved144)(void); Tcl_HashEntry * (*tcl_FirstHashEntry) (Tcl_HashTable *tablePtr, Tcl_HashSearch *searchPtr); /* 145 */ int (*tcl_Flush) (Tcl_Channel chan); /* 146 */ void (*tcl_FreeResult) (Tcl_Interp *interp); /* 147 */ | | | | 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 | int (*tcl_ExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj **resultPtrPtr); /* 141 */ int (*tcl_ExprString) (Tcl_Interp *interp, const char *expr); /* 142 */ void (*tcl_Finalize) (void); /* 143 */ void (*reserved144)(void); Tcl_HashEntry * (*tcl_FirstHashEntry) (Tcl_HashTable *tablePtr, Tcl_HashSearch *searchPtr); /* 145 */ int (*tcl_Flush) (Tcl_Channel chan); /* 146 */ void (*tcl_FreeResult) (Tcl_Interp *interp); /* 147 */ int (*tcl_GetAlias) (Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, const char **targetCmdPtr, size_t *argcPtr, const char ***argvPtr); /* 148 */ int (*tcl_GetAliasObj) (Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, const char **targetCmdPtr, size_t *objcPtr, Tcl_Obj ***objv); /* 149 */ ClientData (*tcl_GetAssocData) (Tcl_Interp *interp, const char *name, Tcl_InterpDeleteProc **procPtr); /* 150 */ Tcl_Channel (*tcl_GetChannel) (Tcl_Interp *interp, const char *chanName, int *modePtr); /* 151 */ int (*tcl_GetChannelBufferSize) (Tcl_Channel chan); /* 152 */ int (*tcl_GetChannelHandle) (Tcl_Channel chan, int direction, ClientData *handlePtr); /* 153 */ ClientData (*tcl_GetChannelInstanceData) (Tcl_Channel chan); /* 154 */ int (*tcl_GetChannelMode) (Tcl_Channel chan); /* 155 */ const char * (*tcl_GetChannelName) (Tcl_Channel chan); /* 156 */ |
︙ | ︙ | |||
1926 1927 1928 1929 1930 1931 1932 | #if defined(__WIN32__) /* WIN */ void (*reserved167)(void); #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ int (*tcl_GetOpenFile) (Tcl_Interp *interp, const char *chanID, int forWriting, int checkUsage, ClientData *filePtr); /* 167 */ #endif /* MACOSX */ Tcl_PathType (*tcl_GetPathType) (const char *path); /* 168 */ | | | | | | | | | | 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 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 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 | #if defined(__WIN32__) /* WIN */ void (*reserved167)(void); #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ int (*tcl_GetOpenFile) (Tcl_Interp *interp, const char *chanID, int forWriting, int checkUsage, ClientData *filePtr); /* 167 */ #endif /* MACOSX */ Tcl_PathType (*tcl_GetPathType) (const char *path); /* 168 */ ssize_t (*tcl_Gets) (Tcl_Channel chan, Tcl_DString *dsPtr); /* 169 */ ssize_t (*tcl_GetsObj) (Tcl_Channel chan, Tcl_Obj *objPtr); /* 170 */ int (*tcl_GetServiceMode) (void); /* 171 */ Tcl_Interp * (*tcl_GetSlave) (Tcl_Interp *interp, const char *slaveName); /* 172 */ Tcl_Channel (*tcl_GetStdChannel) (int type); /* 173 */ const char * (*tcl_GetStringResult) (Tcl_Interp *interp); /* 174 */ void (*reserved175)(void); const char * (*tcl_GetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 176 */ void (*reserved177)(void); void (*reserved178)(void); int (*tcl_HideCommand) (Tcl_Interp *interp, const char *cmdName, const char *hiddenCmdToken); /* 179 */ int (*tcl_Init) (Tcl_Interp *interp); /* 180 */ void (*tcl_InitHashTable) (Tcl_HashTable *tablePtr, int keyType); /* 181 */ int (*tcl_InputBlocked) (Tcl_Channel chan); /* 182 */ int (*tcl_InputBuffered) (Tcl_Channel chan); /* 183 */ int (*tcl_InterpDeleted) (Tcl_Interp *interp); /* 184 */ int (*tcl_IsSafe) (Tcl_Interp *interp); /* 185 */ char * (*tcl_JoinPath) (size_t argc, const char *const *argv, Tcl_DString *resultPtr); /* 186 */ int (*tcl_LinkVar) (Tcl_Interp *interp, const char *varName, char *addr, int type); /* 187 */ void (*reserved188)(void); Tcl_Channel (*tcl_MakeFileChannel) (ClientData handle, int mode); /* 189 */ int (*tcl_MakeSafe) (Tcl_Interp *interp); /* 190 */ Tcl_Channel (*tcl_MakeTcpClientChannel) (ClientData tcpSocket); /* 191 */ char * (*tcl_Merge) (size_t argc, const char *const *argv); /* 192 */ Tcl_HashEntry * (*tcl_NextHashEntry) (Tcl_HashSearch *searchPtr); /* 193 */ void (*tcl_NotifyChannel) (Tcl_Channel channel, int mask); /* 194 */ Tcl_Obj * (*tcl_ObjGetVar2) (Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags); /* 195 */ Tcl_Obj * (*tcl_ObjSetVar2) (Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); /* 196 */ Tcl_Channel (*tcl_OpenCommandChannel) (Tcl_Interp *interp, size_t argc, const char **argv, int flags); /* 197 */ Tcl_Channel (*tcl_OpenFileChannel) (Tcl_Interp *interp, const char *fileName, const char *modeString, int permissions); /* 198 */ Tcl_Channel (*tcl_OpenTcpClient) (Tcl_Interp *interp, int port, const char *address, const char *myaddr, int myport, int async); /* 199 */ Tcl_Channel (*tcl_OpenTcpServer) (Tcl_Interp *interp, int port, const char *host, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 200 */ void (*tcl_Preserve) (ClientData data); /* 201 */ void (*tcl_PrintDouble) (Tcl_Interp *interp, double value, char *dst); /* 202 */ int (*tcl_PutEnv) (const char *assignment); /* 203 */ const char * (*tcl_PosixError) (Tcl_Interp *interp); /* 204 */ void (*tcl_QueueEvent) (Tcl_Event *evPtr, Tcl_QueuePosition position); /* 205 */ ssize_t (*tcl_Read) (Tcl_Channel chan, char *bufPtr, size_t toRead); /* 206 */ void (*tcl_ReapDetachedProcs) (void); /* 207 */ int (*tcl_RecordAndEval) (Tcl_Interp *interp, const char *cmd, int flags); /* 208 */ int (*tcl_RecordAndEvalObj) (Tcl_Interp *interp, Tcl_Obj *cmdPtr, int flags); /* 209 */ void (*tcl_RegisterChannel) (Tcl_Interp *interp, Tcl_Channel chan); /* 210 */ void (*tcl_RegisterObjType) (const Tcl_ObjType *typePtr); /* 211 */ Tcl_RegExp (*tcl_RegExpCompile) (Tcl_Interp *interp, const char *pattern); /* 212 */ int (*tcl_RegExpExec) (Tcl_Interp *interp, Tcl_RegExp regexp, const char *text, const char *start); /* 213 */ int (*tcl_RegExpMatch) (Tcl_Interp *interp, const char *text, const char *pattern); /* 214 */ void (*tcl_RegExpRange) (Tcl_RegExp regexp, int index, const char **startPtr, const char **endPtr); /* 215 */ void (*tcl_Release) (ClientData clientData); /* 216 */ void (*tcl_ResetResult) (Tcl_Interp *interp); /* 217 */ size_t (*tcl_ScanElement) (const char *src, int *flagPtr); /* 218 */ size_t (*tcl_ScanCountedElement) (const char *src, size_t length, int *flagPtr); /* 219 */ void (*reserved220)(void); int (*tcl_ServiceAll) (void); /* 221 */ int (*tcl_ServiceEvent) (int flags); /* 222 */ void (*tcl_SetAssocData) (Tcl_Interp *interp, const char *name, Tcl_InterpDeleteProc *proc, ClientData clientData); /* 223 */ void (*tcl_SetChannelBufferSize) (Tcl_Channel chan, int sz); /* 224 */ int (*tcl_SetChannelOption) (Tcl_Interp *interp, Tcl_Channel chan, const char *optionName, const char *newValue); /* 225 */ int (*tcl_SetCommandInfo) (Tcl_Interp *interp, const char *cmdName, const Tcl_CmdInfo *infoPtr); /* 226 */ |
︙ | ︙ | |||
1999 2000 2001 2002 2003 2004 2005 | void (*tcl_SetObjResult) (Tcl_Interp *interp, Tcl_Obj *resultObjPtr); /* 235 */ void (*tcl_SetStdChannel) (Tcl_Channel channel, int type); /* 236 */ void (*reserved237)(void); const char * (*tcl_SetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, const char *newValue, int flags); /* 238 */ const char * (*tcl_SignalId) (int sig); /* 239 */ const char * (*tcl_SignalMsg) (int sig); /* 240 */ void (*tcl_SourceRCFile) (Tcl_Interp *interp); /* 241 */ | | | | | | | 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 | void (*tcl_SetObjResult) (Tcl_Interp *interp, Tcl_Obj *resultObjPtr); /* 235 */ void (*tcl_SetStdChannel) (Tcl_Channel channel, int type); /* 236 */ void (*reserved237)(void); const char * (*tcl_SetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, const char *newValue, int flags); /* 238 */ const char * (*tcl_SignalId) (int sig); /* 239 */ const char * (*tcl_SignalMsg) (int sig); /* 240 */ void (*tcl_SourceRCFile) (Tcl_Interp *interp); /* 241 */ int (*tcl_SplitList) (Tcl_Interp *interp, const char *listStr, size_t *argcPtr, const char ***argvPtr); /* 242 */ void (*tcl_SplitPath) (const char *path, size_t *argcPtr, const char ***argvPtr); /* 243 */ void (*tcl_StaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 244 */ int (*tcl_StringMatch) (const char *str, const char *pattern); /* 245 */ void (*reserved246)(void); void (*reserved247)(void); int (*tcl_TraceVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 248 */ char * (*tcl_TranslateFileName) (Tcl_Interp *interp, const char *name, Tcl_DString *bufferPtr); /* 249 */ ssize_t (*tcl_Ungets) (Tcl_Channel chan, const char *str, size_t len, int atHead); /* 250 */ void (*tcl_UnlinkVar) (Tcl_Interp *interp, const char *varName); /* 251 */ int (*tcl_UnregisterChannel) (Tcl_Interp *interp, Tcl_Channel chan); /* 252 */ void (*reserved253)(void); int (*tcl_UnsetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 254 */ void (*reserved255)(void); void (*tcl_UntraceVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 256 */ void (*tcl_UpdateLinkedVar) (Tcl_Interp *interp, const char *varName); /* 257 */ void (*reserved258)(void); int (*tcl_UpVar2) (Tcl_Interp *interp, const char *frameName, const char *part1, const char *part2, const char *localName, int flags); /* 259 */ void (*reserved260)(void); void (*reserved261)(void); ClientData (*tcl_VarTraceInfo2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData); /* 262 */ ssize_t (*tcl_Write) (Tcl_Channel chan, const char *s, size_t slen); /* 263 */ void (*tcl_WrongNumArgs) (Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], const char *message); /* 264 */ int (*tcl_DumpActiveMemory) (const char *fileName); /* 265 */ void (*tcl_ValidateAllMemory) (const char *file, int line); /* 266 */ void (*tcl_AppendResultVA) (Tcl_Interp *interp, va_list argList); /* 267 */ void (*tcl_AppendStringsToObjVA) (Tcl_Obj *objPtr, va_list argList); /* 268 */ char * (*tcl_HashStats) (Tcl_HashTable *tablePtr); /* 269 */ const char * (*tcl_ParseVar) (Tcl_Interp *interp, const char *start, const char **termPtr); /* 270 */ void (*reserved271)(void); |
︙ | ︙ | |||
2048 2049 2050 2051 2052 2053 2054 | void (*tcl_SetMainLoop) (Tcl_MainLoopProc *proc); /* 284 */ void (*reserved285)(void); void (*tcl_AppendObjToObj) (Tcl_Obj *objPtr, Tcl_Obj *appendObjPtr); /* 286 */ Tcl_Encoding (*tcl_CreateEncoding) (const Tcl_EncodingType *typePtr); /* 287 */ void (*tcl_CreateThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 288 */ void (*tcl_DeleteThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 289 */ void (*reserved290)(void); | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 | void (*tcl_SetMainLoop) (Tcl_MainLoopProc *proc); /* 284 */ void (*reserved285)(void); void (*tcl_AppendObjToObj) (Tcl_Obj *objPtr, Tcl_Obj *appendObjPtr); /* 286 */ Tcl_Encoding (*tcl_CreateEncoding) (const Tcl_EncodingType *typePtr); /* 287 */ void (*tcl_CreateThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 288 */ void (*tcl_DeleteThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 289 */ void (*reserved290)(void); int (*tcl_EvalEx) (Tcl_Interp *interp, const char *script, size_t numBytes, int flags); /* 291 */ int (*tcl_EvalObjv) (Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags); /* 292 */ int (*tcl_EvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 293 */ void (*tcl_ExitThread) (int status); /* 294 */ int (*tcl_ExternalToUtf) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, size_t srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, size_t dstLen, size_t *srcReadPtr, size_t *dstWrotePtr, size_t *dstCharsPtr); /* 295 */ char * (*tcl_ExternalToUtfDString) (Tcl_Encoding encoding, const char *src, size_t srcLen, Tcl_DString *dsPtr); /* 296 */ void (*tcl_FinalizeThread) (void); /* 297 */ void (*tcl_FinalizeNotifier) (ClientData clientData); /* 298 */ void (*tcl_FreeEncoding) (Tcl_Encoding encoding); /* 299 */ Tcl_ThreadId (*tcl_GetCurrentThread) (void); /* 300 */ Tcl_Encoding (*tcl_GetEncoding) (Tcl_Interp *interp, const char *name); /* 301 */ const char * (*tcl_GetEncodingName) (Tcl_Encoding encoding); /* 302 */ void (*tcl_GetEncodingNames) (Tcl_Interp *interp); /* 303 */ int (*tcl_GetIndexFromObjStruct) (Tcl_Interp *interp, Tcl_Obj *objPtr, const void *tablePtr, int offset, const char *msg, int flags, int *indexPtr); /* 304 */ void * (*tcl_GetThreadData) (Tcl_ThreadDataKey *keyPtr, int size); /* 305 */ Tcl_Obj * (*tcl_GetVar2Ex) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 306 */ ClientData (*tcl_InitNotifier) (void); /* 307 */ void (*tcl_MutexLock) (Tcl_Mutex *mutexPtr); /* 308 */ void (*tcl_MutexUnlock) (Tcl_Mutex *mutexPtr); /* 309 */ void (*tcl_ConditionNotify) (Tcl_Condition *condPtr); /* 310 */ void (*tcl_ConditionWait) (Tcl_Condition *condPtr, Tcl_Mutex *mutexPtr, const Tcl_Time *timePtr); /* 311 */ size_t (*tcl_NumUtfChars) (const char *src, size_t length); /* 312 */ ssize_t (*tcl_ReadChars) (Tcl_Channel channel, Tcl_Obj *objPtr, size_t charsToRead, int appendFlag); /* 313 */ void (*reserved314)(void); void (*reserved315)(void); int (*tcl_SetSystemEncoding) (Tcl_Interp *interp, const char *name); /* 316 */ Tcl_Obj * (*tcl_SetVar2Ex) (Tcl_Interp *interp, const char *part1, const char *part2, Tcl_Obj *newValuePtr, int flags); /* 317 */ void (*tcl_ThreadAlert) (Tcl_ThreadId threadId); /* 318 */ void (*tcl_ThreadQueueEvent) (Tcl_ThreadId threadId, Tcl_Event *evPtr, Tcl_QueuePosition position); /* 319 */ Tcl_UniChar (*tcl_UniCharAtIndex) (const char *src, size_t index); /* 320 */ Tcl_UniChar (*tcl_UniCharToLower) (int ch); /* 321 */ Tcl_UniChar (*tcl_UniCharToTitle) (int ch); /* 322 */ Tcl_UniChar (*tcl_UniCharToUpper) (int ch); /* 323 */ int (*tcl_UniCharToUtf) (int ch, char *buf); /* 324 */ const char * (*tcl_UtfAtIndex) (const char *src, size_t index); /* 325 */ int (*tcl_UtfCharComplete) (const char *src, size_t length); /* 326 */ size_t (*tcl_UtfBackslash) (const char *src, size_t *readPtr, char *dst); /* 327 */ const char * (*tcl_UtfFindFirst) (const char *src, int ch); /* 328 */ const char * (*tcl_UtfFindLast) (const char *src, int ch); /* 329 */ const char * (*tcl_UtfNext) (const char *src); /* 330 */ const char * (*tcl_UtfPrev) (const char *src, const char *start); /* 331 */ int (*tcl_UtfToExternal) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, size_t srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, size_t dstLen, size_t *srcReadPtr, size_t *dstWrotePtr, size_t *dstCharsPtr); /* 332 */ char * (*tcl_UtfToExternalDString) (Tcl_Encoding encoding, const char *src, size_t srcLen, Tcl_DString *dsPtr); /* 333 */ int (*tcl_UtfToLower) (char *src); /* 334 */ int (*tcl_UtfToTitle) (char *src); /* 335 */ int (*tcl_UtfToUniChar) (const char *src, Tcl_UniChar *chPtr); /* 336 */ int (*tcl_UtfToUpper) (char *src); /* 337 */ ssize_t (*tcl_WriteChars) (Tcl_Channel chan, const char *src, size_t srcLen); /* 338 */ ssize_t (*tcl_WriteObj) (Tcl_Channel chan, Tcl_Obj *objPtr); /* 339 */ char * (*tcl_GetString) (Tcl_Obj *objPtr); /* 340 */ void (*reserved341)(void); void (*reserved342)(void); void (*tcl_AlertNotifier) (ClientData clientData); /* 343 */ void (*tcl_ServiceModeHook) (int mode); /* 344 */ int (*tcl_UniCharIsAlnum) (int ch); /* 345 */ int (*tcl_UniCharIsAlpha) (int ch); /* 346 */ int (*tcl_UniCharIsDigit) (int ch); /* 347 */ int (*tcl_UniCharIsLower) (int ch); /* 348 */ int (*tcl_UniCharIsSpace) (int ch); /* 349 */ int (*tcl_UniCharIsUpper) (int ch); /* 350 */ int (*tcl_UniCharIsWordChar) (int ch); /* 351 */ int (*tcl_UniCharLen) (const Tcl_UniChar *uniStr); /* 352 */ int (*tcl_UniCharNcmp) (const Tcl_UniChar *ucs, const Tcl_UniChar *uct, size_t numChars); /* 353 */ char * (*tcl_UniCharToUtfDString) (const Tcl_UniChar *uniStr, size_t uniLength, Tcl_DString *dsPtr); /* 354 */ Tcl_UniChar * (*tcl_UtfToUniCharDString) (const char *src, size_t length, Tcl_DString *dsPtr); /* 355 */ Tcl_RegExp (*tcl_GetRegExpFromObj) (Tcl_Interp *interp, Tcl_Obj *patObj, int flags); /* 356 */ void (*reserved357)(void); void (*tcl_FreeParse) (Tcl_Parse *parsePtr); /* 358 */ void (*tcl_LogCommandInfo) (Tcl_Interp *interp, const char *script, const char *command, size_t length); /* 359 */ int (*tcl_ParseBraces) (Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr, int append, const char **termPtr); /* 360 */ int (*tcl_ParseCommand) (Tcl_Interp *interp, const char *start, size_t numBytes, int nested, Tcl_Parse *parsePtr); /* 361 */ int (*tcl_ParseExpr) (Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr); /* 362 */ int (*tcl_ParseQuotedString) (Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr, int append, const char **termPtr); /* 363 */ int (*tcl_ParseVarName) (Tcl_Interp *interp, const char *start, size_t numBytes, Tcl_Parse *parsePtr, int append); /* 364 */ char * (*tcl_GetCwd) (Tcl_Interp *interp, Tcl_DString *cwdPtr); /* 365 */ int (*tcl_Chdir) (const char *dirName); /* 366 */ int (*tcl_Access) (const char *path, int mode); /* 367 */ int (*tcl_Stat) (const char *path, struct stat *bufPtr); /* 368 */ int (*tcl_UtfNcmp) (const char *s1, const char *s2, size_t n); /* 369 */ int (*tcl_UtfNcasecmp) (const char *s1, const char *s2, size_t n); /* 370 */ int (*tcl_StringCaseMatch) (const char *str, const char *pattern, int nocase); /* 371 */ int (*tcl_UniCharIsControl) (int ch); /* 372 */ int (*tcl_UniCharIsGraph) (int ch); /* 373 */ int (*tcl_UniCharIsPrint) (int ch); /* 374 */ int (*tcl_UniCharIsPunct) (int ch); /* 375 */ int (*tcl_RegExpExecObj) (Tcl_Interp *interp, Tcl_RegExp regexp, Tcl_Obj *textObj, int offset, int nmatches, int flags); /* 376 */ void (*tcl_RegExpGetInfo) (Tcl_RegExp regexp, Tcl_RegExpInfo *infoPtr); /* 377 */ Tcl_Obj * (*tcl_NewUnicodeObj) (const Tcl_UniChar *unicode, size_t numChars); /* 378 */ void (*tcl_SetUnicodeObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t numChars); /* 379 */ size_t (*tcl_GetCharLength) (Tcl_Obj *objPtr); /* 380 */ Tcl_UniChar (*tcl_GetUniChar) (Tcl_Obj *objPtr, size_t index); /* 381 */ Tcl_UniChar * (*tcl_GetUnicode) (Tcl_Obj *objPtr); /* 382 */ Tcl_Obj * (*tcl_GetRange) (Tcl_Obj *objPtr, size_t first, size_t last); /* 383 */ void (*tcl_AppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t length); /* 384 */ int (*tcl_RegExpMatchObj) (Tcl_Interp *interp, Tcl_Obj *textObj, Tcl_Obj *patternObj); /* 385 */ void (*tcl_SetNotifier) (Tcl_NotifierProcs *notifierProcPtr); /* 386 */ Tcl_Mutex * (*tcl_GetAllocMutex) (void); /* 387 */ int (*tcl_GetChannelNames) (Tcl_Interp *interp); /* 388 */ int (*tcl_GetChannelNamesEx) (Tcl_Interp *interp, const char *pattern); /* 389 */ int (*tcl_ProcObjCmd) (ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* 390 */ void (*tcl_ConditionFinalize) (Tcl_Condition *condPtr); /* 391 */ void (*tcl_MutexFinalize) (Tcl_Mutex *mutex); /* 392 */ int (*tcl_CreateThread) (Tcl_ThreadId *idPtr, Tcl_ThreadCreateProc *proc, ClientData clientData, size_t stackSize, int flags); /* 393 */ ssize_t (*tcl_ReadRaw) (Tcl_Channel chan, char *dst, size_t bytesToRead); /* 394 */ ssize_t (*tcl_WriteRaw) (Tcl_Channel chan, const char *src, size_t srcLen); /* 395 */ Tcl_Channel (*tcl_GetTopChannel) (Tcl_Channel chan); /* 396 */ int (*tcl_ChannelBuffered) (Tcl_Channel chan); /* 397 */ const char * (*tcl_ChannelName) (const Tcl_ChannelType *chanTypePtr); /* 398 */ Tcl_ChannelTypeVersion (*tcl_ChannelVersion) (const Tcl_ChannelType *chanTypePtr); /* 399 */ Tcl_DriverBlockModeProc * (*tcl_ChannelBlockModeProc) (const Tcl_ChannelType *chanTypePtr); /* 400 */ Tcl_DriverCloseProc * (*tcl_ChannelCloseProc) (const Tcl_ChannelType *chanTypePtr); /* 401 */ Tcl_DriverClose2Proc * (*tcl_ChannelClose2Proc) (const Tcl_ChannelType *chanTypePtr); /* 402 */ |
︙ | ︙ | |||
2185 2186 2187 2188 2189 2190 2191 | Tcl_HashEntry * (*tcl_FindHashEntry) (Tcl_HashTable *tablePtr, const void *key); /* 421 */ Tcl_HashEntry * (*tcl_CreateHashEntry) (Tcl_HashTable *tablePtr, const void *key, int *newPtr); /* 422 */ void (*tcl_InitCustomHashTable) (Tcl_HashTable *tablePtr, int keyType, const Tcl_HashKeyType *typePtr); /* 423 */ void (*tcl_InitObjHashTable) (Tcl_HashTable *tablePtr); /* 424 */ ClientData (*tcl_CommandTraceInfo) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *procPtr, ClientData prevClientData); /* 425 */ int (*tcl_TraceCommand) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, ClientData clientData); /* 426 */ void (*tcl_UntraceCommand) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, ClientData clientData); /* 427 */ | | | | | | | | 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 | Tcl_HashEntry * (*tcl_FindHashEntry) (Tcl_HashTable *tablePtr, const void *key); /* 421 */ Tcl_HashEntry * (*tcl_CreateHashEntry) (Tcl_HashTable *tablePtr, const void *key, int *newPtr); /* 422 */ void (*tcl_InitCustomHashTable) (Tcl_HashTable *tablePtr, int keyType, const Tcl_HashKeyType *typePtr); /* 423 */ void (*tcl_InitObjHashTable) (Tcl_HashTable *tablePtr); /* 424 */ ClientData (*tcl_CommandTraceInfo) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *procPtr, ClientData prevClientData); /* 425 */ int (*tcl_TraceCommand) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, ClientData clientData); /* 426 */ void (*tcl_UntraceCommand) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, ClientData clientData); /* 427 */ char * (*tcl_AttemptAlloc) (size_t size); /* 428 */ char * (*tcl_AttemptDbCkalloc) (size_t size, const char *file, int line); /* 429 */ char * (*tcl_AttemptRealloc) (char *ptr, size_t size); /* 430 */ char * (*tcl_AttemptDbCkrealloc) (char *ptr, size_t size, const char *file, int line); /* 431 */ int (*tcl_AttemptSetObjLength) (Tcl_Obj *objPtr, size_t length); /* 432 */ Tcl_ThreadId (*tcl_GetChannelThread) (Tcl_Channel channel); /* 433 */ Tcl_UniChar * (*tcl_GetUnicodeFromObj) (Tcl_Obj *objPtr, size_t *lengthPtr); /* 434 */ void (*reserved435)(void); void (*reserved436)(void); Tcl_Obj * (*tcl_SubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 437 */ int (*tcl_DetachChannel) (Tcl_Interp *interp, Tcl_Channel channel); /* 438 */ int (*tcl_IsStandardChannel) (Tcl_Channel channel); /* 439 */ int (*tcl_FSCopyFile) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); /* 440 */ int (*tcl_FSCopyDirectory) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); /* 441 */ |
︙ | ︙ | |||
2218 2219 2220 2221 2222 2223 2224 | int (*tcl_FSStat) (Tcl_Obj *pathPtr, Tcl_StatBuf *buf); /* 454 */ int (*tcl_FSAccess) (Tcl_Obj *pathPtr, int mode); /* 455 */ Tcl_Channel (*tcl_FSOpenFileChannel) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *modeString, int permissions); /* 456 */ Tcl_Obj * (*tcl_FSGetCwd) (Tcl_Interp *interp); /* 457 */ int (*tcl_FSChdir) (Tcl_Obj *pathPtr); /* 458 */ int (*tcl_FSConvertToPathType) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 459 */ Tcl_Obj * (*tcl_FSJoinPath) (Tcl_Obj *listObj, int elements); /* 460 */ | | | | | | | | 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 | int (*tcl_FSStat) (Tcl_Obj *pathPtr, Tcl_StatBuf *buf); /* 454 */ int (*tcl_FSAccess) (Tcl_Obj *pathPtr, int mode); /* 455 */ Tcl_Channel (*tcl_FSOpenFileChannel) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *modeString, int permissions); /* 456 */ Tcl_Obj * (*tcl_FSGetCwd) (Tcl_Interp *interp); /* 457 */ int (*tcl_FSChdir) (Tcl_Obj *pathPtr); /* 458 */ int (*tcl_FSConvertToPathType) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 459 */ Tcl_Obj * (*tcl_FSJoinPath) (Tcl_Obj *listObj, int elements); /* 460 */ Tcl_Obj * (*tcl_FSSplitPath) (Tcl_Obj *pathPtr, size_t *lenPtr); /* 461 */ int (*tcl_FSEqualPaths) (Tcl_Obj *firstPtr, Tcl_Obj *secondPtr); /* 462 */ Tcl_Obj * (*tcl_FSGetNormalizedPath) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 463 */ Tcl_Obj * (*tcl_FSJoinToPath) (Tcl_Obj *pathPtr, size_t objc, Tcl_Obj *const objv[]); /* 464 */ ClientData (*tcl_FSGetInternalRep) (Tcl_Obj *pathPtr, const Tcl_Filesystem *fsPtr); /* 465 */ Tcl_Obj * (*tcl_FSGetTranslatedPath) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 466 */ int (*tcl_FSEvalFile) (Tcl_Interp *interp, Tcl_Obj *fileName); /* 467 */ Tcl_Obj * (*tcl_FSNewNativePath) (const Tcl_Filesystem *fromFilesystem, ClientData clientData); /* 468 */ const void * (*tcl_FSGetNativePath) (Tcl_Obj *pathPtr); /* 469 */ Tcl_Obj * (*tcl_FSFileSystemInfo) (Tcl_Obj *pathPtr); /* 470 */ Tcl_Obj * (*tcl_FSPathSeparator) (Tcl_Obj *pathPtr); /* 471 */ Tcl_Obj * (*tcl_FSListVolumes) (void); /* 472 */ int (*tcl_FSRegister) (ClientData clientData, const Tcl_Filesystem *fsPtr); /* 473 */ int (*tcl_FSUnregister) (const Tcl_Filesystem *fsPtr); /* 474 */ ClientData (*tcl_FSData) (const Tcl_Filesystem *fsPtr); /* 475 */ const char * (*tcl_FSGetTranslatedStringPath) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 476 */ const Tcl_Filesystem * (*tcl_FSGetFileSystemForPath) (Tcl_Obj *pathPtr); /* 477 */ Tcl_PathType (*tcl_FSGetPathType) (Tcl_Obj *pathPtr); /* 478 */ int (*tcl_OutputBuffered) (Tcl_Channel chan); /* 479 */ void (*tcl_FSMountsChanged) (const Tcl_Filesystem *fsPtr); /* 480 */ int (*tcl_EvalTokensStandard) (Tcl_Interp *interp, Tcl_Token *tokenPtr, size_t count); /* 481 */ void (*tcl_GetTime) (Tcl_Time *timeBuf); /* 482 */ Tcl_Trace (*tcl_CreateObjTrace) (Tcl_Interp *interp, int level, int flags, Tcl_CmdObjTraceProc *objProc, ClientData clientData, Tcl_CmdObjTraceDeleteProc *delProc); /* 483 */ int (*tcl_GetCommandInfoFromToken) (Tcl_Command token, Tcl_CmdInfo *infoPtr); /* 484 */ int (*tcl_SetCommandInfoFromToken) (Tcl_Command token, const Tcl_CmdInfo *infoPtr); /* 485 */ Tcl_Obj * (*tcl_DbNewWideIntObj) (Tcl_WideInt wideValue, const char *file, int line); /* 486 */ int (*tcl_GetWideIntFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_WideInt *widePtr); /* 487 */ Tcl_Obj * (*tcl_NewWideIntObj) (Tcl_WideInt wideValue); /* 488 */ void (*tcl_SetWideIntObj) (Tcl_Obj *objPtr, Tcl_WideInt wideValue); /* 489 */ Tcl_StatBuf * (*tcl_AllocStatBuf) (void); /* 490 */ Tcl_WideInt (*tcl_Seek) (Tcl_Channel chan, Tcl_WideInt offset, int mode); /* 491 */ Tcl_WideInt (*tcl_Tell) (Tcl_Channel chan); /* 492 */ Tcl_DriverWideSeekProc * (*tcl_ChannelWideSeekProc) (const Tcl_ChannelType *chanTypePtr); /* 493 */ int (*tcl_DictObjPut) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr, Tcl_Obj *valuePtr); /* 494 */ int (*tcl_DictObjGet) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr, Tcl_Obj **valuePtrPtr); /* 495 */ int (*tcl_DictObjRemove) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr); /* 496 */ int (*tcl_DictObjSize) (Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t *sizePtr); /* 497 */ int (*tcl_DictObjFirst) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr); /* 498 */ void (*tcl_DictObjNext) (Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr); /* 499 */ void (*tcl_DictObjDone) (Tcl_DictSearch *searchPtr); /* 500 */ int (*tcl_DictObjPutKeyList) (Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t keyc, Tcl_Obj *const *keyv, Tcl_Obj *valuePtr); /* 501 */ int (*tcl_DictObjRemoveKeyList) (Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t keyc, Tcl_Obj *const *keyv); /* 502 */ Tcl_Obj * (*tcl_NewDictObj) (void); /* 503 */ Tcl_Obj * (*tcl_DbNewDictObj) (const char *file, int line); /* 504 */ void (*tcl_RegisterConfig) (Tcl_Interp *interp, const char *pkgName, const Tcl_Config *configuration, const char *valEncoding); /* 505 */ Tcl_Namespace * (*tcl_CreateNamespace) (Tcl_Interp *interp, const char *name, ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc); /* 506 */ void (*tcl_DeleteNamespace) (Tcl_Namespace *nsPtr); /* 507 */ int (*tcl_AppendExportList) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *objPtr); /* 508 */ int (*tcl_Export) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern, int resetListFirst); /* 509 */ |
︙ | ︙ | |||
2330 2331 2332 2333 2334 2335 2336 | int (*tcl_InitBignumFromDouble) (Tcl_Interp *interp, double initval, mp_int *toInit); /* 566 */ Tcl_Obj * (*tcl_GetNamespaceUnknownHandler) (Tcl_Interp *interp, Tcl_Namespace *nsPtr); /* 567 */ int (*tcl_SetNamespaceUnknownHandler) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *handlerPtr); /* 568 */ int (*tcl_GetEncodingFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Encoding *encodingPtr); /* 569 */ Tcl_Obj * (*tcl_GetEncodingSearchPath) (void); /* 570 */ int (*tcl_SetEncodingSearchPath) (Tcl_Obj *searchPath); /* 571 */ const char * (*tcl_GetEncodingNameFromEnvironment) (Tcl_DString *bufPtr); /* 572 */ | | | | | | | | | | | | | 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 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 2397 2398 2399 | int (*tcl_InitBignumFromDouble) (Tcl_Interp *interp, double initval, mp_int *toInit); /* 566 */ Tcl_Obj * (*tcl_GetNamespaceUnknownHandler) (Tcl_Interp *interp, Tcl_Namespace *nsPtr); /* 567 */ int (*tcl_SetNamespaceUnknownHandler) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *handlerPtr); /* 568 */ int (*tcl_GetEncodingFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Encoding *encodingPtr); /* 569 */ Tcl_Obj * (*tcl_GetEncodingSearchPath) (void); /* 570 */ int (*tcl_SetEncodingSearchPath) (Tcl_Obj *searchPath); /* 571 */ const char * (*tcl_GetEncodingNameFromEnvironment) (Tcl_DString *bufPtr); /* 572 */ int (*tcl_PkgRequireProc) (Tcl_Interp *interp, const char *name, size_t objc, Tcl_Obj *const objv[], void *clientDataPtr); /* 573 */ void (*tcl_AppendObjToErrorInfo) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 574 */ void (*tcl_AppendLimitedToObj) (Tcl_Obj *objPtr, const char *bytes, size_t length, size_t limit, const char *ellipsis); /* 575 */ Tcl_Obj * (*tcl_Format) (Tcl_Interp *interp, const char *format, size_t objc, Tcl_Obj *const objv[]); /* 576 */ int (*tcl_AppendFormatToObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, const char *format, size_t objc, Tcl_Obj *const objv[]); /* 577 */ Tcl_Obj * (*tcl_ObjPrintf) (const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 578 */ void (*tcl_AppendPrintfToObj) (Tcl_Obj *objPtr, const char *format, ...) TCL_FORMAT_PRINTF(2, 3); /* 579 */ int (*tcl_CancelEval) (Tcl_Interp *interp, Tcl_Obj *resultObjPtr, ClientData clientData, int flags); /* 580 */ int (*tcl_Canceled) (Tcl_Interp *interp, int flags); /* 581 */ int (*tcl_CreatePipe) (Tcl_Interp *interp, Tcl_Channel *rchan, Tcl_Channel *wchan, int flags); /* 582 */ Tcl_Command (*tcl_NRCreateCommand) (Tcl_Interp *interp, const char *cmdName, Tcl_ObjCmdProc *proc, Tcl_ObjCmdProc *nreProc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); /* 583 */ int (*tcl_NREvalObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 584 */ int (*tcl_NREvalObjv) (Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags); /* 585 */ int (*tcl_NRCmdSwap) (Tcl_Interp *interp, Tcl_Command cmd, size_t objc, Tcl_Obj *const objv[], int flags); /* 586 */ void (*tcl_NRAddCallback) (Tcl_Interp *interp, Tcl_NRPostProc *postProcPtr, ClientData data0, ClientData data1, ClientData data2, ClientData data3); /* 587 */ int (*tcl_NRCallObjProc) (Tcl_Interp *interp, Tcl_ObjCmdProc *objProc, ClientData clientData, size_t objc, Tcl_Obj *const objv[]); /* 588 */ unsigned (*tcl_GetFSDeviceFromStat) (const Tcl_StatBuf *statPtr); /* 589 */ unsigned (*tcl_GetFSInodeFromStat) (const Tcl_StatBuf *statPtr); /* 590 */ unsigned (*tcl_GetModeFromStat) (const Tcl_StatBuf *statPtr); /* 591 */ int (*tcl_GetLinkCountFromStat) (const Tcl_StatBuf *statPtr); /* 592 */ int (*tcl_GetUserIdFromStat) (const Tcl_StatBuf *statPtr); /* 593 */ int (*tcl_GetGroupIdFromStat) (const Tcl_StatBuf *statPtr); /* 594 */ int (*tcl_GetDeviceTypeFromStat) (const Tcl_StatBuf *statPtr); /* 595 */ Tcl_WideInt (*tcl_GetAccessTimeFromStat) (const Tcl_StatBuf *statPtr); /* 596 */ Tcl_WideInt (*tcl_GetModificationTimeFromStat) (const Tcl_StatBuf *statPtr); /* 597 */ Tcl_WideInt (*tcl_GetChangeTimeFromStat) (const Tcl_StatBuf *statPtr); /* 598 */ Tcl_WideUInt (*tcl_GetSizeFromStat) (const Tcl_StatBuf *statPtr); /* 599 */ Tcl_WideUInt (*tcl_GetBlocksFromStat) (const Tcl_StatBuf *statPtr); /* 600 */ unsigned (*tcl_GetBlockSizeFromStat) (const Tcl_StatBuf *statPtr); /* 601 */ int (*tcl_SetEnsembleParameterList) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *paramList); /* 602 */ int (*tcl_GetEnsembleParameterList) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **paramListPtr); /* 603 */ int (*tcl_ParseArgsObjv) (Tcl_Interp *interp, const Tcl_ArgvInfo *argTable, size_t *objcPtr, Tcl_Obj *const *objv, Tcl_Obj ***remObjv); /* 604 */ int (*tcl_GetErrorLine) (Tcl_Interp *interp); /* 605 */ void (*tcl_SetErrorLine) (Tcl_Interp *interp, int lineNum); /* 606 */ void (*tcl_TransferResult) (Tcl_Interp *sourceInterp, int result, Tcl_Interp *targetInterp); /* 607 */ int (*tcl_InterpActive) (Tcl_Interp *interp); /* 608 */ void (*tcl_BackgroundException) (Tcl_Interp *interp, int code); /* 609 */ int (*tcl_ZlibDeflate) (Tcl_Interp *interp, int format, Tcl_Obj *data, int level, Tcl_Obj *gzipHeaderDictObj); /* 610 */ int (*tcl_ZlibInflate) (Tcl_Interp *interp, int format, Tcl_Obj *data, int buffersize, Tcl_Obj *gzipHeaderDictObj); /* 611 */ unsigned int (*tcl_ZlibCRC32) (unsigned int crc, const unsigned char *buf, size_t len); /* 612 */ unsigned int (*tcl_ZlibAdler32) (unsigned int adler, const unsigned char *buf, size_t len); /* 613 */ int (*tcl_ZlibStreamInit) (Tcl_Interp *interp, int mode, int format, int level, Tcl_Obj *dictObj, Tcl_ZlibStream *zshandle); /* 614 */ Tcl_Obj * (*tcl_ZlibStreamGetCommandName) (Tcl_ZlibStream zshandle); /* 615 */ int (*tcl_ZlibStreamEof) (Tcl_ZlibStream zshandle); /* 616 */ int (*tcl_ZlibStreamChecksum) (Tcl_ZlibStream zshandle); /* 617 */ int (*tcl_ZlibStreamPut) (Tcl_ZlibStream zshandle, Tcl_Obj *data, int flush); /* 618 */ int (*tcl_ZlibStreamGet) (Tcl_ZlibStream zshandle, Tcl_Obj *data, size_t count); /* 619 */ int (*tcl_ZlibStreamClose) (Tcl_ZlibStream zshandle); /* 620 */ int (*tcl_ZlibStreamReset) (Tcl_ZlibStream zshandle); /* 621 */ void (*tcl_SetStartupScript) (Tcl_Obj *path, const char *encoding); /* 622 */ Tcl_Obj * (*tcl_GetStartupScript) (const char **encodingPtr); /* 623 */ int (*tcl_CloseEx) (Tcl_Interp *interp, Tcl_Channel chan, int flags); /* 624 */ int (*tcl_NRExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *resultPtr); /* 625 */ int (*tcl_NRSubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 626 */ |
︙ | ︙ |
Changes to generic/tclDictObj.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | struct Dict; /* * Prototypes for functions defined later in this file: */ static void DeleteDict(struct Dict *dict); | | < | < | < | | < | | < | < | < | | | < | < | | < < | < | < | < | < | < < < < < | 19 20 21 22 23 24 25 26 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 57 58 59 60 61 62 63 64 65 66 67 | struct Dict; /* * Prototypes for functions defined later in this file: */ static void DeleteDict(struct Dict *dict); static Tcl_ObjCmdProc DictAppendCmd; static Tcl_ObjCmdProc DictCreateCmd; static Tcl_ObjCmdProc DictExistsCmd; static Tcl_ObjCmdProc DictFilterCmd; static Tcl_ObjCmdProc DictForNRCmd; static Tcl_ObjCmdProc DictGetCmd; static Tcl_ObjCmdProc DictIncrCmd; static Tcl_ObjCmdProc DictInfoCmd; static Tcl_ObjCmdProc DictKeysCmd; static Tcl_ObjCmdProc DictLappendCmd; static Tcl_ObjCmdProc DictMapNRCmd; static Tcl_ObjCmdProc DictMergeCmd; static Tcl_ObjCmdProc DictRemoveCmd; static Tcl_ObjCmdProc DictReplaceCmd; static Tcl_ObjCmdProc DictSetCmd; static Tcl_ObjCmdProc DictSizeCmd; static Tcl_ObjCmdProc DictUnsetCmd; static Tcl_ObjCmdProc DictUpdateCmd; static Tcl_ObjCmdProc DictValuesCmd; static Tcl_ObjCmdProc DictWithCmd; static void DupDictInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); static void FreeDictInternalRep(Tcl_Obj *dictPtr); static void InvalidateDictChain(Tcl_Obj *dictObj); static int SetDictFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static void UpdateStringOfDict(Tcl_Obj *dictPtr); static Tcl_HashEntry * AllocChainEntry(Tcl_HashTable *tablePtr,void *keyPtr); static inline void InitChainTable(struct Dict *dict); static inline void DeleteChainTable(struct Dict *dict); static inline Tcl_HashEntry *CreateChainEntry(struct Dict *dict, Tcl_Obj *keyPtr, int *newPtr); static inline int DeleteChainEntry(struct Dict *dict, Tcl_Obj *keyPtr); static int FinalizeDictUpdate(ClientData data[], Tcl_Interp *interp, int result); static int FinalizeDictWith(ClientData data[], Tcl_Interp *interp, int result); static int DictForLoopCallback(ClientData data[], Tcl_Interp *interp, int result); static int DictMapLoopCallback(ClientData data[], Tcl_Interp *interp, int result); /* * Table of dict subcommand names and implementations. |
︙ | ︙ | |||
486 487 488 489 490 491 492 | Tcl_Obj *dictPtr) { #define LOCAL_SIZE 64 char localFlags[LOCAL_SIZE], *flagPtr = NULL; Dict *dict = dictPtr->internalRep.twoPtrValue.ptr1; ChainEntry *cPtr; Tcl_Obj *keyPtr, *valuePtr; | | > | 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | Tcl_Obj *dictPtr) { #define LOCAL_SIZE 64 char localFlags[LOCAL_SIZE], *flagPtr = NULL; Dict *dict = dictPtr->internalRep.twoPtrValue.ptr1; ChainEntry *cPtr; Tcl_Obj *keyPtr, *valuePtr; int i, bytesNeeded = 0; const char *elem; char *dst; size_t length; /* * This field is the most useful one in the whole hash structure, and it * is not exposed by any API function... */ int numElems = dict->table.numEntries * 2; |
︙ | ︙ | |||
605 606 607 608 609 610 611 | /* * Since lists and dictionaries have very closely-related string * representations (i.e. the same parsing code) we can safely special-case * the conversion from lists to dictionaries. */ if (objPtr->typePtr == &tclListType) { | | | 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 | /* * Since lists and dictionaries have very closely-related string * representations (i.e. the same parsing code) we can safely special-case * the conversion from lists to dictionaries. */ if (objPtr->typePtr == &tclListType) { size_t objc, i; Tcl_Obj **objv; /* Cannot fail, we already know the Tcl_ObjType is "list". */ TclListObjGetElements(NULL, objPtr, &objc, &objv); if (objc & 1) { goto missingValue; } |
︙ | ︙ | |||
635 636 637 638 639 640 641 | TclDecrRefCount(discardedValue); } Tcl_SetHashValue(hPtr, objv[i+1]); Tcl_IncrRefCount(objv[i+1]); /* Since hash now holds ref to it */ } } else { | | > | | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 | TclDecrRefCount(discardedValue); } Tcl_SetHashValue(hPtr, objv[i+1]); Tcl_IncrRefCount(objv[i+1]); /* Since hash now holds ref to it */ } } else { size_t length; const char *nextElem = TclGetStringFromObj(objPtr, &length); const char *limit = (nextElem + length); while (nextElem < limit) { Tcl_Obj *keyPtr, *valuePtr; const char *elemStart; size_t elemSize; int literal; result = TclFindElement(interp, nextElem, (limit - nextElem), &elemStart, &nextElem, &elemSize, &literal); if (result != TCL_OK) { goto errorExit; } if (elemStart == limit) { |
︙ | ︙ | |||
713 714 715 716 717 718 719 | objPtr->internalRep.twoPtrValue.ptr1 = dict; objPtr->typePtr = &tclDictType; return TCL_OK; missingValue: if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | objPtr->internalRep.twoPtrValue.ptr1 = dict; objPtr->typePtr = &tclDictType; return TCL_OK; missingValue: if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing value to go with key", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL); } result = TCL_ERROR; errorExit: if (interp != NULL) { Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL); |
︙ | ︙ | |||
763 764 765 766 767 768 769 | *---------------------------------------------------------------------- */ Tcl_Obj * TclTraceDictPath( Tcl_Interp *interp, Tcl_Obj *dictPtr, | | | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 | *---------------------------------------------------------------------- */ Tcl_Obj * TclTraceDictPath( Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t keyc, Tcl_Obj *const keyv[], int flags) { Dict *dict, *newDict; int i; if (dictPtr->typePtr != &tclDictType) { |
︙ | ︙ | |||
1051 1052 1053 1054 1055 1056 1057 | *---------------------------------------------------------------------- */ int Tcl_DictObjSize( Tcl_Interp *interp, Tcl_Obj *dictPtr, | | | 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 | *---------------------------------------------------------------------- */ int Tcl_DictObjSize( Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t *sizePtr) { Dict *dict; if (dictPtr->typePtr != &tclDictType) { int result = SetDictFromAny(interp, dictPtr); if (result != TCL_OK) { return result; |
︙ | ︙ | |||
1272 1273 1274 1275 1276 1277 1278 | *---------------------------------------------------------------------- */ int Tcl_DictObjPutKeyList( Tcl_Interp *interp, Tcl_Obj *dictPtr, | | | 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 | *---------------------------------------------------------------------- */ int Tcl_DictObjPutKeyList( Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t keyc, Tcl_Obj *const keyv[], Tcl_Obj *valuePtr) { Dict *dict; Tcl_HashEntry *hPtr; int isNew; |
︙ | ︙ | |||
1331 1332 1333 1334 1335 1336 1337 | *---------------------------------------------------------------------- */ int Tcl_DictObjRemoveKeyList( Tcl_Interp *interp, Tcl_Obj *dictPtr, | | | 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 | *---------------------------------------------------------------------- */ int Tcl_DictObjRemoveKeyList( Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t keyc, Tcl_Obj *const keyv[]) { Dict *dict; if (Tcl_IsShared(dictPtr)) { Tcl_Panic("%s called with shared object", "Tcl_DictObjRemoveKeyList"); } |
︙ | ︙ | |||
1475 1476 1477 1478 1479 1480 1481 | *---------------------------------------------------------------------- */ static int DictCreateCmd( ClientData dummy, Tcl_Interp *interp, | | | 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 | *---------------------------------------------------------------------- */ static int DictCreateCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *dictObj; int i; /* * Must have an even number of arguments; note that number of preceding |
︙ | ︙ | |||
1525 1526 1527 1528 1529 1530 1531 | *---------------------------------------------------------------------- */ static int DictGetCmd( ClientData dummy, Tcl_Interp *interp, | | | 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 | *---------------------------------------------------------------------- */ static int DictGetCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *dictPtr, *valuePtr = NULL; int result; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "dictionary ?key ...?"); |
︙ | ︙ | |||
1618 1619 1620 1621 1622 1623 1624 | *---------------------------------------------------------------------- */ static int DictReplaceCmd( ClientData dummy, Tcl_Interp *interp, | | | 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 | *---------------------------------------------------------------------- */ static int DictReplaceCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *dictPtr; int i, result; int allocatedDict = 0; if ((objc < 2) || (objc & 1)) { |
︙ | ︙ | |||
1670 1671 1672 1673 1674 1675 1676 | *---------------------------------------------------------------------- */ static int DictRemoveCmd( ClientData dummy, Tcl_Interp *interp, | | | 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 | *---------------------------------------------------------------------- */ static int DictRemoveCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *dictPtr; int i, result; int allocatedDict = 0; if (objc < 2) { |
︙ | ︙ | |||
1722 1723 1724 1725 1726 1727 1728 | *---------------------------------------------------------------------- */ static int DictMergeCmd( ClientData dummy, Tcl_Interp *interp, | | | 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 | *---------------------------------------------------------------------- */ static int DictMergeCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *targetObj, *keyObj = NULL, *valueObj = NULL; int allocatedDict = 0; int i, done; Tcl_DictSearch search; |
︙ | ︙ | |||
1811 1812 1813 1814 1815 1816 1817 | *---------------------------------------------------------------------- */ static int DictKeysCmd( ClientData dummy, Tcl_Interp *interp, | | | 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 | *---------------------------------------------------------------------- */ static int DictKeysCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *listPtr; const char *pattern = NULL; if (objc!=2 && objc!=3) { Tcl_WrongNumArgs(interp, 1, objv, "dictionary ?pattern?"); |
︙ | ︙ | |||
1894 1895 1896 1897 1898 1899 1900 | *---------------------------------------------------------------------- */ static int DictValuesCmd( ClientData dummy, Tcl_Interp *interp, | | | 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 | *---------------------------------------------------------------------- */ static int DictValuesCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *valuePtr = NULL, *listPtr; Tcl_DictSearch search; int done; const char *pattern; |
︙ | ︙ | |||
1954 1955 1956 1957 1958 1959 1960 | *---------------------------------------------------------------------- */ static int DictSizeCmd( ClientData dummy, Tcl_Interp *interp, | | | > | 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 | *---------------------------------------------------------------------- */ static int DictSizeCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { int result; size_t size; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "dictionary"); return TCL_ERROR; } result = Tcl_DictObjSize(interp, objv[1], &size); if (result == TCL_OK) { |
︙ | ︙ | |||
1992 1993 1994 1995 1996 1997 1998 | *---------------------------------------------------------------------- */ static int DictExistsCmd( ClientData dummy, Tcl_Interp *interp, | | | 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 | *---------------------------------------------------------------------- */ static int DictExistsCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *dictPtr, *valuePtr; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "dictionary key ?key ...?"); return TCL_ERROR; |
︙ | ︙ | |||
2036 2037 2038 2039 2040 2041 2042 | *---------------------------------------------------------------------- */ static int DictInfoCmd( ClientData dummy, Tcl_Interp *interp, | | | 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 | *---------------------------------------------------------------------- */ static int DictInfoCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *dictPtr; Dict *dict; char *statsStr; if (objc != 2) { |
︙ | ︙ | |||
2058 2059 2060 2061 2062 2063 2064 | if (result != TCL_OK) { return result; } } dict = dictPtr->internalRep.twoPtrValue.ptr1; statsStr = Tcl_HashStats(&dict->table); | | | 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 | if (result != TCL_OK) { return result; } } dict = dictPtr->internalRep.twoPtrValue.ptr1; statsStr = Tcl_HashStats(&dict->table); Tcl_SetObjResult(interp, Tcl_NewStringObj(statsStr, TCL_STRLEN)); ckfree(statsStr); return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
2085 2086 2087 2088 2089 2090 2091 | *---------------------------------------------------------------------- */ static int DictIncrCmd( ClientData dummy, Tcl_Interp *interp, | | | 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 | *---------------------------------------------------------------------- */ static int DictIncrCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { int code = TCL_OK; Tcl_Obj *dictPtr, *valuePtr = NULL; if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "varName key ?increment?"); |
︙ | ︙ | |||
2206 2207 2208 2209 2210 2211 2212 | *---------------------------------------------------------------------- */ static int DictLappendCmd( ClientData dummy, Tcl_Interp *interp, | | | 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 | *---------------------------------------------------------------------- */ static int DictLappendCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *dictPtr, *valuePtr, *resultPtr; int i, allocatedDict = 0, allocatedValue = 0; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "varName key ?value ...?"); |
︙ | ︙ | |||
2293 2294 2295 2296 2297 2298 2299 | *---------------------------------------------------------------------- */ static int DictAppendCmd( ClientData dummy, Tcl_Interp *interp, | | | 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 | *---------------------------------------------------------------------- */ static int DictAppendCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *dictPtr, *valuePtr, *resultPtr; int i, allocatedDict = 0; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "varName key ?value ...?"); |
︙ | ︙ | |||
2365 2366 2367 2368 2369 2370 2371 | *---------------------------------------------------------------------- */ static int DictForNRCmd( ClientData dummy, Tcl_Interp *interp, | | > | | | 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 | *---------------------------------------------------------------------- */ static int DictForNRCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Interp *iPtr = (Interp *) interp; Tcl_Obj *scriptObj, *keyVarObj, *valueVarObj; Tcl_Obj **varv, *keyObj, *valueObj; Tcl_DictSearch *searchPtr; size_t varc; int done; if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "{keyVar valueVar} dictionary script"); return TCL_ERROR; } /* * Parse arguments. */ if (TclListObjGetElements(interp, objv[1], &varc, &varv) != TCL_OK) { return TCL_ERROR; } if (varc != 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "must have exactly two variable names", TCL_STRLEN)); return TCL_ERROR; } searchPtr = TclStackAlloc(interp, sizeof(Tcl_DictSearch)); if (Tcl_DictObjFirst(interp, objv[2], searchPtr, &keyObj, &valueObj, &done) != TCL_OK) { TclStackFree(interp, searchPtr); return TCL_ERROR; |
︙ | ︙ | |||
2557 2558 2559 2560 2561 2562 2563 | *---------------------------------------------------------------------- */ static int DictMapNRCmd( ClientData dummy, Tcl_Interp *interp, | | > | | | 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 | *---------------------------------------------------------------------- */ static int DictMapNRCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Interp *iPtr = (Interp *) interp; Tcl_Obj **varv, *keyObj, *valueObj; DictMapStorage *storagePtr; size_t varc; int done; if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "{keyVar valueVar} dictionary script"); return TCL_ERROR; } /* * Parse arguments. */ if (TclListObjGetElements(interp, objv[1], &varc, &varv) != TCL_OK) { return TCL_ERROR; } if (varc != 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "must have exactly two variable names", TCL_STRLEN)); return TCL_ERROR; } storagePtr = TclStackAlloc(interp, sizeof(DictMapStorage)); if (Tcl_DictObjFirst(interp, objv[2], &storagePtr->search, &keyObj, &valueObj, &done) != TCL_OK) { TclStackFree(interp, storagePtr); return TCL_ERROR; |
︙ | ︙ | |||
2768 2769 2770 2771 2772 2773 2774 | *---------------------------------------------------------------------- */ static int DictSetCmd( ClientData dummy, Tcl_Interp *interp, | | | 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 | *---------------------------------------------------------------------- */ static int DictSetCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *dictPtr, *resultPtr; int result, allocatedDict = 0; if (objc < 4) { Tcl_WrongNumArgs(interp, 1, objv, "varName key ?key ...? value"); |
︙ | ︙ | |||
2828 2829 2830 2831 2832 2833 2834 | *---------------------------------------------------------------------- */ static int DictUnsetCmd( ClientData dummy, Tcl_Interp *interp, | | | 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 | *---------------------------------------------------------------------- */ static int DictUnsetCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Obj *dictPtr, *resultPtr; int result, allocatedDict = 0; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "varName key ?key ...?"); |
︙ | ︙ | |||
2887 2888 2889 2890 2891 2892 2893 | *---------------------------------------------------------------------- */ static int DictFilterCmd( ClientData dummy, Tcl_Interp *interp, | | | > | 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 | *---------------------------------------------------------------------- */ static int DictFilterCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Interp *iPtr = (Interp *) interp; static const char *const filters[] = { "key", "script", "value", NULL }; enum FilterTypes { FILTER_KEYS, FILTER_SCRIPT, FILTER_VALUES }; Tcl_Obj *scriptObj, *keyVarObj, *valueVarObj; Tcl_Obj **varv, *keyObj = NULL, *valueObj = NULL, *resultObj, *boolObj; Tcl_DictSearch search; int index, done, result, satisfied; const char *pattern; size_t varc; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "dictionary filterType ?arg ...?"); return TCL_ERROR; } if (Tcl_GetIndexFromObjStruct(interp, objv[2], filters, sizeof(char *), "filterType", 0, &index) != TCL_OK) { |
︙ | ︙ | |||
3018 3019 3020 3021 3022 3023 3024 | */ if (TclListObjGetElements(interp, objv[3], &varc, &varv) != TCL_OK) { return TCL_ERROR; } if (varc != 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 | */ if (TclListObjGetElements(interp, objv[3], &varc, &varv) != TCL_OK) { return TCL_ERROR; } if (varc != 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "must have exactly two variable names", TCL_STRLEN)); return TCL_ERROR; } keyVarObj = varv[0]; valueVarObj = varv[1]; scriptObj = objv[4]; /* |
︙ | ︙ | |||
3174 3175 3176 3177 3178 3179 3180 | *---------------------------------------------------------------------- */ static int DictUpdateCmd( ClientData clientData, Tcl_Interp *interp, | | | > | 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 | *---------------------------------------------------------------------- */ static int DictUpdateCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Interp *iPtr = (Interp *) interp; Tcl_Obj *dictPtr, *objPtr; int i; size_t dummy; if (objc < 5 || !(objc & 1)) { Tcl_WrongNumArgs(interp, 1, objv, "varName key varName ?key varName ...? script"); return TCL_ERROR; } |
︙ | ︙ | |||
3232 3233 3234 3235 3236 3237 3238 | FinalizeDictUpdate( ClientData data[], Tcl_Interp *interp, int result) { Tcl_Obj *dictPtr, *objPtr, **objv; Tcl_InterpState state; | | > | 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 | FinalizeDictUpdate( ClientData data[], Tcl_Interp *interp, int result) { Tcl_Obj *dictPtr, *objPtr, **objv; Tcl_InterpState state; int i; size_t objc; Tcl_Obj *varName = data[0]; Tcl_Obj *argsObj = data[1]; /* * ErrorInfo handling. */ |
︙ | ︙ | |||
3333 3334 3335 3336 3337 3338 3339 | *---------------------------------------------------------------------- */ static int DictWithCmd( ClientData dummy, Tcl_Interp *interp, | | | 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 | *---------------------------------------------------------------------- */ static int DictWithCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Interp *iPtr = (Interp *) interp; Tcl_Obj *dictPtr, *keysPtr, *pathPtr; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "dictVar ?key ...? script"); |
︙ | ︙ | |||
3383 3384 3385 3386 3387 3388 3389 | static int FinalizeDictWith( ClientData data[], Tcl_Interp *interp, int result) { Tcl_Obj **pathv; | | | 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 | static int FinalizeDictWith( ClientData data[], Tcl_Interp *interp, int result) { Tcl_Obj **pathv; size_t pathc; Tcl_InterpState state; Tcl_Obj *varName = data[0]; Tcl_Obj *keysPtr = data[1]; Tcl_Obj *pathPtr = data[2]; Var *varPtr, *arrayPtr; if (result == TCL_ERROR) { |
︙ | ︙ | |||
3460 3461 3462 3463 3464 3465 3466 | *---------------------------------------------------------------------- */ Tcl_Obj * TclDictWithInit( Tcl_Interp *interp, Tcl_Obj *dictPtr, | | | 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 | *---------------------------------------------------------------------- */ Tcl_Obj * TclDictWithInit( Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t pathc, Tcl_Obj *const pathv[]) { Tcl_DictSearch s; Tcl_Obj *keyPtr, *valPtr, *keysPtr; int done; if (pathc > 0) { |
︙ | ︙ | |||
3540 3541 3542 3543 3544 3545 3546 | * the name of a variable. NULL if the 'index' * parameter is >= 0 */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ int index, /* Index into the local variable table of the * variable, or -1. Only used when part1Ptr is * NULL. */ | | | > | 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 | * the name of a variable. NULL if the 'index' * parameter is >= 0 */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ int index, /* Index into the local variable table of the * variable, or -1. Only used when part1Ptr is * NULL. */ size_t pathc, /* The number of elements in the path into the * dictionary. */ Tcl_Obj *const pathv[], /* The elements of the path to the subdict. */ Tcl_Obj *keysPtr) /* List of keys to be synchronized. This is * the result value from TclDictWithInit. */ { Tcl_Obj *dictPtr, *leafPtr, *valPtr; size_t i, keyc; Tcl_Obj **keyv; int allocdict; /* * If the dictionary variable doesn't exist, drop everything silently. */ dictPtr = TclPtrGetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr, TCL_LEAVE_ERR_MSG, index); |
︙ | ︙ |
Changes to generic/tclEncoding.c.
︙ | ︙ | |||
33 34 35 36 37 38 39 | Tcl_EncodingFreeProc *freeProc; /* If non-NULL, function to call when this * encoding is deleted. */ int nullSize; /* Number of 0x00 bytes that signify * end-of-string in this encoding. This number * is used to determine the source string * length when the srcLen argument is | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | Tcl_EncodingFreeProc *freeProc; /* If non-NULL, function to call when this * encoding is deleted. */ int nullSize; /* Number of 0x00 bytes that signify * end-of-string in this encoding. This number * is used to determine the source string * length when the srcLen argument is * TCL_STRLEN. This number can be 1 or 2. */ ClientData clientData; /* Arbitrary value associated with encoding * type. Passed to conversion functions. */ LengthProc *lengthProc; /* Function to compute length of * null-terminated strings in this encoding. * If nullSize is 1, this is strlen; if * nullSize is 2, this is a function that * returns the number of bytes in a 0x0000 |
︙ | ︙ | |||
190 191 192 193 194 195 196 | static unsigned short emptyPage[256]; /* * Functions used only in this module. */ | < < | < < | | < | < < < < < < < | | < < < < < | < < | < < < < | < < < < | | | > | | | < < < < | < < < < | < < < < | < < < < | 190 191 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 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | static unsigned short emptyPage[256]; /* * Functions used only in this module. */ static Tcl_EncodingConvertProc BinaryProc; static void DupEncodingIntRep(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr); static Tcl_EncodingFreeProc EscapeFreeProc; static Tcl_EncodingConvertProc EscapeFromUtfProc; static Tcl_EncodingConvertProc EscapeToUtfProc; static void FillEncodingFileMap(void); static void FreeEncoding(Tcl_Encoding encoding); static void FreeEncodingIntRep(Tcl_Obj *objPtr); static Encoding * GetTableEncoding(EscapeEncodingData *dataPtr, int state); static Tcl_Encoding LoadEncodingFile(Tcl_Interp *interp, const char *name); static Tcl_Encoding LoadTableEncoding(const char *name, int type, Tcl_Channel chan); static Tcl_Encoding LoadEscapeEncoding(const char *name, Tcl_Channel chan); static Tcl_Channel OpenEncodingFileChannel(Tcl_Interp *interp, const char *name); static Tcl_EncodingFreeProc TableFreeProc; static Tcl_EncodingConvertProc TableFromUtfProc; static Tcl_EncodingConvertProc TableToUtfProc; static size_t unilen(const char *src); static Tcl_EncodingConvertProc UnicodeToUtfProc; static Tcl_EncodingConvertProc UtfToUnicodeProc; static int UtfToUtfProc(ClientData clientData, const char *src, size_t srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, size_t dstLen, size_t *srcReadPtr, size_t *dstWrotePtr, size_t *dstCharsPtr, int pureNullMode); static Tcl_EncodingConvertProc UtfIntToUtfExtProc; static Tcl_EncodingConvertProc UtfExtToUtfIntProc; static Tcl_EncodingConvertProc Iso88591FromUtfProc; static Tcl_EncodingConvertProc Iso88591ToUtfProc; /* * A Tcl_ObjType for holding a cached Tcl_Encoding in the twoPtrValue.ptr1 field * of the intrep. This should help the lifetime of encodings be more useful. * See concerns raised in [Bug 1077262]. */ |
︙ | ︙ | |||
387 388 389 390 391 392 393 | *---------------------------------------------------------------------- */ int Tcl_SetEncodingSearchPath( Tcl_Obj *searchPath) { | | | 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | *---------------------------------------------------------------------- */ int Tcl_SetEncodingSearchPath( Tcl_Obj *searchPath) { size_t dummy; if (TCL_ERROR == Tcl_ListObjLength(NULL, searchPath, &dummy)) { return TCL_ERROR; } TclSetProcessGlobalValue(&encodingSearchPath, searchPath, NULL); return TCL_OK; } |
︙ | ︙ | |||
435 436 437 438 439 440 441 | *---------------------------------------------------------------------- */ void TclSetLibraryPath( Tcl_Obj *path) { | | | 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | *---------------------------------------------------------------------- */ void TclSetLibraryPath( Tcl_Obj *path) { size_t dummy; if (TCL_ERROR == Tcl_ListObjLength(NULL, path, &dummy)) { return; } TclSetProcessGlobalValue(&libraryPath, path, NULL); } |
︙ | ︙ | |||
472 473 474 475 476 477 478 | * *--------------------------------------------------------------------------- */ static void FillEncodingFileMap(void) { | | | | | 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 | * *--------------------------------------------------------------------------- */ static void FillEncodingFileMap(void) { size_t i, numDirs = 0; Tcl_Obj *map, *searchPath; searchPath = Tcl_GetEncodingSearchPath(); Tcl_IncrRefCount(searchPath); Tcl_ListObjLength(NULL, searchPath, &numDirs); map = Tcl_NewDictObj(); Tcl_IncrRefCount(map); for (i = numDirs; i-->0 ;) { /* * Iterate backwards through the search path so as we overwrite * entries found, we favor files earlier on the search path. */ size_t j, numFiles; Tcl_Obj *directory, *matchFileList = Tcl_NewObj(); Tcl_Obj **filev; Tcl_GlobTypeData readableFiles = { TCL_GLOB_TYPE_FILE, TCL_GLOB_PERM_R, NULL, NULL }; Tcl_ListObjIndex(NULL, searchPath, i, &directory); |
︙ | ︙ | |||
857 858 859 860 861 862 863 | Tcl_MutexLock(&encodingMutex); for (hPtr = Tcl_FirstHashEntry(&encodingTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { Encoding *encodingPtr = Tcl_GetHashValue(hPtr); Tcl_CreateHashEntry(&table, | | | 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 | Tcl_MutexLock(&encodingMutex); for (hPtr = Tcl_FirstHashEntry(&encodingTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { Encoding *encodingPtr = Tcl_GetHashValue(hPtr); Tcl_CreateHashEntry(&table, Tcl_NewStringObj(encodingPtr->name, TCL_STRLEN), &dummy); } Tcl_MutexUnlock(&encodingMutex); FillEncodingFileMap(); map = TclGetProcessGlobalValue(&encodingFileMap); /* |
︙ | ︙ | |||
1037 1038 1039 1040 1041 1042 1043 | */ char * Tcl_ExternalToUtfDString( Tcl_Encoding encoding, /* The encoding for the source string, or NULL * for the default system encoding. */ const char *src, /* Source string in specified encoding. */ | | | > > | | | 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 | */ char * Tcl_ExternalToUtfDString( Tcl_Encoding encoding, /* The encoding for the source string, or NULL * for the default system encoding. */ const char *src, /* Source string in specified encoding. */ size_t srcLen, /* Source string length in bytes, or * TCL_STRLEN for encoding-specific string * length. */ Tcl_DString *dstPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { char *dst; Tcl_EncodingState state; const Encoding *encodingPtr; int flags, result; size_t dstLen, soFar, srcRead, dstWrote, dstChars; Tcl_DStringInit(dstPtr); dst = Tcl_DStringValue(dstPtr); dstLen = dstPtr->spaceAvl - 1; if (encoding == NULL) { encoding = systemEncoding; } encodingPtr = (Encoding *) encoding; if (src == NULL) { srcLen = 0; } else if (srcLen == TCL_STRLEN) { srcLen = encodingPtr->lengthProc(src); } flags = TCL_ENCODING_START | TCL_ENCODING_END; while (1) { result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen, |
︙ | ︙ | |||
1110 1111 1112 1113 1114 1115 1116 | int Tcl_ExternalToUtf( Tcl_Interp *interp, /* Interp for error return, if not NULL. */ Tcl_Encoding encoding, /* The encoding for the source string, or NULL * for the default system encoding. */ const char *src, /* Source string in specified encoding. */ | | | > | | | | > | | | 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 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 | int Tcl_ExternalToUtf( Tcl_Interp *interp, /* Interp for error return, if not NULL. */ Tcl_Encoding encoding, /* The encoding for the source string, or NULL * for the default system encoding. */ const char *src, /* Source string in specified encoding. */ size_t srcLen, /* Source string length in bytes, or * TCL_STRLEN for encoding-specific string * length. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { const Encoding *encodingPtr; int result; size_t srcRead, dstWrote, dstChars; Tcl_EncodingState state; if (encoding == NULL) { encoding = systemEncoding; } encodingPtr = (Encoding *) encoding; if (src == NULL) { srcLen = 0; } else if (srcLen == TCL_STRLEN) { srcLen = encodingPtr->lengthProc(src); } if (statePtr == NULL) { flags |= TCL_ENCODING_START | TCL_ENCODING_END; statePtr = &state; } if (srcReadPtr == NULL) { |
︙ | ︙ | |||
1203 1204 1205 1206 1207 1208 1209 | */ char * Tcl_UtfToExternalDString( Tcl_Encoding encoding, /* The encoding for the converted string, or * NULL for the default system encoding. */ const char *src, /* Source string in UTF-8. */ | | | > | | | 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 | */ char * Tcl_UtfToExternalDString( Tcl_Encoding encoding, /* The encoding for the converted string, or * NULL for the default system encoding. */ const char *src, /* Source string in UTF-8. */ size_t srcLen, /* Source string length in bytes, or * TCL_STRLEN for strlen(). */ Tcl_DString *dstPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { char *dst; Tcl_EncodingState state; const Encoding *encodingPtr; int flags, result; size_t dstLen, soFar, srcRead, dstWrote, dstChars; Tcl_DStringInit(dstPtr); dst = Tcl_DStringValue(dstPtr); dstLen = dstPtr->spaceAvl - 1; if (encoding == NULL) { encoding = systemEncoding; } encodingPtr = (Encoding *) encoding; if (src == NULL) { srcLen = 0; } else if (srcLen == TCL_STRLEN) { srcLen = strlen(src); } flags = TCL_ENCODING_START | TCL_ENCODING_END; while (1) { result = encodingPtr->fromUtfProc(encodingPtr->clientData, src, srcLen, flags, &state, dst, dstLen, &srcRead, &dstWrote, &dstChars); |
︙ | ︙ | |||
1278 1279 1280 1281 1282 1283 1284 | int Tcl_UtfToExternal( Tcl_Interp *interp, /* Interp for error return, if not NULL. */ Tcl_Encoding encoding, /* The encoding for the converted string, or * NULL for the default system encoding. */ const char *src, /* Source string in UTF-8. */ | | | | | | | > | | | 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 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 1289 1290 1291 | int Tcl_UtfToExternal( Tcl_Interp *interp, /* Interp for error return, if not NULL. */ Tcl_Encoding encoding, /* The encoding for the converted string, or * NULL for the default system encoding. */ const char *src, /* Source string in UTF-8. */ size_t srcLen, /* Source string length in bytes, or * TCL_STRLEN for strlen(). */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string * is stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { const Encoding *encodingPtr; int result; size_t srcRead, dstWrote, dstChars; Tcl_EncodingState state; if (encoding == NULL) { encoding = systemEncoding; } encodingPtr = (Encoding *) encoding; if (src == NULL) { srcLen = 0; } else if (srcLen == TCL_STRLEN) { srcLen = strlen(src); } if (statePtr == NULL) { flags |= TCL_ENCODING_START | TCL_ENCODING_END; statePtr = &state; } if (srcReadPtr == NULL) { |
︙ | ︙ | |||
1395 1396 1397 1398 1399 1400 1401 | static Tcl_Channel OpenEncodingFileChannel( Tcl_Interp *interp, /* Interp for error reporting, if not NULL. */ const char *name) /* The name of the encoding file on disk and * also the name for new encoding. */ { | | | | | 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 | static Tcl_Channel OpenEncodingFileChannel( Tcl_Interp *interp, /* Interp for error reporting, if not NULL. */ const char *name) /* The name of the encoding file on disk and * also the name for new encoding. */ { Tcl_Obj *nameObj = Tcl_NewStringObj(name, TCL_STRLEN); Tcl_Obj *fileNameObj = Tcl_DuplicateObj(nameObj); Tcl_Obj *searchPath = Tcl_DuplicateObj(Tcl_GetEncodingSearchPath()); Tcl_Obj *map = TclGetProcessGlobalValue(&encodingFileMap); Tcl_Obj **dir, *path, *directory = NULL; Tcl_Channel chan = NULL; size_t i, numDirs; Tcl_ListObjGetElements(NULL, searchPath, &numDirs, &dir); Tcl_IncrRefCount(nameObj); Tcl_AppendToObj(fileNameObj, ".enc", TCL_STRLEN); Tcl_IncrRefCount(fileNameObj); Tcl_DictObjGet(NULL, map, nameObj, &directory); /* * Check that any cached directory is still on the encoding search path. */ |
︙ | ︙ | |||
1897 1898 1899 1900 1901 1902 1903 | Tcl_EncodingType type; init[0] = '\0'; final[0] = '\0'; Tcl_DStringInit(&escapeData); while (1) { | | | 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 | Tcl_EncodingType type; init[0] = '\0'; final[0] = '\0'; Tcl_DStringInit(&escapeData); while (1) { size_t argc; const char **argv; char *line; Tcl_DString lineString; Tcl_DStringInit(&lineString); if (Tcl_Gets(chan, &lineString) < 0) { break; |
︙ | ︙ | |||
2009 2010 2011 2012 2013 2014 2015 | *------------------------------------------------------------------------- */ static int BinaryProc( ClientData clientData, /* Not used. */ const char *src, /* Source string (unknown encoding). */ | | | | | | | | 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 | *------------------------------------------------------------------------- */ static int BinaryProc( ClientData clientData, /* Not used. */ const char *src, /* Source string (unknown encoding). */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { int result; result = TCL_OK; dstLen -= TCL_UTF_MAX - 1; if (dstLen < 0) { dstLen = 0; } if (srcLen > dstLen) { srcLen = dstLen; result = TCL_CONVERT_NOSPACE; } *srcReadPtr = srcLen; *dstWrotePtr = srcLen; *dstCharsPtr = srcLen; memcpy(dst, src, srcLen); return result; } /* *------------------------------------------------------------------------- * * UtfExtToUtfIntProc -- |
︙ | ︙ | |||
2070 2071 2072 2073 2074 2075 2076 | *------------------------------------------------------------------------- */ static int UtfIntToUtfExtProc( ClientData clientData, /* Not used. */ const char *src, /* Source string in UTF-8. */ | | | | | | | 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 | *------------------------------------------------------------------------- */ static int UtfIntToUtfExtProc( ClientData clientData, /* Not used. */ const char *src, /* Source string in UTF-8. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string * is stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { return UtfToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr, 1); } |
︙ | ︙ | |||
2119 2120 2121 2122 2123 2124 2125 | *------------------------------------------------------------------------- */ static int UtfExtToUtfIntProc( ClientData clientData, /* Not used. */ const char *src, /* Source string in UTF-8. */ | | | | | | | 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 | *------------------------------------------------------------------------- */ static int UtfExtToUtfIntProc( ClientData clientData, /* Not used. */ const char *src, /* Source string in UTF-8. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { return UtfToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr, 0); } |
︙ | ︙ | |||
2168 2169 2170 2171 2172 2173 2174 | *------------------------------------------------------------------------- */ static int UtfToUtfProc( ClientData clientData, /* Not used. */ const char *src, /* Source string in UTF-8. */ | | | | | | | > | 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 | *------------------------------------------------------------------------- */ static int UtfToUtfProc( ClientData clientData, /* Not used. */ const char *src, /* Source string in UTF-8. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr, /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ int pureNullMode) /* Convert embedded nulls from internal * representation to real null-bytes or vice * versa. */ { const char *srcStart, *srcEnd, *srcClose; const char *dstStart, *dstEnd; int result; size_t numChars; Tcl_UniChar ch; result = TCL_OK; srcStart = src; srcEnd = src + srcLen; srcClose = srcEnd; |
︙ | ︙ | |||
2282 2283 2284 2285 2286 2287 2288 | *------------------------------------------------------------------------- */ static int UnicodeToUtfProc( ClientData clientData, /* Not used. */ const char *src, /* Source string in Unicode. */ | | | | | | | > | 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 | *------------------------------------------------------------------------- */ static int UnicodeToUtfProc( ClientData clientData, /* Not used. */ const char *src, /* Source string in Unicode. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { const char *srcStart, *srcEnd; const char *dstEnd, *dstStart; int result; size_t numChars; Tcl_UniChar ch; result = TCL_OK; if ((srcLen % sizeof(Tcl_UniChar)) != 0) { result = TCL_CONVERT_MULTIBYTE; srcLen /= sizeof(Tcl_UniChar); srcLen *= sizeof(Tcl_UniChar); |
︙ | ︙ | |||
2370 2371 2372 2373 2374 2375 2376 | */ static int UtfToUnicodeProc( ClientData clientData, /* TableEncodingData that specifies * encoding. */ const char *src, /* Source string in UTF-8. */ | | | | | | | > | 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 | */ static int UtfToUnicodeProc( ClientData clientData, /* TableEncodingData that specifies * encoding. */ const char *src, /* Source string in UTF-8. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd; int result; size_t numChars; Tcl_UniChar ch; srcStart = src; srcEnd = src + srcLen; srcClose = srcEnd; if ((flags & TCL_ENCODING_END) == 0) { srcClose -= TCL_UTF_MAX; |
︙ | ︙ | |||
2466 2467 2468 2469 2470 2471 2472 | */ static int TableToUtfProc( ClientData clientData, /* TableEncodingData that specifies * encoding. */ const char *src, /* Source string in specified encoding. */ | | | | | | | > | 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 | */ static int TableToUtfProc( ClientData clientData, /* TableEncodingData that specifies * encoding. */ const char *src, /* Source string in specified encoding. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { const char *srcStart, *srcEnd; const char *dstEnd, *dstStart, *prefixBytes; int result, byte; size_t numChars; Tcl_UniChar ch; const unsigned short *const *toUnicode; const unsigned short *pageZero; TableEncodingData *dataPtr = clientData; srcStart = src; srcEnd = src + srcLen; |
︙ | ︙ | |||
2576 2577 2578 2579 2580 2581 2582 | */ static int TableFromUtfProc( ClientData clientData, /* TableEncodingData that specifies * encoding. */ const char *src, /* Source string in UTF-8. */ | | | | | | | > | 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 | */ static int TableFromUtfProc( ClientData clientData, /* TableEncodingData that specifies * encoding. */ const char *src, /* Source string in UTF-8. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { const char *srcStart, *srcEnd, *srcClose; const char *dstStart, *dstEnd, *prefixBytes; Tcl_UniChar ch; int result, word; size_t len, numChars; TableEncodingData *dataPtr = clientData; const unsigned short *const *fromUnicode; result = TCL_OK; prefixBytes = dataPtr->prefixBytes; fromUnicode = (const unsigned short *const *) dataPtr->fromUnicode; |
︙ | ︙ | |||
2697 2698 2699 2700 2701 2702 2703 | *------------------------------------------------------------------------- */ static int Iso88591ToUtfProc( ClientData clientData, /* Ignored. */ const char *src, /* Source string in specified encoding. */ | | | | | | | > | 2666 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 | *------------------------------------------------------------------------- */ static int Iso88591ToUtfProc( ClientData clientData, /* Ignored. */ const char *src, /* Source string in specified encoding. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { const char *srcStart, *srcEnd; const char *dstEnd, *dstStart; int result; size_t numChars; srcStart = src; srcEnd = src + srcLen; dstStart = dst; dstEnd = dst + dstLen - TCL_UTF_MAX; |
︙ | ︙ | |||
2778 2779 2780 2781 2782 2783 2784 | *------------------------------------------------------------------------- */ static int Iso88591FromUtfProc( ClientData clientData, /* Ignored. */ const char *src, /* Source string in UTF-8. */ | | | | | | | > | | 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 | *------------------------------------------------------------------------- */ static int Iso88591FromUtfProc( ClientData clientData, /* Ignored. */ const char *src, /* Source string in UTF-8. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { const char *srcStart, *srcEnd, *srcClose; const char *dstStart, *dstEnd; int result; size_t numChars; result = TCL_OK; srcStart = src; srcEnd = src + srcLen; srcClose = srcEnd; if ((flags & TCL_ENCODING_END) == 0) { srcClose -= TCL_UTF_MAX; } dstStart = dst; dstEnd = dst + dstLen - 1; for (numChars = 0; src < srcEnd; numChars++) { Tcl_UniChar ch; size_t len; if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) { /* * If there is more string to follow, this will ensure that the * last UTF-8 character in the source buffer hasn't been cut off. */ |
︙ | ︙ | |||
2918 2919 2920 2921 2922 2923 2924 | */ static int EscapeToUtfProc( ClientData clientData, /* EscapeEncodingData that specifies * encoding. */ const char *src, /* Source string in specified encoding. */ | | | | | | | > | 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 | */ static int EscapeToUtfProc( ClientData clientData, /* EscapeEncodingData that specifies * encoding. */ const char *src, /* Source string in specified encoding. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { EscapeEncodingData *dataPtr = clientData; const char *prefixBytes, *tablePrefixBytes, *srcStart, *srcEnd; const unsigned short *const *tableToUnicode; const Encoding *encodingPtr; int state, result; size_t numChars; const char *dstStart, *dstEnd; result = TCL_OK; tablePrefixBytes = NULL; /* lint. */ tableToUnicode = NULL; /* lint. */ prefixBytes = dataPtr->prefixBytes; encodingPtr = NULL; |
︙ | ︙ | |||
2974 2975 2976 2977 2978 2979 2980 | if (dst > dstEnd) { result = TCL_CONVERT_NOSPACE; break; } byte = *((unsigned char *) src); if (prefixBytes[byte]) { | | | 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 | if (dst > dstEnd) { result = TCL_CONVERT_NOSPACE; break; } byte = *((unsigned char *) src); if (prefixBytes[byte]) { size_t left, len, longest; int checked, i; const EscapeSubTable *subTablePtr; /* * Saw the beginning of an escape sequence. */ |
︙ | ︙ | |||
3129 3130 3131 3132 3133 3134 3135 | */ static int EscapeFromUtfProc( ClientData clientData, /* EscapeEncodingData that specifies * encoding. */ const char *src, /* Source string in UTF-8. */ | | | | | | | > | 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 | */ static int EscapeFromUtfProc( ClientData clientData, /* EscapeEncodingData that specifies * encoding. */ const char *src, /* Source string in UTF-8. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is * stored. */ size_t dstLen, /* The maximum length of output buffer in * bytes. */ size_t *srcReadPtr, /* Filled with the number of bytes from the * source string that were converted. This may * be less than the original source length if * there was a problem converting some source * characters. */ size_t *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ size_t *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ { EscapeEncodingData *dataPtr = clientData; const Encoding *encodingPtr; const char *srcStart, *srcEnd, *srcClose; const char *dstStart, *dstEnd; int state, result; size_t numChars; const TableEncodingData *tableDataPtr; const char *tablePrefixBytes; const unsigned short *const *tableFromUnicode; result = TCL_OK; srcStart = src; |
︙ | ︙ | |||
3198 3199 3200 3201 3202 3203 3204 | encodingPtr = GetTableEncoding(dataPtr, state); tableDataPtr = encodingPtr->clientData; tablePrefixBytes = tableDataPtr->prefixBytes; tableFromUnicode = (const unsigned short *const *) tableDataPtr->fromUnicode; for (numChars = 0; src < srcEnd; numChars++) { | | | 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 | encodingPtr = GetTableEncoding(dataPtr, state); tableDataPtr = encodingPtr->clientData; tablePrefixBytes = tableDataPtr->prefixBytes; tableFromUnicode = (const unsigned short *const *) tableDataPtr->fromUnicode; for (numChars = 0; src < srcEnd; numChars++) { size_t len; int word; Tcl_UniChar ch; if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) { /* * If there is more string to follow, this will ensure that the * last UTF-8 character in the source buffer hasn't been cut off. |
︙ | ︙ | |||
3469 3470 3471 3472 3473 3474 3475 | * *------------------------------------------------------------------------- */ static void InitializeEncodingSearchPath( char **valuePtr, | | > | | 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 | * *------------------------------------------------------------------------- */ static void InitializeEncodingSearchPath( char **valuePtr, size_t *lengthPtr, Tcl_Encoding *encodingPtr) { const char *bytes; int i; size_t numBytes, numDirs; Tcl_Obj *libPathObj, *encodingObj, *searchPathObj; TclNewLiteralStringObj(encodingObj, "encoding"); TclNewObj(searchPathObj); Tcl_IncrRefCount(encodingObj); Tcl_IncrRefCount(searchPathObj); libPathObj = TclGetLibraryPath(); |
︙ | ︙ |
Changes to generic/tclEnsemble.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | /* * Declarations for functions local to this file: */ static inline Tcl_Obj * NewNsObj(Tcl_Namespace *namespacePtr); static inline int EnsembleUnknownCallback(Tcl_Interp *interp, | | | < | < | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * Declarations for functions local to this file: */ static inline Tcl_Obj * NewNsObj(Tcl_Namespace *namespacePtr); static inline int EnsembleUnknownCallback(Tcl_Interp *interp, EnsembleConfig *ensemblePtr, size_t objc, Tcl_Obj *const objv[], Tcl_Obj **prefixObjPtr); static Tcl_ObjCmdProc NsEnsembleImplementationCmd; static Tcl_ObjCmdProc NsEnsembleImplementationCmdNR; static void BuildEnsembleConfig(EnsembleConfig *ensemblePtr); static int NsEnsembleStringOrder(const void *strPtr1, const void *strPtr2); static void DeleteEnsembleConfig(ClientData clientData); static void MakeCachedEnsembleCommand(Tcl_Obj *objPtr, EnsembleConfig *ensemblePtr, const char *subcmdName, Tcl_Obj *prefixObjPtr); |
︙ | ︙ | |||
91 92 93 94 95 96 97 | Tcl_Namespace *namespacePtr) { register Namespace *nsPtr = (Namespace *) namespacePtr; if (namespacePtr == TclGetGlobalNamespace(nsPtr->interp)) { return Tcl_NewStringObj("::", 2); } else { | | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | Tcl_Namespace *namespacePtr) { register Namespace *nsPtr = (Namespace *) namespacePtr; if (namespacePtr == TclGetGlobalNamespace(nsPtr->interp)) { return Tcl_NewStringObj("::", 2); } else { return Tcl_NewStringObj(nsPtr->fullName, TCL_STRLEN); } } /* *---------------------------------------------------------------------- * * TclNamespaceEnsembleCmd -- |
︙ | ︙ | |||
121 122 123 124 125 126 127 | *---------------------------------------------------------------------- */ int TclNamespaceEnsembleCmd( ClientData dummy, Tcl_Interp *interp, | | | | > | 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 154 155 156 157 158 159 160 161 162 163 164 165 166 | *---------------------------------------------------------------------- */ int TclNamespaceEnsembleCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_Namespace *namespacePtr; Namespace *nsPtr = (Namespace *) TclGetCurrentNamespace(interp); Tcl_Command token; Tcl_DictSearch search; Tcl_Obj *listObj; int index, done; if (nsPtr == NULL || nsPtr->flags & NS_DYING) { if (!Tcl_InterpDeleted(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "tried to manipulate ensemble of deleted namespace", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "DEAD", NULL); } return TCL_ERROR; } if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?arg ...?"); return TCL_ERROR; } if (Tcl_GetIndexFromObjStruct(interp, objv[1], ensembleSubcommands, sizeof(char *), "subcommand", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum EnsSubcmds) index) { case ENS_CREATE: { const char *name; int allocatedMapFlag = 0; size_t len; /* * Defaults */ Tcl_Obj *subcmdObj = NULL; Tcl_Obj *mapObj = NULL; int permitPrefix = 1; Tcl_Obj *unknownObj = NULL; |
︙ | ︙ | |||
255 256 257 258 259 260 261 | Tcl_DecrRefCount(mapObj); } return TCL_ERROR; } if (len < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "ensemble subcommand implementations " | | | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | Tcl_DecrRefCount(mapObj); } return TCL_ERROR; } if (len < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "ensemble subcommand implementations " "must be non-empty lists", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "EMPTY_TARGET", NULL); Tcl_DictObjDone(&search); if (patchedDict) { Tcl_DecrRefCount(patchedDict); } if (allocatedMapFlag) { |
︙ | ︙ | |||
418 419 420 421 422 423 424 | Tcl_Obj *resultObj, *tmpObj = NULL; /* silence gcc 4 warning */ int flags = 0; /* silence gcc 4 warning */ TclNewObj(resultObj); /* -map option */ | | | | | < | | | | | | | | > | | 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 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 | Tcl_Obj *resultObj, *tmpObj = NULL; /* silence gcc 4 warning */ int flags = 0; /* silence gcc 4 warning */ TclNewObj(resultObj); /* -map option */ Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( ensembleConfigOptions[CONF_MAP], TCL_STRLEN)); Tcl_GetEnsembleMappingDict(NULL, token, &tmpObj); Tcl_ListObjAppendElement(NULL, resultObj, (tmpObj != NULL) ? tmpObj : Tcl_NewObj()); /* -namespace option */ Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( ensembleConfigOptions[CONF_NAMESPACE], TCL_STRLEN)); namespacePtr = NULL; /* silence gcc 4 warning */ Tcl_GetEnsembleNamespace(NULL, token, &namespacePtr); Tcl_ListObjAppendElement(NULL, resultObj, NewNsObj(namespacePtr)); /* -parameters option */ Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( ensembleConfigOptions[CONF_PARAM], TCL_STRLEN)); Tcl_GetEnsembleParameterList(NULL, token, &tmpObj); Tcl_ListObjAppendElement(NULL, resultObj, (tmpObj != NULL) ? tmpObj : Tcl_NewObj()); /* -prefix option */ Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( ensembleConfigOptions[CONF_PREFIX], TCL_STRLEN)); Tcl_GetEnsembleFlags(NULL, token, &flags); Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewBooleanObj(flags & TCL_ENSEMBLE_PREFIX)); /* -subcommands option */ Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( ensembleConfigOptions[CONF_SUBCMDS], TCL_STRLEN)); Tcl_GetEnsembleSubcommandList(NULL, token, &tmpObj); Tcl_ListObjAppendElement(NULL, resultObj, (tmpObj != NULL) ? tmpObj : Tcl_NewObj()); /* -unknown option */ Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( ensembleConfigOptions[CONF_UNKNOWN], TCL_STRLEN)); Tcl_GetEnsembleUnknownHandler(NULL, token, &tmpObj); Tcl_ListObjAppendElement(NULL, resultObj, (tmpObj != NULL) ? tmpObj : Tcl_NewObj()); Tcl_SetObjResult(interp, resultObj); } else { size_t len; int allocatedMapFlag = 0; Tcl_Obj *subcmdObj = NULL, *mapObj = NULL, *paramObj = NULL, *unknownObj = NULL; /* Defaults, silence gcc 4 warnings */ int permitPrefix, flags = 0; /* silence gcc 4 warning */ Tcl_GetEnsembleSubcommandList(NULL, token, &subcmdObj); Tcl_GetEnsembleMappingDict(NULL, token, &mapObj); Tcl_GetEnsembleParameterList(NULL, token, ¶mObj); |
︙ | ︙ | |||
534 535 536 537 538 539 540 | Tcl_DecrRefCount(patchedDict); } goto freeMapAndError; } if (len < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "ensemble subcommand implementations " | | | 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 | Tcl_DecrRefCount(patchedDict); } goto freeMapAndError; } if (len < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "ensemble subcommand implementations " "must be non-empty lists", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "EMPTY_TARGET", NULL); Tcl_DictObjDone(&search); if (patchedDict) { Tcl_DecrRefCount(patchedDict); } goto freeMapAndError; |
︙ | ︙ | |||
573 574 575 576 577 578 579 | if (patchedDict) { allocatedMapFlag = 1; } continue; } case CONF_NAMESPACE: Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 | if (patchedDict) { allocatedMapFlag = 1; } continue; } case CONF_NAMESPACE: Tcl_SetObjResult(interp, Tcl_NewStringObj( "option -namespace is read-only", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "READ_ONLY", NULL); goto freeMapAndError; case CONF_PREFIX: if (Tcl_GetBooleanFromObj(interp, objv[1], &permitPrefix) != TCL_OK) { goto freeMapAndError; |
︙ | ︙ | |||
723 724 725 726 727 728 729 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); return TCL_ERROR; } if (subcmdList != NULL) { size_t length; if (TclListObjLength(interp, subcmdList, &length) != TCL_OK) { return TCL_ERROR; } if (length < 1) { subcmdList = NULL; } |
︙ | ︙ | |||
795 796 797 798 799 800 801 | Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *paramList) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; | | | | 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 | Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *paramList) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; size_t length; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); return TCL_ERROR; } if (paramList == NULL) { length = 0; } else { if (TclListObjLength(interp, paramList, &length) != TCL_OK) { |
︙ | ︙ | |||
875 876 877 878 879 880 881 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldDict; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | | | 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldDict; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); return TCL_ERROR; } if (mapDict != NULL) { size_t size; int done; Tcl_DictSearch search; Tcl_Obj *valuePtr; if (Tcl_DictObjSize(interp, mapDict, &size) != TCL_OK) { return TCL_ERROR; } for (Tcl_DictObjFirst(NULL, mapDict, &search, NULL, &valuePtr, &done); !done; Tcl_DictObjNext(&search, NULL, &valuePtr, &done)) { Tcl_Obj *cmdObjPtr; const char *bytes; if (Tcl_ListObjIndex(interp, valuePtr, 0, &cmdObjPtr) != TCL_OK) { Tcl_DictObjDone(&search); return TCL_ERROR; } bytes = TclGetString(cmdObjPtr); if (bytes[0] != ':' || bytes[1] != ':') { Tcl_SetObjResult(interp, Tcl_NewStringObj( "ensemble target is not a fully-qualified command", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "UNQUALIFIED_TARGET", NULL); Tcl_DictObjDone(&search); return TCL_ERROR; } } |
︙ | ︙ | |||
974 975 976 977 978 979 980 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); return TCL_ERROR; } if (unknownList != NULL) { size_t length; if (TclListObjLength(interp, unknownList, &length) != TCL_OK) { return TCL_ERROR; } if (length < 1) { unknownList = NULL; } |
︙ | ︙ | |||
1040 1041 1042 1043 1044 1045 1046 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; int wasCompiled; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; int wasCompiled; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; wasCompiled = ensemblePtr->flags & ENSEMBLE_COMPILE; |
︙ | ︙ | |||
1117 1118 1119 1120 1121 1122 1123 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *subcmdListPtr = ensemblePtr->subcmdList; |
︙ | ︙ | |||
1159 1160 1161 1162 1163 1164 1165 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *paramListPtr = ensemblePtr->parameterList; |
︙ | ︙ | |||
1201 1202 1203 1204 1205 1206 1207 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *mapDictPtr = ensemblePtr->subcommandDict; |
︙ | ︙ | |||
1242 1243 1244 1245 1246 1247 1248 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *unknownListPtr = ensemblePtr->unknownHandler; |
︙ | ︙ | |||
1283 1284 1285 1286 1287 1288 1289 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *flagsPtr = ensemblePtr->flags; |
︙ | ︙ | |||
1324 1325 1326 1327 1328 1329 1330 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *namespacePtrPtr = (Tcl_Namespace *) ensemblePtr->nsPtr; |
︙ | ︙ | |||
1462 1463 1464 1465 1466 1467 1468 | const EnsembleImplMap map[]) /* The subcommands to create */ { Tcl_Command ensemble; Tcl_Namespace *ns; Tcl_DString buf, hiddenBuf; const char **nameParts = NULL; const char *cmdName = NULL; | | > | | | | 1462 1463 1464 1465 1466 1467 1468 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 | const EnsembleImplMap map[]) /* The subcommands to create */ { Tcl_Command ensemble; Tcl_Namespace *ns; Tcl_DString buf, hiddenBuf; const char **nameParts = NULL; const char *cmdName = NULL; int i, ensembleFlags = 0; size_t hiddenLen, nameCount = 0; /* * Construct the path for the ensemble namespace and create it. */ Tcl_DStringInit(&buf); Tcl_DStringInit(&hiddenBuf); TclDStringAppendLiteral(&hiddenBuf, "tcl:"); Tcl_DStringAppend(&hiddenBuf, name, TCL_STRLEN); TclDStringAppendLiteral(&hiddenBuf, ":"); hiddenLen = Tcl_DStringLength(&hiddenBuf); if (name[0] == ':' && name[1] == ':') { /* * An absolute name, so use it directly. */ cmdName = name; Tcl_DStringAppend(&buf, name, TCL_STRLEN); ensembleFlags = TCL_ENSEMBLE_PREFIX; } else { /* * Not an absolute name, so do munging of it. Note that this treats a * multi-word list differently to a single word. */ TclDStringAppendLiteral(&buf, "::tcl"); if (Tcl_SplitList(NULL, name, &nameCount, &nameParts) != TCL_OK) { Tcl_Panic("invalid ensemble name '%s'", name); } for (i = 0; i < nameCount; ++i) { TclDStringAppendLiteral(&buf, "::"); Tcl_DStringAppend(&buf, nameParts[i], TCL_STRLEN); } } ns = Tcl_FindNamespace(interp, Tcl_DStringValue(&buf), NULL, TCL_CREATE_NS_IF_UNKNOWN); if (!ns) { Tcl_Panic("unable to find or create %s namespace!", |
︙ | ︙ | |||
1541 1542 1543 1544 1545 1546 1547 | if (ensemble != NULL) { Tcl_Obj *mapDict, *fromObj, *toObj; Command *cmdPtr; TclDStringAppendLiteral(&buf, "::"); TclNewObj(mapDict); for (i=0 ; map[i].name != NULL ; i++) { | | | | > | 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 | if (ensemble != NULL) { Tcl_Obj *mapDict, *fromObj, *toObj; Command *cmdPtr; TclDStringAppendLiteral(&buf, "::"); TclNewObj(mapDict); for (i=0 ; map[i].name != NULL ; i++) { fromObj = Tcl_NewStringObj(map[i].name, TCL_STRLEN); TclNewStringObj(toObj, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf)); Tcl_AppendToObj(toObj, map[i].name, TCL_STRLEN); Tcl_DictObjPut(NULL, mapDict, fromObj, toObj); if (map[i].proc || map[i].nreProc) { /* * If the command is unsafe, hide it when we're in a safe * interpreter. The code to do this is really hokey! It also * doesn't work properly yet; this function is always * currently called before the safe-interp flag is set so the * Tcl_IsSafe check fails. */ if (map[i].unsafe && Tcl_IsSafe(interp)) { cmdPtr = (Command *) Tcl_NRCreateCommand(interp, "___tmp", map[i].proc, map[i].nreProc, map[i].clientData, NULL); Tcl_DStringSetLength(&hiddenBuf, hiddenLen); if (Tcl_HideCommand(interp, "___tmp", Tcl_DStringAppend(&hiddenBuf, map[i].name, TCL_STRLEN))) { Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp))); } } else { /* * Not hidden, so just create it. Yay! */ |
︙ | ︙ | |||
1615 1616 1617 1618 1619 1620 1621 | *---------------------------------------------------------------------- */ static int NsEnsembleImplementationCmd( ClientData clientData, Tcl_Interp *interp, | | | | 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 | *---------------------------------------------------------------------- */ static int NsEnsembleImplementationCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { return Tcl_NRCallObjProc(interp, NsEnsembleImplementationCmdNR, clientData, objc, objv); } static int NsEnsembleImplementationCmdNR( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { EnsembleConfig *ensemblePtr = clientData; /* The ensemble itself. */ Tcl_Obj *prefixObj; /* An object containing the prefix words of * the command that implements the * subcommand. */ |
︙ | ︙ | |||
1653 1654 1655 1656 1657 1658 1659 | if (objc < 2 + ensemblePtr->numParameters) { /* * We don't have a subcommand argument. Make error message. */ Tcl_DString buf; /* Message being built */ Tcl_Obj **elemPtrs; /* Parameter names */ | | | 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 | if (objc < 2 + ensemblePtr->numParameters) { /* * We don't have a subcommand argument. Make error message. */ Tcl_DString buf; /* Message being built */ Tcl_Obj **elemPtrs; /* Parameter names */ size_t len; /* Number of parameters to append */ Tcl_DStringInit(&buf); if (ensemblePtr->parameterList == NULL) { len = 0; } else if (TclListObjGetElements(NULL, ensemblePtr->parameterList, &len, &elemPtrs) != TCL_OK) { Tcl_Panic("List of ensemble parameters is not a list"); |
︙ | ︙ | |||
1680 1681 1682 1683 1684 1685 1686 | if (ensemblePtr->nsPtr->flags & NS_DYING) { /* * Don't know how we got here, but make things give up quickly. */ if (!Tcl_InterpDeleted(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 | if (ensemblePtr->nsPtr->flags & NS_DYING) { /* * Don't know how we got here, but make things give up quickly. */ if (!Tcl_InterpDeleted(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "ensemble activated for deleted namespace", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "DEAD", NULL); } return TCL_ERROR; } /* * Determine if the table of subcommands is right. If so, we can just look |
︙ | ︙ | |||
1751 1752 1753 1754 1755 1756 1757 | * matches. */ const char *subcmdName; /* Name of the subcommand, or unique prefix of * it (will be an error for a non-unique * prefix). */ char *fullName = NULL; /* Full name of the subcommand. */ | | | | 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 | * matches. */ const char *subcmdName; /* Name of the subcommand, or unique prefix of * it (will be an error for a non-unique * prefix). */ char *fullName = NULL; /* Full name of the subcommand. */ size_t stringLength, i; size_t tableLength = ensemblePtr->subcommandTable.numEntries; subcmdName = TclGetString(objv[1 + ensemblePtr->numParameters]); stringLength = objv[1 + ensemblePtr->numParameters]->length; for (i=0 ; i<tableLength ; i++) { register int cmp = strncmp(subcmdName, ensemblePtr->subcommandArrayPtr[i], (unsigned) stringLength); |
︙ | ︙ | |||
1827 1828 1829 1830 1831 1832 1833 | */ { Tcl_Obj **prefixObjv; /* The list of objects to substitute in as the * target command prefix. */ Tcl_Obj *copyPtr; /* The actual list of words to dispatch to. * Will be freed by the dispatch engine. */ | | | 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 | */ { Tcl_Obj **prefixObjv; /* The list of objects to substitute in as the * target command prefix. */ Tcl_Obj *copyPtr; /* The actual list of words to dispatch to. * Will be freed by the dispatch engine. */ size_t prefixObjc, copyObjc; Interp *iPtr = (Interp *) interp; /* * Get the prefix that we're rewriting to. To do this we need to * ensure that the internal representation of the list does not change * so that we can safely keep the internal representations of the * elements in the list. |
︙ | ︙ | |||
1849 1850 1851 1852 1853 1854 1855 | copyPtr = Tcl_NewListObj(copyObjc, NULL); if (copyObjc > 0) { register Tcl_Obj **copyObjv; /* Space used to construct the list of * arguments to pass to the command that * implements the ensemble subcommand. */ register List *listRepPtr = copyPtr->internalRep.twoPtrValue.ptr1; | | | 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 | copyPtr = Tcl_NewListObj(copyObjc, NULL); if (copyObjc > 0) { register Tcl_Obj **copyObjv; /* Space used to construct the list of * arguments to pass to the command that * implements the ensemble subcommand. */ register List *listRepPtr = copyPtr->internalRep.twoPtrValue.ptr1; register size_t i; listRepPtr->elemCount = copyObjc; copyObjv = &listRepPtr->elements; memcpy(copyObjv, prefixObjv, sizeof(Tcl_Obj *) * prefixObjc); memcpy(copyObjv+prefixObjc, objv+1, sizeof(Tcl_Obj *) * ensemblePtr->numParameters); memcpy(copyObjv+prefixObjc+ensemblePtr->numParameters, |
︙ | ︙ | |||
1881 1882 1883 1884 1885 1886 1887 | iPtr->ensembleRewrite.numRemovedObjs = 2 + ensemblePtr->numParameters; iPtr->ensembleRewrite.numInsertedObjs = prefixObjc + ensemblePtr->numParameters; TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL); } else { | | | 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 | iPtr->ensembleRewrite.numRemovedObjs = 2 + ensemblePtr->numParameters; iPtr->ensembleRewrite.numInsertedObjs = prefixObjc + ensemblePtr->numParameters; TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL); } else { register ssize_t ni = 2 + ensemblePtr->numParameters - iPtr->ensembleRewrite.numInsertedObjs; /* Position in objv of new front of insertion * relative to old one. */ if (ni > 0) { iPtr->ensembleRewrite.numRemovedObjs += ni; iPtr->ensembleRewrite.numInsertedObjs += prefixObjc-1; } else { |
︙ | ︙ | |||
1945 1946 1947 1948 1949 1950 1951 | TclGetString(objv[1+ensemblePtr->numParameters]), NULL); return TCL_ERROR; } errorObj = Tcl_ObjPrintf("unknown%s subcommand \"%s\": must be ", (ensemblePtr->flags & TCL_ENSEMBLE_PREFIX ? " or ambiguous" : ""), TclGetString(objv[1+ensemblePtr->numParameters])); if (ensemblePtr->subcommandTable.numEntries == 1) { | | > | | > | 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 | TclGetString(objv[1+ensemblePtr->numParameters]), NULL); return TCL_ERROR; } errorObj = Tcl_ObjPrintf("unknown%s subcommand \"%s\": must be ", (ensemblePtr->flags & TCL_ENSEMBLE_PREFIX ? " or ambiguous" : ""), TclGetString(objv[1+ensemblePtr->numParameters])); if (ensemblePtr->subcommandTable.numEntries == 1) { Tcl_AppendToObj(errorObj, ensemblePtr->subcommandArrayPtr[0], TCL_STRLEN); } else { size_t i; for (i=0 ; i<ensemblePtr->subcommandTable.numEntries-1 ; i++) { Tcl_AppendToObj(errorObj, ensemblePtr->subcommandArrayPtr[i], TCL_STRLEN); Tcl_AppendToObj(errorObj, ", ", 2); } Tcl_AppendPrintfToObj(errorObj, "or %s", ensemblePtr->subcommandArrayPtr[i]); } Tcl_SetObjResult(interp, errorObj); return TCL_ERROR; |
︙ | ︙ | |||
2005 2006 2007 2008 2009 2010 2011 | int isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL); if (isRootEnsemble) { iPtr->ensembleRewrite.sourceObjs = objv; iPtr->ensembleRewrite.numRemovedObjs = numRemoved; iPtr->ensembleRewrite.numInsertedObjs = numInserted; } else { | | | 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 | int isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL); if (isRootEnsemble) { iPtr->ensembleRewrite.sourceObjs = objv; iPtr->ensembleRewrite.numRemovedObjs = numRemoved; iPtr->ensembleRewrite.numInsertedObjs = numInserted; } else { size_t numIns = iPtr->ensembleRewrite.numInsertedObjs; if (numIns < numRemoved) { iPtr->ensembleRewrite.numRemovedObjs += numRemoved - numIns; iPtr->ensembleRewrite.numInsertedObjs += numInserted - 1; } else { iPtr->ensembleRewrite.numInsertedObjs += numInserted - numRemoved; } |
︙ | ︙ | |||
2076 2077 2078 2079 2080 2081 2082 | * ---------------------------------------------------------------------- */ static inline int EnsembleUnknownCallback( Tcl_Interp *interp, EnsembleConfig *ensemblePtr, | | | > | 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 | * ---------------------------------------------------------------------- */ static inline int EnsembleUnknownCallback( Tcl_Interp *interp, EnsembleConfig *ensemblePtr, size_t objc, Tcl_Obj *const objv[], Tcl_Obj **prefixObjPtr) { size_t paramc, i, prefixObjc; Tcl_Obj **paramv, *unknownCmd, *ensObj; int result; /* * Create the unknown command callback to determine what to do. */ unknownCmd = Tcl_DuplicateObj(ensemblePtr->unknownHandler); TclNewObj(ensObj); |
︙ | ︙ | |||
2110 2111 2112 2113 2114 2115 2116 | Tcl_Preserve(ensemblePtr); TclSkipTailcall(interp); result = Tcl_EvalObjv(interp, paramc, paramv, 0); if ((result == TCL_OK) && (ensemblePtr->flags & ENSEMBLE_DEAD)) { if (!Tcl_InterpDeleted(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 | Tcl_Preserve(ensemblePtr); TclSkipTailcall(interp); result = Tcl_EvalObjv(interp, paramc, paramv, 0); if ((result == TCL_OK) && (ensemblePtr->flags & ENSEMBLE_DEAD)) { if (!Tcl_InterpDeleted(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unknown subcommand handler deleted its ensemble", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "UNKNOWN_DELETED", NULL); } result = TCL_ERROR; } Tcl_Release(ensemblePtr); |
︙ | ︙ | |||
2163 2164 2165 2166 2167 2168 2169 | * Oh no! An exceptional result. Convert to an error. */ if (!Tcl_InterpDeleted(interp)) { if (result != TCL_ERROR) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | > | > | > | 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 | * Oh no! An exceptional result. Convert to an error. */ if (!Tcl_InterpDeleted(interp)) { if (result != TCL_ERROR) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_NewStringObj( "unknown subcommand handler returned bad code: ", TCL_STRLEN)); switch (result) { case TCL_RETURN: Tcl_AppendToObj(Tcl_GetObjResult(interp), "return", TCL_STRLEN); break; case TCL_BREAK: Tcl_AppendToObj(Tcl_GetObjResult(interp), "break", TCL_STRLEN); break; case TCL_CONTINUE: Tcl_AppendToObj(Tcl_GetObjResult(interp), "continue", TCL_STRLEN); break; default: Tcl_AppendPrintfToObj(Tcl_GetObjResult(interp), "%d", result); } Tcl_AddErrorInfo(interp, "\n result of " "ensemble unknown subcommand handler: "); Tcl_AppendObjToErrorInfo(interp, unknownCmd); |
︙ | ︙ | |||
2218 2219 2220 2221 2222 2223 2224 | MakeCachedEnsembleCommand( Tcl_Obj *objPtr, EnsembleConfig *ensemblePtr, const char *subcommandName, Tcl_Obj *prefixObjPtr) { register EnsembleCmdRep *ensembleCmd; | | | 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 | MakeCachedEnsembleCommand( Tcl_Obj *objPtr, EnsembleConfig *ensemblePtr, const char *subcommandName, Tcl_Obj *prefixObjPtr) { register EnsembleCmdRep *ensembleCmd; size_t length; if (objPtr->typePtr == &tclEnsembleCmdType) { ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1; Tcl_DecrRefCount(ensembleCmd->realPrefixObj); TclNsDecrRefCount(ensembleCmd->nsPtr); ckfree(ensembleCmd->fullSubcmdName); } else { |
︙ | ︙ | |||
2405 2406 2407 2408 2409 2410 2411 | * See if we've got an export list. If so, we will only export exactly * those commands, which may be either implemented by the prefix in the * subcommandDict or mapped directly onto the namespace's commands. */ if (ensemblePtr->subcmdList != NULL) { Tcl_Obj **subcmdv, *target, *cmdObj, *cmdPrefixObj; | | | 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 | * See if we've got an export list. If so, we will only export exactly * those commands, which may be either implemented by the prefix in the * subcommandDict or mapped directly onto the namespace's commands. */ if (ensemblePtr->subcmdList != NULL) { Tcl_Obj **subcmdv, *target, *cmdObj, *cmdPrefixObj; size_t subcmdc; TclListObjGetElements(NULL, ensemblePtr->subcmdList, &subcmdc, &subcmdv); for (i=0 ; i<subcmdc ; i++) { const char *name = TclGetString(subcmdv[i]); hPtr = Tcl_CreateHashEntry(hash, name, &isNew); |
︙ | ︙ | |||
2662 2663 2664 2665 2666 2667 2668 | static void DupEnsembleCmdRep( Tcl_Obj *objPtr, Tcl_Obj *copyPtr) { EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1; EnsembleCmdRep *ensembleCopy = ckalloc(sizeof(EnsembleCmdRep)); | | | 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 | static void DupEnsembleCmdRep( Tcl_Obj *objPtr, Tcl_Obj *copyPtr) { EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1; EnsembleCmdRep *ensembleCopy = ckalloc(sizeof(EnsembleCmdRep)); size_t length = strlen(ensembleCmd->fullSubcmdName); copyPtr->typePtr = &tclEnsembleCmdType; copyPtr->internalRep.twoPtrValue.ptr1 = ensembleCopy; ensembleCopy->nsPtr = ensembleCmd->nsPtr; ensembleCopy->epoch = ensembleCmd->epoch; ensembleCopy->token = ensembleCmd->token; ensembleCopy->nsPtr->refCount++; |
︙ | ︙ | |||
2699 2700 2701 2702 2703 2704 2705 | */ static void StringOfEnsembleCmdRep( Tcl_Obj *objPtr) { EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1; | | | 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 | */ static void StringOfEnsembleCmdRep( Tcl_Obj *objPtr) { EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1; size_t length = strlen(ensembleCmd->fullSubcmdName); objPtr->length = length; objPtr->bytes = ckalloc(length + 1); memcpy(objPtr->bytes, ensembleCmd->fullSubcmdName, (unsigned) length+1); } /* |
︙ | ︙ | |||
2741 2742 2743 2744 2745 2746 2747 | CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr); Tcl_Obj *mapObj, *subcmdObj, *targetCmdObj, *listObj, **elems; Tcl_Obj *replaced = Tcl_NewObj(), *replacement; Tcl_Command ensemble = (Tcl_Command) cmdPtr; Command *oldCmdPtr = cmdPtr, *newCmdPtr; | | | < | 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 | CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr); Tcl_Obj *mapObj, *subcmdObj, *targetCmdObj, *listObj, **elems; Tcl_Obj *replaced = Tcl_NewObj(), *replacement; Tcl_Command ensemble = (Tcl_Command) cmdPtr; Command *oldCmdPtr = cmdPtr, *newCmdPtr; size_t len, result, i, numBytes; int flags = 0, depth = 1, invokeAnyway = 0, ourResult = TCL_ERROR; const char *word; Tcl_IncrRefCount(replaced); /* * This is where we return to if we are parsing multiple nested compiled * ensembles. [info object] is such a beast. |
︙ | ︙ | |||
2813 2814 2815 2816 2817 2818 2819 | * Check to see if there's also a subcommand list; must check to see if * the subcommand we are calling is in that list if it exists, since that * list filters the entries in the map. */ (void) Tcl_GetEnsembleSubcommandList(NULL, ensemble, &listObj); if (listObj != NULL) { | | | 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 | * Check to see if there's also a subcommand list; must check to see if * the subcommand we are calling is in that list if it exists, since that * list filters the entries in the map. */ (void) Tcl_GetEnsembleSubcommandList(NULL, ensemble, &listObj); if (listObj != NULL) { size_t sclen; const char *str; Tcl_Obj *matchObj = NULL; if (Tcl_ListObjGetElements(NULL, listObj, &len, &elems) != TCL_OK) { goto failed; } for (i=0 ; i<len ; i++) { |
︙ | ︙ | |||
3123 3124 3125 3126 3127 3128 3129 | Tcl_Obj *replacements, Command *cmdPtr, CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokPtr; Tcl_Obj *objPtr, **words; char *bytes; | | | 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 | Tcl_Obj *replacements, Command *cmdPtr, CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokPtr; Tcl_Obj *objPtr, **words; char *bytes; size_t length, i, numWords, cmdLit; DefineLineInformation; /* * Push the words of the command. Take care; the command words may be * scripts that have backslashes in them, and [info frame 0] can see the * difference. Hence the call to TclContinuationsEnterDerived... */ |
︙ | ︙ |
Changes to generic/tclEnv.c.
︙ | ︙ | |||
105 106 107 108 109 110 111 | */ TclNewLiteralStringObj(varNamePtr, "env"); Tcl_IncrRefCount(varNamePtr); Tcl_InitObjHashTable(&namesHash); varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL, TCL_GLOBAL_ONLY, /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr); | > | > > > | > < | | | | 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 154 | */ TclNewLiteralStringObj(varNamePtr, "env"); Tcl_IncrRefCount(varNamePtr); Tcl_InitObjHashTable(&namesHash); varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL, TCL_GLOBAL_ONLY, /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr); if (varPtr != NULL) { TclFindArrayPtrElements(varPtr, &namesHash); } else { TclArraySet(interp, varNamePtr, NULL); } /* * Go through the environment array and transfer its values into Tcl. At * the same time, remove those elements we add/update from the hash table * of existing elements, so that after this part processes, that table * will hold just the parts to remove. */ if (environ[0] != NULL) { int i; Tcl_MutexLock(&envMutex); for (i = 0; environ[i] != NULL; i++) { Tcl_Obj *obj1, *obj2; char *p1, *p2; p1 = Tcl_ExternalToUtfDString(NULL, environ[i], TCL_STRLEN, &envString); p2 = strchr(p1, '='); if (p2 == NULL) { /* * This condition seem to happen occasionally under some * versions of Solaris, or when encoding accidents swallow the * '='; ignore the entry. */ continue; } *(p2++) = '\0'; obj1 = Tcl_NewStringObj(p1, TCL_STRLEN); obj2 = Tcl_NewStringObj(p2, TCL_STRLEN); Tcl_DStringFree(&envString); Tcl_IncrRefCount(obj1); Tcl_IncrRefCount(obj2); Tcl_ObjSetVar2(interp, varNamePtr, obj1, obj2, TCL_GLOBAL_ONLY); hPtr = Tcl_FindHashEntry(&namesHash, obj1); if (hPtr != NULL) { |
︙ | ︙ | |||
204 205 206 207 208 209 210 | TclSetEnv( const char *name, /* Name of variable whose value is to be set * (UTF-8). */ const char *value) /* New value for variable (UTF-8). */ { Tcl_DString envString; unsigned nameLength, valueLength; | | > | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | TclSetEnv( const char *name, /* Name of variable whose value is to be set * (UTF-8). */ const char *value) /* New value for variable (UTF-8). */ { Tcl_DString envString; unsigned nameLength, valueLength; int index; char *p, *oldValue; const char *p2; size_t length; /* * Figure out where the entry is going to go. If the name doesn't already * exist, enlarge the array if necessary to make room. If the name exists, * free its old entry. */ |
︙ | ︙ | |||
251 252 253 254 255 256 257 | * Compare the new value to the existing value. If they're the same * then quit immediately (e.g. don't rewrite the value or propagate it * to other interpreters). Otherwise, when there are N interpreters * there will be N! propagations of the same value among the * interpreters. */ | | > | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | * Compare the new value to the existing value. If they're the same * then quit immediately (e.g. don't rewrite the value or propagate it * to other interpreters). Otherwise, when there are N interpreters * there will be N! propagations of the same value among the * interpreters. */ env = Tcl_ExternalToUtfDString(NULL, environ[index], TCL_STRLEN, &envString); if (strcmp(value, env + (length + 1)) == 0) { Tcl_DStringFree(&envString); Tcl_MutexUnlock(&envMutex); return; } Tcl_DStringFree(&envString); |
︙ | ︙ | |||
274 275 276 277 278 279 280 | */ valueLength = strlen(value); p = ckalloc(nameLength + valueLength + 2); memcpy(p, name, nameLength); p[nameLength] = '='; memcpy(p+nameLength+1, value, valueLength+1); | | | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | */ valueLength = strlen(value); p = ckalloc(nameLength + valueLength + 2); memcpy(p, name, nameLength); p[nameLength] = '='; memcpy(p+nameLength+1, value, valueLength+1); p2 = Tcl_UtfToExternalDString(NULL, p, TCL_STRLEN, &envString); /* * Copy the native string to heap memory. */ p = ckrealloc(p, Tcl_DStringLength(&envString) + 1); memcpy(p, p2, (unsigned) Tcl_DStringLength(&envString) + 1); |
︙ | ︙ | |||
365 366 367 368 369 370 371 | } /* * First convert the native string to UTF. Then separate the string into * name and value parts, and call TclSetEnv to do all of the real work. */ | | > | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | } /* * First convert the native string to UTF. Then separate the string into * name and value parts, and call TclSetEnv to do all of the real work. */ name = Tcl_ExternalToUtfDString(NULL, assignment, TCL_STRLEN, &nameString); value = strchr(name, '='); if ((value != NULL) && (value != name)) { value[0] = '\0'; TclSetEnv(name, value+1); } |
︙ | ︙ | |||
401 402 403 404 405 406 407 | */ void TclUnsetEnv( const char *name) /* Name of variable to remove (UTF-8). */ { char *oldValue; | | | 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | */ void TclUnsetEnv( const char *name) /* Name of variable to remove (UTF-8). */ { char *oldValue; size_t length; int index; #ifdef USE_PUTENV_FOR_UNSET Tcl_DString envString; char *string; #else char **envPtr; #endif /* USE_PUTENV_FOR_UNSET */ |
︙ | ︙ | |||
451 452 453 454 455 456 457 | string[length+1] = '\0'; #else string = ckalloc(length + 1); memcpy(string, name, (size_t) length); string[length] = '\0'; #endif /* WIN32 */ | | | 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | string[length+1] = '\0'; #else string = ckalloc(length + 1); memcpy(string, name, (size_t) length); string[length] = '\0'; #endif /* WIN32 */ Tcl_UtfToExternalDString(NULL, string, TCL_STRLEN, &envString); string = ckrealloc(string, Tcl_DStringLength(&envString) + 1); memcpy(string, Tcl_DStringValue(&envString), (unsigned) Tcl_DStringLength(&envString)+1); Tcl_DStringFree(&envString); putenv(string); |
︙ | ︙ | |||
517 518 519 520 521 522 523 | TclGetEnv( const char *name, /* Name of environment variable to find * (UTF-8). */ Tcl_DString *valuePtr) /* Uninitialized or free DString in which the * value of the environment variable is * stored. */ { | | > | > | | 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 | TclGetEnv( const char *name, /* Name of environment variable to find * (UTF-8). */ Tcl_DString *valuePtr) /* Uninitialized or free DString in which the * value of the environment variable is * stored. */ { size_t length; int index; const char *result; Tcl_MutexLock(&envMutex); index = TclpFindVariable(name, &length); result = NULL; if (index != -1) { Tcl_DString envStr; result = Tcl_ExternalToUtfDString(NULL, environ[index], TCL_STRLEN, &envStr); result += length; if (*result == '=') { result++; Tcl_DStringInit(valuePtr); Tcl_DStringAppend(valuePtr, result, TCL_STRLEN); result = Tcl_DStringValue(valuePtr); } else { result = NULL; } Tcl_DStringFree(&envStr); } Tcl_MutexUnlock(&envMutex); |
︙ | ︙ |
Changes to generic/tclEvent.c.
︙ | ︙ | |||
209 210 211 212 213 214 215 | * Tcl_SaveInterpState call before calling something like Tcl_DoOneEvent() * that could lead us here. */ Tcl_Preserve(assocPtr); Tcl_Preserve(interp); while (assocPtr->firstBgPtr != NULL) { | | > | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | * Tcl_SaveInterpState call before calling something like Tcl_DoOneEvent() * that could lead us here. */ Tcl_Preserve(assocPtr); Tcl_Preserve(interp); while (assocPtr->firstBgPtr != NULL) { int code; size_t prefixObjc; Tcl_Obj **prefixObjv, **tempObjv; /* * Note we copy the handler command prefix each pass through, so we do * support one handler setting another handler. */ |
︙ | ︙ | |||
266 267 268 269 270 271 272 | TclNewLiteralStringObj(keyPtr, "-errorinfo"); Tcl_IncrRefCount(keyPtr); Tcl_DictObjGet(NULL, options, keyPtr, &valuePtr); Tcl_DecrRefCount(keyPtr); Tcl_WriteChars(errChannel, | | | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | TclNewLiteralStringObj(keyPtr, "-errorinfo"); Tcl_IncrRefCount(keyPtr); Tcl_DictObjGet(NULL, options, keyPtr, &valuePtr); Tcl_DecrRefCount(keyPtr); Tcl_WriteChars(errChannel, "error in background error handler:\n", TCL_STRLEN); if (valuePtr) { Tcl_WriteObj(errChannel, valuePtr); } else { Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); } Tcl_WriteChars(errChannel, "\n", 1); Tcl_Flush(errChannel); |
︙ | ︙ | |||
305 306 307 308 309 310 311 | *---------------------------------------------------------------------- */ int TclDefaultBgErrorHandlerObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | *---------------------------------------------------------------------- */ int TclDefaultBgErrorHandlerObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *keyPtr, *valuePtr; Tcl_Obj *tempObjv[2]; int code, level; Tcl_InterpState saved; |
︙ | ︙ | |||
328 329 330 331 332 333 334 | TclNewLiteralStringObj(keyPtr, "-level"); Tcl_IncrRefCount(keyPtr); Tcl_DictObjGet(NULL, objv[2], keyPtr, &valuePtr); Tcl_DecrRefCount(keyPtr); if (valuePtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | TclNewLiteralStringObj(keyPtr, "-level"); Tcl_IncrRefCount(keyPtr); Tcl_DictObjGet(NULL, objv[2], keyPtr, &valuePtr); Tcl_DecrRefCount(keyPtr); if (valuePtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing return option \"-level\"", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, valuePtr, &level) == TCL_ERROR) { return TCL_ERROR; } TclNewLiteralStringObj(keyPtr, "-code"); Tcl_IncrRefCount(keyPtr); Tcl_DictObjGet(NULL, objv[2], keyPtr, &valuePtr); Tcl_DecrRefCount(keyPtr); if (valuePtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing return option \"-code\"", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, valuePtr, &code) == TCL_ERROR) { return TCL_ERROR; } |
︙ | ︙ | |||
459 460 461 462 463 464 465 | Tcl_IncrRefCount(resultPtr); if (Tcl_FindCommand(interp, "bgerror", NULL, TCL_GLOBAL_ONLY) == NULL) { Tcl_RestoreInterpState(interp, saved); Tcl_WriteObj(errChannel, Tcl_GetVar2Ex(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY)); | | | > | > | | > | | 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 | Tcl_IncrRefCount(resultPtr); if (Tcl_FindCommand(interp, "bgerror", NULL, TCL_GLOBAL_ONLY) == NULL) { Tcl_RestoreInterpState(interp, saved); Tcl_WriteObj(errChannel, Tcl_GetVar2Ex(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY)); Tcl_WriteChars(errChannel, "\n", TCL_STRLEN); } else { Tcl_DiscardInterpState(saved); Tcl_WriteChars(errChannel, "bgerror failed to handle background error.\n", TCL_STRLEN); Tcl_WriteChars(errChannel, " Original error: ", TCL_STRLEN); Tcl_WriteObj(errChannel, tempObjv[1]); Tcl_WriteChars(errChannel, "\n", TCL_STRLEN); Tcl_WriteChars(errChannel, " Error in bgerror: ", TCL_STRLEN); Tcl_WriteObj(errChannel, resultPtr); Tcl_WriteChars(errChannel, "\n", TCL_STRLEN); } Tcl_DecrRefCount(resultPtr); Tcl_Flush(errChannel); } else { Tcl_DiscardInterpState(saved); } } |
︙ | ︙ | |||
1380 1381 1382 1383 1384 1385 1386 | */ /* ARGSUSED */ int Tcl_VwaitObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 | */ /* ARGSUSED */ int Tcl_VwaitObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int done, foundEvent; const char *nameString; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); |
︙ | ︙ | |||
1405 1406 1407 1408 1409 1410 1411 | while (!done && foundEvent) { foundEvent = Tcl_DoOneEvent(TCL_ALL_EVENTS); if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { break; } if (Tcl_LimitExceeded(interp)) { Tcl_ResetResult(interp); | | > | 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 | while (!done && foundEvent) { foundEvent = Tcl_DoOneEvent(TCL_ALL_EVENTS); if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { break; } if (Tcl_LimitExceeded(interp)) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_NewStringObj( "limit exceeded", TCL_STRLEN)); break; } } Tcl_UntraceVar2(interp, nameString, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, VwaitVarProc, &done); |
︙ | ︙ | |||
1476 1477 1478 1479 1480 1481 1482 | */ /* ARGSUSED */ int Tcl_UpdateObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 | */ /* ARGSUSED */ int Tcl_UpdateObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int optionIndex; int flags = 0; /* Initialized to avoid compiler warning. */ static const char *const updateOptions[] = {"idletasks", NULL}; enum updateOptions {OPT_IDLETASKS}; |
︙ | ︙ | |||
1509 1510 1511 1512 1513 1514 1515 | while (Tcl_DoOneEvent(flags) != 0) { if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { return TCL_ERROR; } if (Tcl_LimitExceeded(interp)) { Tcl_ResetResult(interp); | | > | 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 | while (Tcl_DoOneEvent(flags) != 0) { if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { return TCL_ERROR; } if (Tcl_LimitExceeded(interp)) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_NewStringObj( "limit exceeded", TCL_STRLEN)); return TCL_ERROR; } } /* * Must clear the interpreter's result because event handlers could have * executed commands. |
︙ | ︙ | |||
1582 1583 1584 1585 1586 1587 1588 | */ int Tcl_CreateThread( Tcl_ThreadId *idPtr, /* Return, the ID of the thread */ Tcl_ThreadCreateProc *proc, /* Main() function of the thread */ ClientData clientData, /* The one argument to Main() */ | | | 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 | */ int Tcl_CreateThread( Tcl_ThreadId *idPtr, /* Return, the ID of the thread */ Tcl_ThreadCreateProc *proc, /* Main() function of the thread */ ClientData clientData, /* The one argument to Main() */ size_t stackSize, /* Size of stack for the new thread */ int flags) /* Flags controlling behaviour of the new * thread. */ { #ifdef TCL_THREADS ThreadClientData *cdPtr = ckalloc(sizeof(ThreadClientData)); int result; |
︙ | ︙ |
Changes to generic/tclExecute.c.
︙ | ︙ | |||
103 104 105 106 107 108 109 110 111 112 113 114 115 116 | #ifdef TCL_COMPILE_STATS long tclObjsAlloced = 0; long tclObjsFreed = 0; long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS] = { 0, 0, 0, 0, 0 }; #endif /* TCL_COMPILE_STATS */ /* * NR_TEBC * Helpers for NR - non-recursive calls to TEBC * Minimal data required to fully reconstruct the execution state. */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | #ifdef TCL_COMPILE_STATS long tclObjsAlloced = 0; long tclObjsFreed = 0; long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS] = { 0, 0, 0, 0, 0 }; #endif /* TCL_COMPILE_STATS */ /* * Support pre-8.5 bytecodes unless specifically requested otherwise. */ #ifndef TCL_SUPPORT_84_BYTECODE #define TCL_SUPPORT_84_BYTECODE 1 #endif #if TCL_SUPPORT_84_BYTECODE /* * We need to know the tclBuiltinFuncTable to support translation of pre-8.5 * math functions to the namespace-based ::tcl::mathfunc::op in 8.5+. */ typedef struct { const char *name; /* Name of function. */ int numArgs; /* Number of arguments for function. */ } BuiltinFunc; /* * Table describing the built-in math functions. Entries in this table are * indexed by the values of the INST_CALL_BUILTIN_FUNC instruction's * operand byte. */ static BuiltinFunc const tclBuiltinFuncTable[] = { {"acos", 1}, {"asin", 1}, {"atan", 1}, {"atan2", 2}, {"ceil", 1}, {"cos", 1}, {"cosh", 1}, {"exp", 1}, {"floor", 1}, {"fmod", 2}, {"hypot", 2}, {"log", 1}, {"log10", 1}, {"pow", 2}, {"sin", 1}, {"sinh", 1}, {"sqrt", 1}, {"tan", 1}, {"tanh", 1}, {"abs", 1}, {"double", 1}, {"int", 1}, {"rand", 0}, {"round", 1}, {"srand", 1}, {"wide", 1}, {NULL, 0}, }; #define LAST_BUILTIN_FUNC 25 #endif /* * NR_TEBC * Helpers for NR - non-recursive calls to TEBC * Minimal data required to fully reconstruct the execution state. */ |
︙ | ︙ | |||
659 660 661 662 663 664 665 | Tcl_Obj *valuePtr, Tcl_Obj *value2Ptr); static Tcl_Obj * ExecuteExtendedUnaryMathOp(int opcode, Tcl_Obj *valuePtr); static void FreeExprCodeInternalRep(Tcl_Obj *objPtr); static ExceptionRange * GetExceptRangeForPc(const unsigned char *pc, int catchOnly, ByteCode *codePtr); static const char * GetSrcInfoForPc(const unsigned char *pc, | | | | | > | 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 | Tcl_Obj *valuePtr, Tcl_Obj *value2Ptr); static Tcl_Obj * ExecuteExtendedUnaryMathOp(int opcode, Tcl_Obj *valuePtr); static void FreeExprCodeInternalRep(Tcl_Obj *objPtr); static ExceptionRange * GetExceptRangeForPc(const unsigned char *pc, int catchOnly, ByteCode *codePtr); static const char * GetSrcInfoForPc(const unsigned char *pc, ByteCode *codePtr, size_t *lengthPtr, const unsigned char **pcBeg, int *cmdIdxPtr); static Tcl_Obj ** GrowEvaluationStack(ExecEnv *eePtr, size_t growth, int move); static void IllegalExprOperandType(Tcl_Interp *interp, const unsigned char *pc, Tcl_Obj *opndPtr); static void InitByteCodeExecution(Tcl_Interp *interp); static inline int wordSkip(void *ptr); static void ReleaseDictIterator(Tcl_Obj *objPtr); /* Useful elsewhere, make available in tclInt.h or stubs? */ static Tcl_Obj ** StackAllocWords(Tcl_Interp *interp, size_t numWords); static Tcl_Obj ** StackReallocWords(Tcl_Interp *interp, size_t numWords); static Tcl_NRPostProc CopyCallback; static Tcl_NRPostProc ExprObjCallback; static Tcl_NRPostProc TEBCresume; /* * The structure below defines a bytecode Tcl object type to hold the |
︙ | ︙ | |||
987 988 989 990 991 992 993 | *---------------------------------------------------------------------- */ static Tcl_Obj ** GrowEvaluationStack( ExecEnv *eePtr, /* Points to the ExecEnv with an evaluation * stack to enlarge. */ | | | | | | 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 | *---------------------------------------------------------------------- */ static Tcl_Obj ** GrowEvaluationStack( ExecEnv *eePtr, /* Points to the ExecEnv with an evaluation * stack to enlarge. */ size_t growth, /* How much larger than the current used * size. */ int move) /* 1 if move words since last marker. */ { ExecStack *esPtr = eePtr->execStackPtr, *oldPtr = NULL; size_t newBytes, newElems, currElems; ssize_t needed = growth - (esPtr->endPtr - esPtr->tosPtr); Tcl_Obj **markerPtr = esPtr->markerPtr, **memStart; size_t moveWords = 0; if (move) { if (!markerPtr) { Tcl_Panic("STACK: Reallocating with no previous alloc"); } if (needed <= 0) { return MEMSTART(markerPtr); |
︙ | ︙ | |||
1138 1139 1140 1141 1142 1143 1144 | * *-------------------------------------------------------------- */ static Tcl_Obj ** StackAllocWords( Tcl_Interp *interp, | | | | 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 | * *-------------------------------------------------------------- */ static Tcl_Obj ** StackAllocWords( Tcl_Interp *interp, size_t numWords) { /* * Note that GrowEvaluationStack sets a marker in the stack. This marker * is read when rewinding, e.g., by TclStackFree. */ Interp *iPtr = (Interp *) interp; ExecEnv *eePtr = iPtr->execEnvPtr; Tcl_Obj **resPtr = GrowEvaluationStack(eePtr, numWords, 0); eePtr->execStackPtr->tosPtr += numWords; return resPtr; } static Tcl_Obj ** StackReallocWords( Tcl_Interp *interp, size_t numWords) { Interp *iPtr = (Interp *) interp; ExecEnv *eePtr = iPtr->execEnvPtr; Tcl_Obj **resPtr = GrowEvaluationStack(eePtr, numWords, 1); eePtr->execStackPtr->tosPtr += numWords; return resPtr; |
︙ | ︙ | |||
1235 1236 1237 1238 1239 1240 1241 | eePtr->execStackPtr = esPtr; } } void * TclStackAlloc( Tcl_Interp *interp, | | | | | 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 | eePtr->execStackPtr = esPtr; } } void * TclStackAlloc( Tcl_Interp *interp, size_t numBytes) { Interp *iPtr = (Interp *) interp; size_t numWords = (numBytes + (sizeof(Tcl_Obj *) - 1))/sizeof(Tcl_Obj *); if (iPtr == NULL || iPtr->execEnvPtr == NULL) { return (void *) ckalloc(numBytes); } return (void *) StackAllocWords(interp, numWords); } void * TclStackRealloc( Tcl_Interp *interp, void *ptr, size_t numBytes) { Interp *iPtr = (Interp *) interp; ExecEnv *eePtr; ExecStack *esPtr; Tcl_Obj **markerPtr; int numWords; |
︙ | ︙ | |||
1446 1447 1448 1449 1450 1451 1452 | } } if (objPtr->typePtr != &exprCodeType) { /* * TIP #280: No invoker (yet) - Expression compilation. */ | | | 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 | } } if (objPtr->typePtr != &exprCodeType) { /* * TIP #280: No invoker (yet) - Expression compilation. */ size_t length; const char *string = TclGetStringFromObj(objPtr, &length); TclInitCompileEnv(interp, &compEnv, string, length, NULL, 0); TclCompileExpr(interp, string, length, &compEnv, 0); /* * Successful compilation. If the expression yielded no instructions, |
︙ | ︙ | |||
2042 2043 2044 2045 2046 2047 2048 | * Locals - variables that are used within opcodes or bounded sections of * the file (jumps between opcodes within a family). * NOTE: These are now mostly defined locally where needed. */ Tcl_Obj *objPtr, *valuePtr, *value2Ptr, *part1Ptr, *part2Ptr, *tmpPtr; Tcl_Obj **objv; | | | > | 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 | * Locals - variables that are used within opcodes or bounded sections of * the file (jumps between opcodes within a family). * NOTE: These are now mostly defined locally where needed. */ Tcl_Obj *objPtr, *valuePtr, *value2Ptr, *part1Ptr, *part2Ptr, *tmpPtr; Tcl_Obj **objv; size_t objc = 0; int opnd, pcAdjustment; size_t length; Var *varPtr, *arrayPtr; #ifdef TCL_COMPILE_DEBUG char cmdNameBuf[21]; #endif #ifdef TCL_COMPILE_DEBUG int starting = 1; |
︙ | ︙ | |||
2355 2356 2357 2358 2359 2360 2361 | case INST_YIELD: { CoroutineData *corPtr = iPtr->execEnvPtr->corPtr; TRACE(("%.30s => ", O2S(OBJ_AT_TOS))); if (!corPtr) { TRACE_APPEND(("ERROR: yield outside coroutine\n")); Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 | case INST_YIELD: { CoroutineData *corPtr = iPtr->execEnvPtr->corPtr; TRACE(("%.30s => ", O2S(OBJ_AT_TOS))); if (!corPtr) { TRACE_APPEND(("ERROR: yield outside coroutine\n")); Tcl_SetObjResult(interp, Tcl_NewStringObj( "yield can only be called in a coroutine", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL); goto gotError; } #ifdef TCL_COMPILE_DEBUG TRACE_WITH_OBJ(("yield, result="), iPtr->objResultPtr); |
︙ | ︙ | |||
2401 2402 2403 2404 2405 2406 2407 | Tcl_Obj *listPtr, *nsObjPtr; opnd = TclGetUInt1AtPtr(pc+1); if (!(iPtr->varFramePtr->isProcCallFrame & 1)) { TRACE(("%d => ERROR: tailcall in non-proc context\n", opnd)); Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 | Tcl_Obj *listPtr, *nsObjPtr; opnd = TclGetUInt1AtPtr(pc+1); if (!(iPtr->varFramePtr->isProcCallFrame & 1)) { TRACE(("%d => ERROR: tailcall in non-proc context\n", opnd)); Tcl_SetObjResult(interp, Tcl_NewStringObj( "tailcall can only be called from a proc or lambda", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL); goto gotError; } #ifdef TCL_COMPILE_DEBUG { register int i; |
︙ | ︙ | |||
2427 2428 2429 2430 2431 2432 2433 | /* * Push the evaluation of the called command into the NR callback * stack. */ listPtr = Tcl_NewListObj(opnd, &OBJ_AT_DEPTH(opnd-1)); | | > | 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 | /* * Push the evaluation of the called command into the NR callback * stack. */ listPtr = Tcl_NewListObj(opnd, &OBJ_AT_DEPTH(opnd-1)); nsObjPtr = Tcl_NewStringObj(iPtr->varFramePtr->nsPtr->fullName, TCL_STRLEN); TclListObjSetElement(interp, listPtr, 0, nsObjPtr); if (iPtr->varFramePtr->tailcallPtr) { Tcl_DecrRefCount(iPtr->varFramePtr->tailcallPtr); } iPtr->varFramePtr->tailcallPtr = listPtr; result = TCL_RETURN; |
︙ | ︙ | |||
2846 2847 2848 2849 2850 2851 2852 | DECACHE_STACK_INFO(); pc += pcAdjustment; TEBC_YIELD(); return TclNREvalObjv(interp, objc, objv, TCL_EVAL_NOERR | TCL_EVAL_SOURCE_IN_FRAME, NULL); | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 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 | DECACHE_STACK_INFO(); pc += pcAdjustment; TEBC_YIELD(); return TclNREvalObjv(interp, objc, objv, TCL_EVAL_NOERR | TCL_EVAL_SOURCE_IN_FRAME, NULL); #if TCL_SUPPORT_84_BYTECODE case INST_CALL_BUILTIN_FUNC1: /* * Call one of the built-in pre-8.5 Tcl math functions. This * translates to INST_INVOKE_STK1 with the first argument of * ::tcl::mathfunc::$objv[0]. We need to insert the named math * function into the stack. */ opnd = TclGetUInt1AtPtr(pc+1); if ((opnd < 0) || (opnd > LAST_BUILTIN_FUNC)) { TRACE(("UNRECOGNIZED BUILTIN FUNC CODE %d\n", opnd)); Tcl_Panic("TclNRExecuteByteCode: unrecognized builtin function code %d", opnd); } TclNewLiteralStringObj(objPtr, "::tcl::mathfunc::"); Tcl_AppendToObj(objPtr, tclBuiltinFuncTable[opnd].name, TCL_STRLEN); /* * Only 0, 1 or 2 args. */ { int numArgs = tclBuiltinFuncTable[opnd].numArgs; Tcl_Obj *tmpPtr1, *tmpPtr2; if (numArgs == 0) { PUSH_OBJECT(objPtr); } else if (numArgs == 1) { tmpPtr1 = POP_OBJECT(); PUSH_OBJECT(objPtr); PUSH_OBJECT(tmpPtr1); Tcl_DecrRefCount(tmpPtr1); } else { tmpPtr2 = POP_OBJECT(); tmpPtr1 = POP_OBJECT(); PUSH_OBJECT(objPtr); PUSH_OBJECT(tmpPtr1); PUSH_OBJECT(tmpPtr2); Tcl_DecrRefCount(tmpPtr1); Tcl_DecrRefCount(tmpPtr2); } objc = numArgs + 1; } pcAdjustment = 2; goto doInvocation; case INST_CALL_FUNC1: /* * Call a non-builtin Tcl math function previously registered by a * call to Tcl_CreateMathFunc pre-8.5. This is essentially * INST_INVOKE_STK1 converting the first arg to * ::tcl::mathfunc::$objv[0]. */ objc = TclGetUInt1AtPtr(pc+1); /* Number of arguments. The function * name is the 0-th argument. */ objPtr = OBJ_AT_DEPTH(objc-1); TclNewLiteralStringObj(tmpPtr, "::tcl::mathfunc::"); Tcl_AppendObjToObj(tmpPtr, objPtr); Tcl_DecrRefCount(objPtr); /* * Variation of PUSH_OBJECT. */ OBJ_AT_DEPTH(objc-1) = tmpPtr; Tcl_IncrRefCount(tmpPtr); pcAdjustment = 2; goto doInvocation; #else /* * INST_CALL_BUILTIN_FUNC1 and INST_CALL_FUNC1 were made obsolete by the * changes to add a ::tcl::mathfunc namespace in 8.5. Optional support * remains for existing bytecode precompiled files. */ case INST_CALL_BUILTIN_FUNC1: Tcl_Panic("TclNRExecuteByteCode: obsolete INST_CALL_BUILTIN_FUNC1 found"); case INST_CALL_FUNC1: Tcl_Panic("TclNRExecuteByteCode: obsolete INST_CALL_FUNC1 found"); #endif case INST_INVOKE_REPLACE: objc = TclGetUInt4AtPtr(pc+1); opnd = TclGetUInt1AtPtr(pc+5); objPtr = POP_OBJECT(); objv = &OBJ_AT_DEPTH(objc-1); cleanup = objc; |
︙ | ︙ | |||
4270 4271 4272 4273 4274 4275 4276 | CallContext *contextPtr; if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) { TRACE(("=> ERROR: no TclOO call context\n")); Tcl_SetObjResult(interp, Tcl_NewStringObj( "self may only be called from inside a method", | | | 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 | CallContext *contextPtr; if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) { TRACE(("=> ERROR: no TclOO call context\n")); Tcl_SetObjResult(interp, Tcl_NewStringObj( "self may only be called from inside a method", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL); goto gotError; } contextPtr = framePtr->clientData; /* * Call out to get the name; it's expensive to compute but cached. |
︙ | ︙ | |||
4324 4325 4326 4327 4328 4329 4330 | /* * ----------------------------------------------------------------- * Start of INST_LIST and related instructions. */ { | | | > | 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 | /* * ----------------------------------------------------------------- * Start of INST_LIST and related instructions. */ { ssize_t index, fromIdx, toIdx; int nocase, match, cflags; size_t numIndices, length2, s1len, s2len; const char *s1, *s2; case INST_LIST: /* * Pop the opnd (objc) top stack elements into a new list obj and then * decrement their ref counts. */ |
︙ | ︙ | |||
4904 4905 4906 4907 4908 4909 4910 | &toIdx) != TCL_OK) { goto gotError; } if (fromIdx < 0) { fromIdx = 0; } | | | 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 | &toIdx) != TCL_OK) { goto gotError; } if (fromIdx < 0) { fromIdx = 0; } if (toIdx >= length && toIdx > 0) { toIdx = length; } if (toIdx >= fromIdx) { objResultPtr = Tcl_GetRange(OBJ_AT_DEPTH(2), fromIdx, toIdx); } else { TclNewObj(objResultPtr); } |
︙ | ︙ | |||
4954 4955 4956 4957 4958 4959 4960 | TclNewObj(objResultPtr); } TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); NEXT_INST_F(9, 1, 1); { Tcl_UniChar *ustring1, *ustring2, *ustring3, *end, *p; | | | 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 | TclNewObj(objResultPtr); } TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); NEXT_INST_F(9, 1, 1); { Tcl_UniChar *ustring1, *ustring2, *ustring3, *end, *p; size_t length3; Tcl_Obj *value3Ptr; case INST_STR_MAP: valuePtr = OBJ_AT_TOS; /* "Main" string. */ value3Ptr = OBJ_UNDER_TOS; /* "Target" string. */ value2Ptr = OBJ_AT_DEPTH(2); /* "Source" string. */ if (value3Ptr == value2Ptr) { |
︙ | ︙ | |||
5365 5366 5367 5368 5369 5370 5371 | lResult = l1 - l2*lResult; goto longResultOfArithmetic; } case INST_RSHIFT: if (l2 < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 | lResult = l1 - l2*lResult; goto longResultOfArithmetic; } case INST_RSHIFT: if (l2 < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "negative shift argument", TCL_STRLEN)); #if 0 DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "domain error: argument not in valid range", NULL); CACHE_STACK_INFO(); #endif |
︙ | ︙ | |||
5413 5414 5415 5416 5417 5418 5419 | lResult = l1 >> ((int) l2); goto longResultOfArithmetic; } case INST_LSHIFT: if (l2 < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 | lResult = l1 >> ((int) l2); goto longResultOfArithmetic; } case INST_LSHIFT: if (l2 < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "negative shift argument", TCL_STRLEN)); #if 0 DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "domain error: argument not in valid range", NULL); CACHE_STACK_INFO(); #endif |
︙ | ︙ | |||
5436 5437 5438 5439 5440 5441 5442 | * Technically, we could hold the value (1 << (INT_MAX+1)) * in an mp_int, but since we're using mp_mul_2d() to do * the work, and it takes only an int argument, that's a * good place to draw the line. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 | * Technically, we could hold the value (1 << (INT_MAX+1)) * in an mp_int, but since we're using mp_mul_2d() to do * the work, and it takes only an int argument, that's a * good place to draw the line. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "integer value too large to represent", TCL_STRLEN)); #if 0 DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", "integer value too large to represent", NULL); CACHE_STACK_INFO(); #endif goto gotError; |
︙ | ︙ | |||
5875 5876 5877 5878 5879 5880 5881 | goto processExceptionReturn; { ForeachInfo *infoPtr; Var *iterVarPtr, *listVarPtr; Tcl_Obj *oldValuePtr, *listPtr, **elements; ForeachVarList *varListPtr; | | > | 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 | goto processExceptionReturn; { ForeachInfo *infoPtr; Var *iterVarPtr, *listVarPtr; Tcl_Obj *oldValuePtr, *listPtr, **elements; ForeachVarList *varListPtr; int numLists, iterNum, listTmpIndex, numVars; int varIndex, valIndex, continueLoop, j, iterTmpIndex; long i; size_t listLen; case INST_FOREACH_START4: /* * Initialize the temporary local var that holds the count of the * number of iterations of the loop body to -1. */ |
︙ | ︙ | |||
6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 | { int opnd2, allocateDict, done, i, allocdict; Tcl_Obj *dictPtr, *statePtr, *keyPtr, *listPtr, *varNamePtr, *keysPtr; Tcl_Obj *emptyPtr, **keyPtrPtr; Tcl_DictSearch *searchPtr; DictUpdateInfo *duiPtr; case INST_DICT_VERIFY: dictPtr = OBJ_AT_TOS; TRACE(("=> ")); | > | | 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 | { int opnd2, allocateDict, done, i, allocdict; Tcl_Obj *dictPtr, *statePtr, *keyPtr, *listPtr, *varNamePtr, *keysPtr; Tcl_Obj *emptyPtr, **keyPtrPtr; Tcl_DictSearch *searchPtr; DictUpdateInfo *duiPtr; size_t size; case INST_DICT_VERIFY: dictPtr = OBJ_AT_TOS; TRACE(("=> ")); if (Tcl_DictObjSize(interp, dictPtr, &size) != TCL_OK) { TRACE_APPEND(("ERROR verifying dictionary nature of \"%s\": %s\n", O2S(OBJ_AT_DEPTH(opnd)), O2S(Tcl_GetObjResult(interp)))); goto gotError; } TRACE_APPEND(("OK\n")); NEXT_INST_F(1, 1, 0); |
︙ | ︙ | |||
6794 6795 6796 6797 6798 6799 6800 | /* * Division by zero in an expression. Control only reaches this point * by "goto divideByZero". */ divideByZero: DECACHE_STACK_INFO(); | | > | | 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 | /* * Division by zero in an expression. Control only reaches this point * by "goto divideByZero". */ divideByZero: DECACHE_STACK_INFO(); Tcl_SetObjResult(interp, Tcl_NewStringObj("divide by zero", TCL_STRLEN)); Tcl_SetErrorCode(interp, "ARITH", "DIVZERO", "divide by zero", NULL); CACHE_STACK_INFO(); goto gotError; /* * Exponentiation of zero by negative number in an expression. Control * only reaches this point by "goto exponOfZero". */ exponOfZero: DECACHE_STACK_INFO(); Tcl_SetObjResult(interp, Tcl_NewStringObj( "exponentiation of zero by negative power", TCL_STRLEN)); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "exponentiation of zero by negative power", NULL); CACHE_STACK_INFO(); /* * Almost all error paths feed through here rather than assigning to * result themselves (for a small but consistent saving). |
︙ | ︙ | |||
7220 7221 7222 7223 7224 7225 7226 | break; default: /* Unused, here to silence compiler warning */ invalid = 0; } if (invalid) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 | break; default: /* Unused, here to silence compiler warning */ invalid = 0; } if (invalid) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "negative shift argument", TCL_STRLEN)); return GENERAL_ARITHMETIC_ERROR; } /* * Zero shifted any number of bits is still zero. */ |
︙ | ︙ | |||
7251 7252 7253 7254 7255 7256 7257 | * Technically, we could hold the value (1 << (INT_MAX+1)) in * an mp_int, but since we're using mp_mul_2d() to do the * work, and it takes only an int argument, that's a good * place to draw the line. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 | * Technically, we could hold the value (1 << (INT_MAX+1)) in * an mp_int, but since we're using mp_mul_2d() to do the * work, and it takes only an int argument, that's a good * place to draw the line. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "integer value too large to represent", TCL_STRLEN)); return GENERAL_ARITHMETIC_ERROR; } shift = (int)(*((const long *)ptr2)); /* * Handle shifts within the native wide range. */ |
︙ | ︙ | |||
7653 7654 7655 7656 7657 7658 7659 | * range of the long int type. This means any numeric Tcl_Obj value * not using TCL_NUMBER_LONG type must hold a value larger than we * accept. */ if (type2 != TCL_NUMBER_LONG) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 | * range of the long int type. This means any numeric Tcl_Obj value * not using TCL_NUMBER_LONG type must hold a value larger than we * accept. */ if (type2 != TCL_NUMBER_LONG) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "exponent too large", TCL_STRLEN)); return GENERAL_ARITHMETIC_ERROR; } if (type1 == TCL_NUMBER_LONG) { if (l1 == 2) { /* * Reduce small powers of 2 to shifts. |
︙ | ︙ | |||
7892 7893 7894 7895 7896 7897 7898 | #endif overflowExpon: Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); if (big2.used > 1) { mp_clear(&big2); Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 | #endif overflowExpon: Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); if (big2.used > 1) { mp_clear(&big2); Tcl_SetObjResult(interp, Tcl_NewStringObj( "exponent too large", TCL_STRLEN)); return GENERAL_ARITHMETIC_ERROR; } Tcl_TakeBignumFromObj(NULL, valuePtr, &big1); mp_init(&bigResult); mp_expt_d(&big1, big2.dp[0], &bigResult); mp_clear(&big1); mp_clear(&big2); |
︙ | ︙ | |||
8610 8611 8612 8613 8614 8615 8616 | * *---------------------------------------------------------------------- */ Tcl_Obj * TclGetSourceFromFrame( CmdFrame *cfPtr, | | | 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 | * *---------------------------------------------------------------------- */ Tcl_Obj * TclGetSourceFromFrame( CmdFrame *cfPtr, size_t objc, Tcl_Obj *const objv[]) { if (cfPtr == NULL) { return Tcl_NewListObj(objc, objv); } if (cfPtr->cmdObj == NULL) { if (cfPtr->cmd == NULL) { |
︙ | ︙ | |||
8698 8699 8700 8701 8702 8703 8704 | GetSrcInfoForPc( const unsigned char *pc, /* The program counter value for which to * return the closest command's source info. * This points within a bytecode instruction * in codePtr's code. */ ByteCode *codePtr, /* The bytecode sequence in which to look up * the command source for the pc. */ | | | 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 | GetSrcInfoForPc( const unsigned char *pc, /* The program counter value for which to * return the closest command's source info. * This points within a bytecode instruction * in codePtr's code. */ ByteCode *codePtr, /* The bytecode sequence in which to look up * the command source for the pc. */ size_t *lengthPtr, /* If non-NULL, the location where the length * of the command's source should be stored. * If NULL, no length is stored. */ const unsigned char **pcBeg,/* If non-NULL, the bytecode location * where the current instruction starts. * If NULL; no pointer is stored. */ int *cmdIdxPtr) /* If non-NULL, the location where the index * of the command containing the pc should |
︙ | ︙ | |||
8946 8947 8948 8949 8950 8951 8952 | double value) /* Value returned after error; used to * distinguish underflows from overflows. */ { const char *s; if ((errno == EDOM) || TclIsNaN(value)) { s = "domain error: argument not in valid range"; | | | | | 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 | double value) /* Value returned after error; used to * distinguish underflows from overflows. */ { const char *s; if ((errno == EDOM) || TclIsNaN(value)) { s = "domain error: argument not in valid range"; Tcl_SetObjResult(interp, Tcl_NewStringObj(s, TCL_STRLEN)); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", s, NULL); } else if ((errno == ERANGE) || TclIsInfinite(value)) { if (value == 0.0) { s = "floating-point value too small to represent"; Tcl_SetObjResult(interp, Tcl_NewStringObj(s, TCL_STRLEN)); Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW", s, NULL); } else { s = "floating-point value too large to represent"; Tcl_SetObjResult(interp, Tcl_NewStringObj(s, TCL_STRLEN)); Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW", s, NULL); } } else { Tcl_Obj *objPtr = Tcl_ObjPrintf( "unknown floating-point error, errno = %d", errno); Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN", |
︙ | ︙ |
Changes to generic/tclFCmd.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | */ static int CopyRenameOneFile(Tcl_Interp *interp, Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, int copyFlag, int force); static Tcl_Obj * FileBasename(Tcl_Interp *interp, Tcl_Obj *pathPtr); static int FileCopyRename(Tcl_Interp *interp, | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | */ static int CopyRenameOneFile(Tcl_Interp *interp, Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, int copyFlag, int force); static Tcl_Obj * FileBasename(Tcl_Interp *interp, Tcl_Obj *pathPtr); static int FileCopyRename(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int copyFlag); static int FileForceOption(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int*forcePtr); /* *--------------------------------------------------------------------------- * * TclFileRenameCmd * * This function implements the "rename" subcommand of the "file" |
︙ | ︙ | |||
46 47 48 49 50 51 52 | */ int TclFileRenameCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Interp for error reporting or recursive * calls in the case of a tricky rename. */ | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | */ int TclFileRenameCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Interp for error reporting or recursive * calls in the case of a tricky rename. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings passed to Tcl_FileCmd. */ { return FileCopyRename(interp, objc, objv, 0); } /* *--------------------------------------------------------------------------- |
︙ | ︙ | |||
75 76 77 78 79 80 81 | */ int TclFileCopyCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Used for error reporting or recursive calls * in the case of a tricky copy. */ | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | */ int TclFileCopyCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Used for error reporting or recursive calls * in the case of a tricky copy. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings passed to Tcl_FileCmd. */ { return FileCopyRename(interp, objc, objv, 1); } /* *--------------------------------------------------------------------------- |
︙ | ︙ | |||
101 102 103 104 105 106 107 | * *--------------------------------------------------------------------------- */ static int FileCopyRename( Tcl_Interp *interp, /* Used for error reporting. */ | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | * *--------------------------------------------------------------------------- */ static int FileCopyRename( Tcl_Interp *interp, /* Used for error reporting. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[], /* Argument strings passed to Tcl_FileCmd. */ int copyFlag) /* If non-zero, copy source(s). Otherwise, * rename them. */ { int i, result, force; Tcl_StatBuf statBuf; Tcl_Obj *target; |
︙ | ︙ | |||
212 213 214 215 216 217 218 | *---------------------------------------------------------------------- */ int TclFileMakeDirsCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Used for error reporting. */ | | | > | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | *---------------------------------------------------------------------- */ int TclFileMakeDirsCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Used for error reporting. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings passed to Tcl_FileCmd. */ { Tcl_Obj *errfile = NULL; int result, i, j; Tcl_Obj *split = NULL; Tcl_Obj *target = NULL; Tcl_StatBuf statBuf; size_t pobjc; result = TCL_OK; for (i = 1; i < objc; i++) { if (Tcl_FSConvertToPathType(interp, objv[i]) != TCL_OK) { result = TCL_ERROR; break; } |
︙ | ︙ | |||
330 331 332 333 334 335 336 | *---------------------------------------------------------------------- */ int TclFileDeleteCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Used for error reporting */ | | | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | *---------------------------------------------------------------------- */ int TclFileDeleteCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Used for error reporting */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings passed to Tcl_FileCmd. */ { int i, force, result; Tcl_Obj *errfile; Tcl_Obj *errorBuffer = NULL; i = FileForceOption(interp, objc - 1, objv + 1, &force); |
︙ | ︙ | |||
808 809 810 811 812 813 814 | * *--------------------------------------------------------------------------- */ static int FileForceOption( Tcl_Interp *interp, /* Interp, for error return. */ | | | 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 | * *--------------------------------------------------------------------------- */ static int FileForceOption( Tcl_Interp *interp, /* Interp, for error return. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[], /* Argument strings. First command line * option, if it exists, begins at 0. */ int *forcePtr) /* If the "-force" was specified, *forcePtr is * filled with 1, otherwise with 0. */ { int force, i, idx; static const char *const options[] = { |
︙ | ︙ | |||
863 864 865 866 867 868 869 | */ static Tcl_Obj * FileBasename( Tcl_Interp *interp, /* Interp, for error return. */ Tcl_Obj *pathPtr) /* Path whose basename to extract. */ { | | | 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 | */ static Tcl_Obj * FileBasename( Tcl_Interp *interp, /* Interp, for error return. */ Tcl_Obj *pathPtr) /* Path whose basename to extract. */ { size_t objc; Tcl_Obj *splitPtr; Tcl_Obj *resultPtr = NULL; splitPtr = Tcl_FSSplitPath(pathPtr, &objc); Tcl_IncrRefCount(splitPtr); if (objc != 0) { |
︙ | ︙ | |||
938 939 940 941 942 943 944 | *---------------------------------------------------------------------- */ int TclFileAttrsCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The interpreter for error reporting. */ | | | | 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 | *---------------------------------------------------------------------- */ int TclFileAttrsCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The interpreter for error reporting. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The command line objects. */ { int result; const char *const *attributeStrings; const char **attributeStringsAllocated = NULL; Tcl_Obj *objStrings = NULL; size_t numObjStrings = TCL_STRLEN; Tcl_Obj *filePtr; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "name ?-option value ...?"); return TCL_ERROR; } |
︙ | ︙ | |||
1039 1040 1041 1042 1043 1044 1045 | */ Tcl_ResetResult(interp); } res = Tcl_FSFileAttrsGet(interp, index, filePtr, &objPtrAttr); if (res == TCL_OK) { | | | | 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 | */ Tcl_ResetResult(interp); } res = Tcl_FSFileAttrsGet(interp, index, filePtr, &objPtrAttr); if (res == TCL_OK) { Tcl_Obj *objPtr = Tcl_NewStringObj( attributeStrings[index], TCL_STRLEN); Tcl_ListObjAppendElement(interp, listPtr, objPtr); Tcl_ListObjAppendElement(interp, listPtr, objPtrAttr); nbAtts++; } } |
︙ | ︙ | |||
1160 1161 1162 1163 1164 1165 1166 | *---------------------------------------------------------------------- */ int TclFileLinkCmd( ClientData clientData, Tcl_Interp *interp, | | | 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 | *---------------------------------------------------------------------- */ int TclFileLinkCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) { Tcl_Obj *contents; int index; if (objc < 2 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "?-linktype? linkname ?target?"); |
︙ | ︙ | |||
1311 1312 1313 1314 1315 1316 1317 | *---------------------------------------------------------------------- */ int TclFileReadLinkCmd( ClientData clientData, Tcl_Interp *interp, | | | 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 | *---------------------------------------------------------------------- */ int TclFileReadLinkCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) { Tcl_Obj *contents; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; |
︙ | ︙ | |||
1362 1363 1364 1365 1366 1367 1368 | *--------------------------------------------------------------------------- */ int TclFileTemporaryCmd( ClientData clientData, Tcl_Interp *interp, | | | 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 | *--------------------------------------------------------------------------- */ int TclFileTemporaryCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) { Tcl_Obj *nameVarObj = NULL; /* Variable to store the name of the temporary * file in. */ Tcl_Obj *nameObj = NULL; /* Object that will contain the filename. */ Tcl_Channel chan; /* The channel opened (RDWR) on the temporary * file, or NULL if there's an error. */ |
︙ | ︙ | |||
1385 1386 1387 1388 1389 1390 1391 | } if (objc > 1) { nameVarObj = objv[1]; TclNewObj(nameObj); } if (objc > 2) { | | | 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 | } if (objc > 1) { nameVarObj = objv[1]; TclNewObj(nameObj); } if (objc > 2) { size_t length; Tcl_Obj *templateObj = objv[2]; const char *string = TclGetStringFromObj(templateObj, &length); /* * Treat an empty string as if it wasn't there. */ |
︙ | ︙ | |||
1496 1497 1498 1499 1500 1501 1502 | if (nameVarObj != NULL) { if (Tcl_ObjSetVar2(interp, nameVarObj, NULL, nameObj, TCL_LEAVE_ERR_MSG) == NULL) { Tcl_UnregisterChannel(interp, chan); return TCL_ERROR; } } | | > | 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 | if (nameVarObj != NULL) { if (Tcl_ObjSetVar2(interp, nameVarObj, NULL, nameObj, TCL_LEAVE_ERR_MSG) == NULL) { Tcl_UnregisterChannel(interp, chan); return TCL_ERROR; } } Tcl_SetObjResult(interp, Tcl_NewStringObj( Tcl_GetChannelName(chan), TCL_STRLEN)); return TCL_OK; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclFileName.c.
︙ | ︙ | |||
347 348 349 350 351 352 353 | */ Tcl_PathType Tcl_GetPathType( const char *path) { Tcl_PathType type; | | | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | */ Tcl_PathType Tcl_GetPathType( const char *path) { Tcl_PathType type; Tcl_Obj *tempObj = Tcl_NewStringObj(path, TCL_STRLEN); Tcl_IncrRefCount(tempObj); type = Tcl_FSGetPathType(tempObj); Tcl_DecrRefCount(tempObj); return type; } |
︙ | ︙ | |||
386 387 388 389 390 391 392 | * *---------------------------------------------------------------------- */ Tcl_PathType TclpGetNativePathType( Tcl_Obj *pathPtr, /* Native path of interest */ | | | | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | * *---------------------------------------------------------------------- */ Tcl_PathType TclpGetNativePathType( Tcl_Obj *pathPtr, /* Native path of interest */ size_t *driveNameLengthPtr, /* Returns length of drive, if non-NULL and * path was absolute */ Tcl_Obj **driveNameRef) { Tcl_PathType type = TCL_PATH_ABSOLUTE; size_t pathLen; const char *path = Tcl_GetStringFromObj(pathPtr, &pathLen); if (path[0] == '~') { /* * This case is common to all platforms. Paths that begin with ~ are * absolute. */ |
︙ | ︙ | |||
499 500 501 502 503 504 505 | * *--------------------------------------------------------------------------- */ Tcl_Obj * TclpNativeSplitPath( Tcl_Obj *pathPtr, /* Path to split. */ | | | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | * *--------------------------------------------------------------------------- */ Tcl_Obj * TclpNativeSplitPath( Tcl_Obj *pathPtr, /* Path to split. */ size_t *lenPtr) /* int to store number of path elements. */ { Tcl_Obj *resultPtr = NULL; /* Needed only to prevent gcc warnings. */ /* * Perform platform specific splitting. */ |
︙ | ︙ | |||
555 556 557 558 559 560 561 | * *---------------------------------------------------------------------- */ void Tcl_SplitPath( const char *path, /* Pointer to string containing a path. */ | | | | | 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | * *---------------------------------------------------------------------- */ void Tcl_SplitPath( const char *path, /* Pointer to string containing a path. */ size_t *argcPtr, /* Pointer to location to fill in with the * number of elements in the path. */ const char ***argvPtr) /* Pointer to place to store pointer to array * of pointers to path elements. */ { Tcl_Obj *resultPtr = NULL; /* Needed only to prevent gcc warnings. */ Tcl_Obj *tmpPtr, *eltPtr; size_t i, size, len; char *p; const char *str; /* * Perform the splitting, using objectified, vfs-aware code. */ tmpPtr = Tcl_NewStringObj(path, TCL_STRLEN); Tcl_IncrRefCount(tmpPtr); resultPtr = Tcl_FSSplitPath(tmpPtr, argcPtr); Tcl_IncrRefCount(resultPtr); Tcl_DecrRefCount(tmpPtr); /* * Calculate space required for the result. |
︙ | ︙ | |||
768 769 770 771 772 773 774 775 776 777 778 779 780 781 | elementStart = p; while ((*p != '\0') && (*p != '/') && (*p != '\\')) { p++; } length = p - elementStart; if (length > 0) { Tcl_Obj *nextElt; if ((elementStart != path) && ((elementStart[0] == '~') || (isalpha(UCHAR(elementStart[0])) && elementStart[1] == ':'))) { TclNewLiteralStringObj(nextElt, "./"); Tcl_AppendToObj(nextElt, elementStart, length); } else { nextElt = Tcl_NewStringObj(elementStart, length); | > | 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 | elementStart = p; while ((*p != '\0') && (*p != '/') && (*p != '\\')) { p++; } length = p - elementStart; if (length > 0) { Tcl_Obj *nextElt; if ((elementStart != path) && ((elementStart[0] == '~') || (isalpha(UCHAR(elementStart[0])) && elementStart[1] == ':'))) { TclNewLiteralStringObj(nextElt, "./"); Tcl_AppendToObj(nextElt, elementStart, length); } else { nextElt = Tcl_NewStringObj(elementStart, length); |
︙ | ︙ | |||
809 810 811 812 813 814 815 | * *--------------------------------------------------------------------------- */ Tcl_Obj * Tcl_FSJoinToPath( Tcl_Obj *pathPtr, /* Valid path or NULL. */ | | | 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 | * *--------------------------------------------------------------------------- */ Tcl_Obj * Tcl_FSJoinToPath( Tcl_Obj *pathPtr, /* Valid path or NULL. */ size_t objc, /* Number of array elements to join */ Tcl_Obj *const objv[]) /* Path elements to join. */ { if (pathPtr == NULL) { return TclJoinPath(objc, objv); } if (objc == 0) { return TclJoinPath(1, &pathPtr); |
︙ | ︙ | |||
857 858 859 860 861 862 863 | */ void TclpNativeJoinPath( Tcl_Obj *prefix, const char *joining) { | | > | 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 | */ void TclpNativeJoinPath( Tcl_Obj *prefix, const char *joining) { int needsSep; char *dest; const char *p; const char *start; size_t length; start = Tcl_GetStringFromObj(prefix, &length); /* * Remove the ./ from tilde prefixed elements, and drive-letter prefixed * elements on Windows, unless it is the first component. */ |
︙ | ︙ | |||
977 978 979 980 981 982 983 | * Modifies the Tcl_DString. * *---------------------------------------------------------------------- */ char * Tcl_JoinPath( | | | | | 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 | * Modifies the Tcl_DString. * *---------------------------------------------------------------------- */ char * Tcl_JoinPath( size_t argc, const char *const *argv, Tcl_DString *resultPtr) /* Pointer to previously initialized DString */ { size_t i, len; Tcl_Obj *listObj = Tcl_NewObj(); Tcl_Obj *resultObj; const char *resultStr; /* * Build the list of paths. */ for (i = 0; i < argc; i++) { Tcl_ListObjAppendElement(NULL, listObj, Tcl_NewStringObj(argv[i], TCL_STRLEN)); } /* * Ask the objectified code to join the paths. */ Tcl_IncrRefCount(listObj); |
︙ | ︙ | |||
1056 1057 1058 1059 1060 1061 1062 | const char *name, /* File name, which may begin with "~" (to * indicate current user's home directory) or * "~<user>" (to indicate any user's home * directory). */ Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with * name after tilde substitution. */ { | | | 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 | const char *name, /* File name, which may begin with "~" (to * indicate current user's home directory) or * "~<user>" (to indicate any user's home * directory). */ Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with * name after tilde substitution. */ { Tcl_Obj *path = Tcl_NewStringObj(name, TCL_STRLEN); Tcl_Obj *transPtr; Tcl_IncrRefCount(path); transPtr = Tcl_FSGetTranslatedPath(interp, path); if (transPtr == NULL) { Tcl_DecrRefCount(path); return NULL; |
︙ | ︙ | |||
1186 1187 1188 1189 1190 1191 1192 | Tcl_DString dirString; dir = TclGetEnv("HOME", &dirString); if (dir == NULL) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "couldn't find HOME environment " | | | 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 | Tcl_DString dirString; dir = TclGetEnv("HOME", &dirString); if (dir == NULL) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "couldn't find HOME environment " "variable to expand path", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "FILENAME", "NO_HOME", NULL); } return NULL; } Tcl_JoinPath(1, &dir, resultPtr); Tcl_DStringFree(&dirString); } else if (TclpGetUserHome(user, resultPtr) == NULL) { |
︙ | ︙ | |||
1227 1228 1229 1230 1231 1232 1233 | */ /* ARGSUSED */ int Tcl_GlobObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 | */ /* ARGSUSED */ int Tcl_GlobObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int index, i, globFlags, join, dir, result; char *string; size_t length; const char *separators; Tcl_Obj *typePtr, *look; Tcl_Obj *pathOrDir = NULL; Tcl_DString prefix; static const char *const options[] = { "-directory", "-join", "-nocomplain", "-path", "-tails", "-types", "--", NULL |
︙ | ︙ | |||
1283 1284 1285 1286 1287 1288 1289 | * Do nothing; This is normal operations in Tcl 9. * Keep accepting as a no-op option to accommodate old scripts. */ break; case GLOB_DIR: /* -dir */ if (i == (objc-1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | > | | > | | | | 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 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 1337 1338 1339 1340 1341 1342 1343 1344 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 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 | * Do nothing; This is normal operations in Tcl 9. * Keep accepting as a no-op option to accommodate old scripts. */ break; case GLOB_DIR: /* -dir */ if (i == (objc-1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing argument to \"-directory\"", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); return TCL_ERROR; } if (dir != PATH_NONE) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-directory\" cannot be used with \"-path\"", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BADOPTIONCOMBINATION", NULL); return TCL_ERROR; } dir = PATH_DIR; globFlags |= TCL_GLOBMODE_DIR; pathOrDir = objv[i+1]; i++; break; case GLOB_JOIN: /* -join */ join = 1; break; case GLOB_TAILS: /* -tails */ globFlags |= TCL_GLOBMODE_TAILS; break; case GLOB_PATH: /* -path */ if (i == (objc-1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing argument to \"-path\"", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); return TCL_ERROR; } if (dir != PATH_NONE) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-path\" cannot be used with \"-directory\"", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BADOPTIONCOMBINATION", NULL); return TCL_ERROR; } dir = PATH_GENERAL; pathOrDir = objv[i+1]; i++; break; case GLOB_TYPE: /* -types */ if (i == (objc-1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing argument to \"-types\"", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); return TCL_ERROR; } typePtr = objv[i+1]; if (Tcl_ListObjLength(interp, typePtr, &length) != TCL_OK) { return TCL_ERROR; } i++; break; case GLOB_LAST: /* -- */ i++; goto endOfForLoop; } } endOfForLoop: if ((globFlags & TCL_GLOBMODE_TAILS) && (pathOrDir == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-tails\" must be used with either " "\"-directory\" or \"-path\"", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BADOPTIONCOMBINATION", NULL); return TCL_ERROR; } separators = NULL; /* lint. */ switch (tclPlatform) { case TCL_PLATFORM_UNIX: separators = "/"; break; case TCL_PLATFORM_WINDOWS: separators = "/\\:"; break; } if (dir == PATH_GENERAL) { size_t pathlength; const char *last; const char *first = Tcl_GetStringFromObj(pathOrDir,&pathlength); /* * Find the last path separator in the path */ |
︙ | ︙ | |||
1397 1398 1399 1400 1401 1402 1403 | /* * The whole thing is a prefix. This means we must remove any * 'tails' flag too, since it is irrelevant now (the same * effect will happen without it), but in particular its use * in TclGlob requires a non-NULL pathOrDir. */ | | | 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 | /* * The whole thing is a prefix. This means we must remove any * 'tails' flag too, since it is irrelevant now (the same * effect will happen without it), but in particular its use * in TclGlob requires a non-NULL pathOrDir. */ Tcl_DStringAppend(&pref, first, TCL_STRLEN); globFlags &= ~TCL_GLOBMODE_TAILS; pathOrDir = NULL; } else { /* * Have to split off the end. */ |
︙ | ︙ | |||
1436 1437 1438 1439 1440 1441 1442 | Tcl_DStringAppend(&prefix, find, 1); search = find+1; if (*search == '\0') { break; } } if (*search != '\0') { | | | 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 | Tcl_DStringAppend(&prefix, find, 1); search = find+1; if (*search == '\0') { break; } } if (*search != '\0') { Tcl_DStringAppend(&prefix, search, TCL_STRLEN); } Tcl_DStringFree(&pref); } } if (pathOrDir != NULL) { Tcl_IncrRefCount(pathOrDir); |
︙ | ︙ | |||
1463 1464 1465 1466 1467 1468 1469 | } globTypes = TclStackAlloc(interp, sizeof(Tcl_GlobTypeData)); globTypes->type = 0; globTypes->perm = 0; globTypes->macType = NULL; globTypes->macCreator = NULL; | | | | 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 | } globTypes = TclStackAlloc(interp, sizeof(Tcl_GlobTypeData)); globTypes->type = 0; globTypes->perm = 0; globTypes->macType = NULL; globTypes->macCreator = NULL; while (length-->0) { size_t len; const char *str; Tcl_ListObjIndex(interp, typePtr, length, &look); str = Tcl_GetStringFromObj(look, &len); if (strcmp("readonly", str) == 0) { globTypes->perm |= TCL_GLOB_PERM_RONLY; } else if (strcmp("hidden", str) == 0) { |
︙ | ︙ | |||
1565 1566 1567 1568 1569 1570 1571 | result = TCL_ERROR; join = 0; goto endOfGlob; badMacTypesArg: Tcl_SetObjResult(interp, Tcl_NewStringObj( "only one MacOS type or creator argument" | | | 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 | result = TCL_ERROR; join = 0; goto endOfGlob; badMacTypesArg: Tcl_SetObjResult(interp, Tcl_NewStringObj( "only one MacOS type or creator argument" " to \"-types\" allowed", TCL_STRLEN)); result = TCL_ERROR; Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "BAD", NULL); join = 0; goto endOfGlob; } } } |
︙ | ︙ | |||
1591 1592 1593 1594 1595 1596 1597 | if (join) { if (dir != PATH_GENERAL) { Tcl_DStringInit(&prefix); } for (i = 0; i < objc; i++) { TclDStringAppendObj(&prefix, objv[i]); | | | 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 | if (join) { if (dir != PATH_GENERAL) { Tcl_DStringInit(&prefix); } for (i = 0; i < objc; i++) { TclDStringAppendObj(&prefix, objv[i]); if (i != objc-1) { Tcl_DStringAppend(&prefix, separators, 1); } } if (TclGlob(interp, Tcl_DStringValue(&prefix), pathOrDir, globFlags, globTypes) != TCL_OK) { result = TCL_ERROR; goto endOfGlob; |
︙ | ︙ | |||
1744 1745 1746 1747 1748 1749 1750 | *tail = '\0'; head = DoTildeSubst(interp, start+1, &buffer); *tail = c; if (head == NULL) { return TCL_ERROR; } if (head != Tcl_DStringValue(&buffer)) { | | | 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 | *tail = '\0'; head = DoTildeSubst(interp, start+1, &buffer); *tail = c; if (head == NULL) { return TCL_ERROR; } if (head != Tcl_DStringValue(&buffer)) { Tcl_DStringAppend(&buffer, head, TCL_STRLEN); } pathPrefix = TclDStringToObj(&buffer); Tcl_IncrRefCount(pathPrefix); globFlags |= TCL_GLOBMODE_DIR; if (c != '\0') { tail++; } |
︙ | ︙ | |||
1798 1799 1800 1801 1802 1803 1804 | } p++; } tail = p; Tcl_IncrRefCount(pathPrefix); } else if (pathPrefix == NULL && (tail[0] == '/' || (tail[0] == '\\' && tail[1] == '\\'))) { | | | | 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 | } p++; } tail = p; Tcl_IncrRefCount(pathPrefix); } else if (pathPrefix == NULL && (tail[0] == '/' || (tail[0] == '\\' && tail[1] == '\\'))) { size_t driveNameLen; Tcl_Obj *driveName; Tcl_Obj *temp = Tcl_NewStringObj(tail, TCL_STRLEN); Tcl_IncrRefCount(temp); switch (TclGetPathType(temp, NULL, &driveNameLen, &driveName)) { case TCL_PATH_VOLUME_RELATIVE: { /* * Volume relative path which is equivalent to a path in the * root of the cwd's volume. We will actually return |
︙ | ︙ | |||
1866 1867 1868 1869 1870 1871 1872 | /* * Finally if we still haven't managed to generate a path prefix, check if * the path starts with a current volume. */ if (pathPrefix == NULL) { | | > | | 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 | /* * Finally if we still haven't managed to generate a path prefix, check if * the path starts with a current volume. */ if (pathPrefix == NULL) { size_t driveNameLen; Tcl_Obj *driveName; if (TclFSNonnativePathType(tail, strlen(tail), NULL, &driveNameLen, &driveName) == TCL_PATH_ABSOLUTE) { pathPrefix = driveName; tail += driveNameLen; } } /* |
︙ | ︙ | |||
1951 1952 1953 1954 1955 1956 1957 | * that would add a lot of complexity to the code. This way is a little * slower (when the -tails flag is given), but much simpler to code. * * We do it by rewriting the result list in-place. */ if (globFlags & TCL_GLOBMODE_TAILS) { | < | | 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 | * that would add a lot of complexity to the code. This way is a little * slower (when the -tails flag is given), but much simpler to code. * * We do it by rewriting the result list in-place. */ if (globFlags & TCL_GLOBMODE_TAILS) { Tcl_Obj **objv; size_t objc, i, prefixLen; const char *pre; /* * If this length has never been set, set it here. */ if (pathPrefix == NULL) { |
︙ | ︙ | |||
1981 1982 1983 1984 1985 1986 1987 | || (pre[1] != ':')) { prefixLen++; } } Tcl_ListObjGetElements(NULL, filenamesObj, &objc, &objv); for (i = 0; i< objc; i++) { | | | 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 | || (pre[1] != ':')) { prefixLen++; } } Tcl_ListObjGetElements(NULL, filenamesObj, &objc, &objv); for (i = 0; i< objc; i++) { size_t len; const char *oldStr = Tcl_GetStringFromObj(objv[i], &len); Tcl_Obj *elem; if (len == prefixLen) { if ((pattern[0] == '\0') || (strchr(separators, pattern[0]) == NULL)) { TclNewLiteralStringObj(elem, "."); |
︙ | ︙ | |||
2191 2192 2193 2194 2195 2196 2197 | * Balanced braces. */ closeBrace = p; break; } Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 | * Balanced braces. */ closeBrace = p; break; } Tcl_SetObjResult(interp, Tcl_NewStringObj( "unmatched open-brace in file name", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BALANCE", NULL); return TCL_ERROR; } else if (*p == '}') { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unmatched close-brace in file name", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BALANCE", NULL); return TCL_ERROR; } } /* |
︙ | ︙ | |||
2230 2231 2232 2233 2234 2235 2236 | *closeBrace = '\0'; for (p = openBrace; p != closeBrace; ) { p++; element = p; SkipToChar(&p, ','); Tcl_DStringSetLength(&newName, baseLength); Tcl_DStringAppend(&newName, element, p-element); | | | 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 | *closeBrace = '\0'; for (p = openBrace; p != closeBrace; ) { p++; element = p; SkipToChar(&p, ','); Tcl_DStringSetLength(&newName, baseLength); Tcl_DStringAppend(&newName, element, p-element); Tcl_DStringAppend(&newName, closeBrace+1, TCL_STRLEN); result = DoGlob(interp, matchesObj, separators, pathPtr, flags, Tcl_DStringValue(&newName), types); if (result != TCL_OK) { break; } } *closeBrace = '}'; |
︙ | ︙ | |||
2305 2306 2307 2308 2309 2310 2311 | *p = '\0'; TclNewObj(subdirsPtr); Tcl_IncrRefCount(subdirsPtr); result = Tcl_FSMatchInDirectory(interp, subdirsPtr, pathPtr, pattern, &dirOnly); *p = save; if (result == TCL_OK) { | | > | | | | | 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 | *p = '\0'; TclNewObj(subdirsPtr); Tcl_IncrRefCount(subdirsPtr); result = Tcl_FSMatchInDirectory(interp, subdirsPtr, pathPtr, pattern, &dirOnly); *p = save; if (result == TCL_OK) { size_t repair = TCL_STRLEN; Tcl_Obj **subdirv; size_t subdirc, i; result = Tcl_ListObjGetElements(interp, subdirsPtr, &subdirc, &subdirv); for (i=0; result==TCL_OK && i<subdirc; i++) { Tcl_Obj *copy = NULL; if (pathPtr == NULL && Tcl_GetString(subdirv[i])[0] == '~') { Tcl_ListObjLength(NULL, matchesObj, &repair); copy = subdirv[i]; subdirv[i] = Tcl_NewStringObj("./", 2); Tcl_AppendObjToObj(subdirv[i], copy); Tcl_IncrRefCount(subdirv[i]); } result = DoGlob(interp, matchesObj, separators, subdirv[i], 1, p+1, types); if (copy) { size_t end; Tcl_DecrRefCount(subdirv[i]); subdirv[i] = copy; Tcl_ListObjLength(NULL, matchesObj, &end); while (repair < end) { const char *bytes; size_t numBytes; Tcl_Obj *fixme, *newObj; Tcl_ListObjIndex(NULL, matchesObj, repair, &fixme); bytes = Tcl_GetStringFromObj(fixme, &numBytes); newObj = Tcl_NewStringObj(bytes+2, numBytes-2); Tcl_ListObjReplace(NULL, matchesObj, repair, 1, 1, &newObj); repair++; } repair = TCL_STRLEN; } } } TclDecrRefCount(subdirsPtr); return result; } /* * We reach here with no pattern char in current section */ if (*p == '\0') { size_t length; Tcl_DString append; /* * This is the code path reached by a command like 'glob foo'. * * There are no more wildcards in the pattern and no more unprocessed * characters in the pattern, so now we can construct the path, and |
︙ | ︙ | |||
2417 2418 2419 2420 2421 2422 2423 | } else { joinedPtr = Tcl_DuplicateObj(pathPtr); if (strchr(separators, Tcl_DStringValue(&append)[0]) == NULL) { /* * The current prefix must end in a separator. */ | | | 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 | } else { joinedPtr = Tcl_DuplicateObj(pathPtr); if (strchr(separators, Tcl_DStringValue(&append)[0]) == NULL) { /* * The current prefix must end in a separator. */ size_t len; const char *joined = Tcl_GetStringFromObj(joinedPtr,&len); if (strchr(separators, joined[len-1]) == NULL) { Tcl_AppendToObj(joinedPtr, "/", 1); } } Tcl_AppendToObj(joinedPtr, Tcl_DStringValue(&append), |
︙ | ︙ | |||
2454 2455 2456 2457 2458 2459 2460 | * The current prefix must end in a separator, unless this is a * volume-relative path. In particular globbing in Windows shares, * when not using -dir or -path, e.g. 'glob [file join * //machine/share/subdir *]' requires adding a separator here. * This behaviour is not currently tested for in the test suite. */ | | | 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 | * The current prefix must end in a separator, unless this is a * volume-relative path. In particular globbing in Windows shares, * when not using -dir or -path, e.g. 'glob [file join * //machine/share/subdir *]' requires adding a separator here. * This behaviour is not currently tested for in the test suite. */ size_t len; const char *joined = Tcl_GetStringFromObj(joinedPtr,&len); if (strchr(separators, joined[len-1]) == NULL) { if (Tcl_FSGetPathType(pathPtr) != TCL_PATH_VOLUME_RELATIVE) { Tcl_AppendToObj(joinedPtr, "/", 1); } } |
︙ | ︙ |
Changes to generic/tclFileSystem.h.
︙ | ︙ | |||
44 45 46 47 48 49 50 | /* * Private shared functions for use by tclIOUtil.c, tclPathObj.c and * tclFileName.c, and any platform-specific filesystem code. */ MODULE_SCOPE Tcl_PathType TclFSGetPathType(Tcl_Obj *pathPtr, const Tcl_Filesystem **filesystemPtrPtr, | | | | | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | /* * Private shared functions for use by tclIOUtil.c, tclPathObj.c and * tclFileName.c, and any platform-specific filesystem code. */ MODULE_SCOPE Tcl_PathType TclFSGetPathType(Tcl_Obj *pathPtr, const Tcl_Filesystem **filesystemPtrPtr, size_t *driveNameLengthPtr); MODULE_SCOPE Tcl_PathType TclFSNonnativePathType(const char *pathPtr, size_t pathLen, const Tcl_Filesystem **filesystemPtrPtr, size_t *driveNameLengthPtr, Tcl_Obj **driveNameRef); MODULE_SCOPE Tcl_PathType TclGetPathType(Tcl_Obj *pathPtr, const Tcl_Filesystem **filesystemPtrPtr, size_t *driveNameLengthPtr, Tcl_Obj **driveNameRef); MODULE_SCOPE int TclFSEpochOk(int filesystemEpoch); MODULE_SCOPE int TclFSCwdIsNative(void); MODULE_SCOPE Tcl_Obj * TclWinVolumeRelativeNormalize(Tcl_Interp *interp, const char *path, Tcl_Obj **useThisCwdPtr); MODULE_SCOPE Tcl_FSPathInFilesystemProc TclNativePathInFilesystem; MODULE_SCOPE Tcl_FSCreateInternalRepProc TclNativeCreateNativeRep; |
︙ | ︙ |
Changes to generic/tclGetDate.y.
︙ | ︙ | |||
958 959 960 961 962 963 964 | } } int TclClockOldscanObjCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 | } } int TclClockOldscanObjCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Count of parameters */ Tcl_Obj *const *objv) /* Parameters */ { Tcl_Obj *result, *resultElement; int yr, mo, da; DateInfo dateInfo; DateInfo* info = &dateInfo; int status; |
︙ | ︙ |
Changes to generic/tclHash.c.
︙ | ︙ | |||
671 672 673 674 675 676 677 | } /* * Print out the histogram and a few other pieces of information. */ result = ckalloc((NUM_COUNTERS * 60) + 300); | | | 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 | } /* * Print out the histogram and a few other pieces of information. */ result = ckalloc((NUM_COUNTERS * 60) + 300); sprintf(result, "%lu entries in table, %lu buckets\n", tablePtr->numEntries, tablePtr->numBuckets); p = result + strlen(result); for (i = 0; i < NUM_COUNTERS; i++) { sprintf(p, "number of buckets with %d entries: %d\n", i, count[i]); p += strlen(p); } |
︙ | ︙ |
Changes to generic/tclIO.c.
︙ | ︙ | |||
80 81 82 83 84 85 86 | Tcl_Encoding encoding; /* The encoding to use to convert raw bytes * to UTF-8. */ ChannelBuffer *bufPtr; /* The current buffer of raw bytes being * emptied. */ Tcl_EncodingState state; /* The encoding state just before the last * external to UTF-8 conversion in * FilterInputBytes(). */ | | | | | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | Tcl_Encoding encoding; /* The encoding to use to convert raw bytes * to UTF-8. */ ChannelBuffer *bufPtr; /* The current buffer of raw bytes being * emptied. */ Tcl_EncodingState state; /* The encoding state just before the last * external to UTF-8 conversion in * FilterInputBytes(). */ size_t rawRead; /* The number of bytes removed from bufPtr * in the last call to FilterInputBytes(). */ size_t bytesWrote; /* The number of bytes of UTF-8 data * appended to objPtr during the last call to * FilterInputBytes(). */ size_t charsWrote; /* The corresponding number of UTF-8 * characters appended to objPtr during the * last call to FilterInputBytes(). */ size_t totalChars; /* The total number of UTF-8 characters * appended to objPtr so far, just before the * last call to FilterInputBytes(). */ } GetsState; /* * The following structure encapsulates the state for a background channel * copy. Note that the data buffer for the copy will be appended to this |
︙ | ︙ | |||
174 175 176 177 178 179 180 | Channel *chanPtr); static int CloseChannel(Tcl_Interp *interp, Channel *chanPtr, int errorCode); static int CloseChannelPart(Tcl_Interp *interp, Channel *chanPtr, int errorCode, int flags); static int CloseWrite(Tcl_Interp *interp, Channel *chanPtr); static void CommonGetsCleanup(Channel *chanPtr); | | | | > | > | > | | | > | | | | > | > | > | | | | | | | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 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 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 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | Channel *chanPtr); static int CloseChannel(Tcl_Interp *interp, Channel *chanPtr, int errorCode); static int CloseChannelPart(Tcl_Interp *interp, Channel *chanPtr, int errorCode, int flags); static int CloseWrite(Tcl_Interp *interp, Channel *chanPtr); static void CommonGetsCleanup(Channel *chanPtr); static size_t CopyAndTranslateBuffer(ChannelState *statePtr, char *result, size_t space); static size_t CopyBuffer(Channel *chanPtr, char *result, size_t space); static int CopyData(CopyState *csPtr, int mask); static void CopyEventProc(ClientData clientData, int mask); static void CreateScriptRecord(Tcl_Interp *interp, Channel *chanPtr, int mask, Tcl_Obj *scriptPtr); static void DeleteChannelTable(ClientData clientData, Tcl_Interp *interp); static void DeleteScriptRecord(Tcl_Interp *interp, Channel *chanPtr, int mask); static int DetachChannel(Tcl_Interp *interp, Tcl_Channel chan); static void DiscardInputQueued(ChannelState *statePtr, int discardSavedBuffers); static void DiscardOutputQueued(ChannelState *chanPtr); static ssize_t DoRead(Channel *chanPtr, char *srcPtr, size_t slen, int allowShortReads); static ssize_t DoWrite(Channel *chanPtr, const char *src, size_t srcLen); static ssize_t DoReadChars(Channel *chan, Tcl_Obj *objPtr, size_t toRead, int appendFlag); static ssize_t DoWriteChars(Channel *chan, const char *src, size_t len); static int FilterInputBytes(Channel *chanPtr, GetsState *statePtr); static int FlushChannel(Tcl_Interp *interp, Channel *chanPtr, int calledFromAsyncFlush); static ssize_t TclGetsObjBinary(Tcl_Channel chan, Tcl_Obj *objPtr); static void FreeBinaryEncoding(ClientData clientData); static Tcl_HashTable * GetChannelTable(Tcl_Interp *interp); static int GetInput(Channel *chanPtr); static int HaveVersion(const Tcl_ChannelType *typePtr, Tcl_ChannelTypeVersion minimumVersion); static void PeekAhead(Channel *chanPtr, char **dstEndPtr, GetsState *gsPtr); static ssize_t ReadBytes(ChannelState *statePtr, Tcl_Obj *objPtr, size_t charsLeft, size_t *offsetPtr); static ssize_t ReadChars(ChannelState *statePtr, Tcl_Obj *objPtr, size_t charsLeft, size_t *offsetPtr, size_t *factorPtr); static void RecycleBuffer(ChannelState *statePtr, ChannelBuffer *bufPtr, int mustDiscard); static int StackSetBlockMode(Channel *chanPtr, int mode); static int SetBlockMode(Tcl_Interp *interp, Channel *chanPtr, int mode); static void StopCopy(CopyState *csPtr); static int TranslateInputEOL(ChannelState *statePtr, char *dst, const char *src, size_t *dstLenPtr, size_t *srcLenPtr); static int TranslateOutputEOL(ChannelState *statePtr, char *dst, const char *src, size_t *dstLenPtr, size_t *srcLenPtr); static void UpdateInterest(Channel *chanPtr); static ssize_t WriteBytes(Channel *chanPtr, const char *src, size_t srcLen); static ssize_t WriteChars(Channel *chanPtr, const char *src, size_t srcLen); static Tcl_Obj * FixLevelCode(Tcl_Obj *msg); static void SpliceChannel(Tcl_Channel chan); static void CutChannel(Tcl_Channel chan); static inline int WillRead(Channel *chanPtr); /* * Simplifying helper macros. All may use their argument(s) multiple times. * The ANSI C "prototypes" for the macros are listed below, together with a * short description of what the macro does. * * -------------------------------------------------------------------------- * size_t BytesLeft(ChannelBuffer *bufPtr) * * Returns the number of bytes of data remaining in the buffer. * * ssize_t SpaceLeft(ChannelBuffer *bufPtr) * * Returns the number of bytes of space remaining at the end of the * buffer. * * int IsBufferReady(ChannelBuffer *bufPtr) * * Returns whether a buffer has bytes available within it. |
︙ | ︙ | |||
378 379 380 381 382 383 384 | Channel *chanPtr, Tcl_Interp *interp, int flags) { return chanPtr->typePtr->close2Proc(chanPtr->instanceData, interp, flags); } | | | | | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | Channel *chanPtr, Tcl_Interp *interp, int flags) { return chanPtr->typePtr->close2Proc(chanPtr->instanceData, interp, flags); } static inline ssize_t ChanRead( Channel *chanPtr, char *dst, size_t dstSize, int *errnoPtr) { if (WillRead(chanPtr)) { return -1; } return chanPtr->typePtr->inputProc(chanPtr->instanceData, dst, dstSize, errnoPtr); } |
︙ | ︙ | |||
441 442 443 444 445 446 447 | ChanWatch( Channel *chanPtr, int mask) { chanPtr->typePtr->watchProc(chanPtr->instanceData, mask); } | | | | 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | ChanWatch( Channel *chanPtr, int mask) { chanPtr->typePtr->watchProc(chanPtr->instanceData, mask); } static inline ssize_t ChanWrite( Channel *chanPtr, const char *src, size_t srcLen, int *errnoPtr) { return chanPtr->typePtr->outputProc(chanPtr->instanceData, src, srcLen, errnoPtr); } /* |
︙ | ︙ | |||
540 541 542 543 544 545 546 | for (statePtr = tsdPtr->firstCSPtr; statePtr != NULL; statePtr = statePtr->nextCSPtr) { chanPtr = statePtr->topChanPtr; if (GotFlag(statePtr, CHANNEL_DEAD)) { continue; } | | | < | | | > > | | | | | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | for (statePtr = tsdPtr->firstCSPtr; statePtr != NULL; statePtr = statePtr->nextCSPtr) { chanPtr = statePtr->topChanPtr; if (GotFlag(statePtr, CHANNEL_DEAD)) { continue; } if (!GotFlag(statePtr, CHANNEL_INCLOSE | CHANNEL_CLOSED) || GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { ResetFlag(statePtr, BG_FLUSH_SCHEDULED); active = 1; break; } } /* * We've found a live (or bg-closing) channel. Close it. */ if (active) { /* * TIP #398: by default, we no longer set the channel back into * blocking mode. To restore the old blocking behavior, the * environment variable TCL_FLUSH_NONBLOCKING_ON_EXIT must be set * and not be "0". */ if (doflushnb) { /* * Set the channel back into blocking mode to ensure that we * wait for all data to flush out. */ (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr, "-blocking", "on"); } if ((chanPtr == (Channel *) tsdPtr->stdinChannel) || (chanPtr == (Channel *) tsdPtr->stdoutChannel) || (chanPtr == (Channel *) tsdPtr->stderrChannel)) { /* * Decrement the refcount which was earlier artificially |
︙ | ︙ | |||
1147 1148 1149 1150 1151 1152 1153 | statePtr = ((Channel *) chan)->state->bottomChanPtr->state; if (GotFlag(statePtr, CHANNEL_INCLOSE)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal recursive call to close through close-handler" | | | 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 | statePtr = ((Channel *) chan)->state->bottomChanPtr->state; if (GotFlag(statePtr, CHANNEL_INCLOSE)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal recursive call to close through close-handler" " of channel", TCL_STRLEN)); } return TCL_ERROR; } if (DetachChannel(interp, chan) != TCL_OK) { return TCL_OK; } |
︙ | ︙ | |||
2440 2441 2442 2443 2444 2445 2446 | if (!GotFlag(statePtr, CHANNEL_DEAD)) { return 0; } Tcl_SetErrno(EINVAL); if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 | if (!GotFlag(statePtr, CHANNEL_DEAD)) { return 0; } Tcl_SetErrno(EINVAL); if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unable to access channel: invalid channel", TCL_STRLEN)); } return 1; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
2635 2636 2637 2638 2639 2640 2641 | * regular message if nothing was found in the bypasses. */ Tcl_SetErrno(errorCode); if (interp != NULL && !TclChanCaughtErrorBypass(interp, (Tcl_Channel) chanPtr)) { Tcl_SetObjResult(interp, | | > | 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 | * regular message if nothing was found in the bypasses. */ Tcl_SetErrno(errorCode); if (interp != NULL && !TclChanCaughtErrorBypass(interp, (Tcl_Channel) chanPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_PosixError(interp), TCL_STRLEN)); } /* * An unreportable bypassed message is kept, for the caller of * Tcl_Seek, Tcl_Write, etc. */ } |
︙ | ︙ | |||
3174 3175 3176 3177 3178 3179 3180 | Tcl_Panic("called Tcl_Close on channel with refCount > 0"); } if (GotFlag(statePtr, CHANNEL_INCLOSE)) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal recursive call to close through close-handler" | | | 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 | Tcl_Panic("called Tcl_Close on channel with refCount > 0"); } if (GotFlag(statePtr, CHANNEL_INCLOSE)) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal recursive call to close through close-handler" " of channel", TCL_STRLEN)); } return TCL_ERROR; } SetFlag(statePtr, CHANNEL_INCLOSE); /* * When the channel has an escape sequence driven encoding such as |
︙ | ︙ | |||
3275 3276 3277 3278 3279 3280 3281 | result = EINVAL; } if (stickyError != 0) { Tcl_SetErrno(stickyError); if (interp != NULL) { Tcl_SetObjResult(interp, | | | 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 | result = EINVAL; } if (stickyError != 0) { Tcl_SetErrno(stickyError); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_PosixError(interp), TCL_STRLEN)); } flushcode = -1; } if ((flushcode != 0) || (result != 0)) { return TCL_ERROR; } return TCL_OK; |
︙ | ︙ | |||
3344 3345 3346 3347 3348 3349 3350 | /* * Is the channel unstacked ? If not we fail. */ if (chanPtr != statePtr->topChanPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 | /* * Is the channel unstacked ? If not we fail. */ if (chanPtr != statePtr->topChanPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "half-close not applicable to stack of transformations", TCL_STRLEN)); return TCL_ERROR; } /* * Check direction against channel mode. It is an error if we try to close * a direction not supported by the channel (already closed, or never * opened for that direction). |
︙ | ︙ | |||
3377 3378 3379 3380 3381 3382 3383 | * handler. That won't do. */ if (statePtr->flags & CHANNEL_INCLOSE) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal recursive call to close through close-handler" | | | 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 | * handler. That won't do. */ if (statePtr->flags & CHANNEL_INCLOSE) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal recursive call to close through close-handler" " of channel", TCL_STRLEN)); } return TCL_ERROR; } if (flags & TCL_CLOSE_READ) { /* * Call the finalization code directly. There are no events to handle, |
︙ | ︙ | |||
3750 3751 3752 3753 3754 3755 3756 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ | | | | | 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ ssize_t Tcl_Write( Tcl_Channel chan, /* The channel to buffer output for. */ const char *src, /* Data to queue in output buffer. */ size_t srcLen) /* Length of data in bytes, or TCL_STRLEN for * strlen(). */ { /* * Always use the topmost channel of the stack */ Channel *chanPtr; ChannelState *statePtr; /* State info for channel */ statePtr = ((Channel *) chan)->state; chanPtr = statePtr->topChanPtr; if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) { return -1; } if (srcLen == TCL_STRLEN) { srcLen = strlen(src); } return DoWrite(chanPtr, src, srcLen); } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
3801 3802 3803 3804 3805 3806 3807 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ | | | | | 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 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ ssize_t Tcl_WriteRaw( Tcl_Channel chan, /* The channel to buffer output for. */ const char *src, /* Data to queue in output buffer. */ size_t srcLen) /* Length of data in bytes, or TCL_STRLEN for * strlen(). */ { Channel *chanPtr = ((Channel *) chan); ChannelState *statePtr = chanPtr->state; /* State info for channel */ int errorCode, written; if (CheckChannelErrors(statePtr, TCL_WRITABLE | CHANNEL_RAW_MODE) != 0) { return -1; } if (srcLen == TCL_STRLEN) { srcLen = strlen(src); } /* * Go immediately to the driver, do all the error handling by ourselves. * The code was stolen from 'FlushChannel'. */ |
︙ | ︙ | |||
3857 3858 3859 3860 3861 3862 3863 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ | | | | | 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ ssize_t Tcl_WriteChars( Tcl_Channel chan, /* The channel to buffer output for. */ const char *src, /* UTF-8 characters to queue in output * buffer. */ size_t len) /* Length of string in bytes, or TCL_STRLEN * for strlen(). */ { ChannelState *statePtr; /* State info for channel */ statePtr = ((Channel *) chan)->state; if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) { return -1; |
︙ | ︙ | |||
3899 3900 3901 3902 3903 3904 3905 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ | | | | | | 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ static ssize_t DoWriteChars( Channel *chanPtr, /* The channel to buffer output for. */ const char *src, /* UTF-8 characters to queue in output * buffer. */ size_t len) /* Length of string in bytes, or TCL_STRLEN * for strlen(). */ { /* * Always use the topmost channel of the stack */ ChannelState *statePtr; /* State info for channel */ statePtr = chanPtr->state; chanPtr = statePtr->topChanPtr; if (len == TCL_STRLEN) { len = strlen(src); } if (statePtr->encoding == NULL) { /* * Inefficient way to convert UTF-8 to byte-array, but the code * parallels the way it is done for objects. * Special case for 1-byte (used by eg [puts] for the \n) could |
︙ | ︙ | |||
3968 3969 3970 3971 3972 3973 3974 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ | | | | 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ ssize_t Tcl_WriteObj( Tcl_Channel chan, /* The channel to buffer output for. */ Tcl_Obj *objPtr) /* The object to write. */ { /* * Always use the topmost channel of the stack */ Channel *chanPtr; ChannelState *statePtr; /* State info for channel */ const char *src; size_t srcLen; statePtr = ((Channel *) chan)->state; chanPtr = statePtr->topChanPtr; if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) { return -1; } |
︙ | ︙ | |||
4012 4013 4014 4015 4016 4017 4018 | int ignore; DiscardInputQueued(chanPtr->state, 0); ChanSeek(chanPtr, -inputBuffered, SEEK_CUR, &ignore); } } | | | | 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 | int ignore; DiscardInputQueued(chanPtr->state, 0); ChanSeek(chanPtr, -inputBuffered, SEEK_CUR, &ignore); } } static inline int WillRead( Channel *chanPtr) { if ((chanPtr->typePtr->seekProc != NULL) && (Tcl_OutputBuffered((Tcl_Channel) chanPtr) > 0)) { if ((chanPtr->state->curOutPtr != NULL) && IsBufferReady(chanPtr->state->curOutPtr)) { SetFlag(chanPtr->state, BUFFER_READY); } if (FlushChannel(NULL, chanPtr, 0) != 0) { return 1; } } return 0; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
4050 4051 4052 4053 4054 4055 4056 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ | | | > | | 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ static ssize_t WriteBytes( Channel *chanPtr, /* The channel to buffer output for. */ const char *src, /* Bytes to write. */ size_t srcLen) /* Number of bytes to write. */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; char *dst; int translate; size_t dstMax, sawLF, savedLF, total, dstLen, toWrite; if (srcLen) { WillWrite(chanPtr); } total = 0; sawLF = 0; |
︙ | ︙ | |||
4151 4152 4153 4154 4155 4156 4157 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ | | | < < | > > | 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ static ssize_t WriteChars( Channel *chanPtr, /* The channel to buffer output for. */ const char *src, /* UTF-8 string to write. */ size_t srcLen) /* Length of UTF-8 string in bytes. */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; char *dst, *stage; int savedLF, sawLF, endEncoding, result, consumedSomething, translate; size_t saved; size_t total, dstLen, dstWrote, stageLen, stageMax, stageRead, toWrite; Tcl_Encoding encoding; char safe[BUFFER_PADDING]; if (srcLen) { WillWrite(chanPtr); } |
︙ | ︙ | |||
4256 4257 4258 4259 4260 4261 4262 | if (saved != 0) { /* * Here's some translated bytes left over from the last buffer * that we need to stick at the beginning of this buffer. */ | | | | 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 | if (saved != 0) { /* * Here's some translated bytes left over from the last buffer * that we need to stick at the beginning of this buffer. */ memcpy(dst, safe, saved); bufPtr->nextAdded += saved; dst += saved; dstLen -= saved; saved = 0; } result = Tcl_UtfToExternal(NULL, encoding, stage, stageLen, statePtr->outputEncodingFlags, &statePtr->outputEncodingState, dst, dstLen + BUFFER_PADDING, &stageRead, &dstWrote, NULL); /* * Fix for [Bug 506297], reported by Martin Forssen * <[email protected]>. * * The encoding chosen in the script exposing the bug writes out * three intro characters when TCL_ENCODING_START is set, but does * not consume any input as TCL_ENCODING_END is cleared. As some * output was generated the enclosing loop calls UtfToExternal * again, again with START set. Three more characters in the out |
︙ | ︙ | |||
4314 4315 4316 4317 4318 4319 4320 | * allowed the translation to produce a character that crossed * the end of the output buffer, so that we would get a * completely full buffer before flushing it. The extra bytes * will be moved to the beginning of the next buffer. */ saved = -SpaceLeft(bufPtr); | | | 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 | * allowed the translation to produce a character that crossed * the end of the output buffer, so that we would get a * completely full buffer before flushing it. The extra bytes * will be moved to the beginning of the next buffer. */ saved = -SpaceLeft(bufPtr); memcpy(safe, dst + dstLen, saved); bufPtr->nextAdded = bufPtr->bufLength; } if (CheckFlush(chanPtr, bufPtr, sawLF) != 0) { return -1; } total += dstWrote; |
︙ | ︙ | |||
4399 4400 4401 4402 4403 4404 4405 | TranslateOutputEOL( ChannelState *statePtr, /* Channel being read, for translation and * buffering modes. */ char *dst, /* Output buffer filled with UTF-8 chars by * applying appropriate EOL translation to * source characters. */ const char *src, /* Source UTF-8 characters. */ | | | | 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 | TranslateOutputEOL( ChannelState *statePtr, /* Channel being read, for translation and * buffering modes. */ char *dst, /* Output buffer filled with UTF-8 chars by * applying appropriate EOL translation to * source characters. */ const char *src, /* Source UTF-8 characters. */ size_t *dstLenPtr, /* On entry, the maximum length of output * buffer in bytes. On exit, the number of * bytes actually used in output buffer. */ size_t *srcLenPtr) /* On entry, the length of source buffer. On * exit, the number of bytes read from the * source buffer. */ { char *dstEnd; int srcLen, newlineFound; newlineFound = 0; |
︙ | ︙ | |||
4548 4549 4550 4551 4552 4553 4554 | * Side effects: * May flush output on the channel. May cause input to be consumed from * the channel. * *--------------------------------------------------------------------------- */ | | | | 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 | * Side effects: * May flush output on the channel. May cause input to be consumed from * the channel. * *--------------------------------------------------------------------------- */ ssize_t Tcl_Gets( Tcl_Channel chan, /* Channel from which to read. */ Tcl_DString *lineRead) /* The line read will be appended to this * DString as UTF-8 characters. The caller * must have initialized it and is responsible * for managing the storage. */ { Tcl_Obj *objPtr; ssize_t charsStored; TclNewObj(objPtr); charsStored = Tcl_GetsObj(chan, objPtr); if (charsStored > 0) { TclDStringAppendObj(lineRead, objPtr); } TclDecrRefCount(objPtr); |
︙ | ︙ | |||
4591 4592 4593 4594 4595 4596 4597 | * * On reading EOF, leave channel pointing at EOF char. On reading EOL, * leave channel pointing after EOL, but don't return EOL in dst buffer. * *--------------------------------------------------------------------------- */ | | | > | 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 | * * On reading EOF, leave channel pointing at EOF char. On reading EOL, * leave channel pointing after EOL, but don't return EOL in dst buffer. * *--------------------------------------------------------------------------- */ ssize_t Tcl_GetsObj( Tcl_Channel chan, /* Channel from which to read. */ Tcl_Obj *objPtr) /* The line read will be appended to this * object as UTF-8 characters. */ { GetsState gs; Channel *chanPtr = (Channel *) chan; ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; int inEofChar, skip, oldFlags; size_t copiedTotal, oldLength, oldRemoved; Tcl_Encoding encoding; char *dst, *dstEnd, *eol, *eof; Tcl_EncodingState oldState; if (CheckChannelErrors(statePtr, TCL_READABLE) != 0) { copiedTotal = -1; goto done; |
︙ | ︙ | |||
4778 4779 4780 4781 4782 4783 4784 | ResetFlag(statePtr, INPUT_SAW_CR); if ((eol < dstEnd) && (*eol == '\n')) { /* * Skip the raw bytes that make up the '\n'. */ char tmp[1 + TCL_UTF_MAX]; | | | 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 | ResetFlag(statePtr, INPUT_SAW_CR); if ((eol < dstEnd) && (*eol == '\n')) { /* * Skip the raw bytes that make up the '\n'. */ char tmp[1 + TCL_UTF_MAX]; size_t rawRead; bufPtr = gs.bufPtr; Tcl_ExternalToUtf(NULL, gs.encoding, RemovePoint(bufPtr), gs.rawRead, statePtr->inputEncodingFlags, &gs.state, tmp, 1 + TCL_UTF_MAX, &rawRead, NULL, NULL); bufPtr->nextRemoved += rawRead; |
︙ | ︙ | |||
4977 4978 4979 4980 4981 4982 4983 | * * On reading EOF, leave channel pointing at EOF char. On reading EOL, * leave channel pointing after EOL, but don't return EOL in dst buffer. * *--------------------------------------------------------------------------- */ | | | | | 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 | * * On reading EOF, leave channel pointing at EOF char. On reading EOL, * leave channel pointing after EOL, but don't return EOL in dst buffer. * *--------------------------------------------------------------------------- */ static ssize_t TclGetsObjBinary( Tcl_Channel chan, /* Channel from which to read. */ Tcl_Obj *objPtr) /* The line read will be appended to this * object as UTF-8 characters. */ { Channel *chanPtr = (Channel *) chan; ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; int inEofChar, skip, oldFlags, eolChar; size_t rawLen, byteLen, copiedTotal, oldLength, oldRemoved; unsigned char *dst, *dstEnd, *eol, *eof, *byteArray; /* * This operation should occur at the top of a channel stack. */ chanPtr = statePtr->topChanPtr; |
︙ | ︙ | |||
5119 5120 5121 5122 5123 5124 5125 | /* * Copy bytes from the channel buffer to the ByteArray. * This may realloc space, so keep track of result. */ rawLen = dstEnd - dst; byteArray = Tcl_SetByteArrayLength(objPtr, byteLen + rawLen); | | | | 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 | /* * Copy bytes from the channel buffer to the ByteArray. * This may realloc space, so keep track of result. */ rawLen = dstEnd - dst; byteArray = Tcl_SetByteArrayLength(objPtr, byteLen + rawLen); memcpy(byteArray + byteLen, dst, rawLen); byteLen += rawLen; } /* * Found EOL or EOF, but the output buffer may now contain too many bytes. * We need to know how many bytes correspond to the number we want, so we * can remove the correct number of bytes from the channel buffer. */ gotEOL: if (bufPtr == NULL) { Tcl_Panic("TclGetsObjBinary: gotEOL reached with bufPtr==NULL"); } rawLen = eol - dst; byteArray = Tcl_SetByteArrayLength(objPtr, byteLen + rawLen); memcpy(byteArray + byteLen, dst, rawLen); byteLen += rawLen; bufPtr->nextRemoved += rawLen + skip; /* * Convert the buffer if there was an encoding. * XXX - unimplemented. */ |
︙ | ︙ | |||
5261 5262 5263 5264 5265 5266 5267 | Channel *chanPtr, /* Channel to read. */ GetsState *gsPtr) /* Current state of gets operation. */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; char *raw, *rawStart, *dst; | > | | 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 | Channel *chanPtr, /* Channel to read. */ GetsState *gsPtr) /* Current state of gets operation. */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; char *raw, *rawStart, *dst; int result; size_t offset, toRead, dstNeeded, spaceLeft, rawLen; Tcl_Obj *objPtr; #define ENCODING_LINESIZE 20 /* Lower bound on how many bytes to convert at * a time. Since we don't know a priori how * many bytes of storage this many source * bytes will use, we actually need at least * ENCODING_LINESIZE * TCL_MAX_UTF bytes of * room. */ |
︙ | ︙ | |||
5330 5331 5332 5333 5334 5335 5336 | toRead = ENCODING_LINESIZE; if (toRead > rawLen) { toRead = rawLen; } dstNeeded = toRead * TCL_UTF_MAX; spaceLeft = objPtr->length - offset; if (dstNeeded > spaceLeft) { | | | 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 | toRead = ENCODING_LINESIZE; if (toRead > rawLen) { toRead = rawLen; } dstNeeded = toRead * TCL_UTF_MAX; spaceLeft = objPtr->length - offset; if (dstNeeded > spaceLeft) { size_t length = offset + ((offset < dstNeeded) ? dstNeeded : offset); if (Tcl_AttemptSetObjLength(objPtr, length) == 0) { length = offset + dstNeeded; if (Tcl_AttemptSetObjLength(objPtr, length) == 0) { dstNeeded = TCL_UTF_MAX - 1 + toRead; length = offset + dstNeeded; Tcl_SetObjLength(objPtr, length); |
︙ | ︙ | |||
5365 5366 5367 5368 5369 5370 5371 | /* * The last few bytes in this channel buffer were the start of a * multibyte sequence. If this buffer was full, then move them to the * next buffer so the bytes will be contiguous. */ ChannelBuffer *nextPtr; | | | 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 | /* * The last few bytes in this channel buffer were the start of a * multibyte sequence. If this buffer was full, then move them to the * next buffer so the bytes will be contiguous. */ ChannelBuffer *nextPtr; size_t extra; nextPtr = bufPtr->nextPtr; if (!IsBufferFull(bufPtr)) { if (gsPtr->rawRead > 0) { /* * Some raw bytes were converted to UTF-8. Fall through, * returning those UTF-8 characters because a EOL might be |
︙ | ︙ | |||
5398 5399 5400 5401 5402 5403 5404 | if (nextPtr == NULL) { nextPtr = AllocChannelBuffer(statePtr->bufSize); bufPtr->nextPtr = nextPtr; statePtr->inQueueTail = nextPtr; } extra = rawLen - gsPtr->rawRead; memcpy(nextPtr->buf + (BUFFER_PADDING - extra), | | | 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 | if (nextPtr == NULL) { nextPtr = AllocChannelBuffer(statePtr->bufSize); bufPtr->nextPtr = nextPtr; statePtr->inQueueTail = nextPtr; } extra = rawLen - gsPtr->rawRead; memcpy(nextPtr->buf + (BUFFER_PADDING - extra), raw + gsPtr->rawRead, extra); nextPtr->nextRemoved -= extra; bufPtr->nextAdded -= extra; } } gsPtr->bufPtr = bufPtr; return 0; |
︙ | ︙ | |||
5541 5542 5543 5544 5545 5546 5547 | * buffer because the caller could change the channel's encoding which * could change the interpretation of whether those bytes really made * up multi-byte characters after all. */ nextPtr = bufPtr->nextPtr; for ( ; nextPtr != NULL; nextPtr = bufPtr->nextPtr) { | | | < | 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 | * buffer because the caller could change the channel's encoding which * could change the interpretation of whether those bytes really made * up multi-byte characters after all. */ nextPtr = bufPtr->nextPtr; for ( ; nextPtr != NULL; nextPtr = bufPtr->nextPtr) { size_t extra; extra = SpaceLeft(bufPtr); if (extra > 0) { memcpy(InsertPoint(bufPtr), nextPtr->buf + (BUFFER_PADDING - extra), extra); bufPtr->nextAdded += extra; nextPtr->nextRemoved = BUFFER_PADDING; } bufPtr = nextPtr; } } } |
︙ | ︙ | |||
5578 5579 5580 5581 5582 5583 5584 | * * Side effects: * May cause input to be buffered. * *---------------------------------------------------------------------- */ | | | | 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 | * * Side effects: * May cause input to be buffered. * *---------------------------------------------------------------------- */ ssize_t Tcl_Read( Tcl_Channel chan, /* The channel from which to read. */ char *dst, /* Where to store input read. */ size_t bytesToRead) /* Maximum number of bytes to read. */ { Channel *chanPtr = (Channel *) chan; ChannelState *statePtr = chanPtr->state; /* State info for channel */ /* * This operation should occur at the top of a channel stack. |
︙ | ︙ | |||
5623 5624 5625 5626 5627 5628 5629 | * * Side effects: * May cause input to be buffered. * *---------------------------------------------------------------------- */ | | | > | > | 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 | * * Side effects: * May cause input to be buffered. * *---------------------------------------------------------------------- */ ssize_t Tcl_ReadRaw( Tcl_Channel chan, /* The channel from which to read. */ char *bufPtr, /* Where to store input read. */ size_t bytesToRead) /* Maximum number of bytes to read. */ { Channel *chanPtr = (Channel *) chan; ChannelState *statePtr = chanPtr->state; /* State info for channel */ ssize_t nread; size_t copied, copiedNow; int result; /* * The check below does too much because it will reject a call to this * function with a channel which is part of an 'fcopy'. But we have to * allow this here or else the chaining in the transformation drivers will * fail with 'file busy' error instead of retrieving and transforming the * data to copy. |
︙ | ︙ | |||
5712 5713 5714 5715 5716 5717 5718 | /* * If we get a short read, signal up that we may be BLOCKED. * We should avoid calling the driver because on some * platforms we will block in the low level reading code even * though the channel is set into nonblocking mode. */ | | | 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 | /* * If we get a short read, signal up that we may be BLOCKED. * We should avoid calling the driver because on some * platforms we will block in the low level reading code even * though the channel is set into nonblocking mode. */ if (nread < ((ssize_t) bytesToRead - (ssize_t) copied)) { SetFlag(statePtr, CHANNEL_BLOCKED); } #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING if (nread <= (bytesToRead - copied)) { /* * [Bug 943274] We have read the available data, clear |
︙ | ︙ | |||
5779 5780 5781 5782 5783 5784 5785 | * * Side effects: * May cause input to be buffered. * *--------------------------------------------------------------------------- */ | | | | | | 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 | * * Side effects: * May cause input to be buffered. * *--------------------------------------------------------------------------- */ ssize_t Tcl_ReadChars( Tcl_Channel chan, /* The channel to read. */ Tcl_Obj *objPtr, /* Input data is stored in this object. */ size_t toRead, /* Maximum number of characters to store, or * TCL_STRLEN to read all available data (up * to EOF or when channel blocks). */ int appendFlag) /* If non-zero, data read from the channel * will be appended to the object. Otherwise, * the data will replace the existing contents * of the object. */ { Channel *chanPtr = (Channel *) chan; ChannelState *statePtr = chanPtr->state; |
︙ | ︙ | |||
5835 5836 5837 5838 5839 5840 5841 | * * Side effects: * May cause input to be buffered. * *--------------------------------------------------------------------------- */ | | | | | > | > | 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 | * * Side effects: * May cause input to be buffered. * *--------------------------------------------------------------------------- */ static ssize_t DoReadChars( Channel *chanPtr, /* The channel to read. */ Tcl_Obj *objPtr, /* Input data is stored in this object. */ size_t toRead, /* Maximum number of characters to store, or * TCL_STRLEN to read all available data (up * to EOF or when channel blocks). */ int appendFlag) /* If non-zero, data read from the channel * will be appended to the object. Otherwise, * the data will replace the existing contents * of the object. */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; size_t offset, factor; ssize_t copied, copiedNow; int result; Tcl_Encoding encoding; #define UTF_EXPANSION_FACTOR 1024 /* * This operation should occur at the top of a channel stack. */ |
︙ | ︙ | |||
5885 5886 5887 5888 5889 5890 5891 | if (encoding == NULL) { Tcl_GetByteArrayFromObj(objPtr, &offset); } else { TclGetStringFromObj(objPtr, &offset); } } | | | 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 | if (encoding == NULL) { Tcl_GetByteArrayFromObj(objPtr, &offset); } else { TclGetStringFromObj(objPtr, &offset); } } for (copied = 0; toRead > 0; ) { copiedNow = -1; if (statePtr->inQueueHead != NULL) { if (encoding == NULL) { copiedNow = ReadBytes(statePtr, objPtr, toRead, &offset); } else { copiedNow = ReadChars(statePtr, objPtr, toRead, &offset, &factor); |
︙ | ︙ | |||
5911 5912 5913 5914 5915 5916 5917 | statePtr->inQueueHead = nextPtr; if (nextPtr == NULL) { statePtr->inQueueTail = NULL; } } } | | > | > | 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 | statePtr->inQueueHead = nextPtr; if (nextPtr == NULL) { statePtr->inQueueTail = NULL; } } } if (copiedNow == -1) { if (GotFlag(statePtr, CHANNEL_EOF)) { break; } if (GotFlag(statePtr, CHANNEL_BLOCKED)) { if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { break; } ResetFlag(statePtr, CHANNEL_BLOCKED); } result = GetInput(chanPtr); if (result != 0) { if (result == EAGAIN) { break; } copied = -1; goto done; } } else { copied += copiedNow; if (toRead != TCL_STRLEN) { toRead -= copiedNow; } } } ResetFlag(statePtr, CHANNEL_BLOCKED); if (encoding == NULL) { Tcl_SetByteArrayLength(objPtr, offset); } else { |
︙ | ︙ | |||
5984 5985 5986 5987 5988 5989 5990 | * * Side effects: * None. * *--------------------------------------------------------------------------- */ | | | | | | | | | | | | | | 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 | * * Side effects: * None. * *--------------------------------------------------------------------------- */ static ssize_t ReadBytes( ChannelState *statePtr, /* State of the channel to read. */ Tcl_Obj *objPtr, /* Input data is appended to this ByteArray * object. Its length is how much space has * been allocated to hold data, not how many * bytes of data have been stored in the * object. */ size_t bytesToRead, /* Maximum number of bytes to store, or * TCL_STRLEN to get all available bytes. * Bytes are obtained from the first buffer in * the queue - even if this number is larger * than the number of bytes available in the * first buffer, only the bytes from the first * buffer are returned. */ size_t *offsetPtr) /* On input, contains how many bytes of objPtr * have been used to hold data. On output, * filled with how many bytes are now being * used. */ { size_t toRead, srcLen, offset, length, srcRead, dstWrote; ChannelBuffer *bufPtr; char *src, *dst; offset = *offsetPtr; bufPtr = statePtr->inQueueHead; src = RemovePoint(bufPtr); srcLen = BytesLeft(bufPtr); toRead = bytesToRead; if (toRead == TCL_STRLEN || toRead > srcLen) { toRead = srcLen; } dst = (char *) Tcl_GetByteArrayFromObj(objPtr, &length); if (offset + toRead + 1 > length) { /* * Double the existing size of the object or make enough room to hold * all the characters we may get from the source buffer, whichever is * larger. */ length = offset * 2; |
︙ | ︙ | |||
6050 6051 6052 6053 6054 6055 6056 | src++; srcLen--; toRead--; } srcRead = srcLen; dstWrote = toRead; | | | 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 | src++; srcLen--; toRead--; } srcRead = srcLen; dstWrote = toRead; if (TranslateInputEOL(statePtr, dst, src, &dstWrote, &srcRead)) { if (dstWrote == 0) { return -1; } } bufPtr->nextRemoved += srcRead; *offsetPtr += dstWrote; return dstWrote; |
︙ | ︙ | |||
6087 6088 6089 6090 6091 6092 6093 | * * Side effects: * None. * *--------------------------------------------------------------------------- */ | | | | | | | | | | 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 | * * Side effects: * None. * *--------------------------------------------------------------------------- */ static ssize_t ReadChars( ChannelState *statePtr, /* State of channel to read. */ Tcl_Obj *objPtr, /* Input data is appended to this object. * objPtr->length is how much space has been * allocated to hold data, not how many bytes * of data have been stored in the object. */ size_t charsToRead, /* Maximum number of characters to store, or * TCL_STRLEN to get all available characters. * Characters are obtained from the first * buffer in the queue -- even if this number * is larger than the number of characters * available in the first buffer, only the * characters from the first buffer are * returned. */ size_t *offsetPtr, /* On input, contains how many bytes of objPtr * have been used to hold data. On output, * filled with how many bytes are now being * used. */ size_t *factorPtr) /* On input, contains a guess of how many * bytes need to be allocated to hold the * result of converting N source bytes to * UTF-8. On output, contains another guess * based on the data seen so far. */ { size_t toRead, factor, offset, spaceLeft, srcLen, dstNeeded; size_t srcRead, dstWrote, numChars, dstRead; ChannelBuffer *bufPtr; char *src, *dst; Tcl_EncodingState oldState; int encEndFlagSuppressed = 0; factor = *factorPtr; offset = *offsetPtr; bufPtr = statePtr->inQueueHead; src = RemovePoint(bufPtr); srcLen = BytesLeft(bufPtr); toRead = charsToRead; if (toRead == TCL_STRLEN || toRead > srcLen) { toRead = srcLen; } /* * 'factor' is how much we guess that the bytes in the source buffer will * expand when converted to UTF-8 chars. This guess comes from analyzing * how many characters were produced by the previous pass. |
︙ | ︙ | |||
6296 6297 6298 6299 6300 6301 6302 | * * Note that the BUFFER_PADDING (See AllocChannelBuffer) is used to * prevent exactly this situation. I.e. it should never happen. * Therefore it is ok to panic should it happen despite the * precautions. */ | | | | | 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 | * * Note that the BUFFER_PADDING (See AllocChannelBuffer) is used to * prevent exactly this situation. I.e. it should never happen. * Therefore it is ok to panic should it happen despite the * precautions. */ if (nextPtr->nextRemoved < srcLen) { Tcl_Panic("Buffer Underflow, BUFFER_PADDING not enough"); } nextPtr->nextRemoved -= srcLen; memcpy(RemovePoint(nextPtr), src, srcLen); RecycleBuffer(statePtr, bufPtr, 0); statePtr->inQueueHead = nextPtr; return ReadChars(statePtr, objPtr, charsToRead, offsetPtr, factorPtr); } dstRead = dstWrote; if (TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead)) { /* * Hit EOF char. How many bytes of src correspond to where the EOF was * located in dst? Run the conversion again with an output buffer just * big enough to hold the data so we can get the correct value for * srcRead. */ |
︙ | ︙ | |||
6334 6335 6336 6337 6338 6339 6340 | * The number of characters that we got may be less than the number that * we started with because "\r\n" sequences may have been turned into just * '\n' in dst. */ numChars -= dstRead - dstWrote; | | | 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 | * The number of characters that we got may be less than the number that * we started with because "\r\n" sequences may have been turned into just * '\n' in dst. */ numChars -= dstRead - dstWrote; if (numChars > toRead) { /* * Got too many chars. */ const char *eof = Tcl_UtfAtIndex(dst, toRead); statePtr->inputEncodingState = oldState; |
︙ | ︙ | |||
6385 6386 6387 6388 6389 6390 6391 | TranslateInputEOL( ChannelState *statePtr, /* Channel being read, for EOL translation and * EOF character. */ char *dstStart, /* Output buffer filled with chars by applying * appropriate EOL translation to source * characters. */ const char *srcStart, /* Source characters. */ | | | | | 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 | TranslateInputEOL( ChannelState *statePtr, /* Channel being read, for EOL translation and * EOF character. */ char *dstStart, /* Output buffer filled with chars by applying * appropriate EOL translation to source * characters. */ const char *srcStart, /* Source characters. */ size_t *dstLenPtr, /* On entry, the maximum length of output * buffer in bytes; must be <= *srcLenPtr. On * exit, the number of bytes actually used in * output buffer. */ size_t *srcLenPtr) /* On entry, the length of source buffer. On * exit, the number of bytes read from the * source buffer. */ { size_t dstLen, srcLen, inEofChar; const char *eof; dstLen = *dstLenPtr; eof = NULL; inEofChar = statePtr->inEofChar; if (inEofChar != '\0') { |
︙ | ︙ | |||
6425 6426 6427 6428 6429 6430 6431 | break; } } } switch (statePtr->inputTranslation) { case TCL_TRANSLATE_LF: if (dstStart != srcStart) { | | | | 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 | break; } } } switch (statePtr->inputTranslation) { case TCL_TRANSLATE_LF: if (dstStart != srcStart) { memcpy(dstStart, srcStart, dstLen); } srcLen = dstLen; break; case TCL_TRANSLATE_CR: { char *dst, *dstEnd; if (dstStart != srcStart) { memcpy(dstStart, srcStart, dstLen); } dstEnd = dstStart + dstLen; for (dst = dstStart; dst < dstEnd; dst++) { if (*dst == '\r') { *dst = '\n'; } } |
︙ | ︙ | |||
6545 6546 6547 6548 6549 6550 6551 | * * Side effects: * Adds input to the input queue of a channel. * *---------------------------------------------------------------------- */ | | | > | 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 | * * Side effects: * Adds input to the input queue of a channel. * *---------------------------------------------------------------------- */ ssize_t Tcl_Ungets( Tcl_Channel chan, /* The channel for which to add the input. */ const char *str, /* The input itself. */ size_t length, /* The length of the input. */ int atEnd) /* If non-zero, add at end of queue; otherwise * add at head of queue. */ { Channel *chanPtr; /* The real IO channel. */ ChannelState *statePtr; /* State of actual channel. */ ChannelBuffer *bufPtr; /* Buffer to contain the data. */ int flags; ssize_t len = (ssize_t) length; chanPtr = (Channel *) chan; statePtr = chanPtr->state; /* * This operation should occur at the top of a channel stack. */ |
︙ | ︙ | |||
6737 6738 6739 6740 6741 6742 6743 | *--------------------------------------------------------------------------- */ static int GetInput( Channel *chanPtr) /* Channel to read input from. */ { | | | | 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 | *--------------------------------------------------------------------------- */ static int GetInput( Channel *chanPtr) /* Channel to read input from. */ { size_t toRead; /* How much to read? */ int result; /* Of calling driver. */ ssize_t nread; /* How much was read from channel? */ ChannelBuffer *bufPtr; /* New buffer to add to input queue. */ ChannelState *statePtr = chanPtr->state; /* State info for channel */ /* * Prevent reading from a dead channel -- a channel that has been closed * but not yet deallocated, which can happen if the exit handler for |
︙ | ︙ | |||
7223 7224 7225 7226 7227 7228 7229 | /* * Seek first to force a total flush of all pending buffers and ditch any * pre-read input data. */ WillWrite(chanPtr); | | | 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 | /* * Seek first to force a total flush of all pending buffers and ditch any * pre-read input data. */ WillWrite(chanPtr); if (WillRead(chanPtr)) { return TCL_ERROR; } /* * We're all flushed to disk now and we also don't have any unfortunate * input baggage around either; can truncate with impunity. */ |
︙ | ︙ | |||
7623 7624 7625 7626 7627 7628 7629 | Tcl_BadChannelOption( Tcl_Interp *interp, /* Current interpreter (can be NULL).*/ const char *optionName, /* 'bad option' name */ const char *optionList) /* Specific options list to append to the * standard generic options. Can be NULL for * generic options only. */ { | < | | > > | | | | 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 | Tcl_BadChannelOption( Tcl_Interp *interp, /* Current interpreter (can be NULL).*/ const char *optionName, /* 'bad option' name */ const char *optionList) /* Specific options list to append to the * standard generic options. Can be NULL for * generic options only. */ { static const char *genericopt = "blocking buffering buffersize encoding eofchar translation"; if (interp != NULL) { const char **argv; size_t argc, i; Tcl_DString ds; Tcl_Obj *errObj; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, genericopt, TCL_STRLEN); if (optionList && (*optionList)) { TclDStringAppendLiteral(&ds, " "); Tcl_DStringAppend(&ds, optionList, TCL_STRLEN); } if (Tcl_SplitList(interp, Tcl_DStringValue(&ds), &argc, &argv) != TCL_OK) { Tcl_Panic("malformed option list in channel driver"); } Tcl_ResetResult(interp); errObj = Tcl_ObjPrintf("bad option \"%s\": should be one of ", |
︙ | ︙ | |||
7918 7919 7920 7921 7922 7923 7924 | const char *newValue) /* New value for option. */ { Channel *chanPtr = (Channel *) chan; /* The real IO channel. */ ChannelState *statePtr = chanPtr->state; /* State info for channel */ size_t len; /* Length of optionName string. */ | | | | 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 | const char *newValue) /* New value for option. */ { Channel *chanPtr = (Channel *) chan; /* The real IO channel. */ ChannelState *statePtr = chanPtr->state; /* State info for channel */ size_t len; /* Length of optionName string. */ size_t argc; const char **argv; /* * If the channel is in the middle of a background copy, fail. */ if (statePtr->csPtrR || statePtr->csPtrW) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unable to set channel options: background copy in" " progress", TCL_STRLEN)); } return TCL_ERROR; } /* * Disallow options on dead channels -- channels that have been closed but * not yet been deallocated. Such channels can be found if the exit |
︙ | ︙ | |||
7980 7981 7982 7983 7984 7985 7986 | } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { ResetFlag(statePtr, CHANNEL_LINEBUFFERED); SetFlag(statePtr, CHANNEL_UNBUFFERED); } else if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -buffering: must be one of" | | | 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 | } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { ResetFlag(statePtr, CHANNEL_LINEBUFFERED); SetFlag(statePtr, CHANNEL_UNBUFFERED); } else if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -buffering: must be one of" " full, line, or none", TCL_STRLEN)); return TCL_ERROR; } return TCL_OK; } else if (HaveOpt(7, "-buffersize")) { int newBufferSize; if (Tcl_GetInt(interp, newValue, &newBufferSize) == TCL_ERROR) { |
︙ | ︙ | |||
8037 8038 8039 8040 8041 8042 8043 | int inValue = (int) argv[0][0]; int outValue = (int) argv[outIndex][0]; if (inValue & 0x80 || outValue & 0x80) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -eofchar: must be non-NUL ASCII" | | | | 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 | int inValue = (int) argv[0][0]; int outValue = (int) argv[outIndex][0]; if (inValue & 0x80 || outValue & 0x80) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -eofchar: must be non-NUL ASCII" " character", TCL_STRLEN)); } ckfree(argv); return TCL_ERROR; } if (GotFlag(statePtr, TCL_READABLE)) { statePtr->inEofChar = inValue; } if (GotFlag(statePtr, TCL_WRITABLE)) { statePtr->outEofChar = outValue; } } else { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -eofchar: should be a list of zero," " one, or two elements", TCL_STRLEN)); } ckfree(argv); return TCL_ERROR; } if (argv != NULL) { ckfree(argv); } |
︙ | ︙ | |||
8086 8087 8088 8089 8090 8091 8092 | } else if (argc == 2) { readMode = GotFlag(statePtr, TCL_READABLE) ? argv[0] : NULL; writeMode = GotFlag(statePtr, TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -translation: must be a one or two" | | | 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 | } else if (argc == 2) { readMode = GotFlag(statePtr, TCL_READABLE) ? argv[0] : NULL; writeMode = GotFlag(statePtr, TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -translation: must be a one or two" " element list", TCL_STRLEN)); } ckfree(argv); return TCL_ERROR; } if (readMode) { TclEolTranslation translation; |
︙ | ︙ | |||
8116 8117 8118 8119 8120 8121 8122 | translation = TCL_TRANSLATE_CRLF; } else if (strcmp(readMode, "platform") == 0) { translation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -translation: must be one of " | | > | 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 | translation = TCL_TRANSLATE_CRLF; } else if (strcmp(readMode, "platform") == 0) { translation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -translation: must be one of " "auto, binary, cr, lf, crlf, or platform", TCL_STRLEN)); } ckfree(argv); return TCL_ERROR; } /* * Reset the EOL flags since we need to look at any buffered data |
︙ | ︙ | |||
8166 8167 8168 8169 8170 8171 8172 | statePtr->outputTranslation = TCL_TRANSLATE_CRLF; } else if (strcmp(writeMode, "platform") == 0) { statePtr->outputTranslation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -translation: must be one of " | | > | 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 | statePtr->outputTranslation = TCL_TRANSLATE_CRLF; } else if (strcmp(writeMode, "platform") == 0) { statePtr->outputTranslation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -translation: must be one of " "auto, binary, cr, lf, crlf, or platform", TCL_STRLEN)); } ckfree(argv); return TCL_ERROR; } } ckfree(argv); return TCL_OK; |
︙ | ︙ | |||
8956 8957 8958 8959 8960 8961 8962 | /* ARGSUSED */ int Tcl_FileEventObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter in which the channel for which * to create the handler is found. */ | | | 8978 8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 | /* ARGSUSED */ int Tcl_FileEventObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter in which the channel for which * to create the handler is found. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Channel *chanPtr; /* The channel to create the handler for. */ ChannelState *statePtr; /* State info for channel */ Tcl_Channel chan; /* The opaque type for the channel. */ const char *chanName; int modeIndex; /* Index of mode argument. */ |
︙ | ︙ | |||
9206 9207 9208 9209 9210 9211 9212 | CopyState *csPtr, /* State of copy operation. */ int mask) /* Current channel event flags. */ { Tcl_Interp *interp; Tcl_Obj *cmdPtr, *errObj = NULL, *bufObj = NULL, *msg = NULL; Tcl_Channel inChan, outChan; ChannelState *inStatePtr, *outStatePtr; | | > > | 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 | CopyState *csPtr, /* State of copy operation. */ int mask) /* Current channel event flags. */ { Tcl_Interp *interp; Tcl_Obj *cmdPtr, *errObj = NULL, *bufObj = NULL, *msg = NULL; Tcl_Channel inChan, outChan; ChannelState *inStatePtr, *outStatePtr; int result = TCL_OK; ssize_t size, sizeb; size_t sizeout; Tcl_WideInt total; const char *buffer; int inBinary, outBinary, sameEncoding; /* Encoding control */ int underflow; /* Input underflow */ inChan = (Tcl_Channel) csPtr->readPtr; |
︙ | ︙ | |||
9272 9273 9274 9275 9276 9277 9278 | * Read up to bufSize bytes. */ if ((csPtr->toRead == (Tcl_WideInt) -1) || (csPtr->toRead > (Tcl_WideInt) csPtr->bufSize)) { sizeb = csPtr->bufSize; } else { | | | | 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 | * Read up to bufSize bytes. */ if ((csPtr->toRead == (Tcl_WideInt) -1) || (csPtr->toRead > (Tcl_WideInt) csPtr->bufSize)) { sizeb = csPtr->bufSize; } else { sizeb = (size_t) csPtr->toRead; } if (inBinary || sameEncoding) { size = DoRead(inStatePtr->topChanPtr, csPtr->buffer, sizeb, !GotFlag(inStatePtr, CHANNEL_NONBLOCKING)); } else { size = DoReadChars(inStatePtr->topChanPtr, bufObj, sizeb, 0 /* No append */); } underflow = (size >= 0) && (size < sizeb); /* Input underflow */ } |
︙ | ︙ | |||
9314 9315 9316 9317 9318 9319 9320 | * when the channel becomes readable again. */ if ((size == 0) && Tcl_Eof(inChan) && !(cmdPtr && (mask == 0))) { break; } if (cmdPtr && (!Tcl_Eof(inChan) || (mask == 0)) && | | | 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 | * when the channel becomes readable again. */ if ((size == 0) && Tcl_Eof(inChan) && !(cmdPtr && (mask == 0))) { break; } if (cmdPtr && (!Tcl_Eof(inChan) || (mask == 0)) && !(mask & TCL_READABLE)) { if (mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, csPtr); } if (size == 0) { |
︙ | ︙ | |||
9336 9337 9338 9339 9340 9341 9342 | /* * Now write the buffer out. */ if (inBinary || sameEncoding) { buffer = csPtr->buffer; | | | | | | 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 | /* * Now write the buffer out. */ if (inBinary || sameEncoding) { buffer = csPtr->buffer; sizeout = size; } else { buffer = TclGetStringFromObj(bufObj, &sizeout); } if (outBinary || sameEncoding) { sizeb = DoWrite(outStatePtr->topChanPtr, buffer, sizeout); } else { sizeb = DoWriteChars(outStatePtr->topChanPtr, buffer, sizeout); } /* * [Bug 2895565]. At this point 'size' still contains the number of * bytes or characters which have been read. We keep this to later to * update the totals and toRead information, see marker (UP) below. We * must not overwrite it with 'sizeb', which is the number of written |
︙ | ︙ | |||
9512 9513 9514 9515 9516 9517 9518 | * * Side effects: * May cause input to be buffered. * *---------------------------------------------------------------------- */ | | | | | | 9536 9537 9538 9539 9540 9541 9542 9543 9544 9545 9546 9547 9548 9549 9550 9551 9552 9553 9554 9555 9556 9557 9558 9559 9560 9561 | * * Side effects: * May cause input to be buffered. * *---------------------------------------------------------------------- */ static ssize_t DoRead( Channel *chanPtr, /* The channel from which to read. */ char *bufPtr, /* Where to store input read. */ size_t toRead, /* Maximum number of bytes to read. */ int allowShortReads) /* Allow half-blocking (pipes,sockets) */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ size_t copied; /* How many characters were copied into the * result string? */ size_t copiedNow; /* How many characters were copied from the * current input buffer? */ int result; /* Of calling GetInput. */ /* * If we have not encountered a sticky EOF, clear the EOF bit. Either way * clear the BLOCKED bit. We want to discover these anew during each * operation. |
︙ | ︙ | |||
9595 9596 9597 9598 9599 9600 9601 | * * Side effects: * Consumes buffered input. May deallocate one buffer. * *---------------------------------------------------------------------- */ | | | | | | | 9619 9620 9621 9622 9623 9624 9625 9626 9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 9642 9643 9644 9645 | * * Side effects: * Consumes buffered input. May deallocate one buffer. * *---------------------------------------------------------------------- */ static size_t CopyAndTranslateBuffer( ChannelState *statePtr, /* Channel state from which to read input. */ char *result, /* Where to store the copied input. */ size_t space) /* How many bytes are available in result to * store the copied input? */ { ChannelBuffer *bufPtr; /* The buffer from which to copy bytes. */ size_t bytesInBuffer; /* How many bytes are available to be copied * in the current input buffer? */ size_t copied; /* How many characters were already copied * into the destination space? */ size_t i; /* Iterates over the copied input looking for * the input eofChar. */ /* * If there is no input at all, return zero. The invariant is that either * there is no buffer in the queue, or if the first buffer is empty, it is * also the last buffer (and thus there is no input in the queue). Note * also that if the buffer is empty, we leave it in the queue. |
︙ | ︙ | |||
9637 9638 9639 9640 9641 9642 9643 | /* * Copy the current chunk into the result buffer. */ if (bytesInBuffer < space) { space = bytesInBuffer; } | | | | 9661 9662 9663 9664 9665 9666 9667 9668 9669 9670 9671 9672 9673 9674 9675 9676 9677 9678 9679 9680 9681 9682 9683 9684 9685 9686 9687 9688 9689 9690 9691 9692 9693 9694 | /* * Copy the current chunk into the result buffer. */ if (bytesInBuffer < space) { space = bytesInBuffer; } memcpy(result, RemovePoint(bufPtr), space); bufPtr->nextRemoved += space; copied = space; break; case TCL_TRANSLATE_CR: { char *end; if (bytesInBuffer == 0) { return 0; } /* * Copy the current chunk into the result buffer, then replace all \r * with \n. */ if (bytesInBuffer < space) { space = bytesInBuffer; } memcpy(result, RemovePoint(bufPtr), space); bufPtr->nextRemoved += space; copied = space; for (end = result + copied; result < end; result++) { if (*result == '\r') { *result = '\n'; } |
︙ | ︙ | |||
9693 9694 9695 9696 9697 9698 9699 | * Copy the current chunk and replace "\r\n" with "\n" (but not * standalone "\r"!). */ if (bytesInBuffer < space) { space = bytesInBuffer; } | | | 9717 9718 9719 9720 9721 9722 9723 9724 9725 9726 9727 9728 9729 9730 9731 | * Copy the current chunk and replace "\r\n" with "\n" (but not * standalone "\r"!). */ if (bytesInBuffer < space) { space = bytesInBuffer; } memcpy(result, RemovePoint(bufPtr), space); bufPtr->nextRemoved += space; copied = space; end = result + copied; dst = result; for (src = result; src < end; src++) { curByte = *src; |
︙ | ︙ | |||
9733 9734 9735 9736 9737 9738 9739 | /* * Loop over the current buffer, converting "\r" and "\r\n" to "\n". */ if (bytesInBuffer < space) { space = bytesInBuffer; } | | | 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 | /* * Loop over the current buffer, converting "\r" and "\r\n" to "\n". */ if (bytesInBuffer < space) { space = bytesInBuffer; } memcpy(result, RemovePoint(bufPtr), space); bufPtr->nextRemoved += space; copied = space; end = result + copied; dst = result; for (src = result; src < end; src++) { curByte = *src; |
︙ | ︙ | |||
9820 9821 9822 9823 9824 9825 9826 | * * Side effects: * Consumes buffered input. May deallocate one buffer. * *---------------------------------------------------------------------- */ | | | | | | 9844 9845 9846 9847 9848 9849 9850 9851 9852 9853 9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 | * * Side effects: * Consumes buffered input. May deallocate one buffer. * *---------------------------------------------------------------------- */ static size_t CopyBuffer( Channel *chanPtr, /* Channel from which to read input. */ char *result, /* Where to store the copied input. */ size_t space) /* How many bytes are available in result to * store the copied input? */ { ChannelBuffer *bufPtr; /* The buffer from which to copy bytes. */ size_t bytesInBuffer; /* How many bytes are available to be copied * in the current input buffer? */ size_t copied; /* How many characters were already copied * into the destination space? */ /* * If there is no input at all, return zero. The invariant is that either * there is no buffer in the queue, or if the first buffer is empty, it is * also the last buffer (and thus there is no input in the queue). Note * also that if the buffer is empty, we don't leave it in the queue, but |
︙ | ︙ | |||
9864 9865 9866 9867 9868 9869 9870 | * Copy the current chunk into the result buffer. */ if (bytesInBuffer < space) { space = bytesInBuffer; } | | | 9888 9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 | * Copy the current chunk into the result buffer. */ if (bytesInBuffer < space) { space = bytesInBuffer; } memcpy(result, RemovePoint(bufPtr), space); bufPtr->nextRemoved += space; copied = space; /* * We don't care about in-stream EOF characters here as the data read here * may still flow through one or more transformations, i.e. is not in its * final state yet. |
︙ | ︙ | |||
9914 9915 9916 9917 9918 9919 9920 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ | | | | | | | | 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961 9962 9963 9964 9965 9966 9967 9968 9969 9970 9971 9972 | * Side effects: * May buffer up output and may cause output to be produced on the * channel. * *---------------------------------------------------------------------- */ static ssize_t DoWrite( Channel *chanPtr, /* The channel to buffer output for. */ const char *src, /* Data to write. */ size_t srcLen) /* Number of bytes to write. */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *outBufPtr; /* Current output buffer. */ int foundNewline; /* Did we find a newline in output? */ char *dPtr; const char *sPtr; /* Search variables for newline. */ int crsent; /* In CRLF eol translation mode, remember the * fact that a CR was output to the channel * without its following NL. */ size_t i; /* Loop index for newline search. */ size_t destCopied; /* How many bytes were used in this * destination buffer to hold the output? */ size_t totalDestCopied; /* How many bytes total were copied to the * channel buffer? */ size_t srcCopied; /* How many bytes were copied from the source * string? */ char *destPtr; /* Where in line to copy to? */ /* * If we are in network (or windows) translation mode, record the fact * that we have not yet sent a CR to the channel. */ |
︙ | ︙ | |||
9973 9974 9975 9976 9977 9978 9979 | destCopied = srcLen; } destPtr = InsertPoint(outBufPtr); switch (statePtr->outputTranslation) { case TCL_TRANSLATE_LF: srcCopied = destCopied; | | | | 9997 9998 9999 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 10012 10013 10014 10015 | destCopied = srcLen; } destPtr = InsertPoint(outBufPtr); switch (statePtr->outputTranslation) { case TCL_TRANSLATE_LF: srcCopied = destCopied; memcpy(destPtr, src, destCopied); break; case TCL_TRANSLATE_CR: srcCopied = destCopied; memcpy(destPtr, src, destCopied); for (dPtr = destPtr; dPtr < destPtr + destCopied; dPtr++) { if (*dPtr == '\n') { *dPtr = '\r'; } } break; case TCL_TRANSLATE_CRLF: |
︙ | ︙ | |||
10324 10325 10326 10327 10328 10329 10330 | hTblPtr = GetChannelTable(interp); TclNewObj(resultPtr); if ((pattern != NULL) && TclMatchIsTrivial(pattern) && !((pattern[0] == 's') && (pattern[1] == 't') && (pattern[2] == 'd'))) { if ((Tcl_FindHashEntry(hTblPtr, pattern) != NULL) && (Tcl_ListObjAppendElement(interp, resultPtr, | | | 10348 10349 10350 10351 10352 10353 10354 10355 10356 10357 10358 10359 10360 10361 10362 | hTblPtr = GetChannelTable(interp); TclNewObj(resultPtr); if ((pattern != NULL) && TclMatchIsTrivial(pattern) && !((pattern[0] == 's') && (pattern[1] == 't') && (pattern[2] == 'd'))) { if ((Tcl_FindHashEntry(hTblPtr, pattern) != NULL) && (Tcl_ListObjAppendElement(interp, resultPtr, Tcl_NewStringObj(pattern, TCL_STRLEN)) != TCL_OK)) { goto error; } goto done; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { |
︙ | ︙ | |||
10351 10352 10353 10354 10355 10356 10357 | */ name = statePtr->channelName; } if (((pattern == NULL) || Tcl_StringMatch(name, pattern)) && (Tcl_ListObjAppendElement(interp, resultPtr, | | | 10375 10376 10377 10378 10379 10380 10381 10382 10383 10384 10385 10386 10387 10388 10389 | */ name = statePtr->channelName; } if (((pattern == NULL) || Tcl_StringMatch(name, pattern)) && (Tcl_ListObjAppendElement(interp, resultPtr, Tcl_NewStringObj(name, TCL_STRLEN)) != TCL_OK)) { error: TclDecrRefCount(resultPtr); return TCL_ERROR; } } done: |
︙ | ︙ | |||
11028 11029 11030 11031 11032 11033 11034 | *---------------------------------------------------------------------- */ static Tcl_Obj * FixLevelCode( Tcl_Obj *msg) { | | < | | | 11052 11053 11054 11055 11056 11057 11058 11059 11060 11061 11062 11063 11064 11065 11066 11067 11068 11069 11070 11071 11072 11073 11074 11075 11076 11077 11078 11079 11080 11081 11082 11083 11084 11085 11086 11087 | *---------------------------------------------------------------------- */ static Tcl_Obj * FixLevelCode( Tcl_Obj *msg) { size_t explicitResult, numOptions, lc, lcn, i, j; Tcl_Obj **lv, **lvn; int res, val, lignore, cignore, newlevel = -1, newcode = -1; /* ASSERT msg != NULL */ /* * Process the caught message. * * Syntax = (option value)... ?message? * * Bad message syntax causes a panic, because the other side uses * Tcl_GetReturnOptions and list construction functions to marshall the * information. Hence an error means that we've got serious breakage. */ res = Tcl_ListObjGetElements(NULL, msg, &lc, &lv); if (res != TCL_OK) { Tcl_Panic("Tcl_SetChannelError: bad syntax of message"); } explicitResult = (lc % 2); numOptions = lc - explicitResult; /* * No options, nothing to do. */ if (numOptions == 0) { |
︙ | ︙ | |||
11469 11470 11471 11472 11473 11474 11475 | /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * tab-width: 8 | < | 11492 11493 11494 11495 11496 11497 11498 11499 11500 | /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * tab-width: 8 * End: */ |
Changes to generic/tclIO.h.
︙ | ︙ | |||
32 33 34 35 36 37 38 | /* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. */ typedef struct ChannelBuffer { | | | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. */ typedef struct ChannelBuffer { size_t nextAdded; /* The next position into which a character * will be put in the buffer. */ size_t nextRemoved; /* Position of next byte to be removed from * the buffer. */ size_t bufLength; /* How big is the buffer? */ struct ChannelBuffer *nextPtr; /* Next buffer in chain. */ char buf[1]; /* Placeholder for real buffer. The real * buffer occuppies this space + bufSize-1 * bytes. This must be the last field in the * structure. */ } ChannelBuffer; |
︙ | ︙ | |||
202 203 204 205 206 207 208 | /* * TIP #219 ... Info for the I/O system ... * Error message set by channel drivers, for the propagation of arbitrary * Tcl errors. This information, if present (chanMsg not NULL), takes * precedence over a posix error code returned by a channel operation. */ | | | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | /* * TIP #219 ... Info for the I/O system ... * Error message set by channel drivers, for the propagation of arbitrary * Tcl errors. This information, if present (chanMsg not NULL), takes * precedence over a posix error code returned by a channel operation. */ Tcl_Obj *chanMsg; Tcl_Obj *unreportedMsg; /* Non-NULL if an error report was deferred * because it happened in the background. The * value is the chanMg, if any. #219's * companion to 'unreportedError'. */ } ChannelState; /* * Values for the flags field in Channel. Any ORed combination of the |
︙ | ︙ |
Changes to generic/tclIOCmd.c.
︙ | ︙ | |||
35 36 37 38 39 40 41 | /* * Static functions for this file: */ static void FinalizeIOCmdTSD(ClientData clientData); static void AcceptCallbackProc(ClientData callbackData, Tcl_Channel chan, char *address, int port); | | < < | < < | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /* * Static functions for this file: */ static void FinalizeIOCmdTSD(ClientData clientData); static void AcceptCallbackProc(ClientData callbackData, Tcl_Channel chan, char *address, int port); static Tcl_ObjCmdProc ChanPendingObjCmd; static Tcl_ObjCmdProc ChanTruncateObjCmd; static void RegisterTcpServerInterpCleanup(Tcl_Interp *interp, AcceptCallback *acceptCallbackPtr); static void TcpAcceptCallbacksDeleteProc(ClientData clientData, Tcl_Interp *interp); static void TcpServerCloseProc(ClientData callbackData); static void UnregisterTcpServerInterpCleanupProc( Tcl_Interp *interp, |
︙ | ︙ | |||
101 102 103 104 105 106 107 | */ /* ARGSUSED */ int Tcl_PutsObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | < | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | */ /* ARGSUSED */ int Tcl_PutsObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel chan; /* The channel to puts on. */ Tcl_Obj *string; /* String to write. */ Tcl_Obj *chanObjPtr = NULL; /* channel object. */ int newline; /* Add a newline at end? */ int mode; /* Mode in which channel is opened. */ ThreadSpecificData *tsdPtr; switch (objc) { case 2: /* [puts $x] */ string = objv[1]; newline = 1; |
︙ | ︙ | |||
164 165 166 167 168 169 170 | if (!(mode & TCL_WRITABLE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" wasn't opened for writing", TclGetString(chanObjPtr))); return TCL_ERROR; } | | < | < | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | if (!(mode & TCL_WRITABLE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" wasn't opened for writing", TclGetString(chanObjPtr))); return TCL_ERROR; } if (Tcl_WriteObj(chan, string) < 0) { goto error; } if (newline != 0) { if (Tcl_WriteChars(chan, "\n", 1) < 0) { goto error; } } return TCL_OK; /* * TIP #219. |
︙ | ︙ | |||
213 214 215 216 217 218 219 | */ /* ARGSUSED */ int Tcl_FlushObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | */ /* ARGSUSED */ int Tcl_FlushObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *chanObjPtr; Tcl_Channel chan; /* The channel to flush on. */ int mode; if (objc != 2) { |
︙ | ︙ | |||
275 276 277 278 279 280 281 | */ /* ARGSUSED */ int Tcl_GetsObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | */ /* ARGSUSED */ int Tcl_GetsObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel chan; /* The channel to read from. */ int lineLen; /* Length of line just read. */ int mode; /* Mode in which channel is opened. */ Tcl_Obj *linePtr, *chanObjPtr; |
︙ | ︙ | |||
354 355 356 357 358 359 360 | */ /* ARGSUSED */ int Tcl_ReadObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > > | | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | */ /* ARGSUSED */ int Tcl_ReadObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel chan; /* The channel to read from. */ int newline, i; /* Discard newline at end? */ // TODO Allow larger reads on 64-bit int toRead; /* How many bytes to read? */ size_t realToRead; ssize_t charactersRead; /* How many characters were read? */ int mode; /* Mode in which channel is opened. */ Tcl_Obj *resultPtr, *chanObjPtr; if ((objc != 2) && (objc != 3)) { Interp *iPtr; argerror: |
︙ | ︙ | |||
408 409 410 411 412 413 414 | } i++; /* Consumed channel name. */ /* * Compute how many bytes to read. */ | | | | | | | | > | | 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 | } i++; /* Consumed channel name. */ /* * Compute how many bytes to read. */ realToRead = -1; if (i < objc) { if ((Tcl_GetIntFromObj(interp, objv[i], &toRead) != TCL_OK) || (toRead < 0)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected non-negative integer but got \"%s\"", TclGetString(objv[i]))); Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL); return TCL_ERROR; } realToRead = (size_t) toRead; } resultPtr = Tcl_NewObj(); Tcl_IncrRefCount(resultPtr); charactersRead = Tcl_ReadChars(chan, resultPtr, realToRead, 0); if (charactersRead < 0) { /* * TIP #219. * Capture error messages put by the driver into the bypass area and * put them into the regular interpreter result. Fall back to the * regular message if nothing was found in the bypass. */ |
︙ | ︙ | |||
446 447 448 449 450 451 452 | /* * If requested, remove the last newline in the channel if at EOF. */ if ((charactersRead > 0) && (newline != 0)) { const char *result; | | | 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 | /* * If requested, remove the last newline in the channel if at EOF. */ if ((charactersRead > 0) && (newline != 0)) { const char *result; size_t length; result = TclGetStringFromObj(resultPtr, &length); if (result[length - 1] == '\n') { Tcl_SetObjLength(resultPtr, length - 1); } } Tcl_SetObjResult(interp, resultPtr); |
︙ | ︙ | |||
481 482 483 484 485 486 487 | */ /* ARGSUSED */ int Tcl_SeekObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | */ /* ARGSUSED */ int Tcl_SeekObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel chan; /* The channel to tell on. */ Tcl_WideInt offset; /* Where to seek? */ int mode; /* How to seek? */ Tcl_WideInt result; /* Of calling Tcl_Seek. */ int optionIndex; |
︙ | ︙ | |||
554 555 556 557 558 559 560 | */ /* ARGSUSED */ int Tcl_TellObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | */ /* ARGSUSED */ int Tcl_TellObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel chan; /* The channel to tell on. */ Tcl_WideInt newLoc; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "channelId"); |
︙ | ︙ | |||
612 613 614 615 616 617 618 | */ /* ARGSUSED */ int Tcl_CloseObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 | */ /* ARGSUSED */ int Tcl_CloseObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel chan; /* The channel to close. */ static const char *const dirOptions[] = { "read", "write", NULL }; static const int dirArray[] = {TCL_CLOSE_READ, TCL_CLOSE_WRITE}; |
︙ | ︙ | |||
683 684 685 686 687 688 689 | * messages produced by drivers during the closing of a channel, * because the Tcl convention is that such error messages do not have * a terminating newline. */ Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); const char *string; | | | 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 | * messages produced by drivers during the closing of a channel, * because the Tcl convention is that such error messages do not have * a terminating newline. */ Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); const char *string; size_t len; if (Tcl_IsShared(resultPtr)) { resultPtr = Tcl_DuplicateObj(resultPtr); Tcl_SetObjResult(interp, resultPtr); } string = TclGetStringFromObj(resultPtr, &len); if ((len > 0) && (string[len - 1] == '\n')) { |
︙ | ︙ | |||
721 722 723 724 725 726 727 | */ /* ARGSUSED */ int Tcl_FconfigureObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | */ /* ARGSUSED */ int Tcl_FconfigureObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *optionName, *valueName; Tcl_Channel chan; /* The channel to set a mode on. */ int i; /* Iterate over arg-value pairs. */ if ((objc < 2) || (((objc % 2) == 1) && (objc != 3))) { |
︙ | ︙ | |||
797 798 799 800 801 802 803 | */ /* ARGSUSED */ int Tcl_EofObjCmd( ClientData unused, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 | */ /* ARGSUSED */ int Tcl_EofObjCmd( ClientData unused, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel chan; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "channelId"); return TCL_ERROR; |
︙ | ︙ | |||
837 838 839 840 841 842 843 | */ /* ARGSUSED */ int Tcl_ExecObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 | */ /* ARGSUSED */ int Tcl_ExecObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *resultPtr; const char **argv; /* An array for the string arguments. Stored * on the _Tcl_ stack. */ const char *string; Tcl_Channel chan; int background, index, keepNewline, result, ignoreStderr; size_t argc, i, length, skip; static const char *const options[] = { "-ignorestderr", "-keepnewline", "--", NULL }; enum options { EXEC_IGNORESTDERR, EXEC_KEEPNEWLINE, EXEC_LAST }; |
︙ | ︙ | |||
939 940 941 942 943 944 945 | return TCL_ERROR; } return TCL_OK; } resultPtr = Tcl_NewObj(); if (Tcl_GetChannelHandle(chan, TCL_READABLE, NULL) == TCL_OK) { | | | 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 | return TCL_ERROR; } return TCL_OK; } resultPtr = Tcl_NewObj(); if (Tcl_GetChannelHandle(chan, TCL_READABLE, NULL) == TCL_OK) { if (Tcl_ReadChars(chan, resultPtr, TCL_STRLEN, 0) < 0) { /* * TIP #219. * Capture error messages put by the driver into the bypass area * and put them into the regular interpreter result. Fall back to * the regular message if nothing was found in the bypass. */ |
︙ | ︙ | |||
1005 1006 1007 1008 1009 1010 1011 | */ /* ARGSUSED */ int Tcl_FblockedObjCmd( ClientData unused, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 | */ /* ARGSUSED */ int Tcl_FblockedObjCmd( ClientData unused, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel chan; int mode; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "channelId"); |
︙ | ︙ | |||
1052 1053 1054 1055 1056 1057 1058 | */ /* ARGSUSED */ int Tcl_OpenObjCmd( ClientData notUsed, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 | */ /* ARGSUSED */ int Tcl_OpenObjCmd( ClientData notUsed, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int pipeline, prot; const char *modeString, *what; Tcl_Channel chan; if ((objc < 2) || (objc > 4)) { |
︙ | ︙ | |||
1083 1084 1085 1086 1087 1088 1089 | if ((permString[scanned] == '0') && (permString[scanned+1] >= '0') && (permString[scanned+1] <= '7')) { Tcl_Obj *permObj; TclNewLiteralStringObj(permObj, "0o"); | | | 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 | if ((permString[scanned] == '0') && (permString[scanned+1] >= '0') && (permString[scanned+1] <= '7')) { Tcl_Obj *permObj; TclNewLiteralStringObj(permObj, "0o"); Tcl_AppendToObj(permObj, permString+scanned+1, TCL_STRLEN); code = TclGetIntFromObj(NULL, permObj, &prot); Tcl_DecrRefCount(permObj); } if ((code == TCL_ERROR) && TclGetIntFromObj(interp, objv[3], &prot) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
1108 1109 1110 1111 1112 1113 1114 | /* * Open the file or create a process pipeline. */ if (!pipeline) { chan = Tcl_FSOpenFileChannel(interp, objv[1], modeString, prot); } else { | | > | 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 | /* * Open the file or create a process pipeline. */ if (!pipeline) { chan = Tcl_FSOpenFileChannel(interp, objv[1], modeString, prot); } else { int mode, seekFlag, binary; size_t cmdObjc; const char **cmdArgv; if (Tcl_SplitList(interp, what+1, &cmdObjc, &cmdArgv) != TCL_OK) { return TCL_ERROR; } mode = TclGetOpenModeEx(interp, modeString, &seekFlag, &binary); |
︙ | ︙ | |||
1146 1147 1148 1149 1150 1151 1152 | } ckfree(cmdArgv); } if (chan == NULL) { return TCL_ERROR; } Tcl_RegisterChannel(interp, chan); | | > | 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 | } ckfree(cmdArgv); } if (chan == NULL) { return TCL_ERROR; } Tcl_RegisterChannel(interp, chan); Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), TCL_STRLEN)); return TCL_OK; } /* *---------------------------------------------------------------------- * * TcpAcceptCallbacksDeleteProc -- |
︙ | ︙ | |||
1425 1426 1427 1428 1429 1430 1431 | *---------------------------------------------------------------------- */ int Tcl_SocketObjCmd( ClientData notUsed, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 | *---------------------------------------------------------------------- */ int Tcl_SocketObjCmd( ClientData notUsed, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *const socketOptions[] = { "-async", "-myaddr", "-myport", "-server", NULL }; enum socketOptions { SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_SERVER |
︙ | ︙ | |||
1456 1457 1458 1459 1460 1461 1462 | TCL_EXACT, &optionIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum socketOptions) optionIndex) { case SKT_ASYNC: if (server == 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | | | > | | | 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 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 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 | TCL_EXACT, &optionIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum socketOptions) optionIndex) { case SKT_ASYNC: if (server == 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot set -async option for server sockets", TCL_STRLEN)); return TCL_ERROR; } async = 1; break; case SKT_MYADDR: a++; if (a >= objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no argument given for -myaddr option", TCL_STRLEN)); return TCL_ERROR; } myaddr = TclGetString(objv[a]); break; case SKT_MYPORT: { const char *myPortName; a++; if (a >= objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no argument given for -myport option", TCL_STRLEN)); return TCL_ERROR; } myPortName = TclGetString(objv[a]); if (TclSockGetPort(interp, myPortName, "tcp", &myport) != TCL_OK) { return TCL_ERROR; } break; } case SKT_SERVER: if (async == 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot set -async option for server sockets", TCL_STRLEN)); return TCL_ERROR; } server = 1; a++; if (a >= objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no argument given for -server option", TCL_STRLEN)); return TCL_ERROR; } script = TclGetString(objv[a]); break; default: Tcl_Panic("Tcl_SocketObjCmd: bad option index to SocketOptions"); } } if (server) { host = myaddr; /* NULL implies INADDR_ANY */ if (myport != 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "option -myport is not valid for servers", TCL_STRLEN)); return TCL_ERROR; } } else if (a < objc) { host = TclGetString(objv[a]); a++; } else { Interp *iPtr; |
︙ | ︙ | |||
1537 1538 1539 1540 1541 1542 1543 | return TCL_ERROR; } } else { goto wrongNumArgs; } if (server) { | | < | 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 | return TCL_ERROR; } } else { goto wrongNumArgs; } if (server) { AcceptCallback *acceptCallbackPtr = ckalloc(sizeof(AcceptCallback)); unsigned len = strlen(script) + 1; char *copyScript = ckalloc(len); memcpy(copyScript, script, len); acceptCallbackPtr->script = copyScript; acceptCallbackPtr->interp = interp; chan = Tcl_OpenTcpServer(interp, port, host, AcceptCallbackProc, |
︙ | ︙ | |||
1577 1578 1579 1580 1581 1582 1583 | chan = Tcl_OpenTcpClient(interp, port, host, myaddr, myport, async); if (chan == NULL) { return TCL_ERROR; } } Tcl_RegisterChannel(interp, chan); | | > | 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 | chan = Tcl_OpenTcpClient(interp, port, host, myaddr, myport, async); if (chan == NULL) { return TCL_ERROR; } } Tcl_RegisterChannel(interp, chan); Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), TCL_STRLEN)); return TCL_OK; } /* *---------------------------------------------------------------------- * * Tcl_FcopyObjCmd -- |
︙ | ︙ | |||
1603 1604 1605 1606 1607 1608 1609 | *---------------------------------------------------------------------- */ int Tcl_FcopyObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 | *---------------------------------------------------------------------- */ int Tcl_FcopyObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel inChan, outChan; int mode, i, index; Tcl_WideInt toRead; Tcl_Obj *cmdPtr; static const char *const switches[] = { "-size", "-command", NULL }; |
︙ | ︙ | |||
1699 1700 1701 1702 1703 1704 1705 | */ /* ARGSUSED */ static int ChanPendingObjCmd( ClientData unused, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 | */ /* ARGSUSED */ static int ChanPendingObjCmd( ClientData unused, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel chan; int index, mode; static const char *const options[] = {"input", "output", NULL}; enum options {PENDING_INPUT, PENDING_OUTPUT}; |
︙ | ︙ | |||
1761 1762 1763 1764 1765 1766 1767 | *---------------------------------------------------------------------- */ static int ChanTruncateObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 | *---------------------------------------------------------------------- */ static int ChanTruncateObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel chan; Tcl_WideInt length; if ((objc < 2) || (objc > 3)) { Tcl_WrongNumArgs(interp, 1, objv, "channelId ?length?"); |
︙ | ︙ | |||
1785 1786 1787 1788 1789 1790 1791 | */ if (Tcl_GetWideIntFromObj(interp, objv[2], &length) != TCL_OK) { return TCL_ERROR; } if (length < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 | */ if (Tcl_GetWideIntFromObj(interp, objv[2], &length) != TCL_OK) { return TCL_ERROR; } if (length < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot truncate to negative length of file", TCL_STRLEN)); return TCL_ERROR; } } else { /* * User wants to truncate to the current file position. */ |
︙ | ︙ | |||
1834 1835 1836 1837 1838 1839 1840 | *---------------------------------------------------------------------- */ static int ChanPipeObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 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 | *---------------------------------------------------------------------- */ static int ChanPipeObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel rchan, wchan; const char *channelNames[2]; Tcl_Obj *resultPtr; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, ""); return TCL_ERROR; } if (Tcl_CreatePipe(interp, &rchan, &wchan, 0) != TCL_OK) { return TCL_ERROR; } channelNames[0] = Tcl_GetChannelName(rchan); channelNames[1] = Tcl_GetChannelName(wchan); resultPtr = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(channelNames[0], TCL_STRLEN)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(channelNames[1], TCL_STRLEN)); Tcl_SetObjResult(interp, resultPtr); return TCL_OK; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1885 1886 1887 1888 1889 1890 1891 | *---------------------------------------------------------------------- */ int TclChannelNamesCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 | *---------------------------------------------------------------------- */ int TclChannelNamesCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc < 1 || objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?pattern?"); return TCL_ERROR; } return Tcl_GetChannelNamesEx(interp, ((objc == 1) ? NULL : TclGetString(objv[1]))); |
︙ | ︙ | |||
1961 1962 1963 1964 1965 1966 1967 | ensemble = TclMakeEnsemble(interp, "chan", initMap); Tcl_GetEnsembleMappingDict(NULL, ensemble, &mapObj); for (i=0 ; extras[i] ; i+=2) { /* * Can assume that reference counts are all incremented. */ | | | | 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 | ensemble = TclMakeEnsemble(interp, "chan", initMap); Tcl_GetEnsembleMappingDict(NULL, ensemble, &mapObj); for (i=0 ; extras[i] ; i+=2) { /* * Can assume that reference counts are all incremented. */ Tcl_DictObjPut(NULL, mapObj, Tcl_NewStringObj(extras[i], TCL_STRLEN), Tcl_NewStringObj(extras[i+1], TCL_STRLEN)); } Tcl_SetEnsembleMappingDict(interp, ensemble, mapObj); return ensemble; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclIOGT.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | #include "tclIO.h" /* * Forward declarations of internal procedures. First the driver procedures of * the transformation. */ | | < | < | < | < | < | < < | < < | | < | | < | | 15 16 17 18 19 20 21 22 23 24 25 26 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 57 | #include "tclIO.h" /* * Forward declarations of internal procedures. First the driver procedures of * the transformation. */ static Tcl_DriverBlockModeProc TransformBlockModeProc; static Tcl_DriverCloseProc TransformCloseProc; static Tcl_DriverInputProc TransformInputProc; static Tcl_DriverOutputProc TransformOutputProc; static Tcl_DriverSeekProc TransformSeekProc; static Tcl_DriverSetOptionProc TransformSetOptionProc; static Tcl_DriverGetOptionProc TransformGetOptionProc; static Tcl_DriverWatchProc TransformWatchProc; static Tcl_DriverGetHandleProc TransformGetFileHandleProc; static Tcl_DriverHandlerProc TransformNotifyProc; static Tcl_DriverWideSeekProc TransformWideSeekProc; /* * Forward declarations of internal procedures. Secondly the procedures for * handling and generating fileeevents. */ static void TransformChannelHandlerTimer(ClientData clientData); /* * Forward declarations of internal procedures. Third, helper procedures * encapsulating essential tasks. */ typedef struct TransformChannelData TransformChannelData; static int ExecuteCallback(TransformChannelData *ctrl, Tcl_Interp *interp, unsigned char *op, unsigned char *buf, size_t 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. */ |
︙ | ︙ | |||
195 196 197 198 199 200 201 | * sitting in an internal buffer. Required for * full fileevent support. */ /* * Transformation specific data. */ | | | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | * sitting in an internal buffer. Required for * full fileevent support. */ /* * Transformation specific data. */ size_t maxRead; /* Maximum allowed number of bytes to read, as * given to us by the Tcl script implementing * the transformation. */ Tcl_Interp *interp; /* Reference to the interpreter which created * the transformation. Used to execute the * code below. */ Tcl_Obj *command; /* Tcl code to execute for a buffer */ ResultBuffer result; /* Internal buffer used to store the result of |
︙ | ︙ | |||
333 334 335 336 337 338 339 | static int ExecuteCallback( TransformChannelData *dataPtr, /* Transformation with the callback. */ Tcl_Interp *interp, /* Current interpreter, possibly NULL. */ unsigned char *op, /* Operation invoking the callback. */ unsigned char *buf, /* Buffer to give to the script. */ | | | > | | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | static int ExecuteCallback( TransformChannelData *dataPtr, /* Transformation with the callback. */ Tcl_Interp *interp, /* Current interpreter, possibly NULL. */ unsigned char *op, /* Operation invoking the callback. */ unsigned char *buf, /* Buffer to give to the script. */ size_t bufLen, /* And its length. */ int transmit, /* Flag, determines whether the result of the * callback is sent to the underlying channel * or not. */ int preserve) /* Flag. If true the procedure will preserve * the result state of all accessed * interpreters. */ { Tcl_Obj *resObj; /* See below, switch (transmit). */ size_t resLen; int maxRead; unsigned char *resBuf; Tcl_InterpState state = NULL; int res = TCL_OK; Tcl_Obj *command = Tcl_DuplicateObj(dataPtr->command); /* * Step 1, create the complete command to execute. Do this by appending * operation and buffer to operate upon to a copy of the callback * definition. We *cannot* create a list containing 3 objects and then use * 'Tcl_EvalObjv', because the command may contain additional prefixed * arguments. Feather's curried commands would come in handy here. */ if (preserve == P_PRESERVE) { state = Tcl_SaveInterpState(dataPtr->interp, res); } Tcl_IncrRefCount(command); res = Tcl_ListObjAppendElement(dataPtr->interp, command, Tcl_NewStringObj((char *) op, TCL_STRLEN)); if (res != TCL_OK) { goto cleanup; } /* * Use a byte-array to prevent the misinterpretation of binary data coming * through as UTF while at the tcl level. |
︙ | ︙ | |||
431 432 433 434 435 436 437 | case TRANSMIT_NUM: /* * Interpret result as integer number. */ resObj = Tcl_GetObjResult(dataPtr->interp); | | > | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | case TRANSMIT_NUM: /* * Interpret result as integer number. */ resObj = Tcl_GetObjResult(dataPtr->interp); TclGetIntFromObj(dataPtr->interp, resObj, &maxRead); dataPtr->maxRead = (size_t) maxRead; break; } Tcl_ResetResult(dataPtr->interp); if (preserve == P_PRESERVE) { (void) Tcl_RestoreInterpState(dataPtr->interp, state); } |
︙ | ︙ | |||
577 578 579 580 581 582 583 | * * Result: * A transformed buffer. * *---------------------------------------------------------------------- */ | | | | | 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | * * Result: * A transformed buffer. * *---------------------------------------------------------------------- */ static ssize_t TransformInputProc( ClientData instanceData, char *buf, size_t toRead, int *errorCodePtr) { TransformChannelData *dataPtr = instanceData; ssize_t gotBytes, read, copied; Tcl_Channel downChan; /* * Should assert(dataPtr->mode & TCL_READABLE); */ if (toRead == 0) { |
︙ | ︙ | |||
737 738 739 740 741 742 743 | * * Result: * A transformed buffer. * *---------------------------------------------------------------------- */ | | | | 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 | * * Result: * A transformed buffer. * *---------------------------------------------------------------------- */ static ssize_t TransformOutputProc( ClientData instanceData, const char *buf, size_t toWrite, int *errorCodePtr) { TransformChannelData *dataPtr = instanceData; /* * Should assert(dataPtr->mode & TCL_WRITABLE); */ |
︙ | ︙ |
Changes to generic/tclIORChan.c.
︙ | ︙ | |||
27 28 29 30 31 32 33 | #define EOK 0 #endif /* * Signatures of all functions used in the C layer of the reflection. */ | | < | < | < | | | | < | < | < < | < < | 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 | #define EOK 0 #endif /* * Signatures of all functions used in the C layer of the reflection. */ static Tcl_DriverCloseProc ReflectClose; static Tcl_DriverInputProc ReflectInput; static Tcl_DriverOutputProc ReflectOutput; static Tcl_DriverWatchProc ReflectWatch; static Tcl_DriverBlockModeProc ReflectBlock; #ifdef TCL_THREADS static Tcl_DriverThreadActionProc ReflectThread; #endif static Tcl_DriverWideSeekProc ReflectSeekWide; static Tcl_DriverSeekProc ReflectSeek; static Tcl_DriverGetOptionProc ReflectGetOption; static Tcl_DriverSetOptionProc ReflectSetOption; /* * The C layer channel type/driver definition used by the reflection. This is * a version 3 structure. */ static const Tcl_ChannelType tclRChannelType = { |
︙ | ︙ | |||
89 90 91 92 93 94 95 | typedef struct { Tcl_Channel chan; /* Back reference to generic channel * structure. */ Tcl_Interp *interp; /* Reference to the interpreter containing the * Tcl level part of the channel. NULL here * signals the channel is dead because the * interpreter/thread containing its Tcl | | < | > | > | | 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 108 109 110 111 112 113 | typedef struct { Tcl_Channel chan; /* Back reference to generic channel * structure. */ Tcl_Interp *interp; /* Reference to the interpreter containing the * Tcl level part of the channel. NULL here * signals the channel is dead because the * interpreter/thread containing its Tcl * command is gone. */ #ifdef TCL_THREADS Tcl_ThreadId thread; /* Thread the 'interp' belongs to. * == Handler thread */ Tcl_ThreadId owner; /* Thread owning the structure. * == Channel thread */ #endif /* See [==] as well. * Storage for the command prefix and the additional words required for * the invocation of methods in the command handler. * * argv [0] ... [.] | [argc-2] [argc-1] | [argc] [argc+2] * cmd ... pfx | method chan | detail1 detail2 * ~~~~ CT ~~~ ~~ CT ~~ * * CT = Belongs to the 'Command handler Thread'. */ size_t argc; /* Number of preallocated words - 2 */ Tcl_Obj **argv; /* Preallocated array for calling the handler. * args[0] is placeholder for cmd word. * Followed by the arguments in the prefix, * plus 4 placeholders for method, channel, * and at most two varying (method specific) * words. */ int methods; /* Bitmask of supported methods */ |
︙ | ︙ | |||
268 269 270 271 272 273 274 | * ForwardParamBase. Where an operation does not need any special types, it * has no "subtype" and just uses ForwardParamBase, as listed above.) */ struct ForwardParamInput { ForwardParamBase base; /* "Supertype". MUST COME FIRST. */ char *buf; /* O: Where to store the read bytes */ | | | | 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | * ForwardParamBase. Where an operation does not need any special types, it * has no "subtype" and just uses ForwardParamBase, as listed above.) */ struct ForwardParamInput { ForwardParamBase base; /* "Supertype". MUST COME FIRST. */ char *buf; /* O: Where to store the read bytes */ ssize_t toRead; /* I: #bytes to read, * O: #bytes actually read */ }; struct ForwardParamOutput { ForwardParamBase base; /* "Supertype". MUST COME FIRST. */ const char *buf; /* I: Where the bytes to write come from */ ssize_t toWrite; /* I: #bytes to write, * O: #bytes actually written */ }; struct ForwardParamSeek { ForwardParamBase base; /* "Supertype". MUST COME FIRST. */ int seekMode; /* I: How to seek */ Tcl_WideInt offset; /* I: Where to seek, * O: New location */ |
︙ | ︙ | |||
400 401 402 403 404 405 406 | static void ForwardOpToHandlerThread(ReflectedChannel *rcPtr, ForwardedOperation op, const void *param); static int ForwardProc(Tcl_Event *evPtr, int mask); static void SrcExitProc(ClientData clientData); #define FreeReceivedError(p) \ | | | | > | | | | | > > > | | > > | | | > > | > | | 392 393 394 395 396 397 398 399 400 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 438 439 440 441 442 443 444 | static void ForwardOpToHandlerThread(ReflectedChannel *rcPtr, ForwardedOperation op, const void *param); static int ForwardProc(Tcl_Event *evPtr, int mask); static void SrcExitProc(ClientData clientData); #define FreeReceivedError(p) \ if ((p)->base.mustFree) { \ ckfree((p)->base.msgStr); \ } #define PassReceivedErrorInterp(i,p) \ do { \ if ((i) != NULL) { \ Tcl_SetChannelErrorInterp((i), \ Tcl_NewStringObj((p)->base.msgStr, TCL_STRLEN)); \ } \ FreeReceivedError(p); \ } while (0) #define PassReceivedError(c,p) \ do { \ Tcl_SetChannelError((c), \ Tcl_NewStringObj((p)->base.msgStr, TCL_STRLEN)); \ FreeReceivedError(p); \ } while (0) #define ForwardSetStaticError(p,emsg) \ do { \ (p)->base.code = TCL_ERROR; \ (p)->base.mustFree = 0; \ (p)->base.msgStr = (char *) (emsg); \ } while (0) #define ForwardSetDynamicError(p,emsg) \ do { \ (p)->base.code = TCL_ERROR; \ (p)->base.mustFree = 1; \ (p)->base.msgStr = (char *) (emsg); \ } while (0) static void ForwardSetObjError(ForwardParam *p, Tcl_Obj *objPtr); static ReflectedChannelMap * GetThreadReflectedChannelMap(void); static void DeleteThreadReflectedChannelMap(ClientData clientData); #endif /* TCL_THREADS */ #define SetChannelErrorStr(c,msgStr) \ Tcl_SetChannelError((c), Tcl_NewStringObj((msgStr), TCL_STRLEN)) static Tcl_Obj * MarshallError(Tcl_Interp *interp); static void UnmarshallErrorResult(Tcl_Interp *interp, Tcl_Obj *msgObj); /* * Static functions for this file: |
︙ | ︙ | |||
501 502 503 504 505 506 507 | *---------------------------------------------------------------------- */ int TclChanCreateObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | 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 | *---------------------------------------------------------------------- */ int TclChanCreateObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { ReflectedChannel *rcPtr; /* Instance data of the new channel */ Tcl_Obj *rcId; /* Handle of the new channel */ int mode; /* R/W mode of new channel. Has to match * abilities of handler commands */ Tcl_Obj *cmdObj; /* Command prefix, list of words */ Tcl_Obj *cmdNameObj; /* Command name */ Tcl_Channel chan; /* Token for the new channel */ Tcl_Obj *modeObj; /* mode in obj form for method call */ size_t listc; /* Result of 'initialize', and of */ Tcl_Obj **listv; /* its sublist in the 2nd element */ int methIndex; /* Encoded method name */ int result; /* Result code for 'initialize' */ Tcl_Obj *resObj; /* Result data for 'initialize' */ int methods; /* Bitmask for supported methods. */ Channel *chanPtr; /* 'chan' resolved to internal struct. */ Tcl_Obj *err; /* Error message */ |
︙ | ︙ | |||
626 627 628 629 630 631 632 | methods = 0; while (listc > 0) { if (Tcl_GetIndexFromObj(interp, listv[listc-1], methodNames, "method", TCL_EXACT, &methIndex) != TCL_OK) { TclNewLiteralStringObj(err, "chan handler \""); Tcl_AppendObjToObj(err, cmdObj); | | | 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 | methods = 0; while (listc > 0) { if (Tcl_GetIndexFromObj(interp, listv[listc-1], methodNames, "method", TCL_EXACT, &methIndex) != TCL_OK) { TclNewLiteralStringObj(err, "chan handler \""); Tcl_AppendObjToObj(err, cmdObj); Tcl_AppendToObj(err, " initialize\" returned ", TCL_STRLEN); Tcl_AppendObjToObj(err, Tcl_GetObjResult(interp)); Tcl_SetObjResult(interp, err); Tcl_DecrRefCount(resObj); goto error; } methods |= FLAG(methIndex); |
︙ | ︙ | |||
736 737 738 739 740 741 742 | #endif /* * Return handle as result of command. */ Tcl_SetObjResult(interp, | | | 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 | #endif /* * Return handle as result of command. */ Tcl_SetObjResult(interp, Tcl_NewStringObj(chanPtr->state->channelName, TCL_STRLEN)); return TCL_OK; error: /* * Signal to ReflectClose to not call 'finalize'. */ |
︙ | ︙ | |||
818 819 820 821 822 823 824 | return 1; } int TclChanPostEventObjCmd( ClientData clientData, Tcl_Interp *interp, | | | 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 | return 1; } int TclChanPostEventObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { /* * Ensure -> HANDLER thread * * Syntax: chan postevent CHANNEL EVENTSPEC * [0] [1] [2] [3] |
︙ | ︙ | |||
1013 1014 1015 1016 1017 1018 1019 | } static void UnmarshallErrorResult( Tcl_Interp *interp, Tcl_Obj *msgObj) { | | < < | 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 | } static void UnmarshallErrorResult( Tcl_Interp *interp, Tcl_Obj *msgObj) { size_t explicitResult, lc, numOptions; Tcl_Obj **lv; /* * Process the caught message. * * Syntax = (option value)... ?message? * * Bad syntax causes a panic. This is OK because the other side uses |
︙ | ︙ | |||
1272 1273 1274 1275 1276 1277 1278 | * * Side effects: * Allocates memory. Arbitrary, as it calls upon a script. * *---------------------------------------------------------------------- */ | | | | | 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 | * * Side effects: * Allocates memory. Arbitrary, as it calls upon a script. * *---------------------------------------------------------------------- */ static ssize_t ReflectInput( ClientData clientData, char *buf, size_t toRead, int *errorCodePtr) { ReflectedChannel *rcPtr = clientData; Tcl_Obj *toReadObj; size_t bytec; /* Number of returned bytes */ unsigned char *bytev; /* Array of returned bytes */ Tcl_Obj *resObj; /* Result data for 'read' */ /* * The following check can be done before thread redirection, because we * are reading from an item which is readonly, i.e. will never change * during the lifetime of the channel. |
︙ | ︙ | |||
1388 1389 1390 1391 1392 1393 1394 | * * Side effects: * Allocates memory. Arbitrary, as it calls upon a script. * *---------------------------------------------------------------------- */ | | | | 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 | * * Side effects: * Allocates memory. Arbitrary, as it calls upon a script. * *---------------------------------------------------------------------- */ static ssize_t ReflectOutput( ClientData clientData, const char *buf, size_t toWrite, int *errorCodePtr) { ReflectedChannel *rcPtr = clientData; Tcl_Obj *bufObj; Tcl_Obj *resObj; /* Result data for 'write' */ int written; |
︙ | ︙ | |||
1476 1477 1478 1479 1480 1481 1482 | * The handler claims to have written nothing of what it was * given. That is bad. */ SetChannelErrorStr(rcPtr->chan, msg_write_nothing); goto invalid; } | | | 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 | * The handler claims to have written nothing of what it was * given. That is bad. */ SetChannelErrorStr(rcPtr->chan, msg_write_nothing); goto invalid; } if (written >= 0 && toWrite < written) { /* * The handler claims to have written more than it was given. That is * bad. Note that the I/O core would crash if we were to return this * information, trying to write -nnn bytes in the next iteration. */ SetChannelErrorStr(rcPtr->chan, msg_write_toomuch); |
︙ | ︙ | |||
1560 1561 1562 1563 1564 1565 1566 | /* ASSERT: rcPtr->method & FLAG(METH_SEEK) */ Tcl_Preserve(rcPtr); offObj = Tcl_NewWideIntObj(offset); baseObj = Tcl_NewStringObj( (seekMode == SEEK_SET) ? "start" : | | | 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 | /* ASSERT: rcPtr->method & FLAG(METH_SEEK) */ Tcl_Preserve(rcPtr); offObj = Tcl_NewWideIntObj(offset); baseObj = Tcl_NewStringObj( (seekMode == SEEK_SET) ? "start" : (seekMode == SEEK_CUR) ? "current" : "end", TCL_STRLEN); Tcl_IncrRefCount(offObj); Tcl_IncrRefCount(baseObj); if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj) != TCL_OK) { Tcl_SetChannelError(rcPtr->chan, resObj); goto invalid; } |
︙ | ︙ | |||
1832 1833 1834 1835 1836 1837 1838 | p.setOpt.name = optionName; p.setOpt.value = newValue; ForwardOpToHandlerThread(rcPtr, ForwardedSetOpt, &p); if (p.base.code != TCL_OK) { | | | | | 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 | p.setOpt.name = optionName; p.setOpt.value = newValue; ForwardOpToHandlerThread(rcPtr, ForwardedSetOpt, &p); if (p.base.code != TCL_OK) { Tcl_Obj *err = Tcl_NewStringObj(p.base.msgStr, TCL_STRLEN); UnmarshallErrorResult(interp, err); Tcl_DecrRefCount(err); FreeReceivedError(&p); } return p.base.code; } #endif Tcl_Preserve(rcPtr); optionObj = Tcl_NewStringObj(optionName, TCL_STRLEN); valueObj = Tcl_NewStringObj(newValue, TCL_STRLEN); Tcl_IncrRefCount(optionObj); Tcl_IncrRefCount(valueObj); result = InvokeTclMethod(rcPtr, "configure",optionObj,valueObj, &resObj); if (result != TCL_OK) { UnmarshallErrorResult(interp, resObj); |
︙ | ︙ | |||
1893 1894 1895 1896 1897 1898 1899 | * This code is special. It has regular passing of Tcl result, and errors. * The bypass functions are not required. */ ReflectedChannel *rcPtr = clientData; Tcl_Obj *optionObj; Tcl_Obj *resObj; /* Result data for 'configure' */ | | > | 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 | * This code is special. It has regular passing of Tcl result, and errors. * The bypass functions are not required. */ ReflectedChannel *rcPtr = clientData; Tcl_Obj *optionObj; Tcl_Obj *resObj; /* Result data for 'configure' */ int result = TCL_OK; size_t listc; Tcl_Obj **listv; const char *method; /* * Are we in the correct thread? */ |
︙ | ︙ | |||
1918 1919 1920 1921 1922 1923 1924 | } else { opcode = ForwardedGetOpt; } ForwardOpToHandlerThread(rcPtr, opcode, &p); if (p.base.code != TCL_OK) { | | | 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 | } else { opcode = ForwardedGetOpt; } ForwardOpToHandlerThread(rcPtr, opcode, &p); if (p.base.code != TCL_OK) { Tcl_Obj *err = Tcl_NewStringObj(p.base.msgStr, TCL_STRLEN); UnmarshallErrorResult(interp, err); Tcl_DecrRefCount(err); FreeReceivedError(&p); } return p.base.code; |
︙ | ︙ | |||
1942 1943 1944 1945 1946 1947 1948 | optionObj = NULL; } else { /* * Retrieve the value of one option. */ method = "cget"; | | | 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 | optionObj = NULL; } else { /* * Retrieve the value of one option. */ method = "cget"; optionObj = Tcl_NewStringObj(optionName, TCL_STRLEN); Tcl_IncrRefCount(optionObj); } Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, method, optionObj, NULL, &resObj)!=TCL_OK) { UnmarshallErrorResult(interp, resObj); |
︙ | ︙ | |||
1986 1987 1988 1989 1990 1991 1992 | /* * Odd number of elements is wrong. */ Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "Expected list with even number of " | | | | 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 | /* * Odd number of elements is wrong. */ Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "Expected list with even number of " "elements, got %lu element%s instead", listc, (listc == 1 ? "" : "s"))); goto error; } else { size_t len; const char *str = Tcl_GetStringFromObj(resObj, &len); if (len) { TclDStringAppendLiteral(dsPtr, " "); Tcl_DStringAppend(dsPtr, str, len); } goto ok; |
︙ | ︙ | |||
2048 2049 2050 2051 2052 2053 2054 | EncodeEventMask( Tcl_Interp *interp, const char *objName, Tcl_Obj *obj, int *mask) { int events; /* Mask of events to post */ | | | 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 | EncodeEventMask( Tcl_Interp *interp, const char *objName, Tcl_Obj *obj, int *mask) { int events; /* Mask of events to post */ size_t listc; /* #elements in eventspec list */ Tcl_Obj **listv; /* Elements of eventspec list */ int evIndex; /* Id of event for an element of the eventspec * list. */ if (Tcl_ListObjGetElements(interp, obj, &listc, &listv) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
2077 2078 2079 2080 2081 2082 2083 | case EVENT_READ: events |= TCL_READABLE; break; case EVENT_WRITE: events |= TCL_WRITABLE; break; } | | | 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 | case EVENT_READ: events |= TCL_READABLE; break; case EVENT_WRITE: events |= TCL_WRITABLE; break; } listc--; } *mask = events; return TCL_OK; } /* |
︙ | ︙ | |||
2124 2125 2126 2127 2128 2129 2130 | eventStr = "write"; break; default: eventStr = ""; break; } | | | 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 | eventStr = "write"; break; default: eventStr = ""; break; } evObj = Tcl_NewStringObj(eventStr, TCL_STRLEN); Tcl_IncrRefCount(evObj); /* assert evObj.refCount == 1 */ return evObj; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
2155 2156 2157 2158 2159 2160 2161 | NewReflectedChannel( Tcl_Interp *interp, Tcl_Obj *cmdpfxObj, int mode, Tcl_Obj *handleObj) { ReflectedChannel *rcPtr; | | | 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 | NewReflectedChannel( Tcl_Interp *interp, Tcl_Obj *cmdpfxObj, int mode, Tcl_Obj *handleObj) { ReflectedChannel *rcPtr; size_t i, listc; Tcl_Obj **listv; rcPtr = ckalloc(sizeof(ReflectedChannel)); /* rcPtr->chan: Assigned by caller. Dummy data here. */ /* rcPtr->methods: Assigned by caller. Dummy data here. */ |
︙ | ︙ | |||
2354 2355 2356 2357 2358 2359 2360 | if (rcPtr->dead) { /* * The channel is marked as dead. Bail out immediately, with an * appropriate error. */ if (resultObjPtr != NULL) { | | | 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 | if (rcPtr->dead) { /* * The channel is marked as dead. Bail out immediately, with an * appropriate error. */ if (resultObjPtr != NULL) { resObj = Tcl_NewStringObj(msg_dstlost, TCL_STRLEN); *resultObjPtr = resObj; Tcl_IncrRefCount(resObj); } /* * Not touching argOneObj, argTwoObj, they have not been used. * See the contract as well. |
︙ | ︙ | |||
2378 2379 2380 2381 2382 2383 2384 | */ /* * Insert method into the pre-allocated area, after the command prefix, * before the channel id. */ | | | 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 | */ /* * Insert method into the pre-allocated area, after the command prefix, * before the channel id. */ methObj = Tcl_NewStringObj(method, TCL_STRLEN); Tcl_IncrRefCount(methObj); rcPtr->argv[rcPtr->argc - 2] = methObj; /* * Append the additional argument containing method specific details * behind the channel id. If specified. * |
︙ | ︙ | |||
2434 2435 2436 2437 2438 2439 2440 | * * This is complex and ugly, and would be completely unnecessary * if we only added support for a TCL_FORBID_EXCEPTIONS flag. */ if (result != TCL_ERROR) { Tcl_Obj *cmd = Tcl_NewListObj(cmdc, rcPtr->argv); | | | 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 | * * This is complex and ugly, and would be completely unnecessary * if we only added support for a TCL_FORBID_EXCEPTIONS flag. */ if (result != TCL_ERROR) { Tcl_Obj *cmd = Tcl_NewListObj(cmdc, rcPtr->argv); size_t cmdLen; const char *cmdString = Tcl_GetStringFromObj(cmd, &cmdLen); Tcl_IncrRefCount(cmd); Tcl_ResetResult(rcPtr->interp); Tcl_SetObjResult(rcPtr->interp, Tcl_ObjPrintf( "chan handler returned bad code: %d", result)); Tcl_LogCommandInfo(rcPtr->interp, cmdString, cmdString, |
︙ | ︙ | |||
3065 3066 3067 3068 3069 3070 3071 | } paramPtr->input.toRead = -1; } else { /* * Process a regular result. */ | | | 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 | } paramPtr->input.toRead = -1; } else { /* * Process a regular result. */ size_t bytec; /* Number of returned bytes */ unsigned char *bytev; /* Array of returned bytes */ bytev = Tcl_GetByteArrayFromObj(resObj, &bytec); if (paramPtr->input.toRead < bytec) { ForwardSetStaticError(paramPtr, msg_read_toomuch); paramPtr->input.toRead = -1; |
︙ | ︙ | |||
3128 3129 3130 3131 3132 3133 3134 | break; } case ForwardedSeek: { Tcl_Obj *offObj = Tcl_NewWideIntObj(paramPtr->seek.offset); Tcl_Obj *baseObj = Tcl_NewStringObj( (paramPtr->seek.seekMode==SEEK_SET) ? "start" : | | > | 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 | break; } case ForwardedSeek: { Tcl_Obj *offObj = Tcl_NewWideIntObj(paramPtr->seek.offset); Tcl_Obj *baseObj = Tcl_NewStringObj( (paramPtr->seek.seekMode==SEEK_SET) ? "start" : (paramPtr->seek.seekMode==SEEK_CUR) ? "current" : "end", TCL_STRLEN); Tcl_IncrRefCount(offObj); Tcl_IncrRefCount(baseObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj)!=TCL_OK){ ForwardSetObjError(paramPtr, resObj); |
︙ | ︙ | |||
3191 3192 3193 3194 3195 3196 3197 | } Tcl_Release(rcPtr); Tcl_DecrRefCount(blockObj); break; } case ForwardedSetOpt: { | | > | > | > | 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 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 | } Tcl_Release(rcPtr); Tcl_DecrRefCount(blockObj); break; } case ForwardedSetOpt: { Tcl_Obj *optionObj = Tcl_NewStringObj(paramPtr->setOpt.name, TCL_STRLEN); Tcl_Obj *valueObj = Tcl_NewStringObj(paramPtr->setOpt.value, TCL_STRLEN); Tcl_IncrRefCount(optionObj); Tcl_IncrRefCount(valueObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, "configure", optionObj, valueObj, &resObj) != TCL_OK) { ForwardSetObjError(paramPtr, resObj); } Tcl_Release(rcPtr); Tcl_DecrRefCount(optionObj); Tcl_DecrRefCount(valueObj); break; } case ForwardedGetOpt: { /* * Retrieve the value of one option. */ Tcl_Obj *optionObj = Tcl_NewStringObj(paramPtr->getOpt.name, TCL_STRLEN); Tcl_IncrRefCount(optionObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, "cget", optionObj, NULL, &resObj)!=TCL_OK){ ForwardSetObjError(paramPtr, resObj); } else { TclDStringAppendObj(paramPtr->getOpt.value, resObj); |
︙ | ︙ | |||
3240 3241 3242 3243 3244 3245 3246 | ForwardSetObjError(paramPtr, resObj); } else { /* * Extract list, validate that it is a list, and #elements. See * NOTE (4) as well. */ | | > | | | 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 3276 3277 3278 3279 | ForwardSetObjError(paramPtr, resObj); } else { /* * Extract list, validate that it is a list, and #elements. See * NOTE (4) as well. */ size_t listc; Tcl_Obj **listv; if (Tcl_ListObjGetElements(interp, resObj, &listc, &listv) != TCL_OK) { Tcl_DecrRefCount(resObj); resObj = MarshallError(interp); ForwardSetObjError(paramPtr, resObj); } else if ((listc % 2) == 1) { /* * Odd number of elements is wrong. [x]. */ char *buf = ckalloc(200); sprintf(buf, "{Expected list with even number of elements, got %lu %s instead}", listc, (listc == 1 ? "element" : "elements")); ForwardSetDynamicError(paramPtr, buf); } else { size_t len; const char *str = Tcl_GetStringFromObj(resObj, &len); if (len) { TclDStringAppendLiteral(paramPtr->getOpt.value, " "); Tcl_DStringAppend(paramPtr->getOpt.value, str, len); } } |
︙ | ︙ | |||
3359 3360 3361 3362 3363 3364 3365 | } static void ForwardSetObjError( ForwardParam *paramPtr, Tcl_Obj *obj) { | | | 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 | } static void ForwardSetObjError( ForwardParam *paramPtr, Tcl_Obj *obj) { size_t len; const char *msgStr = Tcl_GetStringFromObj(obj, &len); len++; ForwardSetDynamicError(paramPtr, ckalloc(len)); memcpy(paramPtr->base.msgStr, msgStr, (unsigned) len); } #endif |
︙ | ︙ |
Changes to generic/tclIORTrans.c.
︙ | ︙ | |||
31 32 33 34 35 36 37 | static int HaveVersion(const Tcl_ChannelType *typePtr, Tcl_ChannelTypeVersion minimumVersion); /* * Signatures of all functions used in the C layer of the reflection. */ | | < | < | < | | | < | < | < < | < < | < | | 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 | static int HaveVersion(const Tcl_ChannelType *typePtr, Tcl_ChannelTypeVersion minimumVersion); /* * Signatures of all functions used in the C layer of the reflection. */ static Tcl_DriverCloseProc ReflectClose; static Tcl_DriverInputProc ReflectInput; static Tcl_DriverOutputProc ReflectOutput; static Tcl_DriverWatchProc ReflectWatch; static Tcl_DriverBlockModeProc ReflectBlock; static Tcl_DriverWideSeekProc ReflectSeekWide; static Tcl_DriverSeekProc ReflectSeek; static Tcl_DriverGetOptionProc ReflectGetOption; static Tcl_DriverSetOptionProc ReflectSetOption; static Tcl_DriverGetHandleProc ReflectHandle; static Tcl_DriverHandlerProc ReflectNotify; /* * The C layer channel type/driver definition used by the reflection. */ static const Tcl_ChannelType tclRTransformType = { "tclrtransform", /* Type name. */ |
︙ | ︙ | |||
140 141 142 143 144 145 146 | * argv [0] ... [.] | [argc-2] [argc-1] | [argc] [argc+2] * cmd ... pfx | method chan | detail1 detail2 * ~~~~ CT ~~~ ~~ CT ~~ * * CT = Belongs to the 'Command handler Thread'. */ | | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | * argv [0] ... [.] | [argc-2] [argc-1] | [argc] [argc+2] * cmd ... pfx | method chan | detail1 detail2 * ~~~~ CT ~~~ ~~ CT ~~ * * CT = Belongs to the 'Command handler Thread'. */ size_t argc; /* Number of preallocated words - 2. */ Tcl_Obj **argv; /* Preallocated array for calling the handler. * args[0] is placeholder for cmd word. * Followed by the arguments in the prefix, * plus 4 placeholders for method, channel, * and at most two varying (method specific) * words. */ int methods; /* Bitmask of supported methods. */ |
︙ | ︙ | |||
265 266 267 268 269 270 271 | * has no "subtype" and just uses ForwardParamBase, as listed above.) */ struct ForwardParamTransform { ForwardParamBase base; /* "Supertype". MUST COME FIRST. */ char *buf; /* I: Bytes to transform, * O: Bytes in transform result */ | | | | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | * has no "subtype" and just uses ForwardParamBase, as listed above.) */ struct ForwardParamTransform { ForwardParamBase base; /* "Supertype". MUST COME FIRST. */ char *buf; /* I: Bytes to transform, * O: Bytes in transform result */ ssize_t size; /* I: #bytes to transform, * O: #bytes in the transform result */ }; struct ForwardParamLimit { ForwardParamBase base; /* "Supertype". MUST COME FIRST. */ ssize_t max; /* O: Character read limit */ }; /* * Now join all these together in a single union for convenience. */ typedef union ForwardParam { |
︙ | ︙ | |||
359 360 361 362 363 364 365 | static void ForwardOpToOwnerThread(ReflectedTransform *rtPtr, ForwardedOperation op, const void *param); static int ForwardProc(Tcl_Event *evPtr, int mask); static void SrcExitProc(ClientData clientData); #define FreeReceivedError(p) \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | static void ForwardOpToOwnerThread(ReflectedTransform *rtPtr, ForwardedOperation op, const void *param); static int ForwardProc(Tcl_Event *evPtr, int mask); static void SrcExitProc(ClientData clientData); #define FreeReceivedError(p) \ do { \ if ((p)->base.mustFree) { \ ckfree((p)->base.msgStr); \ } \ } while (0) #define PassReceivedErrorInterp(i,p) \ do { \ if ((i) != NULL) { \ Tcl_SetChannelErrorInterp((i), \ Tcl_NewStringObj((p)->base.msgStr, TCL_STRLEN)); \ } \ FreeReceivedError(p); \ } while (0) #define PassReceivedError(c,p) \ do { \ Tcl_SetChannelError((c), \ Tcl_NewStringObj((p)->base.msgStr, TCL_STRLEN)); \ FreeReceivedError(p); \ } while (0) #define ForwardSetStaticError(p,emsg) \ do { \ (p)->base.code = TCL_ERROR; \ (p)->base.mustFree = 0; \ (p)->base.msgStr = (char *) (emsg); \ } while (0) #define ForwardSetDynamicError(p,emsg) \ do { \ (p)->base.code = TCL_ERROR; \ (p)->base.mustFree = 1; \ (p)->base.msgStr = (char *) (emsg); \ } while (0) static void ForwardSetObjError(ForwardParam *p, Tcl_Obj *objPtr); static ReflectedTransformMap * GetThreadReflectedTransformMap(void); static void DeleteThreadReflectedTransformMap( ClientData clientData); #endif /* TCL_THREADS */ #define SetChannelErrorStr(c,msgStr) \ Tcl_SetChannelError((c), Tcl_NewStringObj((msgStr), TCL_STRLEN)) static Tcl_Obj * MarshallError(Tcl_Interp *interp); static void UnmarshallErrorResult(Tcl_Interp *interp, Tcl_Obj *msgObj); /* * Static functions for this file: |
︙ | ︙ | |||
452 453 454 455 456 457 458 | * Helper functions encapsulating some of the thread forwarding to make the * control flow in callers easier. */ static void TimerKill(ReflectedTransform *rtPtr); static void TimerSetup(ReflectedTransform *rtPtr); static void TimerRun(ClientData clientData); | | | | | | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | * Helper functions encapsulating some of the thread forwarding to make the * control flow in callers easier. */ static void TimerKill(ReflectedTransform *rtPtr); static void TimerSetup(ReflectedTransform *rtPtr); static void TimerRun(ClientData clientData); static ssize_t TransformRead(ReflectedTransform *rtPtr, int *errorCodePtr, unsigned char *buf, size_t toRead); static ssize_t TransformWrite(ReflectedTransform *rtPtr, int *errorCodePtr, unsigned char *buf, size_t toWrite); static int TransformDrain(ReflectedTransform *rtPtr, int *errorCodePtr); static int TransformFlush(ReflectedTransform *rtPtr, int *errorCodePtr, int op); static void TransformClear(ReflectedTransform *rtPtr); static int TransformLimit(ReflectedTransform *rtPtr, int *errorCodePtr, int *maxPtr); |
︙ | ︙ | |||
499 500 501 502 503 504 505 | *---------------------------------------------------------------------- */ int TclChanPushObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | *---------------------------------------------------------------------- */ int TclChanPushObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { ReflectedTransform *rtPtr; /* Instance data of the new (transform) * channel. */ Tcl_Obj *chanObj; /* Handle of parent channel */ Tcl_Channel parentChan; /* Token of parent channel */ int mode; /* R/W mode of parent, later the new channel. * Has to match the abilities of the handler * commands */ Tcl_Obj *cmdObj; /* Command prefix, list of words */ Tcl_Obj *cmdNameObj; /* Command name */ Tcl_Obj *rtId; /* Handle of the new transform (channel) */ Tcl_Obj *modeObj; /* mode in obj form for method call */ size_t listc; /* Result of 'initialize', and of */ Tcl_Obj **listv; /* its sublist in the 2nd element */ int methIndex; /* Encoded method name */ int result; /* Result code for 'initialize' */ Tcl_Obj *resObj; /* Result data for 'initialize' */ int methods; /* Bitmask for supported methods. */ ReflectedTransformMap *rtmPtr; /* Map of reflected transforms with handlers |
︙ | ︙ | |||
706 707 708 709 710 711 712 | #endif /* TCL_THREADS */ /* * Return the channel as the result of the command. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | #endif /* TCL_THREADS */ /* * Return the channel as the result of the command. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( Tcl_GetChannelName(rtPtr->chan), TCL_STRLEN)); return TCL_OK; error: /* * We are not going through ReflectClose as we never had a channel * structure. */ |
︙ | ︙ | |||
744 745 746 747 748 749 750 | *---------------------------------------------------------------------- */ int TclChanPopObjCmd( ClientData clientData, Tcl_Interp *interp, | | | 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 | *---------------------------------------------------------------------- */ int TclChanPopObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { /* * Syntax: chan pop CHANNEL * [0] [1] [2] * * Actually: rPop CHANNEL |
︙ | ︙ | |||
822 823 824 825 826 827 828 | } static void UnmarshallErrorResult( Tcl_Interp *interp, Tcl_Obj *msgObj) { | | | 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 | } static void UnmarshallErrorResult( Tcl_Interp *interp, Tcl_Obj *msgObj) { size_t lc; Tcl_Obj **lv; int explicitResult; int numOptions; /* * Process the caught message. * |
︙ | ︙ | |||
1050 1051 1052 1053 1054 1055 1056 | * * Side effects: * Allocates memory. Arbitrary, as it calls upon a script. * *---------------------------------------------------------------------- */ | | | | 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 | * * Side effects: * Allocates memory. Arbitrary, as it calls upon a script. * *---------------------------------------------------------------------- */ static ssize_t ReflectInput( ClientData clientData, char *buf, size_t toRead, int *errorCodePtr) { ReflectedTransform *rtPtr = clientData; int gotBytes, copied, readBytes; /* * The following check can be done before thread redirection, because we |
︙ | ︙ | |||
1239 1240 1241 1242 1243 1244 1245 | * * Side effects: * Allocates memory. Arbitrary, as it calls upon a script. * *---------------------------------------------------------------------- */ | | | | 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 | * * Side effects: * Allocates memory. Arbitrary, as it calls upon a script. * *---------------------------------------------------------------------- */ static ssize_t ReflectOutput( ClientData clientData, const char *buf, size_t toWrite, int *errorCodePtr) { ReflectedTransform *rtPtr = clientData; /* * The following check can be done before thread redirection, because we * are reading from an item which is readonly, i.e. will never change |
︙ | ︙ | |||
1717 1718 1719 1720 1721 1722 1723 | eventStr = "write"; break; default: eventStr = ""; break; } | | | 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 | eventStr = "write"; break; default: eventStr = ""; break; } evObj = Tcl_NewStringObj(eventStr, TCL_STRLEN); Tcl_IncrRefCount(evObj); return evObj; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1748 1749 1750 1751 1752 1753 1754 | Tcl_Interp *interp, Tcl_Obj *cmdpfxObj, int mode, Tcl_Obj *handleObj, Tcl_Channel parentChan) { ReflectedTransform *rtPtr; | | | 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 | Tcl_Interp *interp, Tcl_Obj *cmdpfxObj, int mode, Tcl_Obj *handleObj, Tcl_Channel parentChan) { ReflectedTransform *rtPtr; size_t listc; Tcl_Obj **listv; int i; rtPtr = ckalloc(sizeof(ReflectedTransform)); /* rtPtr->chan: Assigned by caller. Dummy data here. */ /* rtPtr->methods: Assigned by caller. Dummy data here. */ |
︙ | ︙ | |||
1958 1959 1960 1961 1962 1963 1964 | if (rtPtr->dead) { /* * The transform is marked as dead. Bail out immediately, with an * appropriate error. */ if (resultObjPtr != NULL) { | | | | 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 | if (rtPtr->dead) { /* * The transform is marked as dead. Bail out immediately, with an * appropriate error. */ if (resultObjPtr != NULL) { resObj = Tcl_NewStringObj(msg_dstlost, TCL_STRLEN); *resultObjPtr = resObj; Tcl_IncrRefCount(resObj); } return TCL_ERROR; } /* * NOTE (5): Decide impl. issue: Cache objects with method names? * Requires TSD data as reflections can be created in many different * threads. * NO: Caching of command resolutions means storage per channel. */ /* * Insert method into the pre-allocated area, after the command prefix, * before the channel id. */ methObj = Tcl_NewStringObj(method, TCL_STRLEN); Tcl_IncrRefCount(methObj); rtPtr->argv[rtPtr->argc - 2] = methObj; /* * Append the additional argument containing method specific details * behind the channel id. If specified. * |
︙ | ︙ | |||
2032 2033 2034 2035 2036 2037 2038 | * the full state of the result, including additional options. * * This is complex and ugly, and would be completely unnecessary * if we only added support for a TCL_FORBID_EXCEPTIONS flag. */ if (result != TCL_ERROR) { Tcl_Obj *cmd = Tcl_NewListObj(cmdc, rtPtr->argv); | | | 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 | * the full state of the result, including additional options. * * This is complex and ugly, and would be completely unnecessary * if we only added support for a TCL_FORBID_EXCEPTIONS flag. */ if (result != TCL_ERROR) { Tcl_Obj *cmd = Tcl_NewListObj(cmdc, rtPtr->argv); size_t cmdLen; const char *cmdString = Tcl_GetStringFromObj(cmd, &cmdLen); Tcl_IncrRefCount(cmd); Tcl_ResetResult(rtPtr->interp); Tcl_SetObjResult(rtPtr->interp, Tcl_ObjPrintf( "chan handler returned bad code: %d", result)); Tcl_LogCommandInfo(rtPtr->interp, cmdString, cmdString, cmdLen); |
︙ | ︙ | |||
2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 | Tcl_Interp *interp = rtPtr->interp; ForwardParam *paramPtr = evPtr->param; Tcl_Obj *resObj = NULL; /* Interp result of InvokeTclMethod */ ReflectedTransformMap *rtmPtr; /* Map of reflected channels with handlers in * this interp. */ Tcl_HashEntry *hPtr; /* Entry in the above map */ /* * Ignore the event if no one is waiting for its result anymore. */ if (!resultPtr) { return 1; | > > | 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 | Tcl_Interp *interp = rtPtr->interp; ForwardParam *paramPtr = evPtr->param; Tcl_Obj *resObj = NULL; /* Interp result of InvokeTclMethod */ ReflectedTransformMap *rtmPtr; /* Map of reflected channels with handlers in * this interp. */ Tcl_HashEntry *hPtr; /* Entry in the above map */ size_t bytec; /* Number of returned bytes */ unsigned char *bytev; /* Array of returned bytes */ /* * Ignore the event if no one is waiting for its result anymore. */ if (!resultPtr) { return 1; |
︙ | ︙ | |||
2581 2582 2583 2584 2585 2586 2587 | paramPtr->transform.size = -1; } else { /* * Process a regular return. Contains the transformation result. * Sent it back to the request originator. */ | < < < < | | 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 | paramPtr->transform.size = -1; } else { /* * Process a regular return. Contains the transformation result. * Sent it back to the request originator. */ bytev = Tcl_GetByteArrayFromObj(resObj, &bytec); paramPtr->transform.size = bytec; if (bytec > 0) { paramPtr->transform.buf = ckalloc(bytec); memcpy(paramPtr->transform.buf, bytev, (size_t) bytec); } else { paramPtr->transform.buf = NULL; } } Tcl_DecrRefCount(bufObj); break; |
︙ | ︙ | |||
2615 2616 2617 2618 2619 2620 2621 | paramPtr->transform.size = -1; } else { /* * Process a regular return. Contains the transformation result. * Sent it back to the request originator. */ | < < < < < | < < < < | < < < < < | > > > | | > | | > | 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 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 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 | paramPtr->transform.size = -1; } else { /* * Process a regular return. Contains the transformation result. * Sent it back to the request originator. */ bytev = Tcl_GetByteArrayFromObj(resObj, &bytec); paramPtr->transform.size = bytec; if (bytec > 0) { paramPtr->transform.buf = ckalloc(bytec); memcpy(paramPtr->transform.buf, bytev, (size_t) bytec); } else { paramPtr->transform.buf = NULL; } } Tcl_DecrRefCount(bufObj); break; } case ForwardedDrain: if (InvokeTclMethod(rtPtr, "drain", NULL, NULL, &resObj) != TCL_OK) { ForwardSetObjError(paramPtr, resObj); paramPtr->transform.size = -1; } else { /* * Process a regular return. Contains the transformation result. * Sent it back to the request originator. */ bytev = Tcl_GetByteArrayFromObj(resObj, &bytec); paramPtr->transform.size = bytec; if (bytec > 0) { paramPtr->transform.buf = ckalloc(bytec); memcpy(paramPtr->transform.buf, bytev, (size_t) bytec); } else { paramPtr->transform.buf = NULL; } } break; case ForwardedFlush: if (InvokeTclMethod(rtPtr, "flush", NULL, NULL, &resObj) != TCL_OK) { ForwardSetObjError(paramPtr, resObj); paramPtr->transform.size = -1; } else { /* * Process a regular return. Contains the transformation result. * Sent it back to the request originator. */ bytev = Tcl_GetByteArrayFromObj(resObj, &bytec); paramPtr->transform.size = bytec; if (bytec > 0) { paramPtr->transform.buf = ckalloc(bytec); memcpy(paramPtr->transform.buf, bytev, (size_t) bytec); } else { paramPtr->transform.buf = NULL; } } break; case ForwardedClear: (void) InvokeTclMethod(rtPtr, "clear", NULL, NULL, NULL); break; case ForwardedLimit: if (InvokeTclMethod(rtPtr, "limit?", NULL, NULL, &resObj) != TCL_OK) { ForwardSetObjError(paramPtr, resObj); paramPtr->limit.max = -1; } else { int limit; // TODO - should this be larger? if (Tcl_GetIntFromObj(interp, resObj, &limit) == TCL_OK) { paramPtr->limit.max = limit; } else { ForwardSetObjError(paramPtr, MarshallError(interp)); paramPtr->limit.max = -1; } } break; default: /* * Bad operation code. */ |
︙ | ︙ | |||
2789 2790 2791 2792 2793 2794 2795 | } static void ForwardSetObjError( ForwardParam *paramPtr, Tcl_Obj *obj) { | | | 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 | } static void ForwardSetObjError( ForwardParam *paramPtr, Tcl_Obj *obj) { size_t len; const char *msgStr = Tcl_GetStringFromObj(obj, &len); len++; ForwardSetDynamicError(paramPtr, ckalloc(len)); memcpy(paramPtr->base.msgStr, msgStr, (unsigned) len); } #endif /* TCL_THREADS */ |
︙ | ︙ | |||
3057 3058 3059 3060 3061 3062 3063 | } /* -- common postwork code ------- */ return copied; } | | | | | 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 | } /* -- common postwork code ------- */ return copied; } static ssize_t TransformRead( ReflectedTransform *rtPtr, int *errorCodePtr, unsigned char *buf, size_t toRead) { Tcl_Obj *bufObj; Tcl_Obj *resObj; size_t bytec; /* Number of returned bytes */ unsigned char *bytev; /* Array of returned bytes */ /* * Are we in the correct thread? */ #ifdef TCL_THREADS |
︙ | ︙ | |||
3117 3118 3119 3120 3121 3122 3123 | ResultAdd(&rtPtr->result, bytev, bytec); Tcl_DecrRefCount(bufObj); Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ return 1; } | | | < < < < | 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 | ResultAdd(&rtPtr->result, bytev, bytec); Tcl_DecrRefCount(bufObj); Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ return 1; } static ssize_t TransformWrite( ReflectedTransform *rtPtr, int *errorCodePtr, unsigned char *buf, size_t toWrite) { int res; /* * Are we in the correct thread? */ #ifdef TCL_THREADS |
︙ | ︙ | |||
3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 | *errorCodePtr = EOK; res = Tcl_WriteRaw(rtPtr->parent, (char *) p.transform.buf, p.transform.size); ckfree(p.transform.buf); } else #endif /* TCL_THREADS */ { /* ASSERT: rtPtr->method & FLAG(METH_WRITE) */ /* ASSERT: rtPtr->mode & TCL_WRITABLE */ bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toWrite); Tcl_IncrRefCount(bufObj); if (InvokeTclMethod(rtPtr, "write", bufObj, NULL, &resObj) != TCL_OK) { *errorCodePtr = EINVAL; | > > > > > | 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 | *errorCodePtr = EOK; res = Tcl_WriteRaw(rtPtr->parent, (char *) p.transform.buf, p.transform.size); ckfree(p.transform.buf); } else #endif /* TCL_THREADS */ { Tcl_Obj *bufObj; Tcl_Obj *resObj; size_t bytec; /* Number of returned bytes */ unsigned char *bytev; /* Array of returned bytes */ /* ASSERT: rtPtr->method & FLAG(METH_WRITE) */ /* ASSERT: rtPtr->mode & TCL_WRITABLE */ bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toWrite); Tcl_IncrRefCount(bufObj); if (InvokeTclMethod(rtPtr, "write", bufObj, NULL, &resObj) != TCL_OK) { *errorCodePtr = EINVAL; |
︙ | ︙ | |||
3192 3193 3194 3195 3196 3197 3198 | } static int TransformDrain( ReflectedTransform *rtPtr, int *errorCodePtr) { | < < < < | 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 | } static int TransformDrain( ReflectedTransform *rtPtr, int *errorCodePtr) { /* * Are we in the correct thread? */ #ifdef TCL_THREADS if (rtPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; |
︙ | ︙ | |||
3218 3219 3220 3221 3222 3223 3224 | *errorCodePtr = EOK; ResultAdd(&rtPtr->result, UCHARP(p.transform.buf), p.transform.size); ckfree(p.transform.buf); } else #endif /* TCL_THREADS */ { | > > > > | | 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 | *errorCodePtr = EOK; ResultAdd(&rtPtr->result, UCHARP(p.transform.buf), p.transform.size); ckfree(p.transform.buf); } else #endif /* TCL_THREADS */ { Tcl_Obj *resObj; size_t bytec; /* Number of returned bytes */ unsigned char *bytev; /* Array of returned bytes */ if (InvokeTclMethod(rtPtr, "drain", NULL, NULL, &resObj) != TCL_OK) { Tcl_SetChannelError(rtPtr->chan, resObj); Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ *errorCodePtr = EINVAL; return 0; } bytev = Tcl_GetByteArrayFromObj(resObj, &bytec); |
︙ | ︙ | |||
3241 3242 3243 3244 3245 3246 3247 | static int TransformFlush( ReflectedTransform *rtPtr, int *errorCodePtr, int op) { | < < < | 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 | static int TransformFlush( ReflectedTransform *rtPtr, int *errorCodePtr, int op) { int res; /* * Are we in the correct thread? */ #ifdef TCL_THREADS |
︙ | ︙ | |||
3273 3274 3275 3276 3277 3278 3279 | } else { res = 0; } ckfree(p.transform.buf); } else #endif /* TCL_THREADS */ { | > > > > | | 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 | } else { res = 0; } ckfree(p.transform.buf); } else #endif /* TCL_THREADS */ { Tcl_Obj *resObj; size_t bytec; /* Number of returned bytes */ unsigned char *bytev; /* Array of returned bytes */ if (InvokeTclMethod(rtPtr, "flush", NULL, NULL, &resObj) != TCL_OK) { Tcl_SetChannelError(rtPtr->chan, resObj); Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ *errorCodePtr = EINVAL; return 0; } if (op == FLUSH_WRITE) { |
︙ | ︙ |
Changes to generic/tclIOSock.c.
︙ | ︙ | |||
48 49 50 51 52 53 54 | const char *native; if (Tcl_GetInt(NULL, string, portPtr) != TCL_OK) { /* * Don't bother translating 'proto' to native. */ | | | | 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 | const char *native; if (Tcl_GetInt(NULL, string, portPtr) != TCL_OK) { /* * Don't bother translating 'proto' to native. */ native = Tcl_UtfToExternalDString(NULL, string, TCL_STRLEN, &ds); sp = getservbyname(native, proto); /* INTL: Native. */ Tcl_DStringFree(&ds); if (sp != NULL) { *portPtr = ntohs((unsigned short) sp->s_port); return TCL_OK; } } if (Tcl_GetInt(interp, string, portPtr) != TCL_OK) { return TCL_ERROR; } if (*portPtr > 0xFFFF) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "couldn't open socket: port number too high", TCL_STRLEN)); return TCL_ERROR; } return TCL_OK; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
153 154 155 156 157 158 159 | struct addrinfo *v6head = NULL, *v6ptr = NULL; char *native = NULL, portbuf[TCL_INTEGER_SPACE], *portstring; const char *family = NULL; Tcl_DString ds; int result, i; if (host != NULL) { | | | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | struct addrinfo *v6head = NULL, *v6ptr = NULL; char *native = NULL, portbuf[TCL_INTEGER_SPACE], *portstring; const char *family = NULL; Tcl_DString ds; int result, i; if (host != NULL) { native = Tcl_UtfToExternalDString(NULL, host, TCL_STRLEN, &ds); } /* * Workaround for OSX's apparent inability to resolve "localhost", "0" * when the loopback device is the only available network interface. */ if (host != NULL && port == 0) { |
︙ | ︙ |
Changes to generic/tclIOUtil.c.
︙ | ︙ | |||
257 258 259 260 261 262 263 | int Tcl_Stat( const char *path, /* Path of file to stat (in current CP). */ struct stat *oldStyleBuf) /* Filled with results of stat call. */ { int ret; Tcl_StatBuf buf; | | | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | int Tcl_Stat( const char *path, /* Path of file to stat (in current CP). */ struct stat *oldStyleBuf) /* Filled with results of stat call. */ { int ret; Tcl_StatBuf buf; Tcl_Obj *pathPtr = Tcl_NewStringObj(path, TCL_STRLEN); Tcl_IncrRefCount(pathPtr); ret = Tcl_FSStat(pathPtr, &buf); Tcl_DecrRefCount(pathPtr); if (ret != -1) { #ifndef TCL_WIDE_INT_IS_LONG Tcl_WideInt tmp1, tmp2, tmp3 = 0; |
︙ | ︙ | |||
343 344 345 346 347 348 349 | /* Obsolete */ int Tcl_Access( const char *path, /* Path of file to access (in current CP). */ int mode) /* Permission setting. */ { int ret; | | | | > | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | /* Obsolete */ int Tcl_Access( const char *path, /* Path of file to access (in current CP). */ int mode) /* Permission setting. */ { int ret; Tcl_Obj *pathPtr = Tcl_NewStringObj(path, TCL_STRLEN); Tcl_IncrRefCount(pathPtr); ret = Tcl_FSAccess(pathPtr,mode); Tcl_DecrRefCount(pathPtr); return ret; } /* Obsolete */ Tcl_Channel Tcl_OpenFileChannel( Tcl_Interp *interp, /* Interpreter for error reporting; can be * NULL. */ const char *path, /* Name of file to open. */ const char *modeString, /* A list of POSIX open modes or a string such * as "rw". */ int permissions) /* If the open involves creating a file, with * what modes to create it? */ { Tcl_Channel ret; Tcl_Obj *pathPtr = Tcl_NewStringObj(path, TCL_STRLEN); Tcl_IncrRefCount(pathPtr); ret = Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions); Tcl_DecrRefCount(pathPtr); return ret; } /* Obsolete */ int Tcl_Chdir( const char *dirName) { int ret; Tcl_Obj *pathPtr = Tcl_NewStringObj(dirName, TCL_STRLEN); Tcl_IncrRefCount(pathPtr); ret = Tcl_FSChdir(pathPtr); Tcl_DecrRefCount(pathPtr); return ret; } /* Obsolete */ |
︙ | ︙ | |||
516 517 518 519 520 521 522 | if (pathPtrPtr == NULL) { return (tsdPtr->cwdPathPtr == NULL); } if (tsdPtr->cwdPathPtr == *pathPtrPtr) { return 1; } else { | | | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | if (pathPtrPtr == NULL) { return (tsdPtr->cwdPathPtr == NULL); } if (tsdPtr->cwdPathPtr == *pathPtrPtr) { return 1; } else { size_t len1, len2; const char *str1, *str2; str1 = Tcl_GetStringFromObj(tsdPtr->cwdPathPtr, &len1); str2 = Tcl_GetStringFromObj(*pathPtrPtr, &len2); if ((len1 == len2) && !memcmp(str1, str2, len1)) { /* * They are equal, but different objects. Update so they will be |
︙ | ︙ | |||
658 659 660 661 662 663 664 | */ static void FsUpdateCwd( Tcl_Obj *cwdObj, ClientData clientData) { | | | 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 | */ static void FsUpdateCwd( Tcl_Obj *cwdObj, ClientData clientData) { size_t len; const char *str = NULL; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); if (cwdObj != NULL) { str = Tcl_GetStringFromObj(cwdObj, &len); } |
︙ | ︙ | |||
1015 1016 1017 1018 1019 1020 1021 | const char *pattern, /* Pattern to match against. */ Tcl_GlobTypeData *types) /* Object containing list of acceptable types. * May be NULL. In particular the directory * flag is very important. */ { const Tcl_Filesystem *fsPtr; Tcl_Obj *cwd, *tmpResultPtr, **elemsPtr; | > | | 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 | const char *pattern, /* Pattern to match against. */ Tcl_GlobTypeData *types) /* Object containing list of acceptable types. * May be NULL. In particular the directory * flag is very important. */ { const Tcl_Filesystem *fsPtr; Tcl_Obj *cwd, *tmpResultPtr, **elemsPtr; int ret = -1; size_t resLength, i; if (types != NULL && (types->type & TCL_GLOB_TYPE_MOUNT)) { /* * We don't currently allow querying of mounts by external code (a * valuable future step), so since we're the only function that * actually knows about mounts, this means we're being called * recursively by ourself. Return no matches. |
︙ | ︙ | |||
1077 1078 1079 1080 1081 1082 1083 | */ cwd = Tcl_FSGetCwd(NULL); if (cwd == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "glob couldn't determine the current working directory", | | | 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 | */ cwd = Tcl_FSGetCwd(NULL); if (cwd == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "glob couldn't determine the current working directory", TCL_STRLEN)); } return TCL_ERROR; } fsPtr = Tcl_FSGetFileSystemForPath(cwd); if (fsPtr != NULL && fsPtr->matchInDirectoryProc != NULL) { TclNewObj(tmpResultPtr); |
︙ | ︙ | |||
1137 1138 1139 1140 1141 1142 1143 | * not be shared! */ Tcl_Obj *pathPtr, /* The directory in question. */ const char *pattern, /* Pattern to match against. */ Tcl_GlobTypeData *types) /* Object containing list of acceptable types. * May be NULL. In particular the directory * flag is very important. */ { | | | 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 | * not be shared! */ Tcl_Obj *pathPtr, /* The directory in question. */ const char *pattern, /* Pattern to match against. */ Tcl_GlobTypeData *types) /* Object containing list of acceptable types. * May be NULL. In particular the directory * flag is very important. */ { size_t mLength, gLength, i; int dir = (types == NULL || (types->type & TCL_GLOB_TYPE_DIR)); Tcl_Obj *mounts = FsListMounts(pathPtr, pattern); if (mounts == NULL) { return; } |
︙ | ︙ | |||
1177 1178 1179 1180 1181 1182 1183 | gLength--; } break; /* Break out of for loop. */ } } if (!found && dir) { Tcl_Obj *norm; | < > > | 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 | gLength--; } break; /* Break out of for loop. */ } } if (!found && dir) { Tcl_Obj *norm; /* * We know mElt is absolute normalized and lies inside pathPtr, so * now we must add to the result the right representation of mElt, * i.e. the representation which is relative to pathPtr. */ norm = Tcl_FSGetNormalizedPath(NULL, pathPtr); if (norm != NULL) { const char *path, *mount; size_t len, mlen; mount = Tcl_GetStringFromObj(mElt, &mlen); path = Tcl_GetStringFromObj(norm, &len); if (path[len-1] == '/') { /* * 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); } /* * No need to increment gLength, since we don't want to compare * mounts against mounts. */ } } |
︙ | ︙ | |||
1483 1484 1485 1486 1487 1488 1489 | const char *modeString, /* Mode string, e.g. "r+" or "RDONLY CREAT" */ int *seekFlagPtr, /* Set this to 1 if the caller should seek to * EOF during the opening of the file. */ int *binaryPtr) /* Set this to 1 if the caller should * configure the opened channel for binary * operations. */ { | | > | 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 | const char *modeString, /* Mode string, e.g. "r+" or "RDONLY CREAT" */ int *seekFlagPtr, /* Set this to 1 if the caller should seek to * EOF during the opening of the file. */ int *binaryPtr) /* Set this to 1 if the caller should * configure the opened channel for binary * operations. */ { int mode, c, i, gotRW; const char **modeArgv, *flag; size_t modeArgc; #define RW_MODES (O_RDONLY|O_WRONLY|O_RDWR) /* * Check for the simpler fopen-like access modes (e.g. "r"). They are * distinguished from the POSIX access modes by the presence of a * lower-case first letter. */ |
︙ | ︙ | |||
1648 1649 1650 1651 1652 1653 1654 | ckfree(modeArgv); if (!gotRW) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "access mode must include either RDONLY, WRONLY, or RDWR", | | | 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 | ckfree(modeArgv); if (!gotRW) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "access mode must include either RDONLY, WRONLY, or RDWR", TCL_STRLEN)); } return -1; } return mode; } /* |
︙ | ︙ | |||
1693 1694 1695 1696 1697 1698 1699 | Tcl_FSEvalFileEx( Tcl_Interp *interp, /* Interpreter in which to process file. */ Tcl_Obj *pathPtr, /* Path of file to process. Tilde-substitution * will be performed on this name. */ const char *encodingName) /* If non-NULL, then use this encoding for the * file. NULL means use the system encoding. */ { | | > | 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 | Tcl_FSEvalFileEx( Tcl_Interp *interp, /* Interpreter in which to process file. */ Tcl_Obj *pathPtr, /* Path of file to process. Tilde-substitution * will be performed on this name. */ const char *encodingName) /* If non-NULL, then use this encoding for the * file. NULL means use the system encoding. */ { int result = TCL_ERROR; Tcl_StatBuf statBuf; Tcl_Obj *oldScriptFile; Interp *iPtr; const char *string; Tcl_Channel chan; Tcl_Obj *objPtr; size_t length; if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) { return result; } if (Tcl_FSStat(pathPtr, &statBuf) == -1) { Tcl_SetErrno(errno); |
︙ | ︙ | |||
1762 1763 1764 1765 1766 1767 1768 | string = Tcl_GetString(objPtr); /* * If first character is not a BOM, append the remaining characters, * otherwise replace them. [Bug 3466099] */ | | | 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 | string = Tcl_GetString(objPtr); /* * If first character is not a BOM, append the remaining characters, * otherwise replace them. [Bug 3466099] */ if (Tcl_ReadChars(chan, objPtr, TCL_STRLEN, memcmp(string, "\xef\xbb\xbf", 3)) < 0) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", Tcl_GetString(pathPtr), Tcl_PosixError(interp))); goto end; } |
︙ | ︙ | |||
1812 1813 1814 1815 1816 1817 1818 | const char *pathString = Tcl_GetStringFromObj(pathPtr, &length); int limit = 150; int overflow = (length > limit); Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (file \"%.*s%s\" line %d)", | | | 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 | const char *pathString = Tcl_GetStringFromObj(pathPtr, &length); int limit = 150; int overflow = (length > limit); Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (file \"%.*s%s\" line %d)", (overflow ? limit : (int) length), pathString, (overflow ? "..." : ""), Tcl_GetErrorLine(interp))); } end: Tcl_DecrRefCount(objPtr); return result; } |
︙ | ︙ | |||
1897 1898 1899 1900 1901 1902 1903 | string = Tcl_GetString(objPtr); /* * If first character is not a BOM, append the remaining characters, * otherwise replace them. [Bug 3466099] */ | | | 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 | string = Tcl_GetString(objPtr); /* * If first character is not a BOM, append the remaining characters, * otherwise replace them. [Bug 3466099] */ if (Tcl_ReadChars(chan, objPtr, TCL_STRLEN, memcmp(string, "\xef\xbb\xbf", 3)) < 0) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", Tcl_GetString(pathPtr), Tcl_PosixError(interp))); Tcl_DecrRefCount(objPtr); return TCL_ERROR; |
︙ | ︙ | |||
1956 1957 1958 1959 1960 1961 1962 | if (result == TCL_RETURN) { result = TclUpdateReturnInfo(iPtr); } else if (result == TCL_ERROR) { /* * Record information telling where the error occurred. */ | | | | 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 | if (result == TCL_RETURN) { result = TclUpdateReturnInfo(iPtr); } else if (result == TCL_ERROR) { /* * Record information telling where the error occurred. */ size_t length; const char *pathString = Tcl_GetStringFromObj(pathPtr, &length); const int limit = 150; int overflow = (length > limit); Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (file \"%.*s%s\" line %d)", (overflow ? limit : (int) length), pathString, (overflow ? "..." : ""), Tcl_GetErrorLine(interp))); } Tcl_DecrRefCount(objPtr); return result; } |
︙ | ︙ | |||
2465 2466 2467 2468 2469 2470 2471 | } if (attrTable != NULL) { /* * It's a constant attribute table, so use T_GIFO. */ | | | | 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 | } if (attrTable != NULL) { /* * It's a constant attribute table, so use T_GIFO. */ Tcl_Obj *tmpObj = Tcl_NewStringObj(attributeName, TCL_STRLEN); int result; result = Tcl_GetIndexFromObjStruct(NULL, tmpObj, attrTable, sizeof(char *), NULL, TCL_EXACT, indexPtr); TclDecrRefCount(tmpObj); if (listObj != NULL) { TclDecrRefCount(listObj); } return result; } else if (listObj != NULL) { /* * It's a non-constant attribute list, so do a literal search. */ size_t i, objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(NULL, listObj, &objc, &objv) != TCL_OK) { TclDecrRefCount(listObj); return TCL_ERROR; } for (i=0 ; i<objc ; i++) { |
︙ | ︙ | |||
2806 2807 2808 2809 2810 2811 2812 | /* * Note that both 'norm' and 'tsdPtr->cwdPathPtr' are normalized * paths. Therefore we can be more efficient than calling * 'Tcl_FSEqualPaths', and in addition avoid a nasty infinite loop * bug when trying to normalize tsdPtr->cwdPathPtr. */ | | | 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 | /* * Note that both 'norm' and 'tsdPtr->cwdPathPtr' are normalized * paths. Therefore we can be more efficient than calling * 'Tcl_FSEqualPaths', and in addition avoid a nasty infinite loop * bug when trying to normalize tsdPtr->cwdPathPtr. */ size_t len1, len2; const char *str1, *str2; str1 = Tcl_GetStringFromObj(tsdPtr->cwdPathPtr, &len1); str2 = Tcl_GetStringFromObj(norm, &len2); if ((len1 == len2) && (strcmp(str1, str2) == 0)) { /* * If the paths were equal, we can be more efficient and |
︙ | ︙ | |||
3221 3222 3223 3224 3225 3226 3227 | * and we must avoid a possible infinite loop. Try to delete the file * we probably created, and then exit. */ Tcl_FSDeleteFile(copyToPtr); Tcl_DecrRefCount(copyToPtr); Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 | * and we must avoid a possible infinite loop. Try to delete the file * we probably created, and then exit. */ Tcl_FSDeleteFile(copyToPtr); Tcl_DecrRefCount(copyToPtr); Tcl_SetObjResult(interp, Tcl_NewStringObj( "couldn't load from current filesystem", TCL_STRLEN)); return TCL_ERROR; } if (TclCrossFilesystemCopy(interp, pathPtr, copyToPtr) != TCL_OK) { /* * Cross-platform copy failed. */ |
︙ | ︙ | |||
3540 3541 3542 3543 3544 3545 3546 | Tcl_Interp *interp, /* Tcl interpreter */ Tcl_LoadHandle handle) /* Handle of the file to unload */ { if (handle->unloadFileProcPtr == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot unload: filesystem does not support unloading", | | | 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 | Tcl_Interp *interp, /* Tcl interpreter */ Tcl_LoadHandle handle) /* Handle of the file to unload */ { if (handle->unloadFileProcPtr == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot unload: filesystem does not support unloading", TCL_STRLEN)); } return TCL_ERROR; } TclpUnloadFile(handle); return TCL_OK; } |
︙ | ︙ | |||
3855 3856 3857 3858 3859 3860 3861 | * *--------------------------------------------------------------------------- */ Tcl_Obj * Tcl_FSSplitPath( Tcl_Obj *pathPtr, /* Path to split. */ | | | | 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 | * *--------------------------------------------------------------------------- */ Tcl_Obj * Tcl_FSSplitPath( Tcl_Obj *pathPtr, /* Path to split. */ size_t *lenPtr) /* Where to store number of path elements. */ { Tcl_Obj *result = NULL; /* Needed only to prevent gcc warnings. */ const Tcl_Filesystem *fsPtr; char separator = '/'; size_t driveNameLength; const char *p; /* * Perform platform specific splitting. */ if (TclFSGetPathType(pathPtr, &fsPtr, |
︙ | ︙ | |||
3965 3966 3967 3968 3969 3970 3971 | Tcl_PathType TclGetPathType( Tcl_Obj *pathPtr, /* Path to determine type for. */ const Tcl_Filesystem **filesystemPtrPtr, /* If absolute path and this is not NULL, then * set to the filesystem which claims this * path. */ | | | | 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 | Tcl_PathType TclGetPathType( Tcl_Obj *pathPtr, /* Path to determine type for. */ const Tcl_Filesystem **filesystemPtrPtr, /* If absolute path and this is not NULL, then * set to the filesystem which claims this * path. */ size_t *driveNameLengthPtr, /* If the path is absolute, and this is * non-NULL, then set to the length of the * driveName. */ Tcl_Obj **driveNameRef) /* If the path is absolute, and this is * non-NULL, then set to the name of the * drive, network-volume which contains the * path, already with a refCount for the * caller. */ { size_t pathLen; const char *path = Tcl_GetStringFromObj(pathPtr, &pathLen); Tcl_PathType type; type = TclFSNonnativePathType(path, pathLen, filesystemPtrPtr, driveNameLengthPtr, driveNameRef); if (type != TCL_PATH_ABSOLUTE) { |
︙ | ︙ | |||
4016 4017 4018 4019 4020 4021 4022 | * *---------------------------------------------------------------------- */ Tcl_PathType TclFSNonnativePathType( const char *path, /* Path to determine type for. */ | | | | 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 | * *---------------------------------------------------------------------- */ Tcl_PathType TclFSNonnativePathType( const char *path, /* Path to determine type for. */ size_t pathLen, /* Length of the path. */ const Tcl_Filesystem **filesystemPtrPtr, /* If absolute path and this is not NULL, then * set to the filesystem which claims this * path. */ size_t *driveNameLengthPtr, /* If the path is absolute, and this is * non-NULL, then set to the length of the * driveName. */ Tcl_Obj **driveNameRef) /* If the path is absolute, and this is * non-NULL, then set to the name of the * drive, network-volume which contains the * path, already with a refCount for the * caller. */ |
︙ | ︙ | |||
4062 4063 4064 4065 4066 4067 4068 | * that effort here, and this function is actually called quite often, * so if we can save the overhead of the native filesystem returning * us a list of volumes all the time, it is better. */ if ((fsRecPtr->fsPtr != &tclNativeFilesystem) && (fsRecPtr->fsPtr->listVolumesProc != NULL)) { | | | | 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 | * that effort here, and this function is actually called quite often, * so if we can save the overhead of the native filesystem returning * us a list of volumes all the time, it is better. */ if ((fsRecPtr->fsPtr != &tclNativeFilesystem) && (fsRecPtr->fsPtr->listVolumesProc != NULL)) { size_t numVolumes; Tcl_Obj *thisFsVolumes = fsRecPtr->fsPtr->listVolumesProc(); if (thisFsVolumes != NULL) { if (Tcl_ListObjLength(NULL, thisFsVolumes, &numVolumes) != TCL_OK) { /* * This is VERY bad; the listVolumesProc didn't return a * valid list. Set numVolumes to -1 so that we skip the * while loop below and just return with the current value * of 'type'. * * It would be better if we could signal an error here * (but Tcl_Panic seems a bit excessive). */ numVolumes = -1; } while (numVolumes > 0) { Tcl_Obj *vol; size_t len; const char *strVol; numVolumes--; Tcl_ListObjIndex(NULL, thisFsVolumes, numVolumes, &vol); strVol = Tcl_GetStringFromObj(vol,&len); if (pathLen < len) { continue; |
︙ | ︙ | |||
4258 4259 4260 4261 4262 4263 4264 | } /* * Copy it synchronously. We might wish to add an asynchronous option to * support vfs's which are slow (e.g. network sockets). */ | | | 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 | } /* * Copy it synchronously. We might wish to add an asynchronous option to * support vfs's which are slow (e.g. network sockets). */ if (TclCopyChannel(interp, in, out, (Tcl_WideInt) -1, NULL) == TCL_OK) { result = TCL_OK; } /* * If the copy failed, assume that copy channel left a good error message. */ |
︙ | ︙ | |||
4430 4431 4432 4433 4434 4435 4436 | */ if (recursive) { Tcl_Obj *cwdPtr = Tcl_FSGetCwd(NULL); if (cwdPtr != NULL) { const char *cwdStr, *normPathStr; | | | 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 | */ if (recursive) { Tcl_Obj *cwdPtr = Tcl_FSGetCwd(NULL); if (cwdPtr != NULL) { const char *cwdStr, *normPathStr; size_t cwdLen, normLen; Tcl_Obj *normPath = Tcl_FSGetNormalizedPath(NULL, pathPtr); if (normPath != NULL) { normPathStr = Tcl_GetStringFromObj(normPath, &normLen); cwdStr = Tcl_GetStringFromObj(cwdPtr, &cwdLen); if ((cwdLen >= normLen) && (strncmp(normPathStr, cwdStr, (size_t) normLen) == 0)) { |
︙ | ︙ | |||
4635 4636 4637 4638 4639 4640 4641 | if (fsPtr == NULL) { return NULL; } resPtr = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(NULL, resPtr, | | | 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 | if (fsPtr == NULL) { return NULL; } resPtr = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(NULL, resPtr, Tcl_NewStringObj(fsPtr->typeName, TCL_STRLEN)); if (fsPtr->filesystemPathTypeProc != NULL) { Tcl_Obj *typePtr = fsPtr->filesystemPathTypeProc(pathPtr); if (typePtr != NULL) { Tcl_ListObjAppendElement(NULL, resPtr, typePtr); } |
︙ | ︙ | |||
4722 4723 4724 4725 4726 4727 4728 | case TCL_PLATFORM_UNIX: separator = "/"; break; case TCL_PLATFORM_WINDOWS: separator = "\\"; break; } | | | 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 | case TCL_PLATFORM_UNIX: separator = "/"; break; case TCL_PLATFORM_WINDOWS: separator = "\\"; break; } return Tcl_NewStringObj(separator, 1); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclIndexObj.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | static int GetIndexFromObjList(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *tableObjPtr, const char *msg, int flags, int *indexPtr); static int SetIndexFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static void UpdateStringOfIndex(Tcl_Obj *objPtr); static void DupIndex(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr); static void FreeIndex(Tcl_Obj *objPtr); | | < < | < < | < < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | static int GetIndexFromObjList(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *tableObjPtr, const char *msg, int flags, int *indexPtr); static int SetIndexFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static void UpdateStringOfIndex(Tcl_Obj *objPtr); static void DupIndex(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr); static void FreeIndex(Tcl_Obj *objPtr); static Tcl_ObjCmdProc PrefixAllObjCmd; static Tcl_ObjCmdProc PrefixLongestObjCmd; static Tcl_ObjCmdProc PrefixMatchObjCmd; static void PrintUsage(Tcl_Interp *interp, const Tcl_ArgvInfo *argTable); /* * The structure below defines the index Tcl object type by means of functions * that can be invoked by generic object code. */ |
︙ | ︙ | |||
108 109 110 111 112 113 114 | Tcl_Obj *tableObjPtr, /* List of strings to compare against the * value of objPtr. */ const char *msg, /* Identifying word to use in error * messages. */ int flags, /* 0 or TCL_EXACT */ int *indexPtr) /* Place to store resulting integer index. */ { | | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | Tcl_Obj *tableObjPtr, /* List of strings to compare against the * value of objPtr. */ const char *msg, /* Identifying word to use in error * messages. */ int flags, /* 0 or TCL_EXACT */ int *indexPtr) /* Place to store resulting integer index. */ { size_t objc, t; int result; Tcl_Obj **objv; const char **tablePtr; /* * Use Tcl_GetIndexFromObjStruct to do the work to avoid duplicating most * of the code there. This is a bit ineffiecient but simpler. */ |
︙ | ︙ | |||
355 356 357 358 359 360 361 | SetIndexFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ register Tcl_Obj *objPtr) /* The object to convert. */ { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't convert value to index except via Tcl_GetIndexFromObj API", | | | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | SetIndexFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ register Tcl_Obj *objPtr) /* The object to convert. */ { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't convert value to index except via Tcl_GetIndexFromObj API", TCL_STRLEN)); } return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
504 505 506 507 508 509 510 | *---------------------------------------------------------------------- */ static int PrefixMatchObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | *---------------------------------------------------------------------- */ static int PrefixMatchObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int flags = 0, result, index; size_t dummyLength, i, errorLength; Tcl_Obj *errorPtr = NULL; const char *message = "option"; Tcl_Obj *tablePtr, *objPtr, *resultPtr; static const char *const matchOptions[] = { "-error", "-exact", "-message", NULL }; enum matchOptions { |
︙ | ︙ | |||
536 537 538 539 540 541 542 | switch ((enum matchOptions) index) { case PRFMATCH_EXACT: flags |= TCL_EXACT; break; case PRFMATCH_MESSAGE: if (i > objc-4) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | | 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 | switch ((enum matchOptions) index) { case PRFMATCH_EXACT: flags |= TCL_EXACT; break; case PRFMATCH_MESSAGE: if (i > objc-4) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing value for -message", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NOARG", NULL); return TCL_ERROR; } i++; message = Tcl_GetString(objv[i]); break; case PRFMATCH_ERROR: if (i > objc-4) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing value for -error", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NOARG", NULL); return TCL_ERROR; } i++; result = Tcl_ListObjLength(interp, objv[i], &errorLength); if (result != TCL_OK) { return TCL_ERROR; } if ((errorLength % 2) != 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "error options must have an even number of elements", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL); return TCL_ERROR; } errorPtr = objv[i]; break; } } |
︙ | ︙ | |||
628 629 630 631 632 633 634 | *---------------------------------------------------------------------- */ static int PrefixAllObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > < | 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | *---------------------------------------------------------------------- */ static int PrefixAllObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int result; const char *string, *elemString; Tcl_Obj **tableObjv, *resultPtr; size_t t, tableObjc, length, elemLength; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "table string"); return TCL_ERROR; } result = Tcl_ListObjGetElements(interp, objv[1], &tableObjc, &tableObjv); if (result != TCL_OK) { return result; } resultPtr = Tcl_NewListObj(0, NULL); string = Tcl_GetStringFromObj(objv[2], &length); |
︙ | ︙ | |||
685 686 687 688 689 690 691 | *---------------------------------------------------------------------- */ static int PrefixLongestObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 | *---------------------------------------------------------------------- */ static int PrefixLongestObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int result; const char *string, *elemString, *resultString; Tcl_Obj **tableObjv; size_t t, i, tableObjc, length, elemLength, resultLength; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "table string"); return TCL_ERROR; } result = Tcl_ListObjGetElements(interp, objv[1], &tableObjc, &tableObjv); |
︙ | ︙ | |||
803 804 805 806 807 808 809 | * *---------------------------------------------------------------------- */ void Tcl_WrongNumArgs( Tcl_Interp *interp, /* Current interpreter. */ | | | > | 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 | * *---------------------------------------------------------------------- */ void Tcl_WrongNumArgs( Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments to print from objv. */ Tcl_Obj *const objv[], /* Initial argument objects, which should be * included in the error message. */ const char *message) /* Error message to print after the leading * objects in objv. The message may be * NULL. */ { Tcl_Obj *objPtr; int i; char flags; Interp *iPtr = (Interp *) interp; const char *elementStr; size_t elemLen, len; /* * [incr Tcl] does something fairly horrific when generating error * messages for its ensembles; it passes the whole set of ensemble * arguments as a list in the first argument. This means that this code * causes a problem in iTcl if it attempts to correctly quote all * arguments, which would be the correct thing to do. We work around this |
︙ | ︙ | |||
843 844 845 846 847 848 849 | # define AFTER_FIRST_WORD (void) 0 #endif /* AVOID_HACKS_FOR_ITCL */ TclNewObj(objPtr); if (iPtr->flags & INTERP_ALTERNATE_WRONG_ARGS) { iPtr->flags &= ~INTERP_ALTERNATE_WRONG_ARGS; Tcl_AppendObjToObj(objPtr, Tcl_GetObjResult(interp)); | | | | 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 | # define AFTER_FIRST_WORD (void) 0 #endif /* AVOID_HACKS_FOR_ITCL */ TclNewObj(objPtr); if (iPtr->flags & INTERP_ALTERNATE_WRONG_ARGS) { iPtr->flags &= ~INTERP_ALTERNATE_WRONG_ARGS; Tcl_AppendObjToObj(objPtr, Tcl_GetObjResult(interp)); Tcl_AppendToObj(objPtr, " or \"", TCL_STRLEN); } else { Tcl_AppendToObj(objPtr, "wrong # args: should be \"", TCL_STRLEN); } /* * Check to see if we are processing an ensemble implementation, and if so * rewrite the results in terms of how the ensemble was invoked. */ |
︙ | ︙ | |||
1028 1029 1030 1031 1032 1033 1034 | */ int Tcl_ParseArgsObjv( Tcl_Interp *interp, /* Place to store error message. */ const Tcl_ArgvInfo *argTable, /* Array of option descriptions. */ | | | 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 | */ int Tcl_ParseArgsObjv( Tcl_Interp *interp, /* Place to store error message. */ const Tcl_ArgvInfo *argTable, /* Array of option descriptions. */ size_t *objcPtr, /* Number of arguments in objv. Modified to * hold # args left in objv at end. */ Tcl_Obj *const *objv, /* Array of arguments to be parsed. */ Tcl_Obj ***remObjv) /* Pointer to array of arguments that were not * processed here. Should be NULL if no return * of arguments is desired. */ { Tcl_Obj **leftovers; /* Array to write back to remObjv on |
︙ | ︙ | |||
1055 1056 1057 1058 1059 1060 1061 | * because first char. will almost always be * '-'). */ int srcIndex; /* Location from which to read next argument * from objv. */ int dstIndex; /* Used to keep track of current arguments * being processed, primarily for error * reporting. */ | | | | 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 | * because first char. will almost always be * '-'). */ int srcIndex; /* Location from which to read next argument * from objv. */ int dstIndex; /* Used to keep track of current arguments * being processed, primarily for error * reporting. */ size_t objc; /* # arguments in objv still to process. */ size_t length; /* Number of characters in current argument */ if (remObjv != NULL) { /* * Then we should copy the name of the command (0th argument). The * upper bound on the number of elements is known, and (undocumented, * but historically true) there should be a NULL argument after the * last result. [Bug 3413857] |
︙ | ︙ | |||
1323 1324 1325 1326 1327 1328 1329 | } } /* * Now add the option information, with pretty-printing. */ | | | | 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 | } } /* * Now add the option information, with pretty-printing. */ msg = Tcl_NewStringObj("Command-specific options:", TCL_STRLEN); for (infoPtr = argTable; infoPtr->type != TCL_ARGV_END; infoPtr++) { if ((infoPtr->type == TCL_ARGV_HELP) && (infoPtr->keyStr == NULL)) { Tcl_AppendPrintfToObj(msg, "\n%s", infoPtr->helpStr); continue; } Tcl_AppendPrintfToObj(msg, "\n %s:", infoPtr->keyStr); numSpaces = width + 1 - strlen(infoPtr->keyStr); while (numSpaces > 0) { if (numSpaces >= NUM_SPACES) { Tcl_AppendToObj(msg, spaces, NUM_SPACES); } else { Tcl_AppendToObj(msg, spaces, numSpaces); } numSpaces -= NUM_SPACES; } Tcl_AppendToObj(msg, infoPtr->helpStr, TCL_STRLEN); switch (infoPtr->type) { case TCL_ARGV_INT: Tcl_AppendPrintfToObj(msg, "\n\t\tDefault value: %d", *((int *) infoPtr->dstPtr)); break; case TCL_ARGV_FLOAT: Tcl_AppendPrintfToObj(msg, "\n\t\tDefault value: %g", |
︙ | ︙ |
Changes to generic/tclInt.decls.
︙ | ︙ | |||
38 39 40 41 42 43 44 | void TclAllocateFreeObjects(void) } # Replaced by TclpChdir in 8.1: # declare 4 { # int TclChdir(Tcl_Interp *interp, char *dirName) # } declare 5 { | | | | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | void TclAllocateFreeObjects(void) } # Replaced by TclpChdir in 8.1: # declare 4 { # int TclChdir(Tcl_Interp *interp, char *dirName) # } declare 5 { int TclCleanupChildren(Tcl_Interp *interp, int numPids, Tcl_Pid *pidPtr, Tcl_Channel errorChan) } declare 6 { void TclCleanupCommand(Command *cmdPtr) } declare 7 { size_t TclCopyAndCollapse(size_t count, const char *src, char *dst) } # Removed in Tcl 9 #declare 8 { # int TclCopyChannelOld(Tcl_Interp *interp, Tcl_Channel inChan, # Tcl_Channel outChan, int toRead, Tcl_Obj *cmdPtr) #} # TclCreatePipeline unofficially exported for use by BLT. declare 9 { int TclCreatePipeline(Tcl_Interp *interp, size_t argc, const char **argv, Tcl_Pid **pidArrayPtr, TclFile *inPipePtr, TclFile *outPipePtr, TclFile *errFilePtr) } declare 10 { int TclCreateProc(Tcl_Interp *interp, Namespace *nsPtr, const char *procName, Tcl_Obj *argsPtr, Tcl_Obj *bodyPtr, Proc **procPtrPtr) |
︙ | ︙ | |||
104 105 106 107 108 109 110 | # int TclFileMakeDirsCmd(Tcl_Interp *interp, int argc, char **argv) #} #declare 21 { # int TclFileRenameCmd(Tcl_Interp *interp, int argc, char **argv) #} declare 22 { int TclFindElement(Tcl_Interp *interp, const char *listStr, | | | | | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | # int TclFileMakeDirsCmd(Tcl_Interp *interp, int argc, char **argv) #} #declare 21 { # int TclFileRenameCmd(Tcl_Interp *interp, int argc, char **argv) #} declare 22 { int TclFindElement(Tcl_Interp *interp, const char *listStr, size_t listLength, const char **elementPtr, const char **nextPtr, size_t *sizePtr, int *bracePtr) } declare 23 { Proc *TclFindProc(Interp *iPtr, const char *procName) } # Replaced with macro (see tclInt.h) in Tcl 8.5.0, restored in 8.5.10 declare 24 { size_t TclFormatInt(char *buffer, long n) } declare 25 { void TclFreePackageInfo(Interp *iPtr) } # Removed in 8.1: # declare 26 { # char *TclGetCwd(Tcl_Interp *interp) |
︙ | ︙ | |||
151 152 153 154 155 156 157 | } # Removed in Tcl 8.5 #declare 33 { # TclCmdProcType TclGetInterpProc(void) #} declare 34 { int TclGetIntForIndex(Tcl_Interp *interp, Tcl_Obj *objPtr, | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | } # Removed in Tcl 8.5 #declare 33 { # TclCmdProcType TclGetInterpProc(void) #} declare 34 { int TclGetIntForIndex(Tcl_Interp *interp, Tcl_Obj *objPtr, ssize_t endValue, ssize_t *indexPtr) } # Removed in 8.4b2: #declare 35 { # Tcl_Obj *TclGetIndexedScalar(Tcl_Interp *interp, int localIndex, # int flags) #} # Removed in 8.6a2 |
︙ | ︙ | |||
225 226 227 228 229 230 231 | # Removed in Tcl 8.5a2 #declare 52 { # int TclInvoke(Tcl_Interp *interp, int argc, const char **argv, # int flags) #} declare 53 { int TclInvokeObjectCommand(ClientData clientData, Tcl_Interp *interp, | | | | 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | # Removed in Tcl 8.5a2 #declare 52 { # int TclInvoke(Tcl_Interp *interp, int argc, const char **argv, # int flags) #} declare 53 { int TclInvokeObjectCommand(ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv) } declare 54 { int TclInvokeStringCommand(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) } declare 55 { Proc *TclIsProc(Command *cmdPtr) } # Replaced with TclpLoadFile in 8.1: # declare 56 { # int TclLoadFile(Tcl_Interp *interp, char *fileName, char *sym1, |
︙ | ︙ | |||
265 266 267 268 269 270 271 | Tcl_Obj *TclNewProcBodyObj(Proc *procPtr) } declare 62 { int TclObjCommandComplete(Tcl_Obj *cmdPtr) } declare 63 { int TclObjInterpProc(ClientData clientData, Tcl_Interp *interp, | | | | | 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 293 294 295 296 297 298 299 300 301 | Tcl_Obj *TclNewProcBodyObj(Proc *procPtr) } declare 62 { int TclObjCommandComplete(Tcl_Obj *cmdPtr) } declare 63 { int TclObjInterpProc(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) } declare 64 { int TclObjInvoke(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags) } # Removed in Tcl 8.5a2 #declare 65 { # int TclObjInvokeGlobal(Tcl_Interp *interp, int objc, # Tcl_Obj *const objv[], int flags) #} #declare 66 { # int TclOpenFileChannelDeleteProc(TclOpenFileChannelProc_ *proc) #} #declare 67 { # int TclOpenFileChannelInsertProc(TclOpenFileChannelProc_ *proc) #} # Replaced by Tcl_FSAccess in 8.4: #declare 68 { # int TclpAccess(const char *path, int mode) #} declare 69 { char *TclpAlloc(size_t size) } #declare 70 { # int TclpCopyFile(const char *source, const char *dest) #} #declare 71 { # int TclpCopyDirectory(const char *source, const char *dest, # Tcl_DString *errorPtr) |
︙ | ︙ | |||
330 331 332 333 334 335 336 | #} # Replaced by Tcl_FSOpenFileChannel in 8.4: #declare 80 { # Tcl_Channel TclpOpenFileChannel(Tcl_Interp *interp, char *fileName, # char *modeString, int permissions) #} declare 81 { | | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | #} # Replaced by Tcl_FSOpenFileChannel in 8.4: #declare 80 { # Tcl_Channel TclpOpenFileChannel(Tcl_Interp *interp, char *fileName, # char *modeString, int permissions) #} declare 81 { char *TclpRealloc(char *ptr, size_t size) } #declare 82 { # int TclpRemoveDirectory(const char *path, int recursive, # Tcl_DString *errorPtr) #} #declare 83 { # int TclpRenameFile(const char *source, const char *dest) |
︙ | ︙ | |||
685 686 687 688 689 690 691 | declare 165 { void TclpSetInitialEncodings(void) } # New function due to TIP #33 declare 166 { int TclListObjSetElement(Tcl_Interp *interp, Tcl_Obj *listPtr, | | | | | | | | | 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 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 | declare 165 { void TclpSetInitialEncodings(void) } # New function due to TIP #33 declare 166 { int TclListObjSetElement(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t index, Tcl_Obj *valuePtr) } # VFS-aware versions of Tcl*StartupScriptFileName (158 and 159 above) # REMOVED - use public Tcl_SetStartupScript() #declare 167 { # void TclSetStartupScriptPath(Tcl_Obj *pathPtr) #} # REMOVED - use public Tcl_GetStartupScript() #declare 168 { # Tcl_Obj *TclGetStartupScriptPath(void) #} # variant of Tcl_UtfNCmp that takes n as bytes, not chars declare 169 { int TclpUtfNcmp2(const char *s1, const char *s2, size_t n) } declare 170 { int TclCheckInterpTraces(Tcl_Interp *interp, const char *command, size_t numChars, Command *cmdPtr, int result, int traceFlags, size_t objc, Tcl_Obj *const objv[]) } declare 171 { int TclCheckExecutionTraces(Tcl_Interp *interp, const char *command, size_t numChars, Command *cmdPtr, int result, int traceFlags, size_t objc, Tcl_Obj *const objv[]) } declare 172 { int TclInThreadExit(void) } # added for 8.4.2 declare 173 { int TclUniCharMatch(const Tcl_UniChar *string, size_t strLen, const Tcl_UniChar *pattern, size_t ptnLen, int flags) } # added for 8.4.3 #declare 174 { # Tcl_Obj *TclIncrWideVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, # Tcl_Obj *part2Ptr, Tcl_WideInt wideIncrAmount, int part1NotParsed) |
︙ | ︙ | |||
882 883 884 885 886 887 888 | declare 213 { Tcl_Obj *TclGetObjNameOfExecutable(void) } declare 214 { void TclSetObjNameOfExecutable(Tcl_Obj *name, Tcl_Encoding encoding) } declare 215 { | | | | | 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 | declare 213 { Tcl_Obj *TclGetObjNameOfExecutable(void) } declare 214 { void TclSetObjNameOfExecutable(Tcl_Obj *name, Tcl_Encoding encoding) } declare 215 { void *TclStackAlloc(Tcl_Interp *interp, size_t numBytes) } declare 216 { void TclStackFree(Tcl_Interp *interp, void *freePtr) } declare 217 { int TclPushStackFrame(Tcl_Interp *interp, Tcl_CallFrame **framePtrPtr, Tcl_Namespace *namespacePtr, int isProcCallFrame) } declare 218 { void TclPopStackFrame(Tcl_Interp *interp) } # for use in tclTest.c declare 224 { TclPlatformType *TclGetPlatform(void) } # declare 225 { Tcl_Obj *TclTraceDictPath(Tcl_Interp *interp, Tcl_Obj *rootPtr, size_t keyc, Tcl_Obj *const keyv[], int flags) } declare 226 { int TclObjBeingDeleted(Tcl_Obj *objPtr) } declare 227 { void TclSetNsPath(Namespace *nsPtr, size_t pathLength, Tcl_Namespace *pathAry[]) } # Used to be needed for TclOO-extension; unneeded now that TclOO is in the # core and NRE-enabled # declare 228 { # int TclObjInterpProcCore(register Tcl_Interp *interp, Tcl_Obj *procNameObj, # int skip, ProcErrorProc *errorProc) |
︙ | ︙ | |||
965 966 967 968 969 970 971 | int TclResetCancellation(Tcl_Interp *interp, int force) } # NRE functions for "rogue" extensions to exploit NRE; they will need to # include NRE.h too. declare 238 { int TclNRInterpProc(ClientData clientData, Tcl_Interp *interp, | | | | | | | 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 990 991 992 993 994 995 | int TclResetCancellation(Tcl_Interp *interp, int force) } # NRE functions for "rogue" extensions to exploit NRE; they will need to # include NRE.h too. declare 238 { int TclNRInterpProc(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) } declare 239 { int TclNRInterpProcCore(Tcl_Interp *interp, Tcl_Obj *procNameObj, int skip, ProcErrorProc *errorProc) } declare 240 { int TclNRRunCallbacks(Tcl_Interp *interp, int result, struct NRE_callback *rootPtr) } declare 241 { int TclNREvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags, const CmdFrame *invoker, int word) } declare 242 { int TclNREvalObjv(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags, Command *cmdPtr) } # Tcl_Obj leak detection support. declare 243 { void TclDbDumpActiveObjects(FILE *outFile) } |
︙ | ︙ | |||
1011 1012 1013 1014 1015 1016 1017 | declare 248 { int TclCopyChannel(Tcl_Interp *interp, Tcl_Channel inChan, Tcl_Channel outChan, Tcl_WideInt toRead, Tcl_Obj *cmdPtr) } declare 249 { char *TclDoubleDigits(double dv, int ndigits, int flags, | | | 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 | declare 248 { int TclCopyChannel(Tcl_Interp *interp, Tcl_Channel inChan, Tcl_Channel outChan, Tcl_WideInt toRead, Tcl_Obj *cmdPtr) } declare 249 { char *TclDoubleDigits(double dv, int ndigits, int flags, int *decpt, int *signum, char **endPtr) } # TIP #285: Script cancellation support. declare 250 { void TclSetSlaveCancelFlags(Tcl_Interp *interp, int flags, int force) } ############################################################################## |
︙ | ︙ | |||
1041 1042 1043 1044 1045 1046 1047 | #} declare 2 win { struct servent *TclWinGetServByName(const char *nm, const char *proto) } declare 3 win { int TclWinGetSockOpt(SOCKET s, int level, int optname, | | | | 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 | #} declare 2 win { struct servent *TclWinGetServByName(const char *nm, const char *proto) } declare 3 win { int TclWinGetSockOpt(SOCKET s, int level, int optname, char *optval, size_t *optlen) } declare 4 win { HINSTANCE TclWinGetTclInstance(void) } # new for 8.4.20+/8.5.12+ Cygwin only declare 5 win { int TclUnixWaitForFile(int fd, int mask, int timeout) } # Removed in 8.1: # declare 5 win { # HINSTANCE TclWinLoadLibrary(char *name) # } # Removed in 8.1: #declare 6 win { # unsigned short TclWinNToHS(unsigned short ns) #} declare 7 win { int TclWinSetSockOpt(SOCKET s, int level, int optname, const char *optval, size_t optlen) } declare 8 win { int TclpGetPid(Tcl_Pid pid) } declare 9 win { int TclWinGetPlatformId(void) } |
︙ | ︙ | |||
1093 1094 1095 1096 1097 1098 1099 | Tcl_Channel TclpCreateCommandChannel(TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr) } declare 14 win { int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe) } declare 15 win { | | | 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 | Tcl_Channel TclpCreateCommandChannel(TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr) } declare 14 win { int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe) } declare 15 win { int TclpCreateProcess(Tcl_Interp *interp, size_t argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr) } # new for 8.4.20+/8.5.12+ Cygwin only declare 16 win { int TclpIsAtty(int fd) } |
︙ | ︙ | |||
1181 1182 1183 1184 1185 1186 1187 | Tcl_Channel TclpCreateCommandChannel(TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr) } declare 3 unix { int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe) } declare 4 unix { | | | 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 | Tcl_Channel TclpCreateCommandChannel(TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr) } declare 3 unix { int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe) } declare 4 unix { int TclpCreateProcess(Tcl_Interp *interp, size_t argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr) } # Signature changed in 8.1: # declare 5 unix { # TclFile TclpCreateTempFile(char *contents, Tcl_DString *namePtr) # } |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
142 143 144 145 146 147 148 | typedef struct Tcl_ResolvedVarInfo { Tcl_ResolveRuntimeVarProc *fetchProc; Tcl_ResolveVarDeleteProc *deleteProc; } Tcl_ResolvedVarInfo; typedef int (Tcl_ResolveCompiledVarProc)(Tcl_Interp *interp, | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | typedef struct Tcl_ResolvedVarInfo { Tcl_ResolveRuntimeVarProc *fetchProc; Tcl_ResolveVarDeleteProc *deleteProc; } Tcl_ResolvedVarInfo; typedef int (Tcl_ResolveCompiledVarProc)(Tcl_Interp *interp, const char *name, size_t length, Tcl_Namespace *context, Tcl_ResolvedVarInfo **rPtr); typedef int (Tcl_ResolveVarProc)(Tcl_Interp *interp, const char *name, Tcl_Namespace *context, int flags, Tcl_Var *rPtr); typedef int (Tcl_ResolveCmdProc)(Tcl_Interp *interp, const char *name, Tcl_Namespace *context, int flags, Tcl_Command *rPtr); |
︙ | ︙ | |||
309 310 311 312 313 314 315 | * validated efficiently. */ Tcl_Ensemble *ensembles; /* List of structures that contain the details * of the ensembles that are implemented on * top of this namespace. */ Tcl_Obj *unknownHandlerPtr; /* A script fragment to be used when command * resolution in this namespace fails. TIP * 181. */ | | | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | * validated efficiently. */ Tcl_Ensemble *ensembles; /* List of structures that contain the details * of the ensembles that are implemented on * top of this namespace. */ Tcl_Obj *unknownHandlerPtr; /* A script fragment to be used when command * resolution in this namespace fails. TIP * 181. */ size_t commandPathLength; /* The length of the explicit path. */ NamespacePathEntry *commandPathArray; /* The explicit path of the namespace as an * array. */ NamespacePathEntry *commandPathSourceList; /* Linked list of path entries that point to * this namespace. */ Tcl_NamespaceDeleteProc *earlyDeleteProc; |
︙ | ︙ | |||
477 478 479 480 481 482 483 | * results passed directly back to the caller * (including the error code) unless the code * is TCL_CONTINUE in which case the * subcommand will be reparsed by the ensemble * core, presumably because the ensemble * itself has been updated. */ Tcl_Obj *parameterList; /* List of ensemble parameter names. */ | | | 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | * results passed directly back to the caller * (including the error code) unless the code * is TCL_CONTINUE in which case the * subcommand will be reparsed by the ensemble * core, presumably because the ensemble * itself has been updated. */ Tcl_Obj *parameterList; /* List of ensemble parameter names. */ size_t 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. |
︙ | ︙ | |||
903 904 905 906 907 908 909 | */ typedef struct CompiledLocal { struct CompiledLocal *nextPtr; /* Next compiler-recognized local variable for * this procedure, or NULL if this is the last * local. */ | | | | 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 | */ typedef struct CompiledLocal { struct CompiledLocal *nextPtr; /* Next compiler-recognized local variable for * this procedure, or NULL if this is the last * local. */ size_t nameLength; /* The number of characters in local * variable's name. Used to speed up variable * lookups. */ size_t frameIndex; /* Index in the array of compiler-assigned * variables in the procedure call frame. */ int flags; /* Flag bits for the local variable. Same as * the flags for the Var structure above, * although only VAR_ARGUMENT, VAR_TEMPORARY, * and VAR_RESOLVED make sense. */ Tcl_Obj *defValuePtr; /* Pointer to the default value of an * argument, if any. NULL if not an argument |
︙ | ︙ | |||
949 950 951 952 953 954 955 | * becomes zero. */ struct Command *cmdPtr; /* Points to the Command structure for this * procedure. This is used to get the * namespace in which to execute the * procedure. */ Tcl_Obj *bodyPtr; /* Points to the ByteCode object for * procedure's body command. */ | | | | 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 | * becomes zero. */ struct Command *cmdPtr; /* Points to the Command structure for this * procedure. This is used to get the * namespace in which to execute the * procedure. */ Tcl_Obj *bodyPtr; /* Points to the ByteCode object for * procedure's body command. */ size_t numArgs; /* Number of formal parameters. */ size_t numCompiledLocals; /* Count of local variables recognized by the * compiler including arguments and * temporaries. */ CompiledLocal *firstLocalPtr; /* Pointer to first of the procedure's * compiler-allocated local variables, or NULL * if none. The first numArgs entries in this * list describe the procedure's formal |
︙ | ︙ | |||
1056 1057 1058 1059 1060 1061 1062 | /* * Will be grown to contain: pointers to the varnames (allocated at the end), * plus the init values for each variable (suitable to be memcopied on init) */ typedef struct LocalCache { int refCount; | | | | 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 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 | /* * Will be grown to contain: pointers to the varnames (allocated at the end), * plus the init values for each variable (suitable to be memcopied on init) */ typedef struct LocalCache { int refCount; size_t numVars; Tcl_Obj *varName0; } LocalCache; #define localName(framePtr, i) \ ((&((framePtr)->localCachePtr->varName0))[(i)]) MODULE_SCOPE void TclFreeLocalCache(Tcl_Interp *interp, LocalCache *localCachePtr); typedef struct CallFrame { Namespace *nsPtr; /* Points to the namespace used to resolve * commands and global variables. */ 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. */ size_t 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; |
︙ | ︙ | |||
1104 1105 1106 1107 1108 1109 1110 | * (local variables assigned entries ["slots"] * in the compiledLocals array below). */ TclVarHashTable *varTablePtr; /* Hash table containing local variables not * recognized by the compiler, or created at * execution time through, e.g., upvar. * Initially NULL and created if needed. */ | | | 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 | * (local variables assigned entries ["slots"] * in the compiledLocals array below). */ TclVarHashTable *varTablePtr; /* Hash table containing local variables not * recognized by the compiler, or created at * execution time through, e.g., upvar. * Initially NULL and created if needed. */ size_t numCompiledLocals; /* Count of local variables recognized by the * compiler including arguments. */ Var *compiledLocals; /* Points to the array of local variables * recognized by the compiler. The compiler * emits code that refers to these variables * using an index into this array. */ ClientData clientData; /* Pointer to some context that is used by * object systems. The meaning of the contents |
︙ | ︙ | |||
1206 1207 1208 1209 1210 1211 1212 | 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... */ | | | | 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 | 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... */ size_t 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. */ size_t word; /* Index of the word in the command. */ int refCount; /* Number of times the word is on the * stack. */ } CFWord; typedef struct CFWordBC { CmdFrame *framePtr; /* CmdFrame to access. */ int pc; /* Instruction pointer of a command in |
︙ | ︙ | |||
1256 1257 1258 1259 1260 1261 1262 | */ #define CLL_END (-1) typedef struct ContLineLoc { int num; /* Number of entries in loc, not counting the * final -1 marker entry. */ | | | 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 | */ #define CLL_END (-1) typedef struct ContLineLoc { int num; /* Number of entries in loc, not counting the * final -1 marker entry. */ ssize_t loc[1]; /* 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. */ } ContLineLoc; |
︙ | ︙ | |||
1297 1298 1299 1300 1301 1302 1303 | * 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)(ClientData clientData); typedef struct { const char *name; /* Name of this field. */ | | > | | 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 | * 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)(ClientData 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. */ ClientData clientData; /* Context for above function, or Tcl_Obj* if * proc field is NULL. */ } ExtraFrameInfoField; typedef struct { size_t length; /* Length of array. */ ExtraFrameInfoField fields[2]; /* Really as long as necessary, but this is * long enough for nearly anything. */ } ExtraFrameInfo; /* *---------------------------------------------------------------- |
︙ | ︙ | |||
1439 1440 1441 1442 1443 1444 1445 | CorContext running; Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ void *stackLevel; int 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. */ | | | 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 | CorContext running; Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ void *stackLevel; int 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. */ ssize_t nargs; /* Number of args required for resuming this * coroutine; -2 means "0 or 1" (default), -1 * means "any" */ } CoroutineData; typedef struct ExecEnv { ExecStack *execStackPtr; /* Points to the first item in the evaluation * stack on the heap. */ |
︙ | ︙ | |||
1498 1499 1500 1501 1502 1503 1504 | 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. */ | | | | | 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 | 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. */ size_t numBuckets; /* Total number of buckets allocated at * **buckets. */ size_t numEntries; /* Total number of entries present in * table. */ size_t rebuildSize; /* Enlarge table when numEntries gets to be * this large. */ int 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 |
︙ | ︙ | |||
1744 1745 1746 1747 1748 1749 1750 | *---------------------------------------------------------------- */ typedef struct AllocCache { struct Cache *nextPtr; /* Linked list of cache entries. */ Tcl_ThreadId owner; /* Which thread's cache is this? */ Tcl_Obj *firstObjPtr; /* List of free objects for thread. */ | | | 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 | *---------------------------------------------------------------- */ typedef struct AllocCache { struct Cache *nextPtr; /* Linked list of cache entries. */ Tcl_ThreadId owner; /* Which thread's cache is this? */ Tcl_Obj *firstObjPtr; /* List of free objects for thread. */ size_t numObjects; /* Number of objects for thread. */ } AllocCache; /* *---------------------------------------------------------------- * This structure defines an interpreter, which is a collection of commands * plus other state information related to interpreting commands, such as * variable storage. Primary responsibility for this data structure is in |
︙ | ︙ | |||
2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 | * structs for this interp's thread; see * tclObj.c and tclThreadAlloc.c */ int *asyncReadyPtr; /* Pointer to the asyncReady indicator for * this interp's thread; see tclAsync.c */ /* * The pointer to the object system root ekeko. c.f. TIP #257. */ void *objectFoundation; /* Pointer to the Foundation structure of the * object system, which contains things like * references to key namespaces. See * tclOOInt.h and tclOO.c for real definition * and setup. */ struct NRE_callback *deferredCallbacks; | > | 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 | * structs for this interp's thread; see * tclObj.c and tclThreadAlloc.c */ int *asyncReadyPtr; /* Pointer to the asyncReady indicator for * this interp's thread; see tclAsync.c */ /* * The pointer to the object system root ekeko. c.f. TIP #257. */ void *objectFoundation; /* Pointer to the Foundation structure of the * object system, which contains things like * references to key namespaces. See * tclOOInt.h and tclOO.c for real definition * and setup. */ struct NRE_callback *deferredCallbacks; |
︙ | ︙ | |||
2088 2089 2090 2091 2092 2093 2094 | 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. */ | | | | > | 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 | 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 */ |
︙ | ︙ | |||
2326 2327 2328 2329 2330 2331 2332 | * list's element pointers. The struct might contain more slots than currently * used to hold all element pointers. This is done to make append operations * faster. */ typedef struct List { int refCount; | | | | 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 | * list's element pointers. The struct might contain more slots than currently * used to hold all element pointers. This is done to make append operations * faster. */ typedef struct List { int refCount; size_t maxElemCount; /* Total number of element array slots. */ size_t elemCount; /* Current number of list elements. */ int canonicalFlag; /* Set if the string representation was * derived from the list representation. May * be ignored if there is no string rep at * all.*/ Tcl_Obj *elements; /* First list element; the struct is grown to * accomodate all elements. */ } List; |
︙ | ︙ | |||
2516 2517 2518 2519 2520 2521 2522 | /* *---------------------------------------------------------------- * Data structures for process-global values. *---------------------------------------------------------------- */ | | | | | 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 | /* *---------------------------------------------------------------- * Data structures for process-global values. *---------------------------------------------------------------- */ typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, size_t *lengthPtr, Tcl_Encoding *encodingPtr); /* * A ProcessGlobalValue struct exists for each internal value in Tcl that is * to be shared among several threads. Each thread sees a (Tcl_Obj) copy of * the value, and the master 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 { int epoch; /* Epoch counter to detect changes in the * master value. */ size_t numBytes; /* Length of the master string. */ char *value; /* The master string value. */ Tcl_Encoding encoding; /* system encoding when master string was * initialized. */ TclInitProcessGlobalValueProc *proc; /* A procedure to initialize the master string * copy when a "get" request comes in before * any "set" request has been received. */ |
︙ | ︙ | |||
2764 2765 2766 2767 2768 2769 2770 | /* *---------------------------------------------------------------- * Procedures shared among Tcl modules but not used by the outside world: *---------------------------------------------------------------- */ MODULE_SCOPE void TclAppendBytesToByteArray(Tcl_Obj *objPtr, | | | | | | | | | | | | | | 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 2824 | /* *---------------------------------------------------------------- * Procedures shared among Tcl modules but not used by the outside world: *---------------------------------------------------------------- */ MODULE_SCOPE void TclAppendBytesToByteArray(Tcl_Obj *objPtr, const unsigned char *bytes, size_t len); MODULE_SCOPE int TclNREvalCmd(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); MODULE_SCOPE void TclAdvanceContinuations(int *line, ssize_t **next, int loc); MODULE_SCOPE void TclAdvanceLines(int *line, const char *start, const char *end); MODULE_SCOPE void TclArgumentEnter(Tcl_Interp *interp, Tcl_Obj *objv[], size_t objc, CmdFrame *cf); MODULE_SCOPE void TclArgumentRelease(Tcl_Interp *interp, Tcl_Obj *objv[], size_t objc); MODULE_SCOPE void TclArgumentBCEnter(Tcl_Interp *interp, Tcl_Obj *objv[], size_t objc, void *codePtr, CmdFrame *cfPtr, int cmd, int pc); MODULE_SCOPE void TclArgumentBCRelease(Tcl_Interp *interp, CmdFrame *cfPtr); MODULE_SCOPE void TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj, CmdFrame **cfPtrPtr, int *wordPtr); MODULE_SCOPE int TclArraySet(Tcl_Interp *interp, Tcl_Obj *arrayNameObj, Tcl_Obj *arrayElemObj); MODULE_SCOPE double TclBignumToDouble(const mp_int *bignum); MODULE_SCOPE int TclByteArrayMatch(const unsigned char *string, size_t strLen, const unsigned char *pattern, size_t ptnLen, int flags); MODULE_SCOPE double TclCeil(const mp_int *a); MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp, Tcl_Channel chan); MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd; MODULE_SCOPE int TclClearRootEnsemble(ClientData data[], Tcl_Interp *interp, int result); MODULE_SCOPE ContLineLoc *TclContinuationsEnter(Tcl_Obj *objPtr, int num, ssize_t *loc); MODULE_SCOPE void TclContinuationsEnterDerived(Tcl_Obj *objPtr, size_t start, ssize_t *clNext); MODULE_SCOPE ContLineLoc *TclContinuationsGet(Tcl_Obj *objPtr); MODULE_SCOPE void TclContinuationsCopy(Tcl_Obj *objPtr, Tcl_Obj *originObjPtr); MODULE_SCOPE size_t TclConvertElement(const char *src, size_t length, char *dst, char flags); MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); /* TIP #280 - Modified token based evulation, with line information. */ MODULE_SCOPE int TclEvalEx(Tcl_Interp *interp, const char *script, size_t numBytes, int flags, int line, ssize_t *clNextOuter, const char *outerScript); MODULE_SCOPE Tcl_ObjCmdProc TclFileAttrsCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileCopyCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileDeleteCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileLinkCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileMakeDirsCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileReadLinkCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileRenameCmd; |
︙ | ︙ | |||
2857 2858 2859 2860 2861 2862 2863 | const char *encodingName); MODULE_SCOPE void TclFSUnloadTempFile(Tcl_LoadHandle loadHandle); MODULE_SCOPE int * TclGetAsyncReadyPtr(void); MODULE_SCOPE Tcl_Obj * TclGetBgErrorHandler(Tcl_Interp *interp); MODULE_SCOPE int TclGetChannelFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Channel *chanPtr, int *modePtr, int flags); | | | | | | | | | | | | > | | | | | | | | | > | | > | | | | | > | | 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 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 | const char *encodingName); MODULE_SCOPE void TclFSUnloadTempFile(Tcl_LoadHandle loadHandle); MODULE_SCOPE int * TclGetAsyncReadyPtr(void); MODULE_SCOPE Tcl_Obj * TclGetBgErrorHandler(Tcl_Interp *interp); MODULE_SCOPE int TclGetChannelFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Channel *chanPtr, int *modePtr, int flags); MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, Tcl_Obj *value, int *code); MODULE_SCOPE int TclGetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, ClientData *clientDataPtr, int *typePtr); MODULE_SCOPE int TclGetOpenModeEx(Tcl_Interp *interp, const char *modeString, int *seekFlagPtr, int *binaryPtr); MODULE_SCOPE Tcl_Obj * TclGetProcessGlobalValue(ProcessGlobalValue *pgvPtr); MODULE_SCOPE Tcl_Obj * TclGetSourceFromFrame(CmdFrame *cfPtr, size_t objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TclIncrObj(Tcl_Interp *interp, Tcl_Obj *valuePtr, Tcl_Obj *incrPtr); MODULE_SCOPE Tcl_Obj * TclIncrObjVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, int flags); MODULE_SCOPE int TclInfoExistsCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TclInfoCoroutineCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); MODULE_SCOPE Tcl_Obj * TclInfoFrame(Tcl_Interp *interp, CmdFrame *framePtr); MODULE_SCOPE int TclInfoGlobalsCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TclInfoLocalsCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TclInfoVarsCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); MODULE_SCOPE void TclInitAlloc(void); MODULE_SCOPE void TclInitDbCkalloc(void); MODULE_SCOPE void TclInitDoubleConversion(void); MODULE_SCOPE void TclInitEmbeddedConfigurationInformation( Tcl_Interp *interp); MODULE_SCOPE void TclInitEncodingSubsystem(void); MODULE_SCOPE void TclInitIOSubsystem(void); MODULE_SCOPE void TclInitLimitSupport(Tcl_Interp *interp); MODULE_SCOPE void TclInitNamespaceSubsystem(void); MODULE_SCOPE void TclInitNotifier(void); MODULE_SCOPE void TclInitObjSubsystem(void); MODULE_SCOPE void TclInitSubsystems(void); MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); MODULE_SCOPE int TclIsLocalScalar(const char *src, size_t len); MODULE_SCOPE int TclIsSpaceProc(char byte); MODULE_SCOPE Tcl_Obj * TclJoinPath(size_t elements, Tcl_Obj *const objv[]); MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result); MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp); MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *argPtr); MODULE_SCOPE Tcl_Obj * TclLindexFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t indexCount, Tcl_Obj *const indexArray[]); /* TIP #280 */ MODULE_SCOPE void TclListLines(Tcl_Obj *listObj, int line, size_t numLines, int *lines, Tcl_Obj *const *elems); MODULE_SCOPE Tcl_Obj * TclListObjCopy(Tcl_Interp *interp, Tcl_Obj *listPtr); MODULE_SCOPE Tcl_Obj * TclLsetList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *indexPtr, Tcl_Obj *valuePtr); MODULE_SCOPE Tcl_Obj * TclLsetFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t indexCount, Tcl_Obj *const indexArray[], Tcl_Obj *valuePtr); MODULE_SCOPE Tcl_Command TclMakeEnsemble(Tcl_Interp *interp, const char *name, const EnsembleImplMap map[]); MODULE_SCOPE size_t TclMaxListLength(const char *bytes, size_t numBytes, const char **endPtr); MODULE_SCOPE int TclMergeReturnOptions(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], Tcl_Obj **optionsPtrPtr, int *codePtr, int *levelPtr); MODULE_SCOPE Tcl_Obj * TclNoErrorStack(Tcl_Interp *interp, Tcl_Obj *options); MODULE_SCOPE int TclNokia770Doubles(void); MODULE_SCOPE void TclNsDecrRefCount(Namespace *nsPtr); MODULE_SCOPE void TclObjVarErrMsg(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const char *operation, const char *reason, int index); MODULE_SCOPE int TclObjInvokeNamespace(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], Tcl_Namespace *nsPtr, int flags); MODULE_SCOPE int TclObjUnsetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags); MODULE_SCOPE size_t TclParseBackslash(const char *src, size_t numBytes, size_t *readPtr, char *dst); MODULE_SCOPE size_t TclParseHex(const char *src, size_t numBytes, int *resultPtr); MODULE_SCOPE int TclParseNumber(Tcl_Interp *interp, Tcl_Obj *objPtr, const char *expected, const char *bytes, size_t numBytes, const char **endPtrPtr, int flags); MODULE_SCOPE void TclParseInit(Tcl_Interp *interp, const char *string, size_t numBytes, Tcl_Parse *parsePtr); MODULE_SCOPE size_t TclParseAllWhiteSpace(const char *src, size_t numBytes); MODULE_SCOPE int TclProcessReturn(Tcl_Interp *interp, int code, int level, Tcl_Obj *returnOpts); MODULE_SCOPE int TclpObjLstat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); MODULE_SCOPE Tcl_Obj * TclpTempFileName(void); MODULE_SCOPE Tcl_Obj * TclpTempFileNameForLibrary(Tcl_Interp *interp, Tcl_Obj* pathPtr); MODULE_SCOPE Tcl_Obj * TclNewFSPathObj(Tcl_Obj *dirPtr, const char *addStrRep, size_t len); MODULE_SCOPE int TclpDeleteFile(const void *path); MODULE_SCOPE void TclpFinalizeCondition(Tcl_Condition *condPtr); MODULE_SCOPE void TclpFinalizeMutex(Tcl_Mutex *mutexPtr); MODULE_SCOPE void TclpFinalizePipes(void); MODULE_SCOPE void TclpFinalizeSockets(void); MODULE_SCOPE int TclCreateSocketAddress(Tcl_Interp *interp, void **addrlist, const char *host, int port, int willBind, const char **errorMsgPtr); MODULE_SCOPE int TclpThreadCreate(Tcl_ThreadId *idPtr, Tcl_ThreadCreateProc *proc, ClientData clientData, size_t stackSize, int flags); MODULE_SCOPE int TclpFindVariable(const char *name, size_t *lengthPtr); MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr, size_t *lengthPtr, Tcl_Encoding *encodingPtr); MODULE_SCOPE void TclpInitLock(void); MODULE_SCOPE void TclpInitPlatform(void); MODULE_SCOPE void TclpInitUnlock(void); MODULE_SCOPE Tcl_Obj * TclpObjListVolumes(void); MODULE_SCOPE void TclpMasterLock(void); MODULE_SCOPE void TclpMasterUnlock(void); MODULE_SCOPE int TclpMatchFiles(Tcl_Interp *interp, char *separators, Tcl_DString *dirPtr, char *pattern, char *tail); MODULE_SCOPE int TclpObjNormalizePath(Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint); MODULE_SCOPE void TclpNativeJoinPath(Tcl_Obj *prefix, const char *joining); MODULE_SCOPE Tcl_Obj * TclpNativeSplitPath(Tcl_Obj *pathPtr, size_t *lenPtr); MODULE_SCOPE Tcl_PathType TclpGetNativePathType(Tcl_Obj *pathPtr, size_t *driveNameLengthPtr, Tcl_Obj **driveNameRef); MODULE_SCOPE int TclCrossFilesystemCopy(Tcl_Interp *interp, Tcl_Obj *source, Tcl_Obj *target); MODULE_SCOPE int TclpMatchInDirectory(Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); MODULE_SCOPE ClientData TclpGetNativeCwd(ClientData clientData); MODULE_SCOPE Tcl_FSDupInternalRepProc TclNativeDupInternalRep; |
︙ | ︙ | |||
3005 3006 3007 3008 3009 3010 3011 | void *data); MODULE_SCOPE void TclpThreadExit(int status); MODULE_SCOPE void TclRememberCondition(Tcl_Condition *mutex); MODULE_SCOPE void TclRememberJoinableThread(Tcl_ThreadId id); MODULE_SCOPE void TclRememberMutex(Tcl_Mutex *mutex); MODULE_SCOPE void TclRemoveScriptLimitCallbacks(Tcl_Interp *interp); MODULE_SCOPE int TclReToGlob(Tcl_Interp *interp, const char *reStr, | | > | | | | | | | | | | | | | | > > | | > | < < | < < | < < | < < | < < | < < | < < | < < | < | < | < < | < < | < < | < < | < < | | | < < | < < | < < | | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < < | < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | | | | | | | | | | | | | | | < | | < | | < | | < | | < | | | | | | | | | | | | | | < | | < < | < < | < < | < | | < < | < < | < < | < < | < < | < < | < < | < < | < < < < < < < < < < < < < | | | | | < | | < < | < < | < < | < < | < < | < < | < < | < < < < < < < < < < < < < < < < < < < < < < | | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < < < < < < < < < < < < < | < < | < < | < < | < < | < < | < < | < < | < < < < < < < < | < < | < < | < < | < < < < < | < < | < < | < | | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < < < < < < < < < < < < < < < < < < < < < < | | < < < < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < < < < | < < | < < | < < | < < | < < < < < | < < | < < | < < | < < < < < < < < < < < < < < < < < | < | | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | | < < | 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 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 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 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 | void *data); MODULE_SCOPE void TclpThreadExit(int status); MODULE_SCOPE void TclRememberCondition(Tcl_Condition *mutex); MODULE_SCOPE void TclRememberJoinableThread(Tcl_ThreadId id); MODULE_SCOPE void TclRememberMutex(Tcl_Mutex *mutex); MODULE_SCOPE void TclRemoveScriptLimitCallbacks(Tcl_Interp *interp); MODULE_SCOPE int TclReToGlob(Tcl_Interp *interp, const char *reStr, size_t reStrLen, Tcl_DString *dsPtr, int *flagsPtr); MODULE_SCOPE size_t TclScanElement(const char *string, size_t length, char *flagPtr); MODULE_SCOPE void TclSetBgErrorHandler(Tcl_Interp *interp, Tcl_Obj *cmdPrefix); MODULE_SCOPE void TclSetBignumIntRep(Tcl_Obj *objPtr, mp_int *bignumValue); MODULE_SCOPE int TclSetBooleanFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); MODULE_SCOPE void TclSetCmdNameObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Command *cmdPtr); MODULE_SCOPE void TclSetDuplicateObj(Tcl_Obj *dupPtr, Tcl_Obj *objPtr); MODULE_SCOPE void TclSetProcessGlobalValue(ProcessGlobalValue *pgvPtr, Tcl_Obj *newValue, Tcl_Encoding encoding); MODULE_SCOPE void TclSignalExitThread(Tcl_ThreadId id, int result); MODULE_SCOPE void * TclStackRealloc(Tcl_Interp *interp, void *ptr, size_t numBytes); MODULE_SCOPE int TclStringMatch(const char *str, size_t strLen, const char *pattern, size_t ptnLen, int flags); MODULE_SCOPE int TclStringMatchObj(Tcl_Obj *stringObj, Tcl_Obj *patternObj, int flags); MODULE_SCOPE Tcl_Obj * TclStringObjReverse(Tcl_Obj *objPtr); MODULE_SCOPE void TclSubstCompile(Tcl_Interp *interp, const char *bytes, size_t numBytes, int flags, int line, struct CompileEnv *envPtr); MODULE_SCOPE int TclSubstOptions(Tcl_Interp *interp, size_t numOpts, Tcl_Obj *const opts[], int *flagPtr); MODULE_SCOPE void TclSubstParse(Tcl_Interp *interp, const char *bytes, size_t numBytes, int flags, Tcl_Parse *parsePtr, Tcl_InterpState *statePtr); MODULE_SCOPE int TclSubstTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr, size_t count, size_t *tokensLeftPtr, int line, ssize_t *clNextOuter, const char *outerScript); MODULE_SCOPE int TclTrimLeft(const char *bytes, size_t numBytes, const char *trim, size_t numTrim); MODULE_SCOPE int TclTrimRight(const char *bytes, size_t numBytes, const char *trim, size_t numTrim); MODULE_SCOPE int TclUtfCasecmp(const char *cs, const char *ct); MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized(ClientData clientData); MODULE_SCOPE Tcl_Obj * TclpFilesystemPathType(Tcl_Obj *pathPtr); MODULE_SCOPE int TclpDlopen(Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); MODULE_SCOPE int TclpUtime(Tcl_Obj *pathPtr, struct utimbuf *tval); #ifdef TCL_LOAD_FROM_MEMORY MODULE_SCOPE void * TclpLoadMemoryGetBuffer(Tcl_Interp *interp, size_t size); MODULE_SCOPE int TclpLoadMemory(Tcl_Interp *interp, void *buffer, size_t size, size_t codeSize, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); #endif MODULE_SCOPE void TclInitThreadStorage(void); MODULE_SCOPE void TclFinalizeThreadDataThread(void); MODULE_SCOPE void TclFinalizeThreadStorage(void); #ifdef TCL_WIDE_CLICKS MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void); MODULE_SCOPE double TclpWideClicksToNanoseconds(Tcl_WideInt clicks); #endif MODULE_SCOPE Tcl_Obj * TclDisassembleByteCodeObj(Tcl_Obj *objPtr); MODULE_SCOPE int TclZlibInit(Tcl_Interp *interp); MODULE_SCOPE void * TclpThreadCreateKey(void); MODULE_SCOPE void TclpThreadDeleteKey(void *keyPtr); MODULE_SCOPE void TclpThreadSetMasterTSD(void *tsdKeyPtr, void *ptr); MODULE_SCOPE void * TclpThreadGetMasterTSD(void *tsdKeyPtr); MODULE_SCOPE void TclErrorStackResetIf(Tcl_Interp *interp, const char *msg, size_t length); /* *---------------------------------------------------------------- * Command procedures in the generic core: *---------------------------------------------------------------- */ MODULE_SCOPE Tcl_ObjCmdProc Tcl_AfterObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_AppendObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ApplyObjCmd; MODULE_SCOPE Tcl_Command TclInitArrayCmd(Tcl_Interp *interp); MODULE_SCOPE Tcl_Command TclInitBinaryCmd(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc Tcl_BreakObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_CatchObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_CdObjCmd; MODULE_SCOPE Tcl_Command TclInitChanCmd(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc TclChanCreateObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclChanPostEventObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclChanPopObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclChanPushObjCmd; MODULE_SCOPE void TclClockInit(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc TclClockOldscanObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_CloseObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ConcatObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ContinueObjCmd; MODULE_SCOPE Tcl_TimerToken TclCreateAbsoluteTimerHandler( Tcl_Time *timePtr, Tcl_TimerProc *proc, ClientData clientData); MODULE_SCOPE Tcl_ObjCmdProc TclDefaultBgErrorHandlerObjCmd; MODULE_SCOPE Tcl_Command TclInitDictCmd(Tcl_Interp *interp); MODULE_SCOPE int TclDictWithFinish(Tcl_Interp *interp, Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int index, size_t pathc, Tcl_Obj *const pathv[], Tcl_Obj *keysPtr); MODULE_SCOPE Tcl_Obj * TclDictWithInit(Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t pathc, Tcl_Obj *const pathv[]); MODULE_SCOPE Tcl_ObjCmdProc Tcl_DisassembleObjCmd; /* Assemble command function */ MODULE_SCOPE Tcl_ObjCmdProc Tcl_AssembleObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRAssembleObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_EncodingObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_EofObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ErrorObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_EvalObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ExecObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ExitObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ExprObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_FblockedObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_FconfigureObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_FcopyObjCmd; MODULE_SCOPE Tcl_Command TclInitFileCmd(Tcl_Interp *interp); MODULE_SCOPE int TclMakeFileCommandSafe(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc Tcl_FileEventObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_FlushObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ForObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ForeachObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_FormatObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_GetsObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_GlobalObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_GlobObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_IfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_IncrObjCmd; MODULE_SCOPE Tcl_Command TclInitInfoCmd(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc Tcl_InterpObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_JoinObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LappendObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LassignObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LindexObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LinsertObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LlengthObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ListObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LmapObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LoadObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LrangeObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LrepeatObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LreplaceObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LreverseObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LsearchObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LsetObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_LsortObjCmd; MODULE_SCOPE Tcl_Command TclInitNamespaceCmd(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc TclNamespaceEnsembleCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_OpenObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_PackageObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_PidObjCmd; MODULE_SCOPE Tcl_Command TclInitPrefixCmd(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc Tcl_PutsObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_PwdObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ReadObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_RegexpObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_RegsubObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_RenameObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_RepresentationCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ReturnObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ScanObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_SeekObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_SetObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_SplitObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_SocketObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_SourceObjCmd; MODULE_SCOPE Tcl_Command TclInitStringCmd(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc Tcl_SubstObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_SwitchObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_TellObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_ThrowObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_TimeObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_TraceObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_TryObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_UnloadObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_UnsetObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_UpdateObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_UplevelObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_UpvarObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_VariableObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_VwaitObjCmd; MODULE_SCOPE Tcl_ObjCmdProc Tcl_WhileObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclAddOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclAndOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclDivOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclEqOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclGeqOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclGreaterOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclInOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclInvertOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclLeqOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclLessOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclLshiftOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclMinusOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclModOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclMulOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNeqOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNiOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNotOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOrOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclPowOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclRshiftOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclStreqOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclStrneqOpCmd; MODULE_SCOPE Tcl_ObjCmdProc TclXorOpCmd; /* *---------------------------------------------------------------- * Compilation procedures for commands in the generic core: *---------------------------------------------------------------- */ MODULE_SCOPE CompileProc TclCompileAppendCmd; MODULE_SCOPE CompileProc TclCompileArrayExistsCmd; MODULE_SCOPE CompileProc TclCompileArraySetCmd; MODULE_SCOPE CompileProc TclCompileArrayUnsetCmd; MODULE_SCOPE CompileProc TclCompileAssembleCmd; MODULE_SCOPE CompileProc TclCompileBreakCmd; MODULE_SCOPE CompileProc TclCompileCatchCmd; MODULE_SCOPE CompileProc TclCompileContinueCmd; MODULE_SCOPE CompileProc TclCompileDictAppendCmd; MODULE_SCOPE CompileProc TclCompileDictCreateCmd; MODULE_SCOPE CompileProc TclCompileDictExistsCmd; MODULE_SCOPE CompileProc TclCompileDictForCmd; MODULE_SCOPE CompileProc TclCompileDictGetCmd; MODULE_SCOPE CompileProc TclCompileDictIncrCmd; MODULE_SCOPE CompileProc TclCompileDictLappendCmd; MODULE_SCOPE CompileProc TclCompileDictMapCmd; MODULE_SCOPE CompileProc TclCompileDictMergeCmd; MODULE_SCOPE CompileProc TclCompileDictSetCmd; MODULE_SCOPE CompileProc TclCompileDictUnsetCmd; MODULE_SCOPE CompileProc TclCompileDictUpdateCmd; MODULE_SCOPE CompileProc TclCompileDictWithCmd; MODULE_SCOPE CompileProc TclCompileEnsemble; MODULE_SCOPE CompileProc TclCompileErrorCmd; MODULE_SCOPE CompileProc TclCompileExprCmd; MODULE_SCOPE CompileProc TclCompileForCmd; MODULE_SCOPE CompileProc TclCompileForeachCmd; MODULE_SCOPE CompileProc TclCompileFormatCmd; MODULE_SCOPE CompileProc TclCompileGlobalCmd; MODULE_SCOPE CompileProc TclCompileIfCmd; MODULE_SCOPE CompileProc TclCompileInfoCommandsCmd; MODULE_SCOPE CompileProc TclCompileInfoCoroutineCmd; MODULE_SCOPE CompileProc TclCompileInfoExistsCmd; MODULE_SCOPE CompileProc TclCompileInfoLevelCmd; MODULE_SCOPE CompileProc TclCompileInfoObjectClassCmd; MODULE_SCOPE CompileProc TclCompileInfoObjectIsACmd; MODULE_SCOPE CompileProc TclCompileInfoObjectNamespaceCmd; MODULE_SCOPE CompileProc TclCompileIncrCmd; MODULE_SCOPE CompileProc TclCompileLappendCmd; MODULE_SCOPE CompileProc TclCompileLassignCmd; MODULE_SCOPE CompileProc TclCompileLindexCmd; MODULE_SCOPE CompileProc TclCompileListCmd; MODULE_SCOPE CompileProc TclCompileLlengthCmd; MODULE_SCOPE CompileProc TclCompileLmapCmd; MODULE_SCOPE CompileProc TclCompileLrangeCmd; MODULE_SCOPE CompileProc TclCompileLreplaceCmd; MODULE_SCOPE CompileProc TclCompileLsetCmd; MODULE_SCOPE CompileProc TclCompileNamespaceCodeCmd; MODULE_SCOPE CompileProc TclCompileNamespaceCurrentCmd; MODULE_SCOPE CompileProc TclCompileNamespaceQualifiersCmd; MODULE_SCOPE CompileProc TclCompileNamespaceTailCmd; MODULE_SCOPE CompileProc TclCompileNamespaceUpvarCmd; MODULE_SCOPE CompileProc TclCompileNamespaceWhichCmd; MODULE_SCOPE CompileProc TclCompileNoOp; MODULE_SCOPE CompileProc TclCompileObjectSelfCmd; MODULE_SCOPE CompileProc TclCompileRegexpCmd; MODULE_SCOPE CompileProc TclCompileRegsubCmd; MODULE_SCOPE CompileProc TclCompileReturnCmd; MODULE_SCOPE CompileProc TclCompileSetCmd; MODULE_SCOPE CompileProc TclCompileStringCmpCmd; MODULE_SCOPE CompileProc TclCompileStringEqualCmd; MODULE_SCOPE CompileProc TclCompileStringFirstCmd; MODULE_SCOPE CompileProc TclCompileStringIndexCmd; MODULE_SCOPE CompileProc TclCompileStringLastCmd; MODULE_SCOPE CompileProc TclCompileStringLenCmd; MODULE_SCOPE CompileProc TclCompileStringMapCmd; MODULE_SCOPE CompileProc TclCompileStringMatchCmd; MODULE_SCOPE CompileProc TclCompileStringRangeCmd; MODULE_SCOPE CompileProc TclCompileSubstCmd; MODULE_SCOPE CompileProc TclCompileSwitchCmd; MODULE_SCOPE CompileProc TclCompileTailcallCmd; MODULE_SCOPE CompileProc TclCompileThrowCmd; MODULE_SCOPE CompileProc TclCompileTryCmd; MODULE_SCOPE CompileProc TclCompileUnsetCmd; MODULE_SCOPE CompileProc TclCompileUpvarCmd; MODULE_SCOPE CompileProc TclCompileVariableCmd; MODULE_SCOPE CompileProc TclCompileWhileCmd; MODULE_SCOPE CompileProc TclCompileYieldCmd; MODULE_SCOPE CompileProc TclCompileBasic0ArgCmd; MODULE_SCOPE CompileProc TclCompileBasic1ArgCmd; MODULE_SCOPE CompileProc TclCompileBasic2ArgCmd; MODULE_SCOPE CompileProc TclCompileBasic3ArgCmd; MODULE_SCOPE CompileProc TclCompileBasic0Or1ArgCmd; MODULE_SCOPE CompileProc TclCompileBasic1Or2ArgCmd; MODULE_SCOPE CompileProc TclCompileBasic2Or3ArgCmd; MODULE_SCOPE CompileProc TclCompileBasic0To2ArgCmd; MODULE_SCOPE CompileProc TclCompileBasic1To3ArgCmd; MODULE_SCOPE CompileProc TclCompileBasicMin0ArgCmd; MODULE_SCOPE CompileProc TclCompileBasicMin1ArgCmd; MODULE_SCOPE CompileProc TclCompileBasicMin2ArgCmd; MODULE_SCOPE CompileProc TclCompileAddOpCmd; MODULE_SCOPE CompileProc TclCompileAndOpCmd; MODULE_SCOPE CompileProc TclCompileDivOpCmd; MODULE_SCOPE CompileProc TclCompileEqOpCmd; MODULE_SCOPE CompileProc TclCompileGeqOpCmd; MODULE_SCOPE CompileProc TclCompileGreaterOpCmd; MODULE_SCOPE CompileProc TclCompileInOpCmd; MODULE_SCOPE CompileProc TclCompileInvertOpCmd; MODULE_SCOPE CompileProc TclCompileLeqOpCmd; MODULE_SCOPE CompileProc TclCompileLessOpCmd; MODULE_SCOPE CompileProc TclCompileLshiftOpCmd; MODULE_SCOPE CompileProc TclCompileMinusOpCmd; MODULE_SCOPE CompileProc TclCompileModOpCmd; MODULE_SCOPE CompileProc TclCompileMulOpCmd; MODULE_SCOPE CompileProc TclCompileNeqOpCmd; MODULE_SCOPE CompileProc TclCompileNiOpCmd; MODULE_SCOPE CompileProc TclCompileNotOpCmd; MODULE_SCOPE CompileProc TclCompileOrOpCmd; MODULE_SCOPE CompileProc TclCompilePowOpCmd; MODULE_SCOPE CompileProc TclCompileRshiftOpCmd; MODULE_SCOPE CompileProc TclCompileStreqOpCmd; MODULE_SCOPE CompileProc TclCompileStrneqOpCmd; MODULE_SCOPE CompileProc TclCompileXorOpCmd; /* * Functions defined in generic/tclVar.c and currenttly exported only for use * by the bytecode compiler and engine. Some of these could later be placed in * the public interface. */ |
︙ | ︙ | |||
3805 3806 3807 3808 3809 3810 3811 | Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, const int flags, int index); MODULE_SCOPE int TclPtrObjMakeUpvar(Tcl_Interp *interp, Var *otherPtr, Tcl_Obj *myNamePtr, int myFlags, int index); MODULE_SCOPE int TclPtrUnsetVar(Tcl_Interp *interp, Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr, | | < | 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 | Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, const int flags, int index); MODULE_SCOPE int TclPtrObjMakeUpvar(Tcl_Interp *interp, Var *otherPtr, Tcl_Obj *myNamePtr, int myFlags, int index); MODULE_SCOPE int TclPtrUnsetVar(Tcl_Interp *interp, Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags, int index); MODULE_SCOPE void TclInvalidateNsPath(Namespace *nsPtr); MODULE_SCOPE void TclFindArrayPtrElements(Var *arrayPtr, Tcl_HashTable *tablePtr); /* * The new extended interface to the variable traces. */ |
︙ | ︙ | |||
3877 3878 3879 3880 3881 3882 3883 | tclObjsFreed++ #else # define TclIncrObjsAllocated() # define TclIncrObjsFreed() #endif /* TCL_COMPILE_STATS */ # define TclAllocObjStorage(objPtr) \ | | | > | | | | | | | > | | | | | | | | | | | | | | | | | | | | 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 | tclObjsFreed++ #else # define TclIncrObjsAllocated() # define TclIncrObjsFreed() #endif /* TCL_COMPILE_STATS */ # define TclAllocObjStorage(objPtr) \ TclAllocObjStorageEx(NULL, (objPtr)) # define TclFreeObjStorage(objPtr) \ TclFreeObjStorageEx(NULL, (objPtr)) #ifndef TCL_MEM_DEBUG # define TclNewObj(objPtr) \ do { \ TclIncrObjsAllocated(); \ TclAllocObjStorage(objPtr); \ (objPtr)->refCount = 0; \ (objPtr)->bytes = tclEmptyStringRep; \ (objPtr)->length = 0; \ (objPtr)->typePtr = NULL; \ TCL_DTRACE_OBJ_CREATE(objPtr); \ } while (0) /* * Invalidate the string rep first so we can use the bytes value for our * pointer chain, and signal an obj deletion (as opposed to shimmering) with * 'length == TCL_STRLEN'. * * Use do/while0 idiom for optimum correctness without compiler warnings. * http://c2.com/cgi/wiki?TrivialDoWhileLoop * * Decrement refCount AFTER checking it for 0 or 1 (<2), because we cannot * assume anymore that refCount is a signed type; In Tcl8 it was but in Tcl9 * it is subject to change. */ # define TclDecrRefCount(objPtr) \ do { \ Tcl_Obj *_objPtr = (objPtr); \ if (_objPtr->refCount-- < 2) { \ if (!_objPtr->typePtr || !_objPtr->typePtr->freeIntRepProc) { \ TCL_DTRACE_OBJ_FREE(_objPtr); \ if (_objPtr->bytes \ && (_objPtr->bytes != tclEmptyStringRep)) { \ ckfree((char *) _objPtr->bytes); \ } \ _objPtr->length = -1; \ TclFreeObjStorage(_objPtr); \ TclIncrObjsFreed(); \ } else { \ TclFreeObj(_objPtr); \ } \ } \ } while(0) #if defined(PURIFY) /* * The PURIFY mode is like the regular mode, but instead of doing block * Tcl_Obj allocation and keeping a freed list for efficiency, it always |
︙ | ︙ | |||
4035 4036 4037 4038 4039 4040 4041 | #endif #else /* TCL_MEM_DEBUG */ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, int line); # define TclDbNewObj(objPtr, file, line) \ | | | 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 | #endif #else /* TCL_MEM_DEBUG */ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, int line); # define TclDbNewObj(objPtr, file, line) \ do { \ TclIncrObjsAllocated(); \ (objPtr) = (Tcl_Obj *) \ Tcl_DbCkalloc(sizeof(Tcl_Obj), (file), (line)); \ TclDbInitNewObj((objPtr), (file), (line)); \ TCL_DTRACE_OBJ_CREATE(objPtr); \ } while (0) |
︙ | ︙ | |||
4063 4064 4065 4066 4067 4068 4069 | *---------------------------------------------------------------- * Macro used by the Tcl core to set a Tcl_Obj's string representation to a * copy of the "len" bytes starting at "bytePtr". This code works even if the * byte array contains NULLs as long as the length is correct. Because "len" * is referenced multiple times, it should be as simple an expression as * possible. The ANSI C "prototype" for this macro is: * | | | | | | | | | | | | | | | | | | | | | | | | | | 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 | *---------------------------------------------------------------- * Macro used by the Tcl core to set a Tcl_Obj's string representation to a * copy of the "len" bytes starting at "bytePtr". This code works even if the * byte array contains NULLs as long as the length is correct. Because "len" * is referenced multiple times, it should be as simple an expression as * possible. The ANSI C "prototype" for this macro is: * * MODULE_SCOPE void TclInitStringRep(Tcl_Obj *objPtr, char *bytePtr, size_t len); * * This macro should only be called on an unshared objPtr where * objPtr->typePtr->freeIntRepProc == NULL *---------------------------------------------------------------- */ #define TclInitStringRep(objPtr, bytePtr, len) \ if ((len) == 0) { \ (objPtr)->bytes = tclEmptyStringRep; \ (objPtr)->length = 0; \ } else { \ (objPtr)->bytes = ckalloc((unsigned) ((len) + 1)); \ memcpy((objPtr)->bytes, (bytePtr), (len)); \ (objPtr)->bytes[len] = '\0'; \ (objPtr)->length = (len); \ } /* *---------------------------------------------------------------- * Macro used by the Tcl core to get the string representation's byte array * pointer from a Tcl_Obj. This is an inline version of Tcl_GetString(). The * macro's expression result is the string rep's byte pointer which might be * NULL. The bytes referenced by this pointer must not be modified by the * caller. The ANSI C "prototype" for this macro is: * * MODULE_SCOPE char * TclGetString(Tcl_Obj *objPtr); *---------------------------------------------------------------- */ #define TclGetString(objPtr) \ ((objPtr)->bytes? (objPtr)->bytes : Tcl_GetString((objPtr))) #define TclGetStringFromObj(objPtr, lenPtr) \ ((objPtr)->bytes \ ? (*(lenPtr) = (objPtr)->length, (objPtr)->bytes) \ : Tcl_GetStringFromObj((objPtr), (lenPtr))) /* *---------------------------------------------------------------- * Macro used by the Tcl core to clean out an object's internal * representation. Does not actually reset the rep's bytes. The ANSI C * "prototype" for this macro is: * * MODULE_SCOPE void TclFreeIntRep(Tcl_Obj *objPtr); *---------------------------------------------------------------- */ #define TclFreeIntRep(objPtr) \ if ((objPtr)->typePtr == NULL) ; else { \ if ((objPtr)->typePtr->freeIntRepProc != NULL) { \ (objPtr)->typePtr->freeIntRepProc(objPtr); \ } \ (objPtr)->typePtr = NULL; \ } /* *---------------------------------------------------------------- * Macro used by the Tcl core to clean out an object's string representation. * The ANSI C "prototype" for this macro is: * * MODULE_SCOPE void TclInvalidateStringRep(Tcl_Obj *objPtr); *---------------------------------------------------------------- */ #define TclInvalidateStringRep(objPtr) \ if ((objPtr)->bytes == NULL) ; else { \ if ((objPtr)->bytes != tclEmptyStringRep) { \ ckfree((char *) (objPtr)->bytes); \ } \ (objPtr)->bytes = NULL; \ } /* *---------------------------------------------------------------- * Macros used by the Tcl core to grow Tcl_Token arrays. They use the same * growth algorithm as used in tclStringObj.c for growing strings. The ANSI C * "prototype" for this macro is: * * MODULE_SCOPE void TclGrowTokenArray(Tcl_Token *tokenPtr, size_t used, * size_t available, size_t append, * Tcl_Token *staticPtr); * MODULE_SCOPE void TclGrowParseTokenArray(Tcl_Parse *parsePtr, * size_t append); *---------------------------------------------------------------- */ /* General tuning for minimum growth in Tcl growth algorithms */ #ifndef TCL_MIN_GROWTH # ifdef TCL_GROWTH_MIN_ALLOC /* Support for any legacy tuners */ |
︙ | ︙ | |||
4168 4169 4170 4171 4172 4173 4174 | #ifndef TCL_MIN_TOKEN_GROWTH #define TCL_MIN_TOKEN_GROWTH TCL_MIN_GROWTH/sizeof(Tcl_Token) #endif #define TCL_MAX_TOKENS (int)(UINT_MAX / sizeof(Tcl_Token)) #define TclGrowTokenArray(tokenPtr, used, available, append, staticPtr) \ do { \ | | | | 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 | #ifndef TCL_MIN_TOKEN_GROWTH #define TCL_MIN_TOKEN_GROWTH TCL_MIN_GROWTH/sizeof(Tcl_Token) #endif #define TCL_MAX_TOKENS (int)(UINT_MAX / sizeof(Tcl_Token)) #define TclGrowTokenArray(tokenPtr, used, available, append, staticPtr) \ do { \ size_t needed = (used) + (append); \ if (needed > TCL_MAX_TOKENS) { \ Tcl_Panic("max # of tokens for a Tcl parse (%d) exceeded", \ TCL_MAX_TOKENS); \ } \ if (needed > (available)) { \ size_t allocated = 2 * needed; \ Tcl_Token *oldPtr = (tokenPtr); \ Tcl_Token *newPtr; \ if (oldPtr == (staticPtr)) { \ oldPtr = NULL; \ } \ if (allocated > TCL_MAX_TOKENS) { \ allocated = TCL_MAX_TOKENS; \ |
︙ | ︙ | |||
4220 4221 4222 4223 4224 4225 4226 | * the result of Tcl_UtfToUniChar. The ANSI C "prototype" for this macro is: * * MODULE_SCOPE int TclUtfToUniChar(const char *string, Tcl_UniChar *ch); *---------------------------------------------------------------- */ #define TclUtfToUniChar(str, chPtr) \ | | | | | | | | > > > | | | | | | | | 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 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 3843 3844 3845 3846 3847 3848 | * the result of Tcl_UtfToUniChar. The ANSI C "prototype" for this macro is: * * MODULE_SCOPE int TclUtfToUniChar(const char *string, Tcl_UniChar *ch); *---------------------------------------------------------------- */ #define TclUtfToUniChar(str, chPtr) \ ((((unsigned char) *(str)) < 0xC0) ? \ ((*(chPtr) = (Tcl_UniChar) *(str)), 1) \ : Tcl_UtfToUniChar(str, chPtr)) /* *---------------------------------------------------------------- * Macro counterpart of the Tcl_NumUtfChars() function. To be used in speed- * -sensitive points where it pays to avoid a function call in the common case * of counting along a string of all one-byte characters. The ANSI C * "prototype" for this macro is: * * MODULE_SCOPE void TclNumUtfChars(size_t numChars, const char *bytes, * size_t numBytes); *---------------------------------------------------------------- */ #define TclNumUtfChars(numChars, bytes, numBytes) \ do { \ size_t count, i = (numBytes); \ unsigned char *str = (unsigned char *) (bytes); \ while (i && (*str < 0xC0)) { \ i--; \ str++; \ } \ count = (numBytes) - i; \ if (i) { \ count += Tcl_NumUtfChars((bytes) + count, i); \ } \ (numChars) = count; \ } while (0) /* *---------------------------------------------------------------- * Macro that encapsulates the logic that determines when it is safe to * interpret a string as a byte array directly. In summary, the object must be * a byte array and must not have a string representation (as the operations * that it is used in are defined on strings, not byte arrays). Theoretically * it is possible to also be efficient in the case where the object's bytes * field is filled by generation from the byte array (c.f. list canonicality) * but we don't do that at the moment since this is purely about efficiency. * The ANSI C "prototype" for this macro is: * * MODULE_SCOPE int TclIsPureByteArray(Tcl_Obj *objPtr); *---------------------------------------------------------------- */ #define TclIsPureByteArray(objPtr) \ (((objPtr)->typePtr==&tclByteArrayType) && ((objPtr)->bytes==NULL)) /* *---------------------------------------------------------------- * Macro used by the Tcl core to compare Unicode strings. On big-endian * systems we can use the more efficient memcmp, but this would not be * lexically correct on little-endian systems. The ANSI C "prototype" for * this macro is: |
︙ | ︙ | |||
4294 4295 4296 4297 4298 4299 4300 | * counter. The ANSI C "prototype" for this macro is: * * MODULE_SCOPE void TclInvalidateNsCmdLookup(Namespace *nsPtr); *---------------------------------------------------------------- */ #define TclInvalidateNsCmdLookup(nsPtr) \ | > | | | | | | > | 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 | * counter. The ANSI C "prototype" for this macro is: * * MODULE_SCOPE void TclInvalidateNsCmdLookup(Namespace *nsPtr); *---------------------------------------------------------------- */ #define TclInvalidateNsCmdLookup(nsPtr) \ do { \ if ((nsPtr)->numExportPatterns) { \ (nsPtr)->exportLookupEpoch++; \ } \ if ((nsPtr)->commandPathLength) { \ (nsPtr)->cmdRefEpoch++; \ } \ } while (0) /* *---------------------------------------------------------------------- * * Core procedures added to libtommath for bignum manipulation. * *---------------------------------------------------------------------- |
︙ | ︙ | |||
4358 4359 4360 4361 4362 4363 4364 | * MODULE_SCOPE void TclSetLongObj(Tcl_Obj *objPtr, long longValue); * MODULE_SCOPE void TclSetWideIntObj(Tcl_Obj *objPtr, Tcl_WideInt w); * MODULE_SCOPE void TclSetDoubleObj(Tcl_Obj *objPtr, double d); *---------------------------------------------------------------- */ #define TclSetLongObj(objPtr, i) \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 | * MODULE_SCOPE void TclSetLongObj(Tcl_Obj *objPtr, long longValue); * MODULE_SCOPE void TclSetWideIntObj(Tcl_Obj *objPtr, Tcl_WideInt w); * MODULE_SCOPE void TclSetDoubleObj(Tcl_Obj *objPtr, double d); *---------------------------------------------------------------- */ #define TclSetLongObj(objPtr, i) \ do { \ TclInvalidateStringRep(objPtr); \ TclFreeIntRep(objPtr); \ (objPtr)->internalRep.longValue = (long)(i); \ (objPtr)->typePtr = &tclIntType; \ } while (0) /* * NOTE: There is to be no such thing as a "pure" boolean. Boolean values set * programmatically go straight to being "int" Tcl_Obj's, with value 0 or 1. * The only "boolean" Tcl_Obj's shall be those holding the cached boolean * value of strings like: "yes", "no", "true", "false", "on", "off". */ #ifndef TCL_WIDE_INT_IS_LONG #define TclSetWideIntObj(objPtr, w) \ do { \ TclInvalidateStringRep(objPtr); \ TclFreeIntRep(objPtr); \ (objPtr)->internalRep.wideValue = (Tcl_WideInt)(w); \ (objPtr)->typePtr = &tclWideIntType; \ } while (0) #endif #define TclSetDoubleObj(objPtr, d) \ do { \ TclInvalidateStringRep(objPtr); \ TclFreeIntRep(objPtr); \ (objPtr)->internalRep.doubleValue = (double)(d); \ (objPtr)->typePtr = &tclDoubleType; \ } while (0) /* *---------------------------------------------------------------- * Macros used by the Tcl core to create and initialise objects of standard * types, avoiding the corresponding function calls in time critical parts of * the core. The ANSI C "prototypes" for these macros are: * * MODULE_SCOPE void TclNewLongObj(Tcl_Obj *objPtr, long l); * MODULE_SCOPE void TclNewWideObj(Tcl_Obj *objPtr, Tcl_WideInt w); * MODULE_SCOPE void TclNewDoubleObj(Tcl_Obj *objPtr, double d); * MODULE_SCOPE void TclNewStringObj(Tcl_Obj *objPtr, char *s, size_t len); * MODULE_SCOPE void TclNewLiteralStringObj(Tcl_Obj*objPtr, char*sLiteral); * *---------------------------------------------------------------- */ #ifndef TCL_MEM_DEBUG #define TclNewLongObj(objPtr, i) \ do { \ TclIncrObjsAllocated(); \ TclAllocObjStorage(objPtr); \ (objPtr)->refCount = 0; \ (objPtr)->bytes = NULL; \ (objPtr)->internalRep.longValue = (long)(i); \ (objPtr)->typePtr = &tclIntType; \ TCL_DTRACE_OBJ_CREATE(objPtr); \ } while (0) #define TclNewDoubleObj(objPtr, d) \ do { \ TclIncrObjsAllocated(); \ TclAllocObjStorage(objPtr); \ (objPtr)->refCount = 0; \ (objPtr)->bytes = NULL; \ (objPtr)->internalRep.doubleValue = (double)(d); \ (objPtr)->typePtr = &tclDoubleType; \ TCL_DTRACE_OBJ_CREATE(objPtr); \ } while (0) #define TclNewStringObj(objPtr, s, len) \ do { \ TclIncrObjsAllocated(); \ TclAllocObjStorage(objPtr); \ (objPtr)->refCount = 0; \ TclInitStringRep((objPtr), (s), (len)); \ (objPtr)->typePtr = NULL; \ TCL_DTRACE_OBJ_CREATE(objPtr); \ } while (0) #else /* TCL_MEM_DEBUG */ #define TclNewLongObj(objPtr, l) \ (objPtr) = Tcl_NewLongObj(l) #define TclNewDoubleObj(objPtr, d) \ |
︙ | ︙ | |||
4522 4523 4524 4525 4526 4527 4528 | /* *---------------------------------------------------------------- * Inline version of TclCleanupCommand; still need the function as it is in * the internal stubs, but the core can use the macro instead. */ #define TclCleanupCommandMacro(cmdPtr) \ | | | | 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 | /* *---------------------------------------------------------------- * Inline version of TclCleanupCommand; still need the function as it is in * the internal stubs, but the core can use the macro instead. */ #define TclCleanupCommandMacro(cmdPtr) \ if (--(cmdPtr)->refCount <= 0) { \ ckfree((char *) (cmdPtr)); \ } /* *---------------------------------------------------------------- * Inline versions of Tcl_LimitReady() and Tcl_LimitExceeded to limit number * of calls out of the critical path. Note that this code isn't particularly * readable; the non-inline version (in tclInterp.c) is much easier to |
︙ | ︙ |
Changes to generic/tclIntDecls.h.
︙ | ︙ | |||
37 38 39 40 41 42 43 | /* Slot 4 is reserved */ /* 5 */ TCLAPI int TclCleanupChildren(Tcl_Interp *interp, int numPids, Tcl_Pid *pidPtr, Tcl_Channel errorChan); /* 6 */ TCLAPI void TclCleanupCommand(Command *cmdPtr); /* 7 */ | | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | /* Slot 4 is reserved */ /* 5 */ TCLAPI int TclCleanupChildren(Tcl_Interp *interp, int numPids, Tcl_Pid *pidPtr, Tcl_Channel errorChan); /* 6 */ TCLAPI void TclCleanupCommand(Command *cmdPtr); /* 7 */ TCLAPI size_t TclCopyAndCollapse(size_t count, const char *src, char *dst); /* Slot 8 is reserved */ /* 9 */ TCLAPI int TclCreatePipeline(Tcl_Interp *interp, size_t argc, const char **argv, Tcl_Pid **pidArrayPtr, TclFile *inPipePtr, TclFile *outPipePtr, TclFile *errFilePtr); /* 10 */ TCLAPI int TclCreateProc(Tcl_Interp *interp, Namespace *nsPtr, const char *procName, Tcl_Obj *argsPtr, Tcl_Obj *bodyPtr, Proc **procPtrPtr); |
︙ | ︙ | |||
68 69 70 71 72 73 74 | /* Slot 17 is reserved */ /* Slot 18 is reserved */ /* Slot 19 is reserved */ /* Slot 20 is reserved */ /* Slot 21 is reserved */ /* 22 */ TCLAPI int TclFindElement(Tcl_Interp *interp, | | | | | > | 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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | /* Slot 17 is reserved */ /* Slot 18 is reserved */ /* Slot 19 is reserved */ /* Slot 20 is reserved */ /* Slot 21 is reserved */ /* 22 */ TCLAPI int TclFindElement(Tcl_Interp *interp, const char *listStr, size_t listLength, const char **elementPtr, const char **nextPtr, size_t *sizePtr, int *bracePtr); /* 23 */ TCLAPI Proc * TclFindProc(Interp *iPtr, const char *procName); /* 24 */ TCLAPI size_t TclFormatInt(char *buffer, long n); /* 25 */ TCLAPI void TclFreePackageInfo(Interp *iPtr); /* Slot 26 is reserved */ /* Slot 27 is reserved */ /* 28 */ TCLAPI Tcl_Channel TclpGetDefaultStdChannel(int type); /* Slot 29 is reserved */ /* Slot 30 is reserved */ /* 31 */ TCLAPI const char * TclGetExtension(const char *name); /* 32 */ TCLAPI int TclGetFrame(Tcl_Interp *interp, const char *str, CallFrame **framePtrPtr); /* Slot 33 is reserved */ /* 34 */ TCLAPI int TclGetIntForIndex(Tcl_Interp *interp, Tcl_Obj *objPtr, ssize_t endValue, ssize_t *indexPtr); /* Slot 35 is reserved */ /* Slot 36 is reserved */ /* 37 */ TCLAPI int TclGetLoadedPackages(Tcl_Interp *interp, const char *targetName); /* 38 */ TCLAPI int TclGetNamespaceForQualName(Tcl_Interp *interp, |
︙ | ︙ | |||
134 135 136 137 138 139 140 | TCLAPI void TclInitCompiledLocals(Tcl_Interp *interp, CallFrame *framePtr, Namespace *nsPtr); /* 51 */ TCLAPI int TclInterpInit(Tcl_Interp *interp); /* Slot 52 is reserved */ /* 53 */ TCLAPI int TclInvokeObjectCommand(ClientData clientData, | | | | | | | | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 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 192 193 194 195 196 197 198 199 | TCLAPI void TclInitCompiledLocals(Tcl_Interp *interp, CallFrame *framePtr, Namespace *nsPtr); /* 51 */ TCLAPI int TclInterpInit(Tcl_Interp *interp); /* Slot 52 is reserved */ /* 53 */ TCLAPI int TclInvokeObjectCommand(ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv); /* 54 */ TCLAPI int TclInvokeStringCommand(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* 55 */ TCLAPI Proc * TclIsProc(Command *cmdPtr); /* Slot 56 is reserved */ /* Slot 57 is reserved */ /* 58 */ TCLAPI Var * TclLookupVar(Tcl_Interp *interp, const char *part1, const char *part2, int flags, const char *msg, int createPart1, int createPart2, Var **arrayPtrPtr); /* Slot 59 is reserved */ /* 60 */ TCLAPI int TclNeedSpace(const char *start, const char *end); /* 61 */ TCLAPI Tcl_Obj * TclNewProcBodyObj(Proc *procPtr); /* 62 */ TCLAPI int TclObjCommandComplete(Tcl_Obj *cmdPtr); /* 63 */ TCLAPI int TclObjInterpProc(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* 64 */ TCLAPI int TclObjInvoke(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags); /* Slot 65 is reserved */ /* Slot 66 is reserved */ /* Slot 67 is reserved */ /* Slot 68 is reserved */ /* 69 */ TCLAPI char * TclpAlloc(size_t size); /* Slot 70 is reserved */ /* Slot 71 is reserved */ /* Slot 72 is reserved */ /* Slot 73 is reserved */ /* 74 */ TCLAPI void TclpFree(char *ptr); /* 75 */ TCLAPI unsigned long TclpGetClicks(void); /* 76 */ TCLAPI unsigned long TclpGetSeconds(void); /* Slot 77 is reserved */ /* Slot 78 is reserved */ /* Slot 79 is reserved */ /* Slot 80 is reserved */ /* 81 */ TCLAPI char * TclpRealloc(char *ptr, size_t size); /* Slot 82 is reserved */ /* Slot 83 is reserved */ /* Slot 84 is reserved */ /* Slot 85 is reserved */ /* Slot 86 is reserved */ /* Slot 87 is reserved */ /* 88 */ |
︙ | ︙ | |||
351 352 353 354 355 356 357 | TCLAPI const void * TclGetInstructionTable(void); /* 164 */ TCLAPI void TclExpandCodeArray(void *envPtr); /* 165 */ TCLAPI void TclpSetInitialEncodings(void); /* 166 */ TCLAPI int TclListObjSetElement(Tcl_Interp *interp, | | | | | | | | | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | TCLAPI const void * TclGetInstructionTable(void); /* 164 */ TCLAPI void TclExpandCodeArray(void *envPtr); /* 165 */ TCLAPI void TclpSetInitialEncodings(void); /* 166 */ TCLAPI int TclListObjSetElement(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t index, Tcl_Obj *valuePtr); /* Slot 167 is reserved */ /* Slot 168 is reserved */ /* 169 */ TCLAPI int TclpUtfNcmp2(const char *s1, const char *s2, size_t n); /* 170 */ TCLAPI int TclCheckInterpTraces(Tcl_Interp *interp, const char *command, size_t numChars, Command *cmdPtr, int result, int traceFlags, size_t objc, Tcl_Obj *const objv[]); /* 171 */ TCLAPI int TclCheckExecutionTraces(Tcl_Interp *interp, const char *command, size_t numChars, Command *cmdPtr, int result, int traceFlags, size_t objc, Tcl_Obj *const objv[]); /* 172 */ TCLAPI int TclInThreadExit(void); /* 173 */ TCLAPI int TclUniCharMatch(const Tcl_UniChar *string, size_t strLen, const Tcl_UniChar *pattern, size_t ptnLen, int flags); /* Slot 174 is reserved */ /* 175 */ TCLAPI int TclCallVarTraces(Interp *iPtr, Var *arrayPtr, Var *varPtr, const char *part1, const char *part2, int flags, int leaveErrMsg); /* 176 */ |
︙ | ︙ | |||
444 445 446 447 448 449 450 | TCLAPI void TclpFindExecutable(const char *argv0); /* 213 */ TCLAPI Tcl_Obj * TclGetObjNameOfExecutable(void); /* 214 */ TCLAPI void TclSetObjNameOfExecutable(Tcl_Obj *name, Tcl_Encoding encoding); /* 215 */ | | | | | 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 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | TCLAPI void TclpFindExecutable(const char *argv0); /* 213 */ TCLAPI Tcl_Obj * TclGetObjNameOfExecutable(void); /* 214 */ TCLAPI void TclSetObjNameOfExecutable(Tcl_Obj *name, Tcl_Encoding encoding); /* 215 */ TCLAPI void * TclStackAlloc(Tcl_Interp *interp, size_t numBytes); /* 216 */ TCLAPI void TclStackFree(Tcl_Interp *interp, void *freePtr); /* 217 */ TCLAPI int TclPushStackFrame(Tcl_Interp *interp, Tcl_CallFrame **framePtrPtr, Tcl_Namespace *namespacePtr, int isProcCallFrame); /* 218 */ TCLAPI void TclPopStackFrame(Tcl_Interp *interp); /* Slot 219 is reserved */ /* Slot 220 is reserved */ /* Slot 221 is reserved */ /* Slot 222 is reserved */ /* Slot 223 is reserved */ /* 224 */ TCLAPI TclPlatformType * TclGetPlatform(void); /* 225 */ TCLAPI Tcl_Obj * TclTraceDictPath(Tcl_Interp *interp, Tcl_Obj *rootPtr, size_t keyc, Tcl_Obj *const keyv[], int flags); /* 226 */ TCLAPI int TclObjBeingDeleted(Tcl_Obj *objPtr); /* 227 */ TCLAPI void TclSetNsPath(Namespace *nsPtr, size_t pathLength, Tcl_Namespace *pathAry[]); /* Slot 228 is reserved */ /* 229 */ TCLAPI int TclPtrMakeUpvar(Tcl_Interp *interp, Var *otherP1Ptr, const char *myName, int myFlags, int index); /* 230 */ TCLAPI Var * TclObjLookupVar(Tcl_Interp *interp, |
︙ | ︙ | |||
499 500 501 502 503 504 505 | TCLAPI void TclInitVarHashTable(TclVarHashTable *tablePtr, Namespace *nsPtr); /* Slot 236 is reserved */ /* 237 */ TCLAPI int TclResetCancellation(Tcl_Interp *interp, int force); /* 238 */ TCLAPI int TclNRInterpProc(ClientData clientData, | | | | 500 501 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 | TCLAPI void TclInitVarHashTable(TclVarHashTable *tablePtr, Namespace *nsPtr); /* Slot 236 is reserved */ /* 237 */ TCLAPI int TclResetCancellation(Tcl_Interp *interp, int force); /* 238 */ TCLAPI int TclNRInterpProc(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* 239 */ TCLAPI int TclNRInterpProcCore(Tcl_Interp *interp, Tcl_Obj *procNameObj, int skip, ProcErrorProc *errorProc); /* 240 */ TCLAPI int TclNRRunCallbacks(Tcl_Interp *interp, int result, struct NRE_callback *rootPtr); /* 241 */ TCLAPI int TclNREvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags, const CmdFrame *invoker, int word); /* 242 */ TCLAPI int TclNREvalObjv(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags, Command *cmdPtr); /* 243 */ TCLAPI void TclDbDumpActiveObjects(FILE *outFile); /* 244 */ TCLAPI Tcl_HashTable * TclGetNamespaceChildTable(Tcl_Namespace *nsPtr); /* 245 */ |
︙ | ︙ | |||
550 551 552 553 554 555 556 | void (*reserved0)(void); void (*reserved1)(void); void (*reserved2)(void); void (*tclAllocateFreeObjects) (void); /* 3 */ void (*reserved4)(void); int (*tclCleanupChildren) (Tcl_Interp *interp, int numPids, Tcl_Pid *pidPtr, Tcl_Channel errorChan); /* 5 */ void (*tclCleanupCommand) (Command *cmdPtr); /* 6 */ | | | | | | | | | | | | | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 | void (*reserved0)(void); void (*reserved1)(void); void (*reserved2)(void); void (*tclAllocateFreeObjects) (void); /* 3 */ void (*reserved4)(void); int (*tclCleanupChildren) (Tcl_Interp *interp, int numPids, Tcl_Pid *pidPtr, Tcl_Channel errorChan); /* 5 */ void (*tclCleanupCommand) (Command *cmdPtr); /* 6 */ size_t (*tclCopyAndCollapse) (size_t count, const char *src, char *dst); /* 7 */ void (*reserved8)(void); int (*tclCreatePipeline) (Tcl_Interp *interp, size_t argc, const char **argv, Tcl_Pid **pidArrayPtr, TclFile *inPipePtr, TclFile *outPipePtr, TclFile *errFilePtr); /* 9 */ int (*tclCreateProc) (Tcl_Interp *interp, Namespace *nsPtr, const char *procName, Tcl_Obj *argsPtr, Tcl_Obj *bodyPtr, Proc **procPtrPtr); /* 10 */ void (*tclDeleteCompiledLocalVars) (Interp *iPtr, CallFrame *framePtr); /* 11 */ void (*tclDeleteVars) (Interp *iPtr, TclVarHashTable *tablePtr); /* 12 */ void (*reserved13)(void); int (*tclDumpMemoryInfo) (ClientData clientData, int flags); /* 14 */ void (*reserved15)(void); void (*tclExprFloatError) (Tcl_Interp *interp, double value); /* 16 */ void (*reserved17)(void); void (*reserved18)(void); void (*reserved19)(void); void (*reserved20)(void); void (*reserved21)(void); int (*tclFindElement) (Tcl_Interp *interp, const char *listStr, size_t listLength, const char **elementPtr, const char **nextPtr, size_t *sizePtr, int *bracePtr); /* 22 */ Proc * (*tclFindProc) (Interp *iPtr, const char *procName); /* 23 */ size_t (*tclFormatInt) (char *buffer, long n); /* 24 */ void (*tclFreePackageInfo) (Interp *iPtr); /* 25 */ void (*reserved26)(void); void (*reserved27)(void); Tcl_Channel (*tclpGetDefaultStdChannel) (int type); /* 28 */ void (*reserved29)(void); void (*reserved30)(void); const char * (*tclGetExtension) (const char *name); /* 31 */ int (*tclGetFrame) (Tcl_Interp *interp, const char *str, CallFrame **framePtrPtr); /* 32 */ void (*reserved33)(void); int (*tclGetIntForIndex) (Tcl_Interp *interp, Tcl_Obj *objPtr, ssize_t endValue, ssize_t *indexPtr); /* 34 */ void (*reserved35)(void); void (*reserved36)(void); int (*tclGetLoadedPackages) (Tcl_Interp *interp, const char *targetName); /* 37 */ int (*tclGetNamespaceForQualName) (Tcl_Interp *interp, const char *qualName, Namespace *cxtNsPtr, int flags, Namespace **nsPtrPtr, Namespace **altNsPtrPtr, Namespace **actualCxtPtrPtr, const char **simpleNamePtr); /* 38 */ TclObjCmdProcType (*tclGetObjInterpProc) (void); /* 39 */ int (*tclGetOpenMode) (Tcl_Interp *interp, const char *str, int *seekFlagPtr); /* 40 */ Tcl_Command (*tclGetOriginalCommand) (Tcl_Command command); /* 41 */ const char * (*tclpGetUserHome) (const char *name, Tcl_DString *bufferPtr); /* 42 */ void (*reserved43)(void); int (*tclGuessPackageName) (const char *fileName, Tcl_DString *bufPtr); /* 44 */ int (*tclHideUnsafeCommands) (Tcl_Interp *interp); /* 45 */ int (*tclInExit) (void); /* 46 */ void (*reserved47)(void); void (*reserved48)(void); void (*reserved49)(void); void (*tclInitCompiledLocals) (Tcl_Interp *interp, CallFrame *framePtr, Namespace *nsPtr); /* 50 */ int (*tclInterpInit) (Tcl_Interp *interp); /* 51 */ void (*reserved52)(void); int (*tclInvokeObjectCommand) (ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv); /* 53 */ int (*tclInvokeStringCommand) (ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* 54 */ Proc * (*tclIsProc) (Command *cmdPtr); /* 55 */ void (*reserved56)(void); void (*reserved57)(void); Var * (*tclLookupVar) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, const char *msg, int createPart1, int createPart2, Var **arrayPtrPtr); /* 58 */ void (*reserved59)(void); int (*tclNeedSpace) (const char *start, const char *end); /* 60 */ Tcl_Obj * (*tclNewProcBodyObj) (Proc *procPtr); /* 61 */ int (*tclObjCommandComplete) (Tcl_Obj *cmdPtr); /* 62 */ int (*tclObjInterpProc) (ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* 63 */ int (*tclObjInvoke) (Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags); /* 64 */ void (*reserved65)(void); void (*reserved66)(void); void (*reserved67)(void); void (*reserved68)(void); char * (*tclpAlloc) (size_t size); /* 69 */ void (*reserved70)(void); void (*reserved71)(void); void (*reserved72)(void); void (*reserved73)(void); void (*tclpFree) (char *ptr); /* 74 */ unsigned long (*tclpGetClicks) (void); /* 75 */ unsigned long (*tclpGetSeconds) (void); /* 76 */ void (*reserved77)(void); void (*reserved78)(void); void (*reserved79)(void); void (*reserved80)(void); char * (*tclpRealloc) (char *ptr, size_t size); /* 81 */ void (*reserved82)(void); void (*reserved83)(void); void (*reserved84)(void); void (*reserved85)(void); void (*reserved86)(void); void (*reserved87)(void); char * (*tclPrecTraceProc) (ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags); /* 88 */ |
︙ | ︙ | |||
709 710 711 712 713 714 715 | void (*reserved159)(void); void (*reserved160)(void); int (*tclChannelTransform) (Tcl_Interp *interp, Tcl_Channel chan, Tcl_Obj *cmdObjPtr); /* 161 */ void (*tclChannelEventScriptInvoker) (ClientData clientData, int flags); /* 162 */ const void * (*tclGetInstructionTable) (void); /* 163 */ void (*tclExpandCodeArray) (void *envPtr); /* 164 */ void (*tclpSetInitialEncodings) (void); /* 165 */ | | | | | | 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | void (*reserved159)(void); void (*reserved160)(void); int (*tclChannelTransform) (Tcl_Interp *interp, Tcl_Channel chan, Tcl_Obj *cmdObjPtr); /* 161 */ void (*tclChannelEventScriptInvoker) (ClientData clientData, int flags); /* 162 */ const void * (*tclGetInstructionTable) (void); /* 163 */ void (*tclExpandCodeArray) (void *envPtr); /* 164 */ void (*tclpSetInitialEncodings) (void); /* 165 */ int (*tclListObjSetElement) (Tcl_Interp *interp, Tcl_Obj *listPtr, size_t index, Tcl_Obj *valuePtr); /* 166 */ void (*reserved167)(void); void (*reserved168)(void); int (*tclpUtfNcmp2) (const char *s1, const char *s2, size_t n); /* 169 */ int (*tclCheckInterpTraces) (Tcl_Interp *interp, const char *command, size_t numChars, Command *cmdPtr, int result, int traceFlags, size_t objc, Tcl_Obj *const objv[]); /* 170 */ int (*tclCheckExecutionTraces) (Tcl_Interp *interp, const char *command, size_t numChars, Command *cmdPtr, int result, int traceFlags, size_t objc, Tcl_Obj *const objv[]); /* 171 */ int (*tclInThreadExit) (void); /* 172 */ int (*tclUniCharMatch) (const Tcl_UniChar *string, size_t strLen, const Tcl_UniChar *pattern, size_t ptnLen, int flags); /* 173 */ void (*reserved174)(void); int (*tclCallVarTraces) (Interp *iPtr, Var *arrayPtr, Var *varPtr, const char *part1, const char *part2, int flags, int leaveErrMsg); /* 175 */ void (*tclCleanupVar) (Var *varPtr, Var *arrayPtr); /* 176 */ void (*tclVarErrMsg) (Tcl_Interp *interp, const char *part1, const char *part2, const char *operation, const char *reason); /* 177 */ void (*reserved178)(void); void (*reserved179)(void); void (*reserved180)(void); |
︙ | ︙ | |||
758 759 760 761 762 763 764 | Tcl_Channel (*tclpOpenFileChannel) (Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); /* 208 */ void (*reserved209)(void); void (*reserved210)(void); void (*reserved211)(void); void (*tclpFindExecutable) (const char *argv0); /* 212 */ Tcl_Obj * (*tclGetObjNameOfExecutable) (void); /* 213 */ void (*tclSetObjNameOfExecutable) (Tcl_Obj *name, Tcl_Encoding encoding); /* 214 */ | | | | | | | 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 | Tcl_Channel (*tclpOpenFileChannel) (Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); /* 208 */ void (*reserved209)(void); void (*reserved210)(void); void (*reserved211)(void); void (*tclpFindExecutable) (const char *argv0); /* 212 */ Tcl_Obj * (*tclGetObjNameOfExecutable) (void); /* 213 */ void (*tclSetObjNameOfExecutable) (Tcl_Obj *name, Tcl_Encoding encoding); /* 214 */ void * (*tclStackAlloc) (Tcl_Interp *interp, size_t numBytes); /* 215 */ void (*tclStackFree) (Tcl_Interp *interp, void *freePtr); /* 216 */ int (*tclPushStackFrame) (Tcl_Interp *interp, Tcl_CallFrame **framePtrPtr, Tcl_Namespace *namespacePtr, int isProcCallFrame); /* 217 */ void (*tclPopStackFrame) (Tcl_Interp *interp); /* 218 */ void (*reserved219)(void); void (*reserved220)(void); void (*reserved221)(void); void (*reserved222)(void); void (*reserved223)(void); TclPlatformType * (*tclGetPlatform) (void); /* 224 */ Tcl_Obj * (*tclTraceDictPath) (Tcl_Interp *interp, Tcl_Obj *rootPtr, size_t keyc, Tcl_Obj *const keyv[], int flags); /* 225 */ int (*tclObjBeingDeleted) (Tcl_Obj *objPtr); /* 226 */ void (*tclSetNsPath) (Namespace *nsPtr, size_t pathLength, Tcl_Namespace *pathAry[]); /* 227 */ void (*reserved228)(void); int (*tclPtrMakeUpvar) (Tcl_Interp *interp, Var *otherP1Ptr, const char *myName, int myFlags, int index); /* 229 */ Var * (*tclObjLookupVar) (Tcl_Interp *interp, Tcl_Obj *part1Ptr, const char *part2, int flags, const char *msg, const int createPart1, const int createPart2, Var **arrayPtrPtr); /* 230 */ int (*tclGetNamespaceFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Namespace **nsPtrPtr); /* 231 */ int (*tclEvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags, const CmdFrame *invoker, int word); /* 232 */ void (*tclGetSrcInfoForPc) (CmdFrame *contextPtr); /* 233 */ Var * (*tclVarHashCreateVar) (TclVarHashTable *tablePtr, const char *key, int *newPtr); /* 234 */ void (*tclInitVarHashTable) (TclVarHashTable *tablePtr, Namespace *nsPtr); /* 235 */ void (*reserved236)(void); int (*tclResetCancellation) (Tcl_Interp *interp, int force); /* 237 */ int (*tclNRInterpProc) (ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* 238 */ int (*tclNRInterpProcCore) (Tcl_Interp *interp, Tcl_Obj *procNameObj, int skip, ProcErrorProc *errorProc); /* 239 */ int (*tclNRRunCallbacks) (Tcl_Interp *interp, int result, struct NRE_callback *rootPtr); /* 240 */ int (*tclNREvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags, const CmdFrame *invoker, int word); /* 241 */ int (*tclNREvalObjv) (Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int flags, Command *cmdPtr); /* 242 */ void (*tclDbDumpActiveObjects) (FILE *outFile); /* 243 */ Tcl_HashTable * (*tclGetNamespaceChildTable) (Tcl_Namespace *nsPtr); /* 244 */ Tcl_HashTable * (*tclGetNamespaceCommandTable) (Tcl_Namespace *nsPtr); /* 245 */ int (*tclInitRewriteEnsemble) (Tcl_Interp *interp, int numRemoved, int numInserted, Tcl_Obj *const *objv); /* 246 */ void (*tclResetRewriteEnsemble) (Tcl_Interp *interp, int isRootEnsemble); /* 247 */ int (*tclCopyChannel) (Tcl_Interp *interp, Tcl_Channel inChan, Tcl_Channel outChan, Tcl_WideInt toRead, Tcl_Obj *cmdPtr); /* 248 */ char * (*tclDoubleDigits) (double dv, int ndigits, int flags, int *decpt, int *signum, char **endPtr); /* 249 */ |
︙ | ︙ |
Changes to generic/tclIntPlatDecls.h.
︙ | ︙ | |||
34 35 36 37 38 39 40 | /* 2 */ TCLAPI Tcl_Channel TclpCreateCommandChannel(TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 3 */ TCLAPI int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe); /* 4 */ | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* 2 */ TCLAPI Tcl_Channel TclpCreateCommandChannel(TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 3 */ TCLAPI int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe); /* 4 */ TCLAPI int TclpCreateProcess(Tcl_Interp *interp, size_t argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr); /* Slot 5 is reserved */ /* 6 */ TCLAPI TclFile TclpMakeFile(Tcl_Channel channel, int direction); /* 7 */ |
︙ | ︙ | |||
85 86 87 88 89 90 91 | TCLAPI void TclWinConvertError(DWORD errCode); /* Slot 1 is reserved */ /* 2 */ TCLAPI struct servent * TclWinGetServByName(const char *nm, const char *proto); /* 3 */ TCLAPI int TclWinGetSockOpt(SOCKET s, int level, int optname, | | | | | 85 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 | TCLAPI void TclWinConvertError(DWORD errCode); /* Slot 1 is reserved */ /* 2 */ TCLAPI struct servent * TclWinGetServByName(const char *nm, const char *proto); /* 3 */ TCLAPI int TclWinGetSockOpt(SOCKET s, int level, int optname, char *optval, size_t *optlen); /* 4 */ TCLAPI HINSTANCE TclWinGetTclInstance(void); /* 5 */ TCLAPI int TclUnixWaitForFile(int fd, int mask, int timeout); /* Slot 6 is reserved */ /* 7 */ TCLAPI int TclWinSetSockOpt(SOCKET s, int level, int optname, const char *optval, size_t optlen); /* 8 */ TCLAPI int TclpGetPid(Tcl_Pid pid); /* 9 */ TCLAPI int TclWinGetPlatformId(void); /* Slot 10 is reserved */ /* 11 */ TCLAPI void TclGetAndDetachPids(Tcl_Interp *interp, Tcl_Channel chan); /* 12 */ TCLAPI int TclpCloseFile(TclFile file); /* 13 */ TCLAPI Tcl_Channel TclpCreateCommandChannel(TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 14 */ TCLAPI int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe); /* 15 */ TCLAPI int TclpCreateProcess(Tcl_Interp *interp, size_t argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr); /* 16 */ TCLAPI int TclpIsAtty(int fd); /* 17 */ TCLAPI int TclUnixCopyFile(const char *src, const char *dst, |
︙ | ︙ | |||
160 161 162 163 164 165 166 | /* 2 */ TCLAPI Tcl_Channel TclpCreateCommandChannel(TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 3 */ TCLAPI int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe); /* 4 */ | | | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | /* 2 */ TCLAPI Tcl_Channel TclpCreateCommandChannel(TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 3 */ TCLAPI int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe); /* 4 */ TCLAPI int TclpCreateProcess(Tcl_Interp *interp, size_t argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr); /* Slot 5 is reserved */ /* 6 */ TCLAPI TclFile TclpMakeFile(Tcl_Channel channel, int direction); /* 7 */ |
︙ | ︙ | |||
227 228 229 230 231 232 233 | void *hooks; #if !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */ int (*tclpCloseFile) (TclFile file); /* 1 */ Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */ int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */ | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | void *hooks; #if !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */ int (*tclpCloseFile) (TclFile file); /* 1 */ Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */ int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */ int (*tclpCreateProcess) (Tcl_Interp *interp, size_t argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr); /* 4 */ void (*reserved5)(void); TclFile (*tclpMakeFile) (Tcl_Channel channel, int direction); /* 6 */ TclFile (*tclpOpenFile) (const char *fname, int mode); /* 7 */ int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */ TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */ void (*reserved10)(void); void (*reserved11)(void); |
︙ | ︙ | |||
259 260 261 262 263 264 265 | int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */ int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ #endif /* UNIX */ #if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ void (*tclWinConvertError) (DWORD errCode); /* 0 */ void (*reserved1)(void); struct servent * (*tclWinGetServByName) (const char *nm, const char *proto); /* 2 */ | | | | | 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 | int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */ int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ #endif /* UNIX */ #if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ void (*tclWinConvertError) (DWORD errCode); /* 0 */ void (*reserved1)(void); struct servent * (*tclWinGetServByName) (const char *nm, const char *proto); /* 2 */ int (*tclWinGetSockOpt) (SOCKET s, int level, int optname, char *optval, size_t *optlen); /* 3 */ HINSTANCE (*tclWinGetTclInstance) (void); /* 4 */ int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 5 */ void (*reserved6)(void); int (*tclWinSetSockOpt) (SOCKET s, int level, int optname, const char *optval, size_t optlen); /* 7 */ int (*tclpGetPid) (Tcl_Pid pid); /* 8 */ int (*tclWinGetPlatformId) (void); /* 9 */ void (*reserved10)(void); void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 11 */ int (*tclpCloseFile) (TclFile file); /* 12 */ Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 13 */ int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 14 */ int (*tclpCreateProcess) (Tcl_Interp *interp, size_t argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr); /* 15 */ int (*tclpIsAtty) (int fd); /* 16 */ int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 17 */ TclFile (*tclpMakeFile) (Tcl_Channel channel, int direction); /* 18 */ TclFile (*tclpOpenFile) (const char *fname, int mode); /* 19 */ void (*tclWinAddProcess) (HANDLE hProcess, DWORD id); /* 20 */ void (*reserved21)(void); TclFile (*tclpCreateTempFile) (const char *contents); /* 22 */ |
︙ | ︙ | |||
293 294 295 296 297 298 299 | int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */ int (*tclpCloseFile) (TclFile file); /* 1 */ Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */ int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */ | | | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */ int (*tclpCloseFile) (TclFile file); /* 1 */ Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */ int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */ int (*tclpCreateProcess) (Tcl_Interp *interp, size_t argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr); /* 4 */ void (*reserved5)(void); TclFile (*tclpMakeFile) (Tcl_Channel channel, int direction); /* 6 */ TclFile (*tclpOpenFile) (const char *fname, int mode); /* 7 */ int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */ TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */ void (*reserved10)(void); void (*reserved11)(void); |
︙ | ︙ |
Changes to generic/tclInterp.c.
︙ | ︙ | |||
47 48 49 50 51 52 53 | * This is used by alias deletion to remove * the alias from the slave interpreter alias * table. */ struct Target *targetPtr; /* Entry for target command in master. This is * used in the master interpreter to map back * from the target command to aliases * redirecting to it. */ | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | * This is used by alias deletion to remove * the alias from the slave interpreter alias * table. */ struct Target *targetPtr; /* Entry for target command in master. This is * used in the master interpreter to map back * from the target command to aliases * redirecting to it. */ size_t objc; /* Count of Tcl_Obj in the prefix of the * target command to be invoked in the target * interpreter. Additional arguments specified * when calling the alias in the slave interp * will be appended to the prefix before the * command is invoked. */ Tcl_Obj *objPtr; /* The first actual prefix object - the target * command name; this has to be at the end of |
︙ | ︙ | |||
211 212 213 214 215 216 217 | /* * Prototypes for local static functions: */ static int AliasCreate(Tcl_Interp *interp, Tcl_Interp *slaveInterp, Tcl_Interp *masterInterp, | | | < < | < < | | | | | | | | < | | | | | | 211 212 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 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 | /* * Prototypes for local static functions: */ static int AliasCreate(Tcl_Interp *interp, Tcl_Interp *slaveInterp, Tcl_Interp *masterInterp, Tcl_Obj *namePtr, Tcl_Obj *targetPtr, size_t objc, Tcl_Obj *const objv[]); static int AliasDelete(Tcl_Interp *interp, Tcl_Interp *slaveInterp, Tcl_Obj *namePtr); static int AliasDescribe(Tcl_Interp *interp, Tcl_Interp *slaveInterp, Tcl_Obj *objPtr); static int AliasList(Tcl_Interp *interp, Tcl_Interp *slaveInterp); static Tcl_ObjCmdProc AliasObjCmd; static Tcl_ObjCmdProc AliasNRCmd; static void AliasObjCmdDeleteProc(ClientData clientData); static Tcl_Interp * GetInterp(Tcl_Interp *interp, Tcl_Obj *pathPtr); static Tcl_Interp * GetInterp2(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static void InterpInfoDeleteProc(ClientData clientData, Tcl_Interp *interp); static int SlaveBgerror(Tcl_Interp *interp, Tcl_Interp *slaveInterp, size_t objc, Tcl_Obj *const objv[]); static Tcl_Interp * SlaveCreate(Tcl_Interp *interp, Tcl_Obj *pathPtr, int safe); static int SlaveDebugCmd(Tcl_Interp *interp, Tcl_Interp *slaveInterp, size_t objc, Tcl_Obj *const objv[]); static int SlaveEval(Tcl_Interp *interp, Tcl_Interp *slaveInterp, size_t objc, Tcl_Obj *const objv[]); static int SlaveExpose(Tcl_Interp *interp, Tcl_Interp *slaveInterp, size_t objc, Tcl_Obj *const objv[]); static int SlaveHide(Tcl_Interp *interp, Tcl_Interp *slaveInterp, size_t objc, Tcl_Obj *const objv[]); static int SlaveHidden(Tcl_Interp *interp, Tcl_Interp *slaveInterp); static int SlaveInvokeHidden(Tcl_Interp *interp, Tcl_Interp *slaveInterp, const char *namespaceName, size_t objc, Tcl_Obj *const objv[]); static int SlaveMarkTrusted(Tcl_Interp *interp, Tcl_Interp *slaveInterp); static Tcl_ObjCmdProc SlaveObjCmd; static void SlaveObjCmdDeleteProc(ClientData clientData); static int SlaveRecursionLimit(Tcl_Interp *interp, Tcl_Interp *slaveInterp, size_t objc, Tcl_Obj *const objv[]); static int SlaveCommandLimitCmd(Tcl_Interp *interp, Tcl_Interp *slaveInterp, size_t consumedObjc, size_t objc, Tcl_Obj *const objv[]); static int SlaveTimeLimitCmd(Tcl_Interp *interp, Tcl_Interp *slaveInterp, size_t consumedObjc, size_t objc, Tcl_Obj *const objv[]); static void InheritLimitsFromMaster(Tcl_Interp *slaveInterp, Tcl_Interp *masterInterp); static void SetScriptLimitCallback(Tcl_Interp *interp, int type, Tcl_Interp *targetInterp, Tcl_Obj *scriptObj); static void CallScriptLimitCallback(ClientData clientData, Tcl_Interp *interp); static void DeleteScriptLimitCallback(ClientData clientData); |
︙ | ︙ | |||
588 589 590 591 592 593 594 | * See the user documentation. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_InterpObjCmd( | | | | | | | 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 | * See the user documentation. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_InterpObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { return Tcl_NRCallObjProc(interp, NRInterpCmd, clientData, objc, objv); } static int NRInterpCmd( ClientData clientData, /* Unused. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Interp *slaveInterp; int index; static const char *const options[] = { "alias", "aliases", "bgerror", "cancel", "create", "debug", "delete", |
︙ | ︙ | |||
812 813 814 815 816 817 818 | Tcl_CmdInfo cmdInfo; sprintf(buf, "interp%d", i); if (Tcl_GetCommandInfo(interp, buf, &cmdInfo) == 0) { break; } } | | | 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 | Tcl_CmdInfo cmdInfo; sprintf(buf, "interp%d", i); if (Tcl_GetCommandInfo(interp, buf, &cmdInfo) == 0) { break; } } slavePtr = Tcl_NewStringObj(buf, TCL_STRLEN); } if (SlaveCreate(interp, slavePtr, safe) == NULL) { if (buf[0] != '\0') { Tcl_DecrRefCount(slavePtr); } return TCL_ERROR; } |
︙ | ︙ | |||
847 848 849 850 851 852 853 | for (i = 2; i < objc; i++) { slaveInterp = GetInterp(interp, objv[i]); if (slaveInterp == NULL) { return TCL_ERROR; } else if (slaveInterp == interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 | for (i = 2; i < objc; i++) { slaveInterp = GetInterp(interp, objv[i]); if (slaveInterp == NULL) { return TCL_ERROR; } else if (slaveInterp == interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot delete the current interpreter", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "DELETESELF", NULL); return TCL_ERROR; } iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo; Tcl_DeleteCommandFromToken(iiPtr->slave.masterInterp, iiPtr->slave.interpCmd); |
︙ | ︙ | |||
1025 1026 1027 1028 1029 1030 1031 | } iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo; resultPtr = Tcl_NewObj(); hPtr = Tcl_FirstHashEntry(&iiPtr->master.slaveTable, &hashSearch); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&hashSearch)) { string = Tcl_GetHashKey(&iiPtr->master.slaveTable, hPtr); Tcl_ListObjAppendElement(NULL, resultPtr, | | | 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 | } iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo; resultPtr = Tcl_NewObj(); hPtr = Tcl_FirstHashEntry(&iiPtr->master.slaveTable, &hashSearch); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&hashSearch)) { string = Tcl_GetHashKey(&iiPtr->master.slaveTable, hPtr); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(string, TCL_STRLEN)); } Tcl_SetObjResult(interp, resultPtr); return TCL_OK; } case OPT_TRANSFER: case OPT_SHARE: { Tcl_Interp *masterInterp; /* The master of the slave. */ |
︙ | ︙ | |||
1134 1135 1136 1137 1138 1139 1140 | *--------------------------------------------------------------------------- */ static Tcl_Interp * GetInterp2( Tcl_Interp *interp, /* Default interp if no interp was specified * on the command line. */ | | | 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 | *--------------------------------------------------------------------------- */ static Tcl_Interp * GetInterp2( Tcl_Interp *interp, /* Default interp if no interp was specified * on the command line. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc == 2) { return interp; } else if (objc == 3) { return GetInterp(interp, objv[2]); } else { |
︙ | ︙ | |||
1169 1170 1171 1172 1173 1174 1175 | int Tcl_CreateAlias( Tcl_Interp *slaveInterp, /* Interpreter for source command. */ const char *slaveCmd, /* Command to install in slave. */ Tcl_Interp *targetInterp, /* Interpreter for target command. */ const char *targetCmd, /* Name of target command. */ | | | | | | | 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 | int Tcl_CreateAlias( Tcl_Interp *slaveInterp, /* Interpreter for source command. */ const char *slaveCmd, /* Command to install in slave. */ Tcl_Interp *targetInterp, /* Interpreter for target command. */ const char *targetCmd, /* Name of target command. */ size_t argc, /* How many additional arguments? */ const char *const *argv) /* These are the additional args. */ { Tcl_Obj *slaveObjPtr, *targetObjPtr; Tcl_Obj **objv; size_t i; int result; objv = TclStackAlloc(slaveInterp, (unsigned) sizeof(Tcl_Obj *) * argc); for (i = 0; i < argc; i++) { objv[i] = Tcl_NewStringObj(argv[i], TCL_STRLEN); Tcl_IncrRefCount(objv[i]); } slaveObjPtr = Tcl_NewStringObj(slaveCmd, TCL_STRLEN); Tcl_IncrRefCount(slaveObjPtr); targetObjPtr = Tcl_NewStringObj(targetCmd, TCL_STRLEN); Tcl_IncrRefCount(targetObjPtr); result = AliasCreate(slaveInterp, slaveInterp, targetInterp, slaveObjPtr, targetObjPtr, argc, objv); for (i = 0; i < argc; i++) { Tcl_DecrRefCount(objv[i]); |
︙ | ︙ | |||
1224 1225 1226 1227 1228 1229 1230 | int Tcl_CreateAliasObj( Tcl_Interp *slaveInterp, /* Interpreter for source command. */ const char *slaveCmd, /* Command to install in slave. */ Tcl_Interp *targetInterp, /* Interpreter for target command. */ const char *targetCmd, /* Name of target command. */ | | | | | 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 | int Tcl_CreateAliasObj( Tcl_Interp *slaveInterp, /* Interpreter for source command. */ const char *slaveCmd, /* Command to install in slave. */ Tcl_Interp *targetInterp, /* Interpreter for target command. */ const char *targetCmd, /* Name of target command. */ size_t objc, /* How many additional arguments? */ Tcl_Obj *const objv[]) /* Argument vector. */ { Tcl_Obj *slaveObjPtr, *targetObjPtr; int result; slaveObjPtr = Tcl_NewStringObj(slaveCmd, TCL_STRLEN); Tcl_IncrRefCount(slaveObjPtr); targetObjPtr = Tcl_NewStringObj(targetCmd, TCL_STRLEN); Tcl_IncrRefCount(targetObjPtr); result = AliasCreate(slaveInterp, slaveInterp, targetInterp, slaveObjPtr, targetObjPtr, objc, objv); Tcl_DecrRefCount(slaveObjPtr); Tcl_DecrRefCount(targetObjPtr); |
︙ | ︙ | |||
1267 1268 1269 1270 1271 1272 1273 | int Tcl_GetAlias( Tcl_Interp *interp, /* Interp to start search from. */ const char *aliasName, /* Name of alias to find. */ Tcl_Interp **targetInterpPtr, /* (Return) target interpreter. */ const char **targetNamePtr, /* (Return) name of target command. */ | | | | 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 | int Tcl_GetAlias( Tcl_Interp *interp, /* Interp to start search from. */ const char *aliasName, /* Name of alias to find. */ Tcl_Interp **targetInterpPtr, /* (Return) target interpreter. */ const char **targetNamePtr, /* (Return) name of target command. */ size_t *argcPtr, /* (Return) count of addnl args. */ const char ***argvPtr) /* (Return) additional arguments. */ { InterpInfo *iiPtr = (InterpInfo *) ((Interp *) interp)->interpInfo; Tcl_HashEntry *hPtr; Alias *aliasPtr; size_t i, objc; Tcl_Obj **objv; hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "alias \"%s\" not found", aliasName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS", aliasName, NULL); |
︙ | ︙ | |||
1329 1330 1331 1332 1333 1334 1335 | int Tcl_GetAliasObj( Tcl_Interp *interp, /* Interp to start search from. */ const char *aliasName, /* Name of alias to find. */ Tcl_Interp **targetInterpPtr, /* (Return) target interpreter. */ const char **targetNamePtr, /* (Return) name of target command. */ | | | | 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 | int Tcl_GetAliasObj( Tcl_Interp *interp, /* Interp to start search from. */ const char *aliasName, /* Name of alias to find. */ Tcl_Interp **targetInterpPtr, /* (Return) target interpreter. */ const char **targetNamePtr, /* (Return) name of target command. */ size_t *objcPtr, /* (Return) count of addnl args. */ Tcl_Obj ***objvPtr) /* (Return) additional args. */ { InterpInfo *iiPtr = (InterpInfo *) ((Interp *) interp)->interpInfo; Tcl_HashEntry *hPtr; Alias *aliasPtr; size_t objc; Tcl_Obj **objv; hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "alias \"%s\" not found", aliasName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS", aliasName, NULL); |
︙ | ︙ | |||
1493 1494 1495 1496 1497 1498 1499 | Tcl_Interp *interp, /* Interp for error reporting. */ Tcl_Interp *slaveInterp, /* Interp where alias cmd will live or from * which alias will be deleted. */ Tcl_Interp *masterInterp, /* Interp in which target command will be * invoked. */ Tcl_Obj *namePtr, /* Name of alias cmd. */ Tcl_Obj *targetNamePtr, /* Name of target cmd. */ | | | 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 | Tcl_Interp *interp, /* Interp for error reporting. */ Tcl_Interp *slaveInterp, /* Interp where alias cmd will live or from * which alias will be deleted. */ Tcl_Interp *masterInterp, /* Interp in which target command will be * invoked. */ Tcl_Obj *namePtr, /* Name of alias cmd. */ Tcl_Obj *targetNamePtr, /* Name of target cmd. */ size_t objc, /* Additional arguments to store */ Tcl_Obj *const objv[]) /* with alias. */ { Alias *aliasPtr; Tcl_HashEntry *hPtr; Target *targetPtr; Slave *slavePtr; Master *masterPtr; |
︙ | ︙ | |||
1788 1789 1790 1791 1792 1793 1794 | *---------------------------------------------------------------------- */ static int AliasNRCmd( ClientData clientData, /* Alias record. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 | *---------------------------------------------------------------------- */ static int AliasNRCmd( ClientData clientData, /* Alias record. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument vector. */ { Interp *iPtr = (Interp *) interp; Alias *aliasPtr = clientData; int prefc, cmdc, i; Tcl_Obj **prefv, **cmdv; int isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL); |
︙ | ︙ | |||
1852 1853 1854 1855 1856 1857 1858 | return Tcl_NREvalObj(interp, listPtr, flags); } static int AliasObjCmd( ClientData clientData, /* Alias record. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 | return Tcl_NREvalObj(interp, listPtr, flags); } static int AliasObjCmd( ClientData clientData, /* Alias record. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument vector. */ { #define ALIAS_CMDV_PREALLOC 10 Alias *aliasPtr = clientData; Tcl_Interp *targetInterp = aliasPtr->targetInterp; int result, prefc, cmdc, i; Tcl_Obj **prefv, **cmdv; |
︙ | ︙ | |||
2035 2036 2037 2038 2039 2040 2041 | Tcl_Interp *interp, /* Interpreter to start search at. */ const char *slavePath, /* Name of slave to create. */ int isSafe) /* Should new slave be "safe" ? */ { Tcl_Obj *pathPtr; Tcl_Interp *slaveInterp; | | | 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 | Tcl_Interp *interp, /* Interpreter to start search at. */ const char *slavePath, /* Name of slave to create. */ int isSafe) /* Should new slave be "safe" ? */ { Tcl_Obj *pathPtr; Tcl_Interp *slaveInterp; pathPtr = Tcl_NewStringObj(slavePath, TCL_STRLEN); slaveInterp = SlaveCreate(interp, pathPtr, isSafe); Tcl_DecrRefCount(pathPtr); return slaveInterp; } /* |
︙ | ︙ | |||
2066 2067 2068 2069 2070 2071 2072 | Tcl_GetSlave( Tcl_Interp *interp, /* Interpreter to start search from. */ const char *slavePath) /* Path of slave to find. */ { Tcl_Obj *pathPtr; Tcl_Interp *slaveInterp; | | | 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 | Tcl_GetSlave( Tcl_Interp *interp, /* Interpreter to start search from. */ const char *slavePath) /* Path of slave to find. */ { Tcl_Obj *pathPtr; Tcl_Interp *slaveInterp; pathPtr = Tcl_NewStringObj(slavePath, TCL_STRLEN); slaveInterp = GetInterp(interp, pathPtr); Tcl_DecrRefCount(pathPtr); return slaveInterp; } /* |
︙ | ︙ | |||
2212 2213 2214 2215 2216 2217 2218 | } iiPtr = (InterpInfo *) ((Interp *) targetInterp)->interpInfo; if (Tcl_GetInterpPath(askingInterp, iiPtr->slave.masterInterp) != TCL_OK){ return TCL_ERROR; } Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(askingInterp), Tcl_NewStringObj(Tcl_GetHashKey(&iiPtr->master.slaveTable, | | | 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 | } iiPtr = (InterpInfo *) ((Interp *) targetInterp)->interpInfo; if (Tcl_GetInterpPath(askingInterp, iiPtr->slave.masterInterp) != TCL_OK){ return TCL_ERROR; } Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(askingInterp), Tcl_NewStringObj(Tcl_GetHashKey(&iiPtr->master.slaveTable, iiPtr->slave.slaveEntryPtr), TCL_STRLEN)); return TCL_OK; } /* *---------------------------------------------------------------------- * * GetInterp -- |
︙ | ︙ | |||
2242 2243 2244 2245 2246 2247 2248 | Tcl_Interp *interp, /* Interp. to start search from. */ Tcl_Obj *pathPtr) /* List object containing name of interp. to * be found. */ { Tcl_HashEntry *hPtr; /* Search element. */ Slave *slavePtr; /* Interim slave record. */ Tcl_Obj **objv; | | | 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 | Tcl_Interp *interp, /* Interp. to start search from. */ Tcl_Obj *pathPtr) /* List object containing name of interp. to * be found. */ { Tcl_HashEntry *hPtr; /* Search element. */ Slave *slavePtr; /* Interim slave record. */ Tcl_Obj **objv; size_t objc, i; Tcl_Interp *searchInterp; /* Interim storage for interp. to find. */ InterpInfo *masterInfoPtr; if (TclListObjGetElements(interp, pathPtr, &objc, &objv) != TCL_OK) { return NULL; } |
︙ | ︙ | |||
2296 2297 2298 2299 2300 2301 2302 | *---------------------------------------------------------------------- */ static int SlaveBgerror( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* Interp in which limit is set/queried. */ | | | | | 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 | *---------------------------------------------------------------------- */ static int SlaveBgerror( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* Interp in which limit is set/queried. */ size_t objc, /* Set or Query. */ Tcl_Obj *const objv[]) /* Argument strings. */ { if (objc) { size_t length; if (TCL_ERROR == TclListObjLength(NULL, objv[0], &length) || (length < 1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cmdPrefix must be list of length >= 1", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BGERRORFORMAT", NULL); return TCL_ERROR; } TclSetBgErrorHandler(slaveInterp, objv[0]); } Tcl_SetObjResult(interp, TclGetBgErrorHandler(slaveInterp)); |
︙ | ︙ | |||
2346 2347 2348 2349 2350 2351 2352 | int safe) /* Should we make it "safe"? */ { Tcl_Interp *masterInterp, *slaveInterp; Slave *slavePtr; InterpInfo *masterInfoPtr; Tcl_HashEntry *hPtr; const char *path; | | > | 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 | int safe) /* Should we make it "safe"? */ { Tcl_Interp *masterInterp, *slaveInterp; Slave *slavePtr; InterpInfo *masterInfoPtr; Tcl_HashEntry *hPtr; const char *path; int isNew; size_t objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, pathPtr, &objc, &objv) != TCL_OK) { return NULL; } if (objc < 2) { masterInterp = interp; |
︙ | ︙ | |||
2472 2473 2474 2475 2476 2477 2478 | *---------------------------------------------------------------------- */ static int SlaveObjCmd( ClientData clientData, /* Slave interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 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 | *---------------------------------------------------------------------- */ static int SlaveObjCmd( ClientData clientData, /* Slave interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, NRSlaveCmd, clientData, objc, objv); } static int NRSlaveCmd( ClientData clientData, /* Slave interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Interp *slaveInterp = clientData; int index; static const char *const options[] = { "alias", "aliases", "bgerror", "debug", "eval", "expose", "hide", "hidden", |
︙ | ︙ | |||
2733 2734 2735 2736 2737 2738 2739 | */ static int SlaveDebugCmd( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* The slave interpreter in which command * will be evaluated. */ | | | | 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 | */ static int SlaveDebugCmd( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* The slave interpreter in which command * will be evaluated. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *const debugTypes[] = { "-frame", NULL }; enum DebugTypes { DEBUG_TYPE_FRAME }; int debugType; Interp *iPtr; Tcl_Obj *resultPtr; iPtr = (Interp *) slaveInterp; if (objc == 0) { resultPtr = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj("-frame", TCL_STRLEN)); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewBooleanObj(iPtr->flags & INTERP_DEBUG_FRAME)); Tcl_SetObjResult(interp, resultPtr); } else { if (Tcl_GetIndexFromObj(interp, objv[0], debugTypes, "debug option", 0, &debugType) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
2804 2805 2806 2807 2808 2809 2810 | */ static int SlaveEval( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* The slave interpreter in which command * will be evaluated. */ | | | 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 | */ static int SlaveEval( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* The slave interpreter in which command * will be evaluated. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int result; /* * TIP #285: If necessary, reset the cancellation flags for the slave * interpreter now; otherwise, canceling a script in a master interpreter |
︙ | ︙ | |||
2867 2868 2869 2870 2871 2872 2873 | *---------------------------------------------------------------------- */ static int SlaveExpose( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* Interp in which command will be exposed. */ | | | | 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 | *---------------------------------------------------------------------- */ static int SlaveExpose( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* Interp in which command will be exposed. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings. */ { const char *name; if (Tcl_IsSafe(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "permission denied: safe interpreter cannot expose commands", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE", NULL); return TCL_ERROR; } name = TclGetString(objv[(objc == 1) ? 0 : 1]); if (Tcl_ExposeCommand(slaveInterp, TclGetString(objv[0]), |
︙ | ︙ | |||
2911 2912 2913 2914 2915 2916 2917 | *---------------------------------------------------------------------- */ static int SlaveRecursionLimit( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* Interp in which limit is set/queried. */ | | | > | | | 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 | *---------------------------------------------------------------------- */ static int SlaveRecursionLimit( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* Interp in which limit is set/queried. */ size_t objc, /* Set or Query. */ Tcl_Obj *const objv[]) /* Argument strings. */ { Interp *iPtr; int limit; if (objc) { if (Tcl_IsSafe(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("permission denied: " "safe interpreters cannot change recursion limit", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE", NULL); return TCL_ERROR; } if (TclGetIntFromObj(interp, objv[0], &limit) == TCL_ERROR) { return TCL_ERROR; } if (limit <= 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "recursion limit must be > 0", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADLIMIT", NULL); return TCL_ERROR; } Tcl_SetRecursionLimit(slaveInterp, limit); iPtr = (Interp *) slaveInterp; if (interp == slaveInterp && iPtr->numLevels > limit) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "falling back due to new recursion limit", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "RECURSION", NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, objv[0]); return TCL_OK; } else { limit = Tcl_SetRecursionLimit(slaveInterp, 0); |
︙ | ︙ | |||
2973 2974 2975 2976 2977 2978 2979 | *---------------------------------------------------------------------- */ static int SlaveHide( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* Interp in which command will be exposed. */ | | | | 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 | *---------------------------------------------------------------------- */ static int SlaveHide( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* Interp in which command will be exposed. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings. */ { const char *name; if (Tcl_IsSafe(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "permission denied: safe interpreter cannot hide commands", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE", NULL); return TCL_ERROR; } name = TclGetString(objv[(objc == 1) ? 0 : 1]); if (Tcl_HideCommand(slaveInterp, TclGetString(objv[0]), name) != TCL_OK) { |
︙ | ︙ | |||
3027 3028 3029 3030 3031 3032 3033 | Tcl_HashSearch hSearch; /* For local searches. */ hTblPtr = ((Interp *) slaveInterp)->hiddenCmdTablePtr; if (hTblPtr != NULL) { for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { | | | | 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 | Tcl_HashSearch hSearch; /* For local searches. */ hTblPtr = ((Interp *) slaveInterp)->hiddenCmdTablePtr; if (hTblPtr != NULL) { for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { Tcl_ListObjAppendElement(NULL, listObjPtr, Tcl_NewStringObj( Tcl_GetHashKey(hTblPtr, hPtr), TCL_STRLEN)); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; } /* |
︙ | ︙ | |||
3057 3058 3059 3060 3061 3062 3063 | static int SlaveInvokeHidden( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* The slave interpreter in which command will * be invoked. */ const char *namespaceName, /* The namespace to use, if any. */ | | | | 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 | static int SlaveInvokeHidden( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp, /* The slave interpreter in which command will * be invoked. */ const char *namespaceName, /* The namespace to use, if any. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int result; if (Tcl_IsSafe(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "not allowed to invoke hidden commands from safe interpreter", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE", NULL); return TCL_ERROR; } Tcl_Preserve(slaveInterp); Tcl_AllowExceptions(slaveInterp); |
︙ | ︙ | |||
3142 3143 3144 3145 3146 3147 3148 | Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp) /* The slave interpreter which will be marked * trusted. */ { if (Tcl_IsSafe(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "permission denied: safe interpreter cannot mark trusted", | | | 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 | Tcl_Interp *interp, /* Interp for error return. */ Tcl_Interp *slaveInterp) /* The slave interpreter which will be marked * trusted. */ { if (Tcl_IsSafe(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "permission denied: safe interpreter cannot mark trusted", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE", NULL); return TCL_ERROR; } ((Interp *) slaveInterp)->flags &= ~SAFE_INTERP; return TCL_OK; } |
︙ | ︙ | |||
3401 3402 3403 3404 3405 3406 3407 | iPtr->limit.exceeded |= TCL_LIMIT_COMMANDS; Tcl_Preserve(interp); RunLimitHandlers(iPtr->limit.cmdHandlers, interp); if (iPtr->limit.cmdCount >= iPtr->cmdCount) { iPtr->limit.exceeded &= ~TCL_LIMIT_COMMANDS; } else if (iPtr->limit.exceeded & TCL_LIMIT_COMMANDS) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 | iPtr->limit.exceeded |= TCL_LIMIT_COMMANDS; Tcl_Preserve(interp); RunLimitHandlers(iPtr->limit.cmdHandlers, interp); if (iPtr->limit.cmdCount >= iPtr->cmdCount) { iPtr->limit.exceeded &= ~TCL_LIMIT_COMMANDS; } else if (iPtr->limit.exceeded & TCL_LIMIT_COMMANDS) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command count limit exceeded", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LIMIT", "COMMANDS", NULL); Tcl_Release(interp); return TCL_ERROR; } Tcl_Release(interp); } |
︙ | ︙ | |||
3427 3428 3429 3430 3431 3432 3433 | RunLimitHandlers(iPtr->limit.timeHandlers, interp); if (iPtr->limit.time.sec > now.sec || (iPtr->limit.time.sec == now.sec && iPtr->limit.time.usec >= now.usec)) { iPtr->limit.exceeded &= ~TCL_LIMIT_TIME; } else if (iPtr->limit.exceeded & TCL_LIMIT_TIME) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 | RunLimitHandlers(iPtr->limit.timeHandlers, interp); if (iPtr->limit.time.sec > now.sec || (iPtr->limit.time.sec == now.sec && iPtr->limit.time.usec >= now.usec)) { iPtr->limit.exceeded &= ~TCL_LIMIT_TIME; } else if (iPtr->limit.exceeded & TCL_LIMIT_TIME) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "time limit exceeded", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LIMIT", "TIME", NULL); Tcl_Release(interp); return TCL_ERROR; } Tcl_Release(interp); } } |
︙ | ︙ | |||
4409 4410 4411 4412 4413 4414 4415 | *---------------------------------------------------------------------- */ static int SlaveCommandLimitCmd( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Interp *slaveInterp, /* Interpreter being adjusted. */ | | | | 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 | *---------------------------------------------------------------------- */ static int SlaveCommandLimitCmd( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Interp *slaveInterp, /* Interpreter being adjusted. */ size_t consumedObjc, /* Number of args already parsed. */ size_t objc, /* Total number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *const options[] = { "-command", "-granularity", "-value", NULL }; enum Options { OPT_CMD, OPT_GRAN, OPT_VAL |
︙ | ︙ | |||
4434 4435 4436 4437 4438 4439 4440 | * interpreter's limits; it may only manipulate its children. Note that * the low level API enforces this with Tcl_Panic, which we want to * avoid. [Bug 3398794] */ if (interp == slaveInterp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | > | | > | | > | | 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 | * interpreter's limits; it may only manipulate its children. Note that * the low level API enforces this with Tcl_Panic, which we want to * avoid. [Bug 3398794] */ if (interp == slaveInterp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "limits on current interpreter inaccessible", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "SELF", NULL); return TCL_ERROR; } if (objc == consumedObjc) { Tcl_Obj *dictPtr; TclNewObj(dictPtr); key.interp = slaveInterp; key.type = TCL_LIMIT_COMMANDS; hPtr = Tcl_FindHashEntry(&iPtr->limit.callbacks, (char *) &key); if (hPtr != NULL) { limitCBPtr = Tcl_GetHashValue(hPtr); if (limitCBPtr != NULL && limitCBPtr->scriptObj != NULL) { Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[0], TCL_STRLEN), limitCBPtr->scriptObj); } else { goto putEmptyCommandInDict; } } else { Tcl_Obj *empty; putEmptyCommandInDict: TclNewObj(empty); Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[0], TCL_STRLEN), empty); } Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[1], TCL_STRLEN), Tcl_NewIntObj(Tcl_LimitGetGranularity(slaveInterp, TCL_LIMIT_COMMANDS))); if (Tcl_LimitTypeEnabled(slaveInterp, TCL_LIMIT_COMMANDS)) { Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[2], TCL_STRLEN), Tcl_NewIntObj(Tcl_LimitGetCommands(slaveInterp))); } else { Tcl_Obj *empty; TclNewObj(empty); Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[2], TCL_STRLEN), empty); } Tcl_SetObjResult(interp, dictPtr); return TCL_OK; } else if (objc == consumedObjc+1) { if (Tcl_GetIndexFromObj(interp, objv[consumedObjc], options, "option", 0, &index) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
4511 4512 4513 4514 4515 4516 4517 | break; } return TCL_OK; } else if ((objc-consumedObjc) & 1 /* isOdd(objc-consumedObjc) */) { Tcl_WrongNumArgs(interp, consumedObjc, objv, "?-option value ...?"); return TCL_ERROR; } else { | | | | > | 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 | break; } return TCL_OK; } else if ((objc-consumedObjc) & 1 /* isOdd(objc-consumedObjc) */) { Tcl_WrongNumArgs(interp, consumedObjc, objv, "?-option value ...?"); return TCL_ERROR; } else { size_t i, scriptLen = 0, limitLen = 0; Tcl_Obj *scriptObj = NULL, *granObj = NULL, *limitObj = NULL; int gran = 0, limit = 0; for (i=consumedObjc ; i<objc ; i+=2) { if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum Options) index) { case OPT_CMD: scriptObj = objv[i+1]; (void) Tcl_GetStringFromObj(objv[i+1], &scriptLen); break; case OPT_GRAN: granObj = objv[i+1]; if (TclGetIntFromObj(interp, objv[i+1], &gran) != TCL_OK) { return TCL_ERROR; } if (gran < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "granularity must be at least 1", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADVALUE", NULL); return TCL_ERROR; } break; case OPT_VAL: limitObj = objv[i+1]; (void) Tcl_GetStringFromObj(objv[i+1], &limitLen); if (limitLen == 0) { break; } if (TclGetIntFromObj(interp, objv[i+1], &limit) != TCL_OK) { return TCL_ERROR; } if (limit < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command limit value must be at least 0", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADVALUE", NULL); return TCL_ERROR; } break; } } |
︙ | ︙ | |||
4595 4596 4597 4598 4599 4600 4601 | * Depends on the arguments. * *---------------------------------------------------------------------- */ static int SlaveTimeLimitCmd( | | | | | | | 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 | * Depends on the arguments. * *---------------------------------------------------------------------- */ static int SlaveTimeLimitCmd( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Interp *slaveInterp, /* Interpreter being adjusted. */ size_t consumedObjc, /* Number of args already parsed. */ size_t objc, /* Total number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *const options[] = { "-command", "-granularity", "-milliseconds", "-seconds", NULL }; enum Options { OPT_CMD, OPT_GRAN, OPT_MILLI, OPT_SEC }; |
︙ | ︙ | |||
4622 4623 4624 4625 4626 4627 4628 | * interpreter's limits; it may only manipulate its children. Note that * the low level API enforces this with Tcl_Panic, which we want to * avoid. [Bug 3398794] */ if (interp == slaveInterp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | > | | > | | > | > | | | 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 | * interpreter's limits; it may only manipulate its children. Note that * the low level API enforces this with Tcl_Panic, which we want to * avoid. [Bug 3398794] */ if (interp == slaveInterp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "limits on current interpreter inaccessible", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "SELF", NULL); return TCL_ERROR; } if (objc == consumedObjc) { Tcl_Obj *dictPtr; TclNewObj(dictPtr); key.interp = slaveInterp; key.type = TCL_LIMIT_TIME; hPtr = Tcl_FindHashEntry(&iPtr->limit.callbacks, (char *) &key); if (hPtr != NULL) { limitCBPtr = Tcl_GetHashValue(hPtr); if (limitCBPtr != NULL && limitCBPtr->scriptObj != NULL) { Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[0], TCL_STRLEN), limitCBPtr->scriptObj); } else { goto putEmptyCommandInDict; } } else { Tcl_Obj *empty; putEmptyCommandInDict: TclNewObj(empty); Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[0], TCL_STRLEN), empty); } Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[1], TCL_STRLEN), Tcl_NewIntObj(Tcl_LimitGetGranularity(slaveInterp, TCL_LIMIT_TIME))); if (Tcl_LimitTypeEnabled(slaveInterp, TCL_LIMIT_TIME)) { Tcl_Time limitMoment; Tcl_LimitGetTime(slaveInterp, &limitMoment); Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[2], TCL_STRLEN), Tcl_NewLongObj(limitMoment.usec/1000)); Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[3], TCL_STRLEN), Tcl_NewLongObj(limitMoment.sec)); } else { Tcl_Obj *empty; TclNewObj(empty); Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[2], TCL_STRLEN), empty); Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[3], TCL_STRLEN), empty); } Tcl_SetObjResult(interp, dictPtr); return TCL_OK; } else if (objc == consumedObjc+1) { if (Tcl_GetIndexFromObj(interp, objv[consumedObjc], options, "option", 0, &index) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
4716 4717 4718 4719 4720 4721 4722 | break; } return TCL_OK; } else if ((objc-consumedObjc) & 1 /* isOdd(objc-consumedObjc) */) { Tcl_WrongNumArgs(interp, consumedObjc, objv, "?-option value ...?"); return TCL_ERROR; } else { | | | 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 | break; } return TCL_OK; } else if ((objc-consumedObjc) & 1 /* isOdd(objc-consumedObjc) */) { Tcl_WrongNumArgs(interp, consumedObjc, objv, "?-option value ...?"); return TCL_ERROR; } else { size_t i, scriptLen = 0, milliLen = 0, secLen = 0; Tcl_Obj *scriptObj = NULL, *granObj = NULL; Tcl_Obj *milliObj = NULL, *secObj = NULL; int gran = 0; Tcl_Time limitMoment; int tmp; Tcl_LimitGetTime(slaveInterp, &limitMoment); |
︙ | ︙ | |||
4741 4742 4743 4744 4745 4746 4747 | case OPT_GRAN: granObj = objv[i+1]; if (TclGetIntFromObj(interp, objv[i+1], &gran) != TCL_OK) { return TCL_ERROR; } if (gran < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | | | | 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 | case OPT_GRAN: granObj = objv[i+1]; if (TclGetIntFromObj(interp, objv[i+1], &gran) != TCL_OK) { return TCL_ERROR; } if (gran < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "granularity must be at least 1", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADVALUE", NULL); return TCL_ERROR; } break; case OPT_MILLI: milliObj = objv[i+1]; (void) Tcl_GetStringFromObj(objv[i+1], &milliLen); if (milliLen == 0) { break; } if (TclGetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) { return TCL_ERROR; } if (tmp < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "milliseconds must be at least 0", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADVALUE", NULL); return TCL_ERROR; } limitMoment.usec = ((long) tmp)*1000; break; case OPT_SEC: secObj = objv[i+1]; (void) Tcl_GetStringFromObj(objv[i+1], &secLen); if (secLen == 0) { break; } if (TclGetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) { return TCL_ERROR; } if (tmp < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "seconds must be at least 0", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADVALUE", NULL); return TCL_ERROR; } limitMoment.sec = tmp; break; } } if (milliObj != NULL || secObj != NULL) { if (milliObj != NULL) { /* * Setting -milliseconds but clearing -seconds, or resetting * -milliseconds but not resetting -seconds? Bad voodoo! */ if (secObj != NULL && secLen == 0 && milliLen > 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may only set -milliseconds if -seconds is not " "also being reset", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADUSAGE", NULL); return TCL_ERROR; } if (milliLen == 0 && (secObj == NULL || secLen > 0)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may only reset -milliseconds if -seconds is " "also being reset", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADUSAGE", NULL); return TCL_ERROR; } } if (milliLen > 0 || secLen > 0) { |
︙ | ︙ |
Changes to generic/tclLink.c.
︙ | ︙ | |||
118 119 120 121 122 123 124 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( "variable '%s' is already linked", varName)); return TCL_ERROR; } linkPtr = ckalloc(sizeof(Link)); linkPtr->interp = interp; | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( "variable '%s' is already linked", varName)); return TCL_ERROR; } linkPtr = ckalloc(sizeof(Link)); linkPtr->interp = interp; linkPtr->varName = Tcl_NewStringObj(varName, TCL_STRLEN); Tcl_IncrRefCount(linkPtr->varName); linkPtr->addr = addr; linkPtr->type = type & ~TCL_LINK_READ_ONLY; if (type & TCL_LINK_READ_ONLY) { linkPtr->flags = LINK_READ_ONLY; } else { linkPtr->flags = 0; |
︙ | ︙ | |||
255 256 257 258 259 260 261 | ClientData clientData, /* Contains information about the link. */ Tcl_Interp *interp, /* Interpreter containing Tcl variable. */ const char *name1, /* First part of variable name. */ const char *name2, /* Second part of variable name. */ int flags) /* Miscellaneous additional information. */ { Link *linkPtr = clientData; | | > | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | ClientData clientData, /* Contains information about the link. */ Tcl_Interp *interp, /* Interpreter containing Tcl variable. */ const char *name1, /* First part of variable name. */ const char *name2, /* Second part of variable name. */ int flags) /* Miscellaneous additional information. */ { Link *linkPtr = clientData; int changed; size_t valueLength; const char *value; char **pp; Tcl_Obj *valueObj; int valueInt; Tcl_WideInt valueWide; double valueDouble; |
︙ | ︙ | |||
610 611 612 613 614 615 616 | return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.uw); case TCL_LINK_STRING: p = LinkedVar(char *); if (p == NULL) { TclNewLiteralStringObj(resultObj, "NULL"); return resultObj; } | | | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.uw); case TCL_LINK_STRING: p = LinkedVar(char *); if (p == NULL) { TclNewLiteralStringObj(resultObj, "NULL"); return resultObj; } return Tcl_NewStringObj(p, TCL_STRLEN); /* * This code only gets executed if the link type is unknown (shouldn't * ever happen). */ default: |
︙ | ︙ |
Changes to generic/tclListObj.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | #include "tclInt.h" /* * Prototypes for functions defined later in this file: */ | | | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include "tclInt.h" /* * Prototypes for functions defined later in this file: */ static List * AttemptNewList(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static List * NewListIntRep(size_t objc, Tcl_Obj *const objv[], int p); 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); /* * The structure below defines the list Tcl object type by means of functions |
︙ | ︙ | |||
71 72 73 74 75 76 77 | * resulting list now refers to them. * *---------------------------------------------------------------------- */ static List * NewListIntRep( | | | | | 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 | * resulting list now refers to them. * *---------------------------------------------------------------------- */ static List * NewListIntRep( size_t objc, Tcl_Obj *const objv[], int p) /* Flag to say if we should panic */ { List *listRepPtr; if (objc <= 0) { Tcl_Panic("NewListIntRep: expects postive element count"); } /* * First check to see if we'd overflow and try to allocate an object * larger than our memory allocator allows. Note that this is actually a * fairly small value when you're on a serious 64-bit machine, but that * requires API changes to fix. See [Bug 219196] for a discussion. */ if (objc > LIST_MAX) { if (p) { Tcl_Panic("max length of a Tcl list (%d elements) exceeded", LIST_MAX); } return NULL; } |
︙ | ︙ | |||
111 112 113 114 115 116 117 | listRepPtr->canonicalFlag = 0; listRepPtr->refCount = 0; listRepPtr->maxElemCount = objc; if (objv) { Tcl_Obj **elemPtrs; | | | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | listRepPtr->canonicalFlag = 0; listRepPtr->refCount = 0; listRepPtr->maxElemCount = objc; if (objv) { Tcl_Obj **elemPtrs; size_t i; listRepPtr->elemCount = objc; elemPtrs = &listRepPtr->elements; for (i = 0; i < objc; i++) { elemPtrs[i] = objv[i]; Tcl_IncrRefCount(elemPtrs[i]); } |
︙ | ︙ | |||
150 151 152 153 154 155 156 | * *---------------------------------------------------------------------- */ static List * AttemptNewList( Tcl_Interp *interp, | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | * *---------------------------------------------------------------------- */ static List * AttemptNewList( Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { List *listRepPtr = NewListIntRep(objc, objv, 0); if (interp != NULL && listRepPtr == NULL) { if (objc > LIST_MAX) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( |
︙ | ︙ | |||
201 202 203 204 205 206 207 | */ #ifdef TCL_MEM_DEBUG #undef Tcl_NewListObj Tcl_Obj * Tcl_NewListObj( | | | | 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 | */ #ifdef TCL_MEM_DEBUG #undef Tcl_NewListObj Tcl_Obj * Tcl_NewListObj( size_t objc, /* Count of objects referenced by objv. */ Tcl_Obj *const objv[]) /* An array of pointers to Tcl objects. */ { return Tcl_DbNewListObj(objc, objv, "unknown", 0); } #else /* if not TCL_MEM_DEBUG */ Tcl_Obj * Tcl_NewListObj( size_t objc, /* Count of objects referenced by objv. */ Tcl_Obj *const objv[]) /* An array of pointers to Tcl objects. */ { List *listRepPtr; Tcl_Obj *listPtr; TclNewObj(listPtr); |
︙ | ︙ | |||
272 273 274 275 276 277 278 | *---------------------------------------------------------------------- */ #ifdef TCL_MEM_DEBUG Tcl_Obj * Tcl_DbNewListObj( | | | 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | *---------------------------------------------------------------------- */ #ifdef TCL_MEM_DEBUG Tcl_Obj * Tcl_DbNewListObj( size_t objc, /* Count of objects referenced by objv. */ Tcl_Obj *const objv[], /* An array of pointers to Tcl objects. */ const char *file, /* The name of the source file calling this * function; used for debugging. */ int line) /* Line number in the source file; used for * debugging. */ { Tcl_Obj *listPtr; |
︙ | ︙ | |||
308 309 310 311 312 313 314 | return listPtr; } #else /* if not TCL_MEM_DEBUG */ Tcl_Obj * Tcl_DbNewListObj( | | | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | return listPtr; } #else /* if not TCL_MEM_DEBUG */ Tcl_Obj * Tcl_DbNewListObj( size_t objc, /* Count of objects referenced by objv. */ Tcl_Obj *const objv[], /* An array of pointers to Tcl objects. */ const char *file, /* The name of the source file calling this * function; used for debugging. */ int line) /* Line number in the source file; used for * debugging. */ { return Tcl_NewListObj(objc, objv); |
︙ | ︙ | |||
344 345 346 347 348 349 350 | * *---------------------------------------------------------------------- */ void Tcl_SetListObj( Tcl_Obj *objPtr, /* Object whose internal rep to init. */ | | | 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | * *---------------------------------------------------------------------- */ void Tcl_SetListObj( Tcl_Obj *objPtr, /* Object whose internal rep to init. */ size_t objc, /* Count of objects referenced by objv. */ Tcl_Obj *const objv[]) /* An array of pointers to Tcl objects. */ { List *listRepPtr; if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetListObj"); } |
︙ | ︙ | |||
451 452 453 454 455 456 457 | */ int Tcl_ListObjGetElements( Tcl_Interp *interp, /* Used to report errors if not NULL. */ register Tcl_Obj *listPtr, /* List object for which an element array is * to be returned. */ | | | 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | */ int Tcl_ListObjGetElements( Tcl_Interp *interp, /* Used to report errors if not NULL. */ register Tcl_Obj *listPtr, /* List object for which an element array is * to be returned. */ size_t *objcPtr, /* Where to store the count of objects * referenced by objv. */ Tcl_Obj ***objvPtr) /* Where to store the pointer to an array of * pointers to the list's objects. */ { register List *listRepPtr; if (listPtr->typePtr != &tclListType) { |
︙ | ︙ | |||
506 507 508 509 510 511 512 | int Tcl_ListObjAppendList( Tcl_Interp *interp, /* Used to report errors if not NULL. */ register Tcl_Obj *listPtr, /* List object to append elements to. */ Tcl_Obj *elemListPtr) /* List obj with elements to append. */ { | | | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 | int Tcl_ListObjAppendList( Tcl_Interp *interp, /* Used to report errors if not NULL. */ register Tcl_Obj *listPtr, /* List object to append elements to. */ Tcl_Obj *elemListPtr) /* List obj with elements to append. */ { size_t objc; Tcl_Obj **objv; if (Tcl_IsShared(listPtr)) { Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendList"); } /* |
︙ | ︙ | |||
563 564 565 566 567 568 569 | int Tcl_ListObjAppendElement( Tcl_Interp *interp, /* Used to report errors if not NULL. */ Tcl_Obj *listPtr, /* List object to append objPtr to. */ Tcl_Obj *objPtr) /* Object to append to listPtr's list. */ { register List *listRepPtr, *newPtr = NULL; | | > < < | 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | int Tcl_ListObjAppendElement( Tcl_Interp *interp, /* Used to report errors if not NULL. */ Tcl_Obj *listPtr, /* List object to append objPtr to. */ Tcl_Obj *objPtr) /* Object to append to listPtr's list. */ { register List *listRepPtr, *newPtr = NULL; size_t numElems, numRequired, needGrow, attempt; int isShared, result; if (Tcl_IsShared(listPtr)) { Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendElement"); } if (listPtr->typePtr != &tclListType) { if (listPtr->bytes == tclEmptyStringRep) { Tcl_SetListObj(listPtr, 1, &objPtr); return TCL_OK; } result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; |
︙ | ︙ | |||
727 728 729 730 731 732 733 | *---------------------------------------------------------------------- */ int Tcl_ListObjIndex( Tcl_Interp *interp, /* Used to report errors if not NULL. */ register Tcl_Obj *listPtr, /* List object to index into. */ | | < < | > | | 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 | *---------------------------------------------------------------------- */ int Tcl_ListObjIndex( Tcl_Interp *interp, /* Used to report errors if not NULL. */ register Tcl_Obj *listPtr, /* List object to index into. */ register size_t index, /* Index of element to return. */ Tcl_Obj **objPtrPtr) /* The resulting Tcl_Obj* is stored here. */ { register List *listRepPtr; int result; if (listPtr->typePtr != &tclListType) { if (listPtr->bytes == tclEmptyStringRep) { *objPtrPtr = NULL; return TCL_OK; } result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; } } listRepPtr = ListRepPtr(listPtr); if (index >= listRepPtr->elemCount) { *objPtrPtr = NULL; } else { *objPtrPtr = (&listRepPtr->elements)[index]; } return TCL_OK; } |
︙ | ︙ | |||
781 782 783 784 785 786 787 | *---------------------------------------------------------------------- */ int Tcl_ListObjLength( Tcl_Interp *interp, /* Used to report errors if not NULL. */ register Tcl_Obj *listPtr, /* List object whose #elements to return. */ | | < < | > | 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | *---------------------------------------------------------------------- */ int Tcl_ListObjLength( Tcl_Interp *interp, /* Used to report errors if not NULL. */ register Tcl_Obj *listPtr, /* List object whose #elements to return. */ register size_t *intPtr) /* The resulting int is stored here. */ { register List *listRepPtr; int result; if (listPtr->typePtr != &tclListType) { if (listPtr->bytes == tclEmptyStringRep) { *intPtr = 0; return TCL_OK; } result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; |
︙ | ︙ | |||
845 846 847 848 849 850 851 | *---------------------------------------------------------------------- */ int Tcl_ListObjReplace( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *listPtr, /* List object whose elements to replace. */ | | | | | > | 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 | *---------------------------------------------------------------------- */ int Tcl_ListObjReplace( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *listPtr, /* List object whose elements to replace. */ size_t first, /* Index of first element to replace. */ size_t count, /* Number of elements to replace. */ size_t objc, /* Number of objects to insert. */ Tcl_Obj *const objv[]) /* An array of objc pointers to Tcl objects to * insert. */ { List *listRepPtr; register Tcl_Obj **elemPtrs; size_t numElems, numRequired, numAfterLast, start, i, j; int isShared; if (Tcl_IsShared(listPtr)) { Tcl_Panic("%s called with shared object", "Tcl_ListObjReplace"); } if (listPtr->typePtr != &tclListType) { if (listPtr->bytes == tclEmptyStringRep) { if (!objc) { |
︙ | ︙ | |||
910 911 912 913 914 915 916 | numRequired = numElems - count + objc; for (i = 0; i < objc; i++) { Tcl_IncrRefCount(objv[i]); } if ((numRequired <= listRepPtr->maxElemCount) && !isShared) { | | | | | | < | | 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 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 | numRequired = numElems - count + objc; for (i = 0; i < objc; i++) { Tcl_IncrRefCount(objv[i]); } if ((numRequired <= listRepPtr->maxElemCount) && !isShared) { ssize_t shift; /* * Can use the current List struct. First "delete" count elements * starting at first. */ for (j = first; j < first + count; j++) { Tcl_Obj *victimPtr = elemPtrs[j]; TclDecrRefCount(victimPtr); } /* * Shift the elements after the last one removed to their new * locations. */ start = first + count; numAfterLast = numElems - start; shift = objc - (ssize_t) count; /* numNewElems - numDeleted */ if ((numAfterLast > 0) && (shift != 0)) { Tcl_Obj **src = elemPtrs + start; memmove(src+shift, src, (size_t) numAfterLast * sizeof(Tcl_Obj*)); } } else { /* * Cannot use the current List struct; it is shared, too small, or * both. Allocate a new struct and insert elements into it. */ List *oldListRepPtr = listRepPtr; Tcl_Obj **oldPtrs = elemPtrs; size_t newMax; if (numRequired > listRepPtr->maxElemCount){ newMax = 2 * numRequired; } else { newMax = listRepPtr->maxElemCount; } listRepPtr = AttemptNewList(NULL, newMax, NULL); if (listRepPtr == NULL) { size_t limit = LIST_MAX - numRequired; size_t extra = numRequired - numElems + TCL_MIN_ELEMENT_GROWTH; size_t growth = ((extra > limit) ? limit : extra); listRepPtr = AttemptNewList(NULL, numRequired + growth, NULL); if (listRepPtr == NULL) { listRepPtr = AttemptNewList(interp, numRequired, NULL); if (listRepPtr == NULL) { for (i = 0; i < objc; i++) { /* See bug 3598580 */ |
︙ | ︙ | |||
1001 1002 1003 1004 1005 1006 1007 | oldListRepPtr->refCount--; } else { /* * The old struct will be removed; use its inherited refCounts. */ if (first > 0) { | | | 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | oldListRepPtr->refCount--; } else { /* * The old struct will be removed; use its inherited refCounts. */ if (first > 0) { memcpy(elemPtrs, oldPtrs, first * sizeof(Tcl_Obj *)); } /* * "Delete" count elements starting at first. */ for (j = first; j < first + count; j++) { |
︙ | ︙ | |||
1023 1024 1025 1026 1027 1028 1029 | * new locations. */ start = first + count; numAfterLast = numElems - start; if (numAfterLast > 0) { memcpy(elemPtrs + first + objc, oldPtrs + start, | | | 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 | * new locations. */ start = first + count; numAfterLast = numElems - start; if (numAfterLast > 0) { memcpy(elemPtrs + first + objc, oldPtrs + start, numAfterLast * sizeof(Tcl_Obj *)); } ckfree(oldListRepPtr); } } /* |
︙ | ︙ | |||
1084 1085 1086 1087 1088 1089 1090 | Tcl_Obj * TclLindexList( Tcl_Interp *interp, /* Tcl interpreter. */ Tcl_Obj *listPtr, /* List being unpacked. */ Tcl_Obj *argPtr) /* Index or index list. */ { | < | | | 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 | Tcl_Obj * TclLindexList( Tcl_Interp *interp, /* Tcl interpreter. */ Tcl_Obj *listPtr, /* List being unpacked. */ Tcl_Obj *argPtr) /* Index or index list. */ { ssize_t index; /* Index into the list. */ Tcl_Obj *indexListCopy; /* * Determine whether argPtr designates a list or a single index. We have * to be careful about the order of the checks to avoid repeated * shimmering; see TIP#22 and TIP#33 for the details. */ if (argPtr->typePtr != &tclListType && TclGetIntForIndexM(NULL, argPtr, 0, &index) == TCL_OK) { /* * argPtr designates a single index. */ return TclLindexFlat(interp, listPtr, 1, &argPtr); } |
︙ | ︙ | |||
1131 1132 1133 1134 1135 1136 1137 | if (indexListCopy->typePtr == &tclListType) { List *listRepPtr = ListRepPtr(indexListCopy); listPtr = TclLindexFlat(interp, listPtr, listRepPtr->elemCount, &listRepPtr->elements); } else { | | | 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 | if (indexListCopy->typePtr == &tclListType) { List *listRepPtr = ListRepPtr(indexListCopy); listPtr = TclLindexFlat(interp, listPtr, listRepPtr->elemCount, &listRepPtr->elements); } else { size_t indexCount = 0; /* Size of the array of list indices. */ Tcl_Obj **indices = NULL; /* Array of list indices. */ Tcl_ListObjGetElements(NULL, indexListCopy, &indexCount, &indices); listPtr = TclLindexFlat(interp, listPtr, indexCount, indices); } Tcl_DecrRefCount(indexListCopy); |
︙ | ︙ | |||
1172 1173 1174 1175 1176 1177 1178 | *---------------------------------------------------------------------- */ Tcl_Obj * TclLindexFlat( Tcl_Interp *interp, /* Tcl interpreter. */ Tcl_Obj *listPtr, /* Tcl object representing the list. */ | | > | | 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 | *---------------------------------------------------------------------- */ Tcl_Obj * TclLindexFlat( Tcl_Interp *interp, /* Tcl interpreter. */ Tcl_Obj *listPtr, /* Tcl object representing the list. */ size_t indexCount, /* Count of indices. */ Tcl_Obj *const indexArray[])/* Array of pointers to Tcl objects that * represent the indices in the list. */ { int i; Tcl_IncrRefCount(listPtr); for (i=0 ; i<indexCount && listPtr ; i++) { ssize_t index; size_t listLen = 0; Tcl_Obj **elemPtrs = NULL, *sublistCopy; /* * Here we make a private copy of the current sublist, so we avoid any * shimmering issues that might invalidate the elemPtr array below * while we are still using it. See test lindex-8.4. */ |
︙ | ︙ | |||
1267 1268 1269 1270 1271 1272 1273 | Tcl_Obj * TclLsetList( Tcl_Interp *interp, /* Tcl interpreter. */ Tcl_Obj *listPtr, /* Pointer to the list being modified. */ Tcl_Obj *indexArgPtr, /* Index or index-list arg to 'lset'. */ Tcl_Obj *valuePtr) /* Value arg to 'lset'. */ { | | | | 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 | Tcl_Obj * TclLsetList( Tcl_Interp *interp, /* Tcl interpreter. */ Tcl_Obj *listPtr, /* Pointer to the list being modified. */ Tcl_Obj *indexArgPtr, /* Index or index-list arg to 'lset'. */ Tcl_Obj *valuePtr) /* Value arg to 'lset'. */ { size_t indexCount = 0; /* Number of indices in the index list. */ Tcl_Obj **indices = NULL; /* Vector of indices in the index list. */ Tcl_Obj *retValuePtr; /* Pointer to the list to be returned. */ ssize_t index; /* Current index in the list - discarded. */ Tcl_Obj *indexListCopy; /* * Determine whether the index arg designates a list or a single index. * We have to be careful about the order of the checks to avoid repeated * shimmering; see TIP #22 and #23 for details. */ |
︙ | ︙ | |||
1357 1358 1359 1360 1361 1362 1363 | *---------------------------------------------------------------------- */ Tcl_Obj * TclLsetFlat( Tcl_Interp *interp, /* Tcl interpreter. */ Tcl_Obj *listPtr, /* Pointer to the list being modified. */ | | > | > | 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 | *---------------------------------------------------------------------- */ Tcl_Obj * TclLsetFlat( Tcl_Interp *interp, /* Tcl interpreter. */ Tcl_Obj *listPtr, /* Pointer to the list being modified. */ size_t indexCount, /* Number of index args. */ Tcl_Obj *const indexArray[], /* Index args. */ Tcl_Obj *valuePtr) /* Value arg to 'lset'. */ { ssize_t index; int result; size_t len; Tcl_Obj *subListPtr, *retValuePtr, *chainPtr; /* * If there are no indices, simply return the new value. (Without * indices, [lset] is a synonym for [set]. */ |
︙ | ︙ | |||
1403 1404 1405 1406 1407 1408 1409 | /* * Loop through all the index arguments, and for each one dive into the * appropriate sublist. */ do { | | | 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 | /* * Loop through all the index arguments, and for each one dive into the * appropriate sublist. */ do { size_t elemCount; Tcl_Obj *parentList, **elemPtrs; /* * Check for the possible error conditions... */ if (TclListObjGetElements(interp, subListPtr, &elemCount, &elemPtrs) |
︙ | ︙ | |||
1435 1436 1437 1438 1439 1440 1441 | } indexArray++; if (index < 0 || index > elemCount) { /* ...the index points outside the sublist. */ if (interp != NULL) { Tcl_SetObjResult(interp, | | > | 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 | } indexArray++; if (index < 0 || index > elemCount) { /* ...the index points outside the sublist. */ if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("list index out of range", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSET", "BADINDEX", NULL); } result = TCL_ERROR; break; } |
︙ | ︙ | |||
1544 1545 1546 1547 1548 1549 1550 | /* * Store valuePtr in proper sublist and return. The -1 is to avoid a * compiler warning (not a problem because we checked that we have a * proper list - or something convertible to one - above). */ | | | 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 | /* * Store valuePtr in proper sublist and return. The -1 is to avoid a * compiler warning (not a problem because we checked that we have a * proper list - or something convertible to one - above). */ len = TCL_STRLEN; TclListObjLength(NULL, subListPtr, &len); if (index == len) { Tcl_ListObjAppendElement(NULL, subListPtr, valuePtr); } else { TclListObjSetElement(NULL, subListPtr, index, valuePtr); } TclInvalidateStringRep(subListPtr); |
︙ | ︙ | |||
1591 1592 1593 1594 1595 1596 1597 | int TclListObjSetElement( Tcl_Interp *interp, /* Tcl interpreter; used for error reporting * if not NULL. */ Tcl_Obj *listPtr, /* List object in which element should be * stored. */ | | | 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 | int TclListObjSetElement( Tcl_Interp *interp, /* Tcl interpreter; used for error reporting * if not NULL. */ Tcl_Obj *listPtr, /* List object in which element should be * stored. */ size_t index, /* Index of element to store. */ Tcl_Obj *valuePtr) /* Tcl object to store in the designated list * element. */ { List *listRepPtr; /* Internal representation of the list being * modified. */ Tcl_Obj **elemPtrs; /* Pointers to elements of the list. */ int elemCount; /* Number of elements in the list. */ |
︙ | ︙ | |||
1613 1614 1615 1616 1617 1618 1619 | } if (listPtr->typePtr != &tclListType) { int result; if (listPtr->bytes == tclEmptyStringRep) { if (interp != NULL) { Tcl_SetObjResult(interp, | | > | | | 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 | } if (listPtr->typePtr != &tclListType) { int result; if (listPtr->bytes == tclEmptyStringRep) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("list index out of range", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSET", "BADINDEX", NULL); } return TCL_ERROR; } result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; } } listRepPtr = ListRepPtr(listPtr); elemCount = listRepPtr->elemCount; /* * Ensure that the index is in bounds. */ if (index>=elemCount) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("list index out of range", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSET", "BADINDEX", NULL); } return TCL_ERROR; } /* |
︙ | ︙ | |||
1720 1721 1722 1723 1724 1725 1726 | FreeListInternalRep( Tcl_Obj *listPtr) /* List object with internal rep to free. */ { List *listRepPtr = ListRepPtr(listPtr); if (--listRepPtr->refCount <= 0) { Tcl_Obj **elemPtrs = &listRepPtr->elements; | | | 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 | FreeListInternalRep( Tcl_Obj *listPtr) /* List object with internal rep to free. */ { List *listRepPtr = ListRepPtr(listPtr); if (--listRepPtr->refCount <= 0) { Tcl_Obj **elemPtrs = &listRepPtr->elements; size_t i, numElems = listRepPtr->elemCount; for (i = 0; i < numElems; i++) { Tcl_DecrRefCount(elemPtrs[i]); } ckfree(listRepPtr); } |
︙ | ︙ | |||
1796 1797 1798 1799 1800 1801 1802 | * there is, it is the string rep that's authoritative (because it could * describe duplicate keys). */ if (objPtr->typePtr == &tclDictType && !objPtr->bytes) { Tcl_Obj *keyPtr, *valuePtr; Tcl_DictSearch search; | | > | 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 | * there is, it is the string rep that's authoritative (because it could * describe duplicate keys). */ if (objPtr->typePtr == &tclDictType && !objPtr->bytes) { Tcl_Obj *keyPtr, *valuePtr; Tcl_DictSearch search; int done; size_t size; /* * Create the new list representation. Note that we do not need to do * anything with the string representation as the transformation (and * the reverse back to a dictionary) are both order-preserving. Also * note that since we know we've got a valid dictionary (by * representation) we also know that fetching the size of the |
︙ | ︙ | |||
1828 1829 1830 1831 1832 1833 1834 | *elemPtrs++ = keyPtr; *elemPtrs++ = valuePtr; Tcl_IncrRefCount(keyPtr); Tcl_IncrRefCount(valuePtr); Tcl_DictObjNext(&search, &keyPtr, &valuePtr, &done); } } else { | | | 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 | *elemPtrs++ = keyPtr; *elemPtrs++ = valuePtr; Tcl_IncrRefCount(keyPtr); Tcl_IncrRefCount(valuePtr); Tcl_DictObjNext(&search, &keyPtr, &valuePtr, &done); } } else { size_t estCount, length; const char *limit, *nextElem = TclGetStringFromObj(objPtr, &length); /* * Allocate enough space to hold a (Tcl_Obj *) for each * (possible) list element. */ |
︙ | ︙ | |||
1851 1852 1853 1854 1855 1856 1857 | /* * Each iteration, parse and store a list element. */ while (nextElem < limit) { const char *elemStart; | > | | 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 | /* * Each iteration, parse and store a list element. */ while (nextElem < limit) { const char *elemStart; size_t elemSize; int literal; if (TCL_OK != TclFindElement(interp, nextElem, limit - nextElem, &elemStart, &nextElem, &elemSize, &literal)) { while (--elemPtrs >= &listRepPtr->elements) { Tcl_DecrRefCount(*elemPtrs); } ckfree((char *) listRepPtr); |
︙ | ︙ | |||
1920 1921 1922 1923 1924 1925 1926 | static void UpdateStringOfList( Tcl_Obj *listPtr) /* List object with string rep to update. */ { # define LOCAL_SIZE 64 char localFlags[LOCAL_SIZE], *flagPtr = NULL; List *listRepPtr = ListRepPtr(listPtr); | | | | 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 | static void UpdateStringOfList( Tcl_Obj *listPtr) /* List object with string rep to update. */ { # define LOCAL_SIZE 64 char localFlags[LOCAL_SIZE], *flagPtr = NULL; List *listRepPtr = ListRepPtr(listPtr); size_t numElems = listRepPtr->elemCount; size_t i, length, bytesNeeded = 0; const char *elem; char *dst; Tcl_Obj **elemPtrs; /* * Mark the list as being canonical; although it will now have a string * rep, it is one we derived through proper "canonical" quoting and so |
︙ | ︙ |
Changes to generic/tclLiteral.c.
︙ | ︙ | |||
27 28 29 30 31 32 33 | /* * Function prototypes for static functions in this file: */ static int AddLocalLiteralEntry(CompileEnv *envPtr, Tcl_Obj *objPtr, int localHash); static void ExpandLocalLiteralArray(CompileEnv *envPtr); | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /* * Function prototypes for static functions in this file: */ static int AddLocalLiteralEntry(CompileEnv *envPtr, Tcl_Obj *objPtr, int localHash); static void ExpandLocalLiteralArray(CompileEnv *envPtr); static unsigned HashString(const char *string, size_t length); #ifdef TCL_COMPILE_DEBUG static LiteralEntry * LookupLiteralEntry(Tcl_Interp *interp, Tcl_Obj *objPtr); #endif static void RebuildLiteralTable(LiteralTable *tablePtr); /* |
︙ | ︙ | |||
172 173 174 175 176 177 178 | */ Tcl_Obj * TclCreateLiteral( Interp *iPtr, char *bytes, /* The start of the string. Note that this is * not a NUL-terminated string. */ | | | | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | */ Tcl_Obj * TclCreateLiteral( Interp *iPtr, char *bytes, /* The start of the string. Note that this is * not a NUL-terminated string. */ size_t length, /* Number of bytes in the string. */ unsigned hash, /* The string's hash. If ((unsigned)-1), it * will be computed here. */ int *newPtr, Namespace *nsPtr, int flags, LiteralEntry **globalPtrPtr) { LiteralTable *globalTablePtr = &iPtr->literalTable; LiteralEntry *globalPtr; |
︙ | ︙ | |||
471 472 473 474 475 476 477 | * that was previously created by a call to * TclRegisterLiteral. */ { Interp *iPtr = (Interp *) interp; LiteralTable *globalTablePtr = &iPtr->literalTable; register LiteralEntry *entryPtr; const char *bytes; | > | | 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | * that was previously created by a call to * TclRegisterLiteral. */ { Interp *iPtr = (Interp *) interp; LiteralTable *globalTablePtr = &iPtr->literalTable; register LiteralEntry *entryPtr; const char *bytes; size_t length; int globalHash; bytes = TclGetStringFromObj(objPtr, &length); globalHash = (HashString(bytes, length) & globalTablePtr->mask); for (entryPtr=globalTablePtr->buckets[globalHash] ; entryPtr!=NULL; entryPtr=entryPtr->nextPtr) { if (entryPtr->objPtr == objPtr) { return entryPtr; |
︙ | ︙ | |||
516 517 518 519 520 521 522 | register CompileEnv *envPtr,/* Points to CompileEnv whose literal array * contains the entry being hidden. */ int index) /* The index of the entry in the literal * array. */ { LiteralEntry **nextPtrPtr, *entryPtr, *lPtr; LiteralTable *localTablePtr = &envPtr->localLitTable; | | > | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 | register CompileEnv *envPtr,/* Points to CompileEnv whose literal array * contains the entry being hidden. */ int index) /* The index of the entry in the literal * array. */ { LiteralEntry **nextPtrPtr, *entryPtr, *lPtr; LiteralTable *localTablePtr = &envPtr->localLitTable; int localHash; size_t length; const char *bytes; Tcl_Obj *newObjPtr; lPtr = &envPtr->literalArrayPtr[index]; /* * To avoid unwanted sharing we need to copy the object and remove it from |
︙ | ︙ | |||
653 654 655 656 657 658 659 | RebuildLiteralTable(localTablePtr); } #ifdef TCL_COMPILE_DEBUG TclVerifyLocalLiteralTable(envPtr); { char *bytes; | > | | 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 | RebuildLiteralTable(localTablePtr); } #ifdef TCL_COMPILE_DEBUG TclVerifyLocalLiteralTable(envPtr); { char *bytes; size_t length; int found, i; found = 0; for (i=0 ; i<localTablePtr->numBuckets ; i++) { for (localPtr=localTablePtr->buckets[i] ; localPtr!=NULL ; localPtr=localPtr->nextPtr) { if (localPtr->objPtr == objPtr) { found = 1; |
︙ | ︙ | |||
782 783 784 785 786 787 788 | * previously created by a call to * TclRegisterLiteral. */ { Interp *iPtr = (Interp *) interp; LiteralTable *globalTablePtr; register LiteralEntry *entryPtr, *prevPtr; const char *bytes; | | > | > > | | | | | | | | | | | | | | | | | | < | 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 836 837 838 839 840 841 842 843 844 | * previously created by a call to * TclRegisterLiteral. */ { Interp *iPtr = (Interp *) interp; LiteralTable *globalTablePtr; register LiteralEntry *entryPtr, *prevPtr; const char *bytes; size_t length; int index; if (iPtr == NULL) { goto done; } globalTablePtr = &iPtr->literalTable; bytes = TclGetStringFromObj(objPtr, &length); index = (HashString(bytes, length) & globalTablePtr->mask); /* * Check to see if the object is in the global literal table and remove * this reference. The object may not be in the table if it is a hidden * local literal. */ for (prevPtr=NULL, entryPtr=globalTablePtr->buckets[index]; entryPtr!=NULL ; prevPtr=entryPtr, entryPtr=entryPtr->nextPtr) { if (entryPtr->objPtr != objPtr) { continue; } entryPtr->refCount--; /* * If the literal is no longer being used by any ByteCode, delete the * entry then remove the reference corresponding to the global literal * table entry (decrement the ref count of the object). */ if (entryPtr->refCount == 0) { if (prevPtr == NULL) { globalTablePtr->buckets[index] = entryPtr->nextPtr; } else { prevPtr->nextPtr = entryPtr->nextPtr; } ckfree(entryPtr); globalTablePtr->numEntries--; TclDecrRefCount(objPtr); #ifdef TCL_COMPILE_STATS iPtr->stats.currentLitStringBytes -= (double) (length + 1); #endif /*TCL_COMPILE_STATS*/ } break; } /* * Remove the reference corresponding to the local literal table entry. */ done: |
︙ | ︙ | |||
855 856 857 858 859 860 861 | * None. * *---------------------------------------------------------------------- */ static unsigned HashString( | | | | 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 | * None. * *---------------------------------------------------------------------- */ static unsigned HashString( register const char *string,/* String for which to compute hash value. */ size_t length) /* Number of bytes in the string. */ { register unsigned int result = 0; /* * I tried a zillion different hash functions and asked many other people * for advice. Many people had their own favorite functions, all * different, but no-one had much idea why they were good ones. I chose |
︙ | ︙ | |||
927 928 929 930 931 932 933 | /* Local or global table to enlarge. */ { LiteralEntry **oldBuckets; register LiteralEntry **oldChainPtr, **newChainPtr; register LiteralEntry *entryPtr; LiteralEntry **bucketPtr; const char *bytes; | | > | 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 | /* Local or global table to enlarge. */ { LiteralEntry **oldBuckets; register LiteralEntry **oldChainPtr, **newChainPtr; register LiteralEntry *entryPtr; LiteralEntry **bucketPtr; const char *bytes; int oldSize, count, index; size_t length; oldSize = tablePtr->numBuckets; oldBuckets = tablePtr->buckets; /* * Allocate and initialize the new bucket array, and set up hashing * constants for new array size. |
︙ | ︙ |
Changes to generic/tclLoad.c.
︙ | ︙ | |||
113 114 115 116 117 118 119 | *---------------------------------------------------------------------- */ int Tcl_LoadObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | *---------------------------------------------------------------------- */ int Tcl_LoadObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Interp *target; LoadedPackage *pkgPtr, *defaultPtr; Tcl_DString pkgName, tmp, initName, safeInitName; Tcl_DString unloadName, safeUnloadName; InterpPackage *ipFirstPtr, *ipPtr; |
︙ | ︙ | |||
179 180 181 182 183 184 185 | packageName = Tcl_GetString(objv[2]); if (packageName[0] == '\0') { packageName = NULL; } } if ((fullFileName[0] == 0) && (packageName == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | packageName = Tcl_GetString(objv[2]); if (packageName[0] == '\0') { packageName = NULL; } } if ((fullFileName[0] == 0) && (packageName == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "must specify either file name or package name", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "NOLIBRARY", NULL); code = TCL_ERROR; goto done; } /* |
︙ | ︙ | |||
219 220 221 222 223 224 225 | defaultPtr = NULL; for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { if (packageName == NULL) { namesMatch = 0; } else { TclDStringClear(&pkgName); | | | | 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | defaultPtr = NULL; for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { if (packageName == NULL) { namesMatch = 0; } else { TclDStringClear(&pkgName); Tcl_DStringAppend(&pkgName, packageName, TCL_STRLEN); TclDStringClear(&tmp); Tcl_DStringAppend(&tmp, pkgPtr->packageName, TCL_STRLEN); Tcl_UtfToLower(Tcl_DStringValue(&pkgName)); Tcl_UtfToLower(Tcl_DStringValue(&tmp)); if (strcmp(Tcl_DStringValue(&tmp), Tcl_DStringValue(&pkgName)) == 0) { namesMatch = 1; } else { namesMatch = 0; |
︙ | ︙ | |||
296 297 298 299 300 301 302 | } /* * Figure out the module name if it wasn't provided explicitly. */ if (packageName != NULL) { | | | | | 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | } /* * Figure out the module name if it wasn't provided explicitly. */ if (packageName != NULL) { Tcl_DStringAppend(&pkgName, packageName, TCL_STRLEN); } else { int retc; /* * Threading note - this call used to be protected by a mutex. */ retc = TclGuessPackageName(fullFileName, &pkgName); if (!retc) { Tcl_Obj *splitPtr, *pkgGuessPtr; size_t pElements; const char *pkgGuess; /* * The platform-specific code couldn't figure out the module * name. Make a guess by taking the last element of the file * name, stripping off any leading "lib", and then using all * of the alphabetic and underline characters that follow * that. */ splitPtr = Tcl_FSSplitPath(objv[1], &pElements); Tcl_ListObjIndex(NULL, splitPtr, pElements-1, &pkgGuessPtr); pkgGuess = Tcl_GetString(pkgGuessPtr); if ((pkgGuess[0] == 'l') && (pkgGuess[1] == 'i') && (pkgGuess[2] == 'b')) { pkgGuess += 3; } #ifdef __CYGWIN__ if ((pkgGuess[0] == 'c') && (pkgGuess[1] == 'y') |
︙ | ︙ | |||
466 467 468 469 470 471 472 473 474 475 476 477 478 | /* * Test for whether the initialization failed. If so, transfer the error * from the target interpreter to the originating one. */ if (code != TCL_OK) { Interp *iPtr = (Interp *) target; if (iPtr->legacyResult && !iPtr->legacyFreeProc) { /* * A call to Tcl_InitStubs() determined the caller extension and * this interp are incompatible in their stubs mechanisms, and * recorded the error in the oldest legacy place we have to do so. */ | > > | > | 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | /* * Test for whether the initialization failed. If so, transfer the error * from the target interpreter to the originating one. */ if (code != TCL_OK) { Interp *iPtr = (Interp *) target; if (iPtr->legacyResult && !iPtr->legacyFreeProc) { /* * A call to Tcl_InitStubs() determined the caller extension and * this interp are incompatible in their stubs mechanisms, and * recorded the error in the oldest legacy place we have to do so. */ Tcl_SetObjResult(target, Tcl_NewStringObj(iPtr->legacyResult, TCL_STRLEN)); iPtr->legacyResult = NULL; iPtr->legacyFreeProc = (void (*) (void))-1; } Tcl_TransferResult(target, code, interp); goto done; } |
︙ | ︙ | |||
537 538 539 540 541 542 543 | *---------------------------------------------------------------------- */ int Tcl_UnloadObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | *---------------------------------------------------------------------- */ int Tcl_UnloadObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Interp *target; /* Which interpreter to unload from. */ LoadedPackage *pkgPtr, *defaultPtr; Tcl_DString pkgName, tmp; Tcl_PackageUnloadProc *unloadProc; InterpPackage *ipFirstPtr, *ipPtr; |
︙ | ︙ | |||
612 613 614 615 616 617 618 | packageName = Tcl_GetString(objv[i+1]); if (packageName[0] == '\0') { packageName = NULL; } } if ((fullFileName[0] == 0) && (packageName == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | packageName = Tcl_GetString(objv[i+1]); if (packageName[0] == '\0') { packageName = NULL; } } if ((fullFileName[0] == 0) && (packageName == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "must specify either file name or package name", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NOLIBRARY", NULL); code = TCL_ERROR; goto done; } /* |
︙ | ︙ | |||
653 654 655 656 657 658 659 | for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { int namesMatch, filesMatch; if (packageName == NULL) { namesMatch = 0; } else { TclDStringClear(&pkgName); | | | | 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 | for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { int namesMatch, filesMatch; if (packageName == NULL) { namesMatch = 0; } else { TclDStringClear(&pkgName); Tcl_DStringAppend(&pkgName, packageName, TCL_STRLEN); TclDStringClear(&tmp); Tcl_DStringAppend(&tmp, pkgPtr->packageName, TCL_STRLEN); Tcl_UtfToLower(Tcl_DStringValue(&pkgName)); Tcl_UtfToLower(Tcl_DStringValue(&tmp)); if (strcmp(Tcl_DStringValue(&tmp), Tcl_DStringValue(&pkgName)) == 0) { namesMatch = 1; } else { namesMatch = 0; |
︙ | ︙ | |||
1059 1060 1061 1062 1063 1064 1065 | * Return information about all of the available packages. */ resultObj = Tcl_NewObj(); Tcl_MutexLock(&packageMutex); for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { | | | | 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 | * Return information about all of the available packages. */ resultObj = Tcl_NewObj(); Tcl_MutexLock(&packageMutex); for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { pkgDesc[0] = Tcl_NewStringObj(pkgPtr->fileName, TCL_STRLEN); pkgDesc[1] = Tcl_NewStringObj(pkgPtr->packageName, TCL_STRLEN); Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewListObj(2, pkgDesc)); } Tcl_MutexUnlock(&packageMutex); Tcl_SetObjResult(interp, resultObj); return TCL_OK; } |
︙ | ︙ | |||
1082 1083 1084 1085 1086 1087 1088 | if (target == NULL) { return TCL_ERROR; } ipPtr = Tcl_GetAssocData(target, "tclLoad", NULL); resultObj = Tcl_NewObj(); for (; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { pkgPtr = ipPtr->pkgPtr; | | | | 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 | if (target == NULL) { return TCL_ERROR; } ipPtr = Tcl_GetAssocData(target, "tclLoad", NULL); resultObj = Tcl_NewObj(); for (; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { pkgPtr = ipPtr->pkgPtr; pkgDesc[0] = Tcl_NewStringObj(pkgPtr->fileName, TCL_STRLEN); pkgDesc[1] = Tcl_NewStringObj(pkgPtr->packageName, TCL_STRLEN); Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewListObj(2, pkgDesc)); } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } /* |
︙ | ︙ |
Changes to generic/tclLoadNone.c.
︙ | ︙ | |||
43 44 45 46 47 48 49 | /* Filled with address of Tcl_FSUnloadFileProc * function which should be used for this * file. */ int flags) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "dynamic loading is not currently available on this system", | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /* Filled with address of Tcl_FSUnloadFileProc * function which should be used for this * file. */ int flags) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "dynamic loading is not currently available on this system", TCL_STRLEN)); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclGuessPackageName -- |
︙ | ︙ |
Changes to generic/tclMain.c.
︙ | ︙ | |||
61 62 63 64 65 66 67 | #ifdef UNICODE # define NewNativeObj Tcl_NewUnicodeObj #else /* !UNICODE */ static inline Tcl_Obj * NewNativeObj( char *string, | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | #ifdef UNICODE # define NewNativeObj Tcl_NewUnicodeObj #else /* !UNICODE */ static inline Tcl_Obj * NewNativeObj( char *string, size_t length) { Tcl_DString ds; Tcl_ExternalToUtfDString(NULL, string, length, &ds); return TclDStringToObj(&ds); } #endif /* !UNICODE */ |
︙ | ︙ | |||
155 156 157 158 159 160 161 | Tcl_Obj *path, /* Filesystem path of startup script file */ const char *encoding) /* Encoding of the data in that file */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Tcl_Obj *newEncoding = NULL; if (encoding != NULL) { | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | Tcl_Obj *path, /* Filesystem path of startup script file */ const char *encoding) /* Encoding of the data in that file */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Tcl_Obj *newEncoding = NULL; if (encoding != NULL) { newEncoding = Tcl_NewStringObj(encoding, TCL_STRLEN); } if (tsdPtr->path != NULL) { Tcl_DecrRefCount(tsdPtr->path); } tsdPtr->path = path; if (tsdPtr->path != NULL) { |
︙ | ︙ | |||
338 339 340 341 342 343 344 | * -encoding ENCODING FILENAME * or like * FILENAME */ if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1])) && ('-' != argv[3][0])) { | | | | | | > | > | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | * -encoding ENCODING FILENAME * or like * FILENAME */ if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1])) && ('-' != argv[3][0])) { Tcl_Obj *value = NewNativeObj(argv[2], TCL_STRLEN); Tcl_SetStartupScript(NewNativeObj(argv[3], TCL_STRLEN), Tcl_GetString(value)); Tcl_DecrRefCount(value); argc -= 3; argv += 3; } else if ((argc > 1) && ('-' != argv[1][0])) { Tcl_SetStartupScript(NewNativeObj(argv[1], TCL_STRLEN), NULL); argc--; argv++; } } path = Tcl_GetStartupScript(&encodingName); if (path == NULL) { appName = NewNativeObj(argv[0], TCL_STRLEN); } else { appName = path; } Tcl_SetVar2Ex(interp, "argv0", NULL, appName, TCL_GLOBAL_ONLY); argc--; argv++; Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewLongObj(argc), TCL_GLOBAL_ONLY); argvPtr = Tcl_NewListObj(0, NULL); while (argc--) { Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(*argv++, TCL_STRLEN)); } Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY); /* * Set the "tcl_interactive" variable. */ is.tty = isatty(0); Tcl_SetVar2Ex(interp, "tcl_interactive", NULL, Tcl_NewLongObj(!path && is.tty), TCL_GLOBAL_ONLY); /* * Invoke application-specific initialization. */ Tcl_Preserve(interp); if (appInitProc(interp) != TCL_OK) { chan = Tcl_GetStdChannel(TCL_STDERR); if (chan) { Tcl_WriteChars(chan, "application-specific initialization failed: ", TCL_STRLEN); Tcl_WriteObj(chan, Tcl_GetObjResult(interp)); Tcl_WriteChars(chan, "\n", 1); } } if (Tcl_InterpDeleted(interp)) { goto done; } |
︙ | ︙ | |||
464 465 466 467 468 469 470 | */ Tcl_LinkVar(interp, "tcl_interactive", (char *) &is.tty, TCL_LINK_BOOLEAN); is.input = Tcl_GetStdChannel(TCL_STDIN); while ((is.input != NULL) && !Tcl_InterpDeleted(interp)) { mainLoopProc = TclGetMainLoop(); if (mainLoopProc == NULL) { | > | | | | 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | */ Tcl_LinkVar(interp, "tcl_interactive", (char *) &is.tty, TCL_LINK_BOOLEAN); is.input = Tcl_GetStdChannel(TCL_STDIN); while ((is.input != NULL) && !Tcl_InterpDeleted(interp)) { mainLoopProc = TclGetMainLoop(); if (mainLoopProc == NULL) { ssize_t inputLength; size_t cmdLength; if (is.tty) { Prompt(interp, &is); if (Tcl_InterpDeleted(interp)) { break; } if (Tcl_LimitExceeded(interp)) { break; } is.input = Tcl_GetStdChannel(TCL_STDIN); if (is.input == NULL) { break; } } if (Tcl_IsShared(is.commandPtr)) { Tcl_DecrRefCount(is.commandPtr); is.commandPtr = Tcl_DuplicateObj(is.commandPtr); Tcl_IncrRefCount(is.commandPtr); } inputLength = Tcl_GetsObj(is.input, is.commandPtr); if (inputLength < 0) { if (Tcl_InputBlocked(is.input)) { /* * This can only happen if stdin has been set to * non-blocking. In that case cycle back and try again. * This sets up a tight polling loop (since we have no * event loop running). If this causes bad CPU hogging, we * might try toggling the blocking on stdin instead. |
︙ | ︙ | |||
529 530 531 532 533 534 535 | is.prompt = PROMPT_START; /* * The final newline is syntactically redundant, and causes some * error messages troubles deeper in, so lop it back off. */ | | | | | | 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 | is.prompt = PROMPT_START; /* * The final newline is syntactically redundant, and causes some * error messages troubles deeper in, so lop it back off. */ Tcl_GetStringFromObj(is.commandPtr, &cmdLength); Tcl_SetObjLength(is.commandPtr, --cmdLength); code = Tcl_RecordAndEvalObj(interp, is.commandPtr, TCL_EVAL_GLOBAL); is.input = Tcl_GetStdChannel(TCL_STDIN); Tcl_DecrRefCount(is.commandPtr); is.commandPtr = Tcl_NewObj(); Tcl_IncrRefCount(is.commandPtr); if (code != TCL_OK) { chan = Tcl_GetStdChannel(TCL_STDERR); if (chan) { Tcl_WriteObj(chan, Tcl_GetObjResult(interp)); Tcl_WriteChars(chan, "\n", 1); } } else if (is.tty) { resultPtr = Tcl_GetObjResult(interp); Tcl_IncrRefCount(resultPtr); Tcl_GetStringFromObj(resultPtr, &cmdLength); chan = Tcl_GetStdChannel(TCL_STDOUT); if ((cmdLength > 0) && chan) { Tcl_WriteObj(chan, resultPtr); Tcl_WriteChars(chan, "\n", 1); } Tcl_DecrRefCount(resultPtr); } } else { /* (mainLoopProc != NULL) */ /* |
︙ | ︙ | |||
750 751 752 753 754 755 756 | /* ARGSUSED */ static void StdinProc( ClientData clientData, /* The state of interactive cmd line */ int mask) /* Not used. */ { | | > > | | | 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 | /* ARGSUSED */ static void StdinProc( ClientData clientData, /* The state of interactive cmd line */ int mask) /* Not used. */ { int code; ssize_t inputLength; size_t cmdLength; InteractiveState *isPtr = clientData; Tcl_Channel chan = isPtr->input; Tcl_Obj *commandPtr = isPtr->commandPtr; Tcl_Interp *interp = isPtr->interp; if (Tcl_IsShared(commandPtr)) { Tcl_DecrRefCount(commandPtr); commandPtr = Tcl_DuplicateObj(commandPtr); Tcl_IncrRefCount(commandPtr); } inputLength = Tcl_GetsObj(chan, commandPtr); if (inputLength < 0) { if (Tcl_InputBlocked(chan)) { return; } if (isPtr->tty) { /* * Would be better to find a way to exit the mainLoop? Or perhaps * evaluate [exit]? Leaving as is for now due to compatibility |
︙ | ︙ | |||
790 791 792 793 794 795 796 | } Tcl_AppendToObj(commandPtr, "\n", 1); if (!TclObjCommandComplete(commandPtr)) { isPtr->prompt = PROMPT_CONTINUE; goto prompt; } isPtr->prompt = PROMPT_START; | | | | 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 | } Tcl_AppendToObj(commandPtr, "\n", 1); if (!TclObjCommandComplete(commandPtr)) { isPtr->prompt = PROMPT_CONTINUE; goto prompt; } isPtr->prompt = PROMPT_START; Tcl_GetStringFromObj(commandPtr, &cmdLength); Tcl_SetObjLength(commandPtr, --cmdLength); /* * Disable the stdin channel handler while evaluating the command; * otherwise if the command re-enters the event loop we might process * commands from stdin before the current command is finished. Among other * things, this will trash the text of the command being evaluated. */ |
︙ | ︙ | |||
821 822 823 824 825 826 827 | Tcl_WriteChars(chan, "\n", 1); } } else if (isPtr->tty) { Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); chan = Tcl_GetStdChannel(TCL_STDOUT); Tcl_IncrRefCount(resultPtr); | | | | 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 | Tcl_WriteChars(chan, "\n", 1); } } else if (isPtr->tty) { Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); chan = Tcl_GetStdChannel(TCL_STDOUT); Tcl_IncrRefCount(resultPtr); Tcl_GetStringFromObj(resultPtr, &cmdLength); if ((cmdLength > 0) && (chan != NULL)) { Tcl_WriteObj(chan, resultPtr); Tcl_WriteChars(chan, "\n", 1); } Tcl_DecrRefCount(resultPtr); } /* |
︙ | ︙ |
Changes to generic/tclNamesp.c.
︙ | ︙ | |||
85 86 87 88 89 90 91 | const char *name2, int flags); static char * EstablishErrorInfoTraces(ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags); static void FreeNsNameInternalRep(Tcl_Obj *objPtr); static int GetNamespaceFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Namespace **nsPtrPtr); | | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < | 85 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 | const char *name2, int flags); static char * EstablishErrorInfoTraces(ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags); static void FreeNsNameInternalRep(Tcl_Obj *objPtr); static int GetNamespaceFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Namespace **nsPtrPtr); static Tcl_ObjCmdProc InvokeImportedCmd; static Tcl_ObjCmdProc InvokeImportedNRCmd; static Tcl_ObjCmdProc NamespaceChildrenCmd; static Tcl_ObjCmdProc NamespaceCodeCmd; static Tcl_ObjCmdProc NamespaceCurrentCmd; static Tcl_ObjCmdProc NamespaceDeleteCmd; static Tcl_ObjCmdProc NamespaceEvalCmd; static Tcl_ObjCmdProc NRNamespaceEvalCmd; static Tcl_ObjCmdProc NamespaceExistsCmd; static Tcl_ObjCmdProc NamespaceExportCmd; static Tcl_ObjCmdProc NamespaceForgetCmd; static void NamespaceFree(Namespace *nsPtr); static Tcl_ObjCmdProc NamespaceImportCmd; static Tcl_ObjCmdProc NamespaceInscopeCmd; static Tcl_ObjCmdProc NRNamespaceInscopeCmd; static Tcl_ObjCmdProc NamespaceOriginCmd; static Tcl_ObjCmdProc NamespaceParentCmd; static Tcl_ObjCmdProc NamespacePathCmd; static Tcl_ObjCmdProc NamespaceQualifiersCmd; static Tcl_ObjCmdProc NamespaceTailCmd; static Tcl_ObjCmdProc NamespaceUpvarCmd; static Tcl_ObjCmdProc NamespaceUnknownCmd; static Tcl_ObjCmdProc NamespaceWhichCmd; static int SetNsNameFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static void UnlinkNsPath(Namespace *nsPtr); static Tcl_NRPostProc NsEval_Callback; /* * This structure defines a Tcl object type that contains a namespace |
︙ | ︙ | |||
667 668 669 670 671 672 673 | register Namespace *nsPtr, *ancestorPtr; Namespace *parentPtr, *dummy1Ptr, *dummy2Ptr; Namespace *globalNsPtr = iPtr->globalNsPtr; const char *simpleName; Tcl_HashEntry *entryPtr; Tcl_DString buffer1, buffer2; Tcl_DString *namePtr, *buffPtr; | | > | 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 | register Namespace *nsPtr, *ancestorPtr; Namespace *parentPtr, *dummy1Ptr, *dummy2Ptr; Namespace *globalNsPtr = iPtr->globalNsPtr; const char *simpleName; Tcl_HashEntry *entryPtr; Tcl_DString buffer1, buffer2; Tcl_DString *namePtr, *buffPtr; int newEntry; size_t nameLen; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); const char *nameStr; Tcl_DString tmpBuffer; Tcl_DStringInit(&tmpBuffer); /* |
︙ | ︙ | |||
697 698 699 700 701 702 703 | * Ensure that there are no trailing colons as that causes chaos when a * deleteProc is specified. [Bug d614d63989] */ if (deleteProc != NULL) { nameStr = name + strlen(name) - 2; if (nameStr >= name && nameStr[1] == ':' && nameStr[0] == ':') { | | | > | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 | * Ensure that there are no trailing colons as that causes chaos when a * deleteProc is specified. [Bug d614d63989] */ if (deleteProc != NULL) { nameStr = name + strlen(name) - 2; if (nameStr >= name && nameStr[1] == ':' && nameStr[0] == ':') { Tcl_DStringAppend(&tmpBuffer, name, TCL_STRLEN); while ((nameLen = Tcl_DStringLength(&tmpBuffer)) > 0 && Tcl_DStringValue(&tmpBuffer)[nameLen-1] == ':') { Tcl_DStringSetLength(&tmpBuffer, nameLen-1); } name = Tcl_DStringValue(&tmpBuffer); } } /* * If we've ended up with an empty string now, we're attempting to create * the global namespace despite the global namespace existing. That's * naughty! */ if (*name == '\0') { Tcl_SetObjResult(interp, Tcl_NewStringObj("can't create namespace" " \"\": only global namespace can have empty name", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE", "CREATEGLOBAL", NULL); Tcl_DStringFree(&tmpBuffer); return NULL; } /* |
︙ | ︙ | |||
832 833 834 835 836 837 838 | buffPtr = &buffer2; for (ancestorPtr = nsPtr; ancestorPtr != NULL; ancestorPtr = ancestorPtr->parentPtr) { if (ancestorPtr != globalNsPtr) { register Tcl_DString *tempPtr = namePtr; TclDStringAppendLiteral(buffPtr, "::"); | | | 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 | buffPtr = &buffer2; for (ancestorPtr = nsPtr; ancestorPtr != NULL; ancestorPtr = ancestorPtr->parentPtr) { if (ancestorPtr != globalNsPtr) { register Tcl_DString *tempPtr = namePtr; TclDStringAppendLiteral(buffPtr, "::"); Tcl_DStringAppend(buffPtr, ancestorPtr->name, TCL_STRLEN); TclDStringAppendDString(buffPtr, namePtr); /* * Clear the unwanted buffer or we end up appending to previous * results, making the namespace fullNames of nested namespaces * very wrong (and strange). */ |
︙ | ︙ | |||
1471 1472 1473 1474 1475 1476 1477 | /* * Append the export pattern list onto objPtr. */ for (i = 0; i < nsPtr->numExportPatterns; i++) { result = Tcl_ListObjAppendElement(interp, objPtr, | | | 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 | /* * Append the export pattern list onto objPtr. */ for (i = 0; i < nsPtr->numExportPatterns; i++) { result = Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(nsPtr->exportArrayPtr[i], TCL_STRLEN)); if (result != TCL_OK) { return result; } } return TCL_OK; } |
︙ | ︙ | |||
1550 1551 1552 1553 1554 1555 1556 | */ if (Tcl_FindCommand(interp,"auto_import",NULL,TCL_GLOBAL_ONLY) != NULL) { Tcl_Obj *objv[2]; int result; TclNewLiteralStringObj(objv[0], "auto_import"); | | | > | 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 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 | */ if (Tcl_FindCommand(interp,"auto_import",NULL,TCL_GLOBAL_ONLY) != NULL) { Tcl_Obj *objv[2]; int result; TclNewLiteralStringObj(objv[0], "auto_import"); objv[1] = Tcl_NewStringObj(pattern, TCL_STRLEN); Tcl_IncrRefCount(objv[0]); Tcl_IncrRefCount(objv[1]); result = Tcl_EvalObjv(interp, 2, objv, TCL_GLOBAL_ONLY); Tcl_DecrRefCount(objv[0]); Tcl_DecrRefCount(objv[1]); if (result != TCL_OK) { return TCL_ERROR; } Tcl_ResetResult(interp); } /* * From the pattern, find the namespace from which we are importing and * get the simple pattern (no namespace qualifiers or ::'s) at the end. */ if (strlen(pattern) == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj("empty import pattern", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "IMPORT", "EMPTY", NULL); return TCL_ERROR; } TclGetNamespaceForQualName(interp, pattern, nsPtr, TCL_NAMESPACE_ONLY, &importNsPtr, &dummyPtr, &dummyPtr, &simplePattern); if (importNsPtr == NULL) { |
︙ | ︙ | |||
1691 1692 1693 1694 1695 1696 1697 | Tcl_DString ds; Tcl_Command importedCmd; ImportedCmdData *dataPtr; Command *cmdPtr; ImportRef *refPtr; Tcl_DStringInit(&ds); | | | | 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 | Tcl_DString ds; Tcl_Command importedCmd; ImportedCmdData *dataPtr; Command *cmdPtr; ImportRef *refPtr; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, nsPtr->fullName, TCL_STRLEN); if (nsPtr != ((Interp *) interp)->globalNsPtr) { TclDStringAppendLiteral(&ds, "::"); } Tcl_DStringAppend(&ds, cmdName, TCL_STRLEN); /* * Check whether creating the new imported command in the current * namespace would create a cycle of imported command references. */ cmdPtr = Tcl_GetHashValue(hPtr); |
︙ | ︙ | |||
1966 1967 1968 1969 1970 1971 1972 | */ static int InvokeImportedNRCmd( ClientData clientData, /* Points to the imported command's * ImportedCmdData structure. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 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 | */ static int InvokeImportedNRCmd( ClientData clientData, /* Points to the imported command's * ImportedCmdData structure. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { ImportedCmdData *dataPtr = clientData; Command *realCmdPtr = dataPtr->realCmdPtr; TclSkipTailcall(interp); return TclNREvalObjv(interp, objc, objv, TCL_EVAL_NOERR, realCmdPtr); } static int InvokeImportedCmd( ClientData clientData, /* Points to the imported command's * ImportedCmdData structure. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { return Tcl_NRCallObjProc(interp, InvokeImportedNRCmd, clientData, objc, objv); } /* |
︙ | ︙ | |||
2901 2902 2903 2904 2905 2906 2907 | *---------------------------------------------------------------------- */ static int NamespaceChildrenCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 | *---------------------------------------------------------------------- */ static int NamespaceChildrenCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_Namespace *namespacePtr; Namespace *nsPtr, *childNsPtr; Namespace *globalNsPtr = (Namespace *) TclGetGlobalNamespace(interp); const char *pattern = NULL; Tcl_DString buffer; register Tcl_HashEntry *entryPtr; |
︙ | ︙ | |||
2940 2941 2942 2943 2944 2945 2946 | Tcl_DStringInit(&buffer); if (objc == 3) { const char *name = TclGetString(objv[2]); if ((*name == ':') && (*(name+1) == ':')) { pattern = name; } else { | | | | 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 | Tcl_DStringInit(&buffer); if (objc == 3) { const char *name = TclGetString(objv[2]); if ((*name == ':') && (*(name+1) == ':')) { pattern = name; } else { Tcl_DStringAppend(&buffer, nsPtr->fullName, TCL_STRLEN); if (nsPtr != globalNsPtr) { TclDStringAppendLiteral(&buffer, "::"); } Tcl_DStringAppend(&buffer, name, TCL_STRLEN); pattern = Tcl_DStringValue(&buffer); } } /* * Create a list containing the full names of all child namespaces whose * names match the specified pattern, if any. |
︙ | ︙ | |||
2970 2971 2972 2973 2974 2975 2976 | Tcl_FindHashEntry(&nsPtr->childTable, pattern+length) != NULL #else nsPtr->childTablePtr != NULL && Tcl_FindHashEntry(nsPtr->childTablePtr, pattern+length) != NULL #endif ) { Tcl_ListObjAppendElement(interp, listPtr, | | | | 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 | Tcl_FindHashEntry(&nsPtr->childTable, pattern+length) != NULL #else nsPtr->childTablePtr != NULL && Tcl_FindHashEntry(nsPtr->childTablePtr, pattern+length) != NULL #endif ) { Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(pattern, TCL_STRLEN)); } goto searchDone; } #ifndef BREAK_NAMESPACE_COMPAT entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search); #else if (nsPtr->childTablePtr == NULL) { goto searchDone; } entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search); #endif while (entryPtr != NULL) { childNsPtr = Tcl_GetHashValue(entryPtr); if ((pattern == NULL) || Tcl_StringMatch(childNsPtr->fullName, pattern)) { elemPtr = Tcl_NewStringObj(childNsPtr->fullName, TCL_STRLEN); Tcl_ListObjAppendElement(interp, listPtr, elemPtr); } entryPtr = Tcl_NextHashEntry(&search); } searchDone: Tcl_SetObjResult(interp, listPtr); |
︙ | ︙ | |||
3030 3031 3032 3033 3034 3035 3036 | *---------------------------------------------------------------------- */ static int NamespaceCodeCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 | *---------------------------------------------------------------------- */ static int NamespaceCodeCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Namespace *currNsPtr; Tcl_Obj *listPtr, *objPtr; register const char *arg; size_t length; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "arg"); return TCL_ERROR; } /* |
︙ | ︙ | |||
3076 3077 3078 3079 3080 3081 3082 | TclNewLiteralStringObj(objPtr, "inscope"); Tcl_ListObjAppendElement(interp, listPtr, objPtr); currNsPtr = (Namespace *) TclGetCurrentNamespace(interp); if (currNsPtr == (Namespace *) TclGetGlobalNamespace(interp)) { TclNewLiteralStringObj(objPtr, "::"); } else { | | | 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 | TclNewLiteralStringObj(objPtr, "inscope"); Tcl_ListObjAppendElement(interp, listPtr, objPtr); currNsPtr = (Namespace *) TclGetCurrentNamespace(interp); if (currNsPtr == (Namespace *) TclGetGlobalNamespace(interp)) { TclNewLiteralStringObj(objPtr, "::"); } else { objPtr = Tcl_NewStringObj(currNsPtr->fullName, TCL_STRLEN); } Tcl_ListObjAppendElement(interp, listPtr, objPtr); Tcl_ListObjAppendElement(interp, listPtr, objv[1]); Tcl_SetObjResult(interp, listPtr); return TCL_OK; |
︙ | ︙ | |||
3111 3112 3113 3114 3115 3116 3117 | *---------------------------------------------------------------------- */ static int NamespaceCurrentCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 | *---------------------------------------------------------------------- */ static int NamespaceCurrentCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { register Namespace *currNsPtr; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } |
︙ | ︙ | |||
3134 3135 3136 3137 3138 3139 3140 | * namespace [namespace current]::bar { ... } */ currNsPtr = (Namespace *) TclGetCurrentNamespace(interp); if (currNsPtr == (Namespace *) TclGetGlobalNamespace(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("::", 2)); } else { | | > | 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 | * namespace [namespace current]::bar { ... } */ currNsPtr = (Namespace *) TclGetCurrentNamespace(interp); if (currNsPtr == (Namespace *) TclGetGlobalNamespace(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("::", 2)); } else { Tcl_SetObjResult(interp, Tcl_NewStringObj(currNsPtr->fullName, TCL_STRLEN)); } return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3174 3175 3176 3177 3178 3179 3180 | *---------------------------------------------------------------------- */ static int NamespaceDeleteCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 | *---------------------------------------------------------------------- */ static int NamespaceDeleteCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_Namespace *namespacePtr; const char *name; register int i; if (objc < 1) { Tcl_WrongNumArgs(interp, 1, objv, "?name name...?"); |
︙ | ︙ | |||
3251 3252 3253 3254 3255 3256 3257 | *---------------------------------------------------------------------- */ static int NamespaceEvalCmd( ClientData clientData, /* Arbitrary value passed to cmd. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | | 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 | *---------------------------------------------------------------------- */ static int NamespaceEvalCmd( ClientData clientData, /* Arbitrary value passed to cmd. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { return Tcl_NRCallObjProc(interp, NRNamespaceEvalCmd, clientData, objc, objv); } static int NRNamespaceEvalCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Interp *iPtr = (Interp *) interp; CmdFrame *invoker; int word; Tcl_Namespace *namespacePtr; CallFrame *framePtr, **framePtrPtr; Tcl_Obj *objPtr; |
︙ | ︙ | |||
3404 3405 3406 3407 3408 3409 3410 | *---------------------------------------------------------------------- */ static int NamespaceExistsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 | *---------------------------------------------------------------------- */ static int NamespaceExistsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_Namespace *namespacePtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } |
︙ | ︙ | |||
3459 3460 3461 3462 3463 3464 3465 | *---------------------------------------------------------------------- */ static int NamespaceExportCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 | *---------------------------------------------------------------------- */ static int NamespaceExportCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { int firstArg, i; if (objc < 1) { Tcl_WrongNumArgs(interp, 1, objv, "?-clear? ?pattern pattern...?"); return TCL_ERROR; } |
︙ | ︙ | |||
3540 3541 3542 3543 3544 3545 3546 | *---------------------------------------------------------------------- */ static int NamespaceForgetCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 | *---------------------------------------------------------------------- */ static int NamespaceForgetCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { const char *pattern; register int i, result; if (objc < 1) { Tcl_WrongNumArgs(interp, 1, objv, "?pattern pattern...?"); return TCL_ERROR; |
︙ | ︙ | |||
3605 3606 3607 3608 3609 3610 3611 | *---------------------------------------------------------------------- */ static int NamespaceImportCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 | *---------------------------------------------------------------------- */ static int NamespaceImportCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { int allowOverwrite = 0; const char *string, *pattern; register int i, result; int firstArg; if (objc < 1) { |
︙ | ︙ | |||
3647 3648 3649 3650 3651 3652 3653 | TclNewObj(listPtr); for (hPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { Command *cmdPtr = Tcl_GetHashValue(hPtr); if (cmdPtr->deleteProc == DeleteImportedCmd) { Tcl_ListObjAppendElement(NULL, listPtr, Tcl_NewStringObj( | | | 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 | TclNewObj(listPtr); for (hPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { Command *cmdPtr = Tcl_GetHashValue(hPtr); if (cmdPtr->deleteProc == DeleteImportedCmd) { Tcl_ListObjAppendElement(NULL, listPtr, Tcl_NewStringObj( Tcl_GetHashKey(&nsPtr->cmdTable, hPtr), TCL_STRLEN)); } } Tcl_SetObjResult(interp, listPtr); return TCL_OK; } /* |
︙ | ︙ | |||
3709 3710 3711 3712 3713 3714 3715 | *---------------------------------------------------------------------- */ static int NamespaceInscopeCmd( ClientData clientData, /* Arbitrary value passed to cmd. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | | 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 | *---------------------------------------------------------------------- */ static int NamespaceInscopeCmd( ClientData clientData, /* Arbitrary value passed to cmd. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { return Tcl_NRCallObjProc(interp, NRNamespaceInscopeCmd, clientData, objc, objv); } static int NRNamespaceInscopeCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_Namespace *namespacePtr; CallFrame *framePtr, **framePtrPtr; register Interp *iPtr = (Interp *) interp; int i, result; Tcl_Obj *cmdObjPtr; |
︙ | ︙ | |||
3828 3829 3830 3831 3832 3833 3834 | *---------------------------------------------------------------------- */ static int NamespaceOriginCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 | *---------------------------------------------------------------------- */ static int NamespaceOriginCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_Command command, origCommand; Tcl_Obj *resultPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; |
︙ | ︙ | |||
3889 3890 3891 3892 3893 3894 3895 | *---------------------------------------------------------------------- */ static int NamespaceParentCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 | *---------------------------------------------------------------------- */ static int NamespaceParentCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_Namespace *nsPtr; if (objc == 1) { nsPtr = TclGetCurrentNamespace(interp); } else if (objc == 2) { if (TclGetNamespaceFromObj(interp, objv[1], &nsPtr) != TCL_OK) { return TCL_ERROR; } } else { Tcl_WrongNumArgs(interp, 1, objv, "?name?"); return TCL_ERROR; } /* * Report the parent of the specified namespace. */ if (nsPtr->parentPtr != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( nsPtr->parentPtr->fullName, TCL_STRLEN)); } return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3947 3948 3949 3950 3951 3952 3953 | *---------------------------------------------------------------------- */ static int NamespacePathCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | > | > | 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 | *---------------------------------------------------------------------- */ static int NamespacePathCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Namespace *nsPtr = (Namespace *) TclGetCurrentNamespace(interp); int result = TCL_ERROR; size_t i, nsObjc; Tcl_Obj **nsObjv; Tcl_Namespace **namespaceList = NULL; if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?pathList?"); return TCL_ERROR; } /* * If no path is given, return the current path. */ if (objc == 1) { Tcl_Obj *resultObj = Tcl_NewObj(); for (i=0 ; i<nsPtr->commandPathLength ; i++) { if (nsPtr->commandPathArray[i].nsPtr != NULL) { Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( nsPtr->commandPathArray[i].nsPtr->fullName, TCL_STRLEN)); } } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } /* |
︙ | ︙ | |||
4033 4034 4035 4036 4037 4038 4039 | * *---------------------------------------------------------------------- */ void TclSetNsPath( Namespace *nsPtr, /* Namespace whose path is to be set. */ | | | 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 | * *---------------------------------------------------------------------- */ void TclSetNsPath( Namespace *nsPtr, /* Namespace whose path is to be set. */ size_t pathLength, /* Length of pathAry. */ Tcl_Namespace *pathAry[]) /* Array of namespaces that are the path. */ { if (pathLength != 0) { NamespacePathEntry *tmpPathArray = ckalloc(sizeof(NamespacePathEntry) * pathLength); int i; |
︙ | ︙ | |||
4172 4173 4174 4175 4176 4177 4178 | *---------------------------------------------------------------------- */ static int NamespaceQualifiersCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 | *---------------------------------------------------------------------- */ static int NamespaceQualifiersCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { register const char *name, *p; int length; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "string"); return TCL_ERROR; |
︙ | ︙ | |||
4240 4241 4242 4243 4244 4245 4246 | *---------------------------------------------------------------------- */ static int NamespaceUnknownCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 | *---------------------------------------------------------------------- */ static int NamespaceUnknownCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_Namespace *currNsPtr; Tcl_Obj *resultPtr; int rc; if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?script?"); |
︙ | ︙ | |||
4341 4342 4343 4344 4345 4346 4347 | int Tcl_SetNamespaceUnknownHandler( Tcl_Interp *interp, /* Interpreter in which the namespace * exists. */ Tcl_Namespace *nsPtr, /* Namespace which is being updated. */ Tcl_Obj *handlerPtr) /* The new handler, or NULL to reset. */ { | | | 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 | int Tcl_SetNamespaceUnknownHandler( Tcl_Interp *interp, /* Interpreter in which the namespace * exists. */ Tcl_Namespace *nsPtr, /* Namespace which is being updated. */ Tcl_Obj *handlerPtr) /* The new handler, or NULL to reset. */ { size_t lstlen = 0; Namespace *currNsPtr = (Namespace *) nsPtr; /* * Ensure that we check for errors *first* before we change anything. */ if (handlerPtr != NULL) { |
︙ | ︙ | |||
4427 4428 4429 4430 4431 4432 4433 | *---------------------------------------------------------------------- */ static int NamespaceTailCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 | *---------------------------------------------------------------------- */ static int NamespaceTailCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { register const char *name, *p; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "string"); return TCL_ERROR; } |
︙ | ︙ | |||
4454 4455 4456 4457 4458 4459 4460 | if ((*p == ':') && (*(p-1) == ':')) { p++; /* Just after the last "::" */ break; } } if (p >= name) { | | | 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 | if ((*p == ':') && (*(p-1) == ':')) { p++; /* Just after the last "::" */ break; } } if (p >= name) { Tcl_SetObjResult(interp, Tcl_NewStringObj(p, TCL_STRLEN)); } return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
4485 4486 4487 4488 4489 4490 4491 | *---------------------------------------------------------------------- */ static int NamespaceUpvarCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 | *---------------------------------------------------------------------- */ static int NamespaceUpvarCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Interp *iPtr = (Interp *) interp; Tcl_Namespace *nsPtr, *savedNsPtr; Var *otherPtr, *arrayPtr; const char *myName; if (objc < 2 || (objc & 1)) { |
︙ | ︙ | |||
4559 4560 4561 4562 4563 4564 4565 | *---------------------------------------------------------------------- */ static int NamespaceWhichCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 | *---------------------------------------------------------------------- */ static int NamespaceWhichCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { static const char *const opts[] = { "-command", "-variable", NULL }; int lookupType = 0; Tcl_Obj *resultPtr; |
︙ | ︙ | |||
4847 4848 4849 4850 4851 4852 4853 | void TclLogCommandInfo( Tcl_Interp *interp, /* Interpreter in which to log information. */ const char *script, /* First character in script containing * command (must be <= command). */ const char *command, /* First character in command that generated * the error. */ | | | > | 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 | void TclLogCommandInfo( Tcl_Interp *interp, /* Interpreter in which to log information. */ const char *script, /* First character in script containing * command (must be <= command). */ const char *command, /* First character in command that generated * the error. */ size_t length, /* Number of bytes in command (TCL_STRLEN * means use all bytes up to first null * byte). */ const unsigned char *pc, /* Current pc of bytecode execution context */ Tcl_Obj **tosPtr) /* Current stack of bytecode execution * context */ { register const char *p; Interp *iPtr = (Interp *) interp; int overflow, limit = 150; |
︙ | ︙ | |||
4879 4880 4881 4882 4883 4884 4885 | iPtr->errorLine = 1; for (p = script; p != command; p++) { if (*p == '\n') { iPtr->errorLine++; } } | | | | 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 | iPtr->errorLine = 1; for (p = script; p != command; p++) { if (*p == '\n') { iPtr->errorLine++; } } if (length == TCL_STRLEN) { length = strlen(command); } overflow = (length > limit); Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n %s\n\"%.*s%s\"", ((iPtr->errorInfo == NULL) ? "while executing" : "invoked from within"), (overflow ? limit : (int) length), command, (overflow ? "..." : ""))); varPtr = TclObjLookupVarEx(interp, iPtr->eiVar, NULL, TCL_GLOBAL_ONLY, NULL, 0, 0, &arrayPtr); if ((varPtr == NULL) || !TclIsVarTraced(varPtr)) { /* * Should not happen. |
︙ | ︙ | |||
4932 4933 4934 4935 4936 4937 4938 | newObj = Tcl_DuplicateObj(iPtr->errorStack); Tcl_DecrRefCount(iPtr->errorStack); Tcl_IncrRefCount(newObj); iPtr->errorStack = newObj; } if (iPtr->resetErrorStack) { | | | 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 | newObj = Tcl_DuplicateObj(iPtr->errorStack); Tcl_DecrRefCount(iPtr->errorStack); Tcl_IncrRefCount(newObj); iPtr->errorStack = newObj; } if (iPtr->resetErrorStack) { size_t len; iPtr->resetErrorStack = 0; Tcl_ListObjLength(interp, iPtr->errorStack, &len); /* * Reset while keeping the list intrep as much as possible. */ |
︙ | ︙ | |||
5004 5005 5006 5007 5008 5009 5010 | *---------------------------------------------------------------------- */ void TclErrorStackResetIf( Tcl_Interp *interp, const char *msg, | | | | 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 | *---------------------------------------------------------------------- */ void TclErrorStackResetIf( Tcl_Interp *interp, const char *msg, size_t length) { Interp *iPtr = (Interp *) interp; if (Tcl_IsShared(iPtr->errorStack)) { Tcl_Obj *newObj; newObj = Tcl_DuplicateObj(iPtr->errorStack); Tcl_DecrRefCount(iPtr->errorStack); Tcl_IncrRefCount(newObj); iPtr->errorStack = newObj; } if (iPtr->resetErrorStack) { size_t len; iPtr->resetErrorStack = 0; Tcl_ListObjLength(interp, iPtr->errorStack, &len); /* * Reset while keeping the list intrep as much as possible. */ |
︙ | ︙ | |||
5059 5060 5061 5062 5063 5064 5065 | void Tcl_LogCommandInfo( Tcl_Interp *interp, /* Interpreter in which to log information. */ const char *script, /* First character in script containing * command (must be <= command). */ const char *command, /* First character in command that generated * the error. */ | | | > < | 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 | void Tcl_LogCommandInfo( Tcl_Interp *interp, /* Interpreter in which to log information. */ const char *script, /* First character in script containing * command (must be <= command). */ const char *command, /* First character in command that generated * the error. */ size_t length) /* Number of bytes in command (TCL_STRLEN * means use all bytes up to first null * byte). */ { TclLogCommandInfo(interp, script, command, length, NULL, NULL); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * tab-width: 8 * End: */ |
Changes to generic/tclOO.c.
︙ | ︙ | |||
81 82 83 84 85 86 87 | Tcl_Interp *interp, const char *oldName, const char *newName, int flags); static void ReleaseClassContents(Tcl_Interp *interp,Object *oPtr); static inline void SquelchCachedName(Object *oPtr); static void SquelchedNsFirst(ClientData clientData); static int PublicObjectCmd(ClientData clientData, | | | | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | Tcl_Interp *interp, const char *oldName, const char *newName, int flags); static void ReleaseClassContents(Tcl_Interp *interp,Object *oPtr); static inline void SquelchCachedName(Object *oPtr); static void SquelchedNsFirst(ClientData clientData); static int PublicObjectCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv); static int PublicNRObjectCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv); static int PrivateObjectCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv); static int PrivateNRObjectCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv); /* * Methods in the oo::object and oo::class classes. First, we define a helper * macro that makes building the method type declaration structure a lot * easier. No point in making life harder than it has to be! * |
︙ | ︙ | |||
355 356 357 358 359 360 361 | /* * 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::"); | | | | 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | /* * 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_STRLEN); 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_STRLEN); Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer), objdefCmds[i].objProc, INT2PTR(objdefCmds[i].flag), NULL); Tcl_DStringFree(&buffer); } Tcl_CallWhenDeleted(interp, KillFoundation, NULL); |
︙ | ︙ | |||
411 412 413 414 415 416 417 | /* * Create the default <cloned> method implementation, used when 'oo::copy' * is called to finish the copying of one object to another. */ TclNewLiteralStringObj(argsPtr, "originObject"); Tcl_IncrRefCount(argsPtr); | | | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 | /* * Create the default <cloned> method implementation, used when 'oo::copy' * is called to finish the copying of one object to another. */ TclNewLiteralStringObj(argsPtr, "originObject"); Tcl_IncrRefCount(argsPtr); bodyPtr = Tcl_NewStringObj(clonedBody, TCL_STRLEN); TclOONewProcMethod(interp, fPtr->objectCls, 0, fPtr->clonedName, argsPtr, bodyPtr, NULL); TclDecrRefCount(argsPtr); /* * Finish setting up the class of classes by marking the 'new' method as * private; classes, unlike general objects, must have explicit names. We |
︙ | ︙ | |||
655 656 657 658 659 660 661 | oPtr->command = Tcl_CreateObjCommand(interp, nameStr, PublicObjectCmd, oPtr, NULL); } else { Tcl_DString buffer; Tcl_DStringInit(&buffer); Tcl_DStringAppend(&buffer, | | | | 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 | oPtr->command = Tcl_CreateObjCommand(interp, nameStr, PublicObjectCmd, oPtr, NULL); } else { Tcl_DString buffer; Tcl_DStringInit(&buffer); Tcl_DStringAppend(&buffer, Tcl_GetCurrentNamespace(interp)->fullName, TCL_STRLEN); TclDStringAppendLiteral(&buffer, "::"); Tcl_DStringAppend(&buffer, nameStr, TCL_STRLEN); oPtr->command = Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer), PublicObjectCmd, oPtr, NULL); Tcl_DStringFree(&buffer); } /* * Add the NRE command and trace directly. While this breaks a number of |
︙ | ︙ | |||
1563 1564 1565 1566 1567 1568 1569 | 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. */ | | | | | 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 | 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. */ size_t objc, /* Number of arguments. TCL_STRLEN means do * not call constructor. */ Tcl_Obj *const *objv, /* Argument list. */ size_t skip) /* Number of arguments to _not_ pass to the * constructor. */ { register Class *classPtr = (Class *) cls; Foundation *fPtr = GetFoundation(interp); Object *oPtr; /* |
︙ | ︙ | |||
1614 1615 1616 1617 1618 1619 1620 | AllocClass(interp, oPtr); oPtr->selfCls = classPtr; TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls); } /* | | | | | 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 | AllocClass(interp, oPtr); oPtr->selfCls = classPtr; TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls); } /* * Run constructors, except when objc == TCL_STRLEN (a special flag case * used for object cloning only). */ if (objc != TCL_STRLEN) { CallContext *contextPtr = TclOOGetCallContext(oPtr, NULL, CONSTRUCTOR, NULL); if (contextPtr != NULL) { int result; Tcl_InterpState state; |
︙ | ︙ | |||
1649 1650 1651 1652 1653 1654 1655 | * It's an error if the object was whacked in the constructor. * Force this if it isn't already an error (don't want to lose * errors by accident...) [Bug 2903011] */ if (result != TCL_ERROR && Deleted(oPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 | * It's an error if the object was whacked in the constructor. * Force this if it isn't already an error (don't want to lose * errors by accident...) [Bug 2903011] */ if (result != TCL_ERROR && Deleted(oPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "object deleted in constructor", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "STILLBORN", NULL); result = TCL_ERROR; } TclOODeleteContext(contextPtr); if (result != TCL_OK) { Tcl_DiscardInterpState(state); |
︙ | ︙ | |||
1683 1684 1685 1686 1687 1688 1689 | 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. */ | | | | | 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 | 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. */ size_t objc, /* Number of arguments. TCL_STRLEN means do * not call constructor. */ Tcl_Obj *const *objv, /* Argument list. */ size_t skip, /* Number of arguments to _not_ pass to the * constructor. */ Tcl_Object *objectPtr) /* Place to write the object reference upon * successful allocation. */ { register Class *classPtr = (Class *) cls; Foundation *fPtr = GetFoundation(interp); CallContext *contextPtr; |
︙ | ︙ | |||
1738 1739 1740 1741 1742 1743 1744 | AllocClass(interp, oPtr); oPtr->selfCls = classPtr; TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls); } /* | | | > | | 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 | AllocClass(interp, oPtr); oPtr->selfCls = classPtr; TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls); } /* * Run constructors, except when objc == TCL_STRLEN (a special flag case * used for object cloning only). If there aren't any constructors, we do * nothing. */ if (objc == TCL_STRLEN) { *objectPtr = (Tcl_Object) oPtr; return TCL_OK; } contextPtr = TclOOGetCallContext(oPtr, NULL, CONSTRUCTOR, NULL); if (contextPtr == NULL) { *objectPtr = (Tcl_Object) oPtr; return TCL_OK; |
︙ | ︙ | |||
1795 1796 1797 1798 1799 1800 1801 | * It's an error if the object was whacked in the constructor. Force this * if it isn't already an error (don't want to lose errors by accident...) * [Bug 2903011] */ if (result != TCL_ERROR && Deleted(oPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 | * It's an error if the object was whacked in the constructor. Force this * if it isn't already an error (don't want to lose errors by accident...) * [Bug 2903011] */ if (result != TCL_ERROR && Deleted(oPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "object deleted in constructor", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "STILLBORN", NULL); result = TCL_ERROR; } TclOODeleteContext(contextPtr); if (result != TCL_OK) { Tcl_DiscardInterpState(state); |
︙ | ︙ | |||
1853 1854 1855 1856 1857 1858 1859 | /* * Sanity check. */ if (IsRootClass(oPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | | 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 | /* * Sanity check. */ if (IsRootClass(oPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not clone the class of classes", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "CLONING_CLASS", NULL); return NULL; } /* * Build the instance. Note that this does not run any constructors. */ o2Ptr = (Object *) Tcl_NewObjectInstance(interp, (Tcl_Class) oPtr->selfCls, targetName, targetNamespaceName, TCL_STRLEN, NULL, TCL_STRLEN); if (o2Ptr == NULL) { return NULL; } /* * Copy the object-local methods to the new object. */ |
︙ | ︙ | |||
2378 2379 2380 2381 2382 2383 2384 | * ---------------------------------------------------------------------- */ static int PublicObjectCmd( ClientData clientData, Tcl_Interp *interp, | | | | | | | 2379 2380 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 2443 | * ---------------------------------------------------------------------- */ static int PublicObjectCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { return Tcl_NRCallObjProc(interp, PublicNRObjectCmd, clientData,objc,objv); } static int PublicNRObjectCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { return TclOOObjectCmdCore(clientData, interp, objc, objv, PUBLIC_METHOD, NULL); } static int PrivateObjectCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { return Tcl_NRCallObjProc(interp, PrivateNRObjectCmd,clientData,objc,objv); } static int PrivateNRObjectCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { return TclOOObjectCmdCore(clientData, interp, objc, objv, 0, NULL); } int TclOOInvokeObject( Tcl_Interp *interp, /* Interpreter for commands, variables, * results, error reporting, etc. */ Tcl_Object object, /* The object to invoke. */ Tcl_Class startCls, /* Where in the class chain to start the * 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). */ size_t 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, |
︙ | ︙ | |||
2462 2463 2464 2465 2466 2467 2468 | * ---------------------------------------------------------------------- */ int TclOOObjectCmdCore( Object *oPtr, /* The object being invoked. */ Tcl_Interp *interp, /* The interpreter containing the object. */ | | | 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 | * ---------------------------------------------------------------------- */ int TclOOObjectCmdCore( Object *oPtr, /* The object being invoked. */ Tcl_Interp *interp, /* The interpreter containing the object. */ size_t objc, /* How many arguments are being passed in. */ Tcl_Obj *const *objv, /* The array of arguments. */ int flags, /* Whether this is an invokation 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). */ |
︙ | ︙ | |||
2561 2562 2563 2564 2565 2566 2567 | } if (miPtr->mPtr->declaringClassPtr == startCls) { break; } } if (contextPtr->index >= contextPtr->callPtr->numChain) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 | } if (miPtr->mPtr->declaringClassPtr == startCls) { break; } } if (contextPtr->index >= contextPtr->callPtr->numChain) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no valid method implementation", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(methodNamePtr), NULL); TclOODeleteContext(contextPtr); return TCL_ERROR; } } |
︙ | ︙ | |||
2611 2612 2613 2614 2615 2616 2617 | * ---------------------------------------------------------------------- */ int Tcl_ObjectContextInvokeNext( Tcl_Interp *interp, Tcl_ObjectContext context, | | | | 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 | * ---------------------------------------------------------------------- */ int Tcl_ObjectContextInvokeNext( Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv, size_t skip) { CallContext *contextPtr = (CallContext *) context; int savedIndex = contextPtr->index; int savedSkip = contextPtr->skip; int result; if (contextPtr->index+1 >= contextPtr->callPtr->numChain) { |
︙ | ︙ | |||
2683 2684 2685 2686 2687 2688 2689 | return result; } int TclNRObjectContextInvokeNext( Tcl_Interp *interp, Tcl_ObjectContext context, | | | | 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 | return result; } int TclNRObjectContextInvokeNext( Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv, size_t skip) { register CallContext *contextPtr = (CallContext *) context; if (contextPtr->index+1 >= contextPtr->callPtr->numChain) { /* * We're at the end of the chain; generate an error message unless the * interpreter is being torn down, in which case we might be getting |
︙ | ︙ | |||
2905 2906 2907 2908 2909 2910 2911 | Tcl_Object Tcl_ObjectContextObject( Tcl_ObjectContext context) { return (Tcl_Object) ((CallContext *)context)->oPtr; } | | | 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 | Tcl_Object Tcl_ObjectContextObject( Tcl_ObjectContext context) { return (Tcl_Object) ((CallContext *)context)->oPtr; } size_t Tcl_ObjectContextSkippedArgs( Tcl_ObjectContext context) { return ((CallContext *)context)->skip; } Tcl_Namespace * |
︙ | ︙ |
Changes to generic/tclOO.decls.
︙ | ︙ | |||
52 53 54 55 56 57 58 | declare 12 { Tcl_Method Tcl_NewMethod(Tcl_Interp *interp, Tcl_Class cls, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData) } declare 13 { Tcl_Object Tcl_NewObjectInstance(Tcl_Interp *interp, Tcl_Class cls, | | | | | | | 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 94 95 96 97 98 99 100 101 102 103 | declare 12 { Tcl_Method Tcl_NewMethod(Tcl_Interp *interp, Tcl_Class cls, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData) } declare 13 { Tcl_Object Tcl_NewObjectInstance(Tcl_Interp *interp, Tcl_Class cls, const char *nameStr, const char *nsNameStr, size_t objc, Tcl_Obj *const *objv, size_t skip) } declare 14 { int Tcl_ObjectDeleted(Tcl_Object object) } declare 15 { int Tcl_ObjectContextIsFiltering(Tcl_ObjectContext context) } declare 16 { Tcl_Method Tcl_ObjectContextMethod(Tcl_ObjectContext context) } declare 17 { Tcl_Object Tcl_ObjectContextObject(Tcl_ObjectContext context) } declare 18 { size_t Tcl_ObjectContextSkippedArgs(Tcl_ObjectContext context) } declare 19 { ClientData Tcl_ClassGetMetadata(Tcl_Class clazz, const Tcl_ObjectMetadataType *typePtr) } declare 20 { void Tcl_ClassSetMetadata(Tcl_Class clazz, const Tcl_ObjectMetadataType *typePtr, ClientData metadata) } declare 21 { ClientData Tcl_ObjectGetMetadata(Tcl_Object object, const Tcl_ObjectMetadataType *typePtr) } declare 22 { void Tcl_ObjectSetMetadata(Tcl_Object object, const Tcl_ObjectMetadataType *typePtr, ClientData metadata) } declare 23 { int Tcl_ObjectContextInvokeNext(Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv, size_t skip) } declare 24 { Tcl_ObjectMapMethodNameProc *Tcl_ObjectGetMethodNameMapper( Tcl_Object object) } declare 25 { void Tcl_ObjectSetMethodNameMapper(Tcl_Object object, |
︙ | ︙ | |||
143 144 145 146 147 148 149 | } declare 4 { Method *TclOONewProcMethod(Tcl_Interp *interp, Class *clsPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, ProcedureMethod **pmPtrPtr) } declare 5 { | | | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | } declare 4 { Method *TclOONewProcMethod(Tcl_Interp *interp, Class *clsPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, ProcedureMethod **pmPtrPtr) } declare 5 { int TclOOObjectCmdCore(Object *oPtr, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv, int publicOnly, Class *startCls) } declare 6 { int TclOOIsReachable(Class *targetPtr, Class *startPtr) } declare 7 { Method *TclOONewForwardMethod(Tcl_Interp *interp, Class *clsPtr, |
︙ | ︙ | |||
173 174 175 176 177 178 179 | TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, ClientData clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr) } declare 11 { int TclOOInvokeObject(Tcl_Interp *interp, Tcl_Object object, | | | | | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, ClientData clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr) } declare 11 { int TclOOInvokeObject(Tcl_Interp *interp, Tcl_Object object, Tcl_Class startCls, int publicPrivate, size_t objc, Tcl_Obj *const *objv) } declare 12 { void TclOOObjectSetFilters(Object *oPtr, size_t numFilters, Tcl_Obj *const *filters) } declare 13 { void TclOOClassSetFilters(Tcl_Interp *interp, Class *classPtr, size_t numFilters, Tcl_Obj *const *filters) } declare 14 { void TclOOObjectSetMixins(Object *oPtr, size_t numMixins, Class *const *mixins) } declare 15 { void TclOOClassSetMixins(Tcl_Interp *interp, Class *classPtr, size_t numMixins, Class *const *mixins) } return # Local Variables: # mode: tcl # End: |
Changes to generic/tclOO.h.
︙ | ︙ | |||
54 55 56 57 58 59 60 | /* * Public datatypes for callbacks and structures used in the TIP#257 (OO) * implementation. These are used to implement custom types of method calls * and to allow the attachment of arbitrary data to objects and classes. */ typedef int (Tcl_MethodCallProc)(ClientData clientData, Tcl_Interp *interp, | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | /* * Public datatypes for callbacks and structures used in the TIP#257 (OO) * implementation. These are used to implement custom types of method calls * and to allow the attachment of arbitrary data to objects and classes. */ typedef int (Tcl_MethodCallProc)(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext, size_t objc, Tcl_Obj *const *objv); typedef void (Tcl_MethodDeleteProc)(ClientData clientData); typedef int (Tcl_CloneProc)(Tcl_Interp *interp, ClientData oldClientData, ClientData *newClientData); typedef void (Tcl_ObjectMetadataDeleteProc)(ClientData clientData); typedef int (Tcl_ObjectMapMethodNameProc)(Tcl_Interp *interp, Tcl_Object object, Tcl_Class *startClsPtr, Tcl_Obj *methodNameObj); |
︙ | ︙ |
Changes to generic/tclOOBasic.c.
︙ | ︙ | |||
80 81 82 83 84 85 86 | */ int TclOO_Class_Constructor( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, | | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | */ int TclOO_Class_Constructor( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) Tcl_ObjectContextObject(context); Tcl_Obj **invoke; if (objc-1 > Tcl_ObjectContextSkippedArgs(context)) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, |
︙ | ︙ | |||
153 154 155 156 157 158 159 | int TclOO_Class_Create( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ | | | | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | int TclOO_Class_Create( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { Object *oPtr = (Object *) Tcl_ObjectContextObject(context); const char *objName; size_t len; /* * Sanity check; should not be possible to invoke this method on a * non-class. */ if (oPtr->classPtr == NULL) { |
︙ | ︙ | |||
187 188 189 190 191 192 193 | "objectName ?arg ...?"); return TCL_ERROR; } objName = Tcl_GetStringFromObj( objv[Tcl_ObjectContextSkippedArgs(context)], &len); if (len == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | "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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", NULL); return TCL_ERROR; } /* * Make the object and return its name. */ |
︙ | ︙ | |||
218 219 220 221 222 223 224 | int TclOO_Class_CreateNs( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ | | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | int TclOO_Class_CreateNs( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { Object *oPtr = (Object *) Tcl_ObjectContextObject(context); const char *objName, *nsName; size_t len; /* * Sanity check; should not be possible to invoke this method on a * non-class. */ if (oPtr->classPtr == NULL) { |
︙ | ︙ | |||
252 253 254 255 256 257 258 | "objectName namespaceName ?arg ...?"); return TCL_ERROR; } objName = Tcl_GetStringFromObj( objv[Tcl_ObjectContextSkippedArgs(context)], &len); if (len == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | "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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", 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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", NULL); return TCL_ERROR; } /* * Make the object and return its name. */ |
︙ | ︙ | |||
291 292 293 294 295 296 297 | int TclOO_Class_New( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ | | | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | int TclOO_Class_New( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { Object *oPtr = (Object *) Tcl_ObjectContextObject(context); /* * Sanity check; should not be possible to invoke this method on a * non-class. |
︙ | ︙ | |||
335 336 337 338 339 340 341 | int TclOO_Object_Destroy( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ | | | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | int TclOO_Object_Destroy( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { Object *oPtr = (Object *) Tcl_ObjectContextObject(context); CallContext *contextPtr; if (objc != Tcl_ObjectContextSkippedArgs(context)) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, |
︙ | ︙ | |||
395 396 397 398 399 400 401 | int TclOO_Object_Eval( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ | | | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | int TclOO_Object_Eval( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { CallContext *contextPtr = (CallContext *) context; Tcl_Object object = Tcl_ObjectContextObject(context); register const int skip = Tcl_ObjectContextSkippedArgs(context); CallFrame *framePtr, **framePtrPtr = &framePtr; Tcl_Obj *scriptPtr; |
︙ | ︙ | |||
500 501 502 503 504 505 506 | int TclOO_Object_Unknown( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ | | | | 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 | int TclOO_Object_Unknown( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { CallContext *contextPtr = (CallContext *) context; Object *oPtr = contextPtr->oPtr; const char **methodNames; size_t numMethodNames, i, skip = Tcl_ObjectContextSkippedArgs(context); Tcl_Obj *errorMsg; /* * If no method name, generate an error asking for a method name. (Only by * overriding *this* method can an object handle the absence of a method * name without an error). */ |
︙ | ︙ | |||
551 552 553 554 555 556 557 | return TCL_ERROR; } errorMsg = Tcl_ObjPrintf("unknown method \"%s\": must be ", TclGetString(objv[skip])); for (i=0 ; i<numMethodNames-1 ; i++) { if (i) { | | | | | | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 | 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_STRLEN); } Tcl_AppendToObj(errorMsg, methodNames[i], TCL_STRLEN); } if (i) { Tcl_AppendToObj(errorMsg, " or ", TCL_STRLEN); } Tcl_AppendToObj(errorMsg, methodNames[i], TCL_STRLEN); ckfree(methodNames); Tcl_SetObjResult(interp, errorMsg); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[skip]), NULL); return TCL_ERROR; } |
︙ | ︙ | |||
582 583 584 585 586 587 588 | int TclOO_Object_LinkVar( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ | | | | 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 | int TclOO_Object_LinkVar( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { Interp *iPtr = (Interp *) interp; Tcl_Object object = Tcl_ObjectContextObject(context); Namespace *savedNsPtr; size_t i; if (objc-Tcl_ObjectContextSkippedArgs(context) < 0) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "?varName ...?"); return TCL_ERROR; } |
︙ | ︙ | |||
684 685 686 687 688 689 690 | int TclOO_Object_VarName( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ | | | 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | int TclOO_Object_VarName( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Interpreter in which to create the object; * also used for error reporting. */ Tcl_ObjectContext context, /* The object/call context. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { Var *varPtr, *aryVar; Tcl_Obj *varNamePtr, *argPtr; const char *arg; if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) { |
︙ | ︙ | |||
747 748 749 750 751 752 753 | * WARNING! This code pokes inside the implementation of hash tables! */ hPtr = Tcl_FirstHashEntry((Tcl_HashTable *) aryVar->value.tablePtr, &search); while (hPtr != NULL) { if (varPtr == Tcl_GetHashValue(hPtr)) { | | | | 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 | * WARNING! This code pokes inside the implementation of hash tables! */ hPtr = Tcl_FirstHashEntry((Tcl_HashTable *) aryVar->value.tablePtr, &search); while (hPtr != NULL) { if (varPtr == Tcl_GetHashValue(hPtr)) { Tcl_AppendToObj(varNamePtr, "(", TCL_STRLEN); Tcl_AppendObjToObj(varNamePtr, hPtr->key.objPtr); Tcl_AppendToObj(varNamePtr, ")", TCL_STRLEN); break; } hPtr = Tcl_NextHashEntry(&search); } } else { Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, varNamePtr); } |
︙ | ︙ | |||
777 778 779 780 781 782 783 | * ---------------------------------------------------------------------- */ int TclOONextObjCmd( ClientData clientData, Tcl_Interp *interp, | | | 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 | * ---------------------------------------------------------------------- */ int TclOONextObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Interp *iPtr = (Interp *) interp; CallFrame *framePtr = iPtr->varFramePtr; Tcl_ObjectContext context; /* |
︙ | ︙ | |||
813 814 815 816 817 818 819 | return TclNRObjectContextInvokeNext(interp, context, objc, objv, 1); } int TclOONextToObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 | return TclNRObjectContextInvokeNext(interp, context, objc, objv, 1); } int TclOONextToObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Interp *iPtr = (Interp *) interp; CallFrame *framePtr = iPtr->varFramePtr; Class *classPtr; CallContext *contextPtr; size_t i; Tcl_Object object; /* * Start with sanity checks on the calling context to make sure that we * are invoked from a suitable method context. If so, we can safely * retrieve the handle to the object call context. */ |
︙ | ︙ | |||
887 888 889 890 891 892 893 | } /* * Generate an appropriate error message, depending on whether the value * is on the chain but unreachable, or not on the chain at all. */ | | | 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 | } /* * Generate an appropriate error message, depending on whether the value * is on the chain but unreachable, or not on the chain at all. */ for (i=contextPtr->index ; i-->0 ;) { struct MInvoke *miPtr = contextPtr->callPtr->chain + i; if (!miPtr->isFilter && miPtr->mPtr->declaringClassPtr == classPtr) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "method implementation by \"%s\" not reachable from here", TclGetString(objv[1]))); return TCL_ERROR; |
︙ | ︙ | |||
934 935 936 937 938 939 940 | * ---------------------------------------------------------------------- */ int TclOOSelfObjCmd( ClientData clientData, Tcl_Interp *interp, | | | 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 | * ---------------------------------------------------------------------- */ int TclOOSelfObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { static const char *const subcmds[] = { "call", "caller", "class", "filter", "method", "namespace", "next", "object", "target", NULL }; enum SelfCmds { |
︙ | ︙ | |||
989 990 991 992 993 994 995 | switch ((enum SelfCmds) index) { case SELF_OBJECT: Tcl_SetObjResult(interp, TclOOObjectName(interp, contextPtr->oPtr)); return TCL_OK; case SELF_NS: Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | | | | | 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 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 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 | switch ((enum SelfCmds) 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_STRLEN)); 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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOOObjectName(interp, clsPtr->thisPtr)); return TCL_OK; } case SELF_METHOD: if (contextPtr->callPtr->flags & CONSTRUCTOR) { Tcl_SetObjResult(interp, contextPtr->oPtr->fPtr->constructorName); } else if (contextPtr->callPtr->flags & DESTRUCTOR) { Tcl_SetObjResult(interp, contextPtr->oPtr->fPtr->destructorName); } else { Tcl_SetObjResult(interp, CurrentlyInvoked(contextPtr).mPtr->namePtr); } return TCL_OK; case SELF_FILTER: if (!CurrentlyInvoked(contextPtr).isFilter) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "not inside a filtering context", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", NULL); return TCL_ERROR; } else { register 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_STRLEN); 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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL); return TCL_ERROR; } else { CallContext *callerPtr = framePtr->callerVarPtr->clientData; Method *mPtr = callerPtr->callPtr->chain[callerPtr->index].mPtr; Object *declarerPtr; if (mPtr->declaringClassPtr != NULL) { declarerPtr = mPtr->declaringClassPtr->thisPtr; } else if (mPtr->declaringObjectPtr != NULL) { declarerPtr = mPtr->declaringObjectPtr; } else { /* * This should be unreachable code. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "method without declarer!", TCL_STRLEN)); return TCL_ERROR; } result[0] = TclOOObjectName(interp, declarerPtr); result[1] = TclOOObjectName(interp, callerPtr->oPtr); if (callerPtr->callPtr->flags & CONSTRUCTOR) { result[2] = declarerPtr->fPtr->constructorName; |
︙ | ︙ | |||
1093 1094 1095 1096 1097 1098 1099 | declarerPtr = mPtr->declaringObjectPtr; } else { /* * This should be unreachable code. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 1093 1094 1095 1096 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 | declarerPtr = mPtr->declaringObjectPtr; } else { /* * This should be unreachable code. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "method without declarer!", TCL_STRLEN)); return TCL_ERROR; } result[0] = TclOOObjectName(interp, declarerPtr); if (contextPtr->callPtr->flags & CONSTRUCTOR) { result[1] = declarerPtr->fPtr->constructorName; } else if (contextPtr->callPtr->flags & DESTRUCTOR) { result[1] = declarerPtr->fPtr->destructorName; } else { result[1] = mPtr->namePtr; } 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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", NULL); return TCL_ERROR; } else { Method *mPtr; Object *declarerPtr; int i; |
︙ | ︙ | |||
1138 1139 1140 1141 1142 1143 1144 | declarerPtr = mPtr->declaringObjectPtr; } else { /* * This should be unreachable code. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 | declarerPtr = mPtr->declaringObjectPtr; } else { /* * This should be unreachable code. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "method without declarer!", TCL_STRLEN)); return TCL_ERROR; } result[0] = TclOOObjectName(interp, declarerPtr); result[1] = mPtr->namePtr; Tcl_SetObjResult(interp, Tcl_NewListObj(2, result)); return TCL_OK; } |
︙ | ︙ | |||
1171 1172 1173 1174 1175 1176 1177 | * ---------------------------------------------------------------------- */ int TclOOCopyObjectCmd( ClientData clientData, Tcl_Interp *interp, | | | 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 | * ---------------------------------------------------------------------- */ int TclOOCopyObjectCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Tcl_Object oPtr, o2Ptr; if (objc < 2 || objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "sourceName ?targetName?"); return TCL_ERROR; |
︙ | ︙ | |||
1207 1208 1209 1210 1211 1212 1213 | name = TclGetString(objv[2]); Tcl_DStringInit(&buffer); if (name[0]!=':' || name[1]!=':') { Interp *iPtr = (Interp *) interp; if (iPtr->varFramePtr != NULL) { Tcl_DStringAppend(&buffer, | | | | 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 | name = TclGetString(objv[2]); Tcl_DStringInit(&buffer); if (name[0]!=':' || name[1]!=':') { Interp *iPtr = (Interp *) interp; if (iPtr->varFramePtr != NULL) { Tcl_DStringAppend(&buffer, iPtr->varFramePtr->nsPtr->fullName, TCL_STRLEN); } TclDStringAppendLiteral(&buffer, "::"); Tcl_DStringAppend(&buffer, name, TCL_STRLEN); name = Tcl_DStringValue(&buffer); } o2Ptr = Tcl_CopyObjectInstance(interp, oPtr, name, NULL); Tcl_DStringFree(&buffer); } if (o2Ptr == NULL) { |
︙ | ︙ |
Changes to generic/tclOOCall.c.
︙ | ︙ | |||
238 239 240 241 242 243 244 | int TclOOInvokeContext( ClientData 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. */ | | | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | int TclOOInvokeContext( ClientData 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. */ size_t objc, /* The number of arguments. */ Tcl_Obj *const objv[]) /* The arguments as actually seen. */ { register CallContext *const contextPtr = clientData; Method *const mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; const int isFilter = contextPtr->callPtr->chain[contextPtr->index].isFilter; |
︙ | ︙ | |||
1422 1423 1424 1425 1426 1427 1428 | Foundation *fPtr = TclOOGetFoundation(interp); int i; /* * Allocate the literals (potentially) used in our description. */ | | | | | 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 | Foundation *fPtr = TclOOGetFoundation(interp); int i; /* * Allocate the literals (potentially) used in our description. */ filterLiteral = Tcl_NewStringObj("filter", TCL_STRLEN); Tcl_IncrRefCount(filterLiteral); methodLiteral = Tcl_NewStringObj("method", TCL_STRLEN); Tcl_IncrRefCount(methodLiteral); objectLiteral = Tcl_NewStringObj("object", TCL_STRLEN); Tcl_IncrRefCount(objectLiteral); /* * Do the actual construction of the descriptions. They consist of a list * of triples that describe the details of how a method is understood. For * each triple, the first word is the type of invokation ("method" is * normal, "unknown" is special because it adds the method name as an |
︙ | ︙ | |||
1459 1460 1461 1462 1463 1464 1465 | : callPtr->flags & DESTRUCTOR ? fPtr->destructorName : miPtr->mPtr->namePtr; descObjs[2] = miPtr->mPtr->declaringClassPtr ? Tcl_GetObjectName(interp, (Tcl_Object) miPtr->mPtr->declaringClassPtr->thisPtr) : objectLiteral; | | > | 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 | : callPtr->flags & DESTRUCTOR ? fPtr->destructorName : miPtr->mPtr->namePtr; descObjs[2] = miPtr->mPtr->declaringClassPtr ? Tcl_GetObjectName(interp, (Tcl_Object) miPtr->mPtr->declaringClassPtr->thisPtr) : objectLiteral; descObjs[3] = Tcl_NewStringObj(miPtr->mPtr->typePtr->name, TCL_STRLEN); objv[i] = Tcl_NewListObj(4, descObjs); } /* * Drop the local references to the literals; if they're actually used, * they'll live on the description itself. |
︙ | ︙ |
Changes to generic/tclOODecls.h.
︙ | ︙ | |||
48 49 50 51 52 53 54 | TCLOOAPI Tcl_Method Tcl_NewMethod(Tcl_Interp *interp, Tcl_Class cls, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData); /* 13 */ TCLOOAPI Tcl_Object Tcl_NewObjectInstance(Tcl_Interp *interp, Tcl_Class cls, const char *nameStr, | | | | | | | 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 | TCLOOAPI Tcl_Method Tcl_NewMethod(Tcl_Interp *interp, Tcl_Class cls, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData); /* 13 */ TCLOOAPI Tcl_Object Tcl_NewObjectInstance(Tcl_Interp *interp, Tcl_Class cls, const char *nameStr, const char *nsNameStr, size_t objc, Tcl_Obj *const *objv, size_t skip); /* 14 */ TCLOOAPI int Tcl_ObjectDeleted(Tcl_Object object); /* 15 */ TCLOOAPI int Tcl_ObjectContextIsFiltering( Tcl_ObjectContext context); /* 16 */ TCLOOAPI Tcl_Method Tcl_ObjectContextMethod(Tcl_ObjectContext context); /* 17 */ TCLOOAPI Tcl_Object Tcl_ObjectContextObject(Tcl_ObjectContext context); /* 18 */ TCLOOAPI size_t Tcl_ObjectContextSkippedArgs( Tcl_ObjectContext context); /* 19 */ TCLOOAPI ClientData Tcl_ClassGetMetadata(Tcl_Class clazz, const Tcl_ObjectMetadataType *typePtr); /* 20 */ TCLOOAPI void Tcl_ClassSetMetadata(Tcl_Class clazz, const Tcl_ObjectMetadataType *typePtr, ClientData metadata); /* 21 */ TCLOOAPI ClientData Tcl_ObjectGetMetadata(Tcl_Object object, const Tcl_ObjectMetadataType *typePtr); /* 22 */ TCLOOAPI void Tcl_ObjectSetMetadata(Tcl_Object object, const Tcl_ObjectMetadataType *typePtr, ClientData metadata); /* 23 */ TCLOOAPI int Tcl_ObjectContextInvokeNext(Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv, size_t skip); /* 24 */ TCLOOAPI Tcl_ObjectMapMethodNameProc * Tcl_ObjectGetMethodNameMapper( Tcl_Object object); /* 25 */ TCLOOAPI void Tcl_ObjectSetMethodNameMapper(Tcl_Object object, Tcl_ObjectMapMethodNameProc *mapMethodNameProc); /* 26 */ |
︙ | ︙ | |||
117 118 119 120 121 122 123 | Tcl_Class (*tcl_MethodDeclarerClass) (Tcl_Method method); /* 6 */ Tcl_Object (*tcl_MethodDeclarerObject) (Tcl_Method method); /* 7 */ int (*tcl_MethodIsPublic) (Tcl_Method method); /* 8 */ int (*tcl_MethodIsType) (Tcl_Method method, const Tcl_MethodType *typePtr, ClientData *clientDataPtr); /* 9 */ Tcl_Obj * (*tcl_MethodName) (Tcl_Method method); /* 10 */ Tcl_Method (*tcl_NewInstanceMethod) (Tcl_Interp *interp, Tcl_Object object, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData); /* 11 */ Tcl_Method (*tcl_NewMethod) (Tcl_Interp *interp, Tcl_Class cls, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData); /* 12 */ | | | | | 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 | Tcl_Class (*tcl_MethodDeclarerClass) (Tcl_Method method); /* 6 */ Tcl_Object (*tcl_MethodDeclarerObject) (Tcl_Method method); /* 7 */ int (*tcl_MethodIsPublic) (Tcl_Method method); /* 8 */ int (*tcl_MethodIsType) (Tcl_Method method, const Tcl_MethodType *typePtr, ClientData *clientDataPtr); /* 9 */ Tcl_Obj * (*tcl_MethodName) (Tcl_Method method); /* 10 */ Tcl_Method (*tcl_NewInstanceMethod) (Tcl_Interp *interp, Tcl_Object object, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData); /* 11 */ Tcl_Method (*tcl_NewMethod) (Tcl_Interp *interp, Tcl_Class cls, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData); /* 12 */ Tcl_Object (*tcl_NewObjectInstance) (Tcl_Interp *interp, Tcl_Class cls, const char *nameStr, const char *nsNameStr, size_t objc, Tcl_Obj *const *objv, size_t skip); /* 13 */ int (*tcl_ObjectDeleted) (Tcl_Object object); /* 14 */ int (*tcl_ObjectContextIsFiltering) (Tcl_ObjectContext context); /* 15 */ Tcl_Method (*tcl_ObjectContextMethod) (Tcl_ObjectContext context); /* 16 */ Tcl_Object (*tcl_ObjectContextObject) (Tcl_ObjectContext context); /* 17 */ size_t (*tcl_ObjectContextSkippedArgs) (Tcl_ObjectContext context); /* 18 */ ClientData (*tcl_ClassGetMetadata) (Tcl_Class clazz, const Tcl_ObjectMetadataType *typePtr); /* 19 */ void (*tcl_ClassSetMetadata) (Tcl_Class clazz, const Tcl_ObjectMetadataType *typePtr, ClientData metadata); /* 20 */ ClientData (*tcl_ObjectGetMetadata) (Tcl_Object object, const Tcl_ObjectMetadataType *typePtr); /* 21 */ void (*tcl_ObjectSetMetadata) (Tcl_Object object, const Tcl_ObjectMetadataType *typePtr, ClientData metadata); /* 22 */ int (*tcl_ObjectContextInvokeNext) (Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv, size_t skip); /* 23 */ Tcl_ObjectMapMethodNameProc * (*tcl_ObjectGetMethodNameMapper) (Tcl_Object object); /* 24 */ void (*tcl_ObjectSetMethodNameMapper) (Tcl_Object object, Tcl_ObjectMapMethodNameProc *mapMethodNameProc); /* 25 */ void (*tcl_ClassSetConstructor) (Tcl_Interp *interp, Tcl_Class clazz, Tcl_Method method); /* 26 */ void (*tcl_ClassSetDestructor) (Tcl_Interp *interp, Tcl_Class clazz, Tcl_Method method); /* 27 */ Tcl_Obj * (*tcl_GetObjectName) (Tcl_Interp *interp, Tcl_Object object); /* 28 */ } TclOOStubs; |
︙ | ︙ |
Changes to generic/tclOODefineCmds.c.
︙ | ︙ | |||
49 50 51 52 53 54 55 | Tcl_Namespace *const namespacePtr); static void GenerateErrorInfo(Tcl_Interp *interp, Object *oPtr, Tcl_Obj *savedNameObj, const char *typeOfSubject); static inline Class * GetClassInOuterContext(Tcl_Interp *interp, Tcl_Obj *className, const char *errMsg); static inline int InitDefineContext(Tcl_Interp *interp, Tcl_Namespace *namespacePtr, Object *oPtr, | | | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | 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 | Tcl_Namespace *const namespacePtr); static void GenerateErrorInfo(Tcl_Interp *interp, Object *oPtr, Tcl_Obj *savedNameObj, const char *typeOfSubject); static inline Class * GetClassInOuterContext(Tcl_Interp *interp, Tcl_Obj *className, const char *errMsg); static inline int InitDefineContext(Tcl_Interp *interp, Tcl_Namespace *namespacePtr, Object *oPtr, size_t objc, Tcl_Obj *const objv[]); static inline void RecomputeClassCacheFlag(Object *oPtr); static int RenameDeleteMethod(Tcl_Interp *interp, Object *oPtr, int useClass, Tcl_Obj *const fromPtr, Tcl_Obj *const toPtr); static Tcl_MethodCallProc ClassFilterGet; static Tcl_MethodCallProc ClassFilterSet; static Tcl_MethodCallProc ClassMixinGet; static Tcl_MethodCallProc ClassMixinSet; static Tcl_MethodCallProc ClassSuperGet; static Tcl_MethodCallProc ClassSuperSet; static Tcl_MethodCallProc ClassVarsGet; static Tcl_MethodCallProc ClassVarsSet; static Tcl_MethodCallProc ObjFilterGet; static Tcl_MethodCallProc ObjFilterSet; static Tcl_MethodCallProc ObjMixinGet; static Tcl_MethodCallProc ObjMixinSet; static Tcl_MethodCallProc ObjVarsGet; static Tcl_MethodCallProc ObjVarsSet; /* * Now define the slots used in declarations. */ static const struct DeclaredSlot slots[] = { SLOT("define::filter", ClassFilterGet, ClassFilterSet), |
︙ | ︙ | |||
190 191 192 193 194 195 196 | * * ---------------------------------------------------------------------- */ void TclOOObjectSetFilters( Object *oPtr, | | | | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | * * ---------------------------------------------------------------------- */ void TclOOObjectSetFilters( Object *oPtr, size_t numFilters, Tcl_Obj *const *filters) { size_t i; if (oPtr->filters.num) { Tcl_Obj *filterObj; FOREACH(filterObj, oPtr->filters) { Tcl_DecrRefCount(filterObj); } |
︙ | ︙ | |||
218 219 220 221 222 223 224 | RecomputeClassCacheFlag(oPtr); } else { /* * We've got a list of filters, so we're creating filters. */ Tcl_Obj **filtersList; | | | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | RecomputeClassCacheFlag(oPtr); } else { /* * We've got a list of filters, so we're creating filters. */ Tcl_Obj **filtersList; size_t size = sizeof(Tcl_Obj *) * numFilters; if (oPtr->filters.num == 0) { filtersList = ckalloc(size); } else { filtersList = ckrealloc(oPtr->filters.list, size); } for (i=0 ; i<numFilters ; i++) { |
︙ | ︙ | |||
249 250 251 252 253 254 255 | * ---------------------------------------------------------------------- */ void TclOOClassSetFilters( Tcl_Interp *interp, Class *classPtr, | | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | * ---------------------------------------------------------------------- */ void TclOOClassSetFilters( Tcl_Interp *interp, Class *classPtr, size_t numFilters, Tcl_Obj *const *filters) { size_t i; if (classPtr->filters.num) { Tcl_Obj *filterObj; FOREACH(filterObj, classPtr->filters) { Tcl_DecrRefCount(filterObj); } |
︙ | ︙ | |||
276 277 278 279 280 281 282 | classPtr->filters.num = 0; } else { /* * We've got a list of filters, so we're creating filters. */ Tcl_Obj **filtersList; | | | 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | classPtr->filters.num = 0; } else { /* * We've got a list of filters, so we're creating filters. */ Tcl_Obj **filtersList; size_t size = sizeof(Tcl_Obj *) * numFilters; if (classPtr->filters.num == 0) { filtersList = ckalloc(size); } else { filtersList = ckrealloc(classPtr->filters.list, size); } for (i=0 ; i<numFilters ; i++) { |
︙ | ︙ | |||
310 311 312 313 314 315 316 | * * ---------------------------------------------------------------------- */ void TclOOObjectSetMixins( Object *oPtr, | | | | 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | * * ---------------------------------------------------------------------- */ void TclOOObjectSetMixins( Object *oPtr, size_t numMixins, Class *const *mixins) { Class *mixinPtr; size_t i; if (numMixins == 0) { if (oPtr->mixins.num != 0) { FOREACH(mixinPtr, oPtr->mixins) { TclOORemoveFromInstances(oPtr, mixinPtr); } ckfree(oPtr->mixins.list); |
︙ | ︙ | |||
362 363 364 365 366 367 368 | * ---------------------------------------------------------------------- */ void TclOOClassSetMixins( Tcl_Interp *interp, Class *classPtr, | | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | * ---------------------------------------------------------------------- */ void TclOOClassSetMixins( Tcl_Interp *interp, Class *classPtr, size_t numMixins, Class *const *mixins) { Class *mixinPtr; size_t i; if (numMixins == 0) { if (classPtr->mixins.num != 0) { FOREACH(mixinPtr, classPtr->mixins) { TclOORemoveFromMixinSubs(classPtr, mixinPtr); } ckfree(classPtr->mixins.list); |
︙ | ︙ | |||
435 436 437 438 439 440 441 | } if (toPtr) { newHPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, (char *) toPtr, &isNew); if (hPtr == newHPtr) { renameToSelf: Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 | } if (toPtr) { newHPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, (char *) toPtr, &isNew); if (hPtr == newHPtr) { renameToSelf: Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot rename method to itself", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "RENAME_TO_SELF", NULL); return TCL_ERROR; } else if (!isNew) { renameToExisting: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "method called %s already exists", TclGetString(toPtr))); |
︙ | ︙ | |||
500 501 502 503 504 505 506 | * ---------------------------------------------------------------------- */ int TclOOUnknownDefinition( ClientData clientData, Tcl_Interp *interp, | | | | | 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 | * ---------------------------------------------------------------------- */ int TclOOUnknownDefinition( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Namespace *nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp); Tcl_HashSearch search; Tcl_HashEntry *hPtr; size_t soughtLen; const char *soughtStr, *matchedStr = NULL; if (objc < 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad call of unknown handler", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_UNKNOWN", NULL); return TCL_ERROR; } if (TclOOGetDefineCmdContext(interp) == NULL) { return TCL_ERROR; } |
︙ | ︙ | |||
544 545 546 547 548 549 550 | /* * Got one match, and only one match! */ Tcl_Obj **newObjv = TclStackAlloc(interp, sizeof(Tcl_Obj*)*(objc-1)); int result; | | | 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 | /* * Got one match, and only one match! */ Tcl_Obj **newObjv = TclStackAlloc(interp, sizeof(Tcl_Obj*)*(objc-1)); int result; newObjv[0] = Tcl_NewStringObj(matchedStr, TCL_STRLEN); 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); |
︙ | ︙ | |||
578 579 580 581 582 583 584 | static Tcl_Command FindCommand( Tcl_Interp *interp, Tcl_Obj *stringObj, Tcl_Namespace *const namespacePtr) { | | | 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | static Tcl_Command FindCommand( Tcl_Interp *interp, Tcl_Obj *stringObj, Tcl_Namespace *const namespacePtr) { size_t length; const char *nameStr, *string = Tcl_GetStringFromObj(stringObj, &length); register Namespace *const nsPtr = (Namespace *) namespacePtr; FOREACH_HASH_DECLS; Tcl_Command cmd, cmd2; /* * If someone is playing games, we stop playing right now. |
︙ | ︙ | |||
638 639 640 641 642 643 644 | */ static inline int InitDefineContext( Tcl_Interp *interp, Tcl_Namespace *namespacePtr, Object *oPtr, | | | | 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 | */ static inline int InitDefineContext( Tcl_Interp *interp, Tcl_Namespace *namespacePtr, Object *oPtr, size_t objc, Tcl_Obj *const objv[]) { CallFrame *framePtr, **framePtrPtr = &framePtr; int result; if (namespacePtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot process definitions; support namespace deleted", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } /* framePtrPtr is needed to satisfy GCC 3.3's strict aliasing rules */ result = TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr, |
︙ | ︙ | |||
687 688 689 690 691 692 693 | Interp *iPtr = (Interp *) interp; Tcl_Object object; if ((iPtr->varFramePtr == NULL) || (iPtr->varFramePtr->isProcCallFrame != FRAME_IS_OO_DEFINE)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "this command may only be called from within the context of" | | | | 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 | Interp *iPtr = (Interp *) interp; Tcl_Object object; if ((iPtr->varFramePtr == NULL) || (iPtr->varFramePtr->isProcCallFrame != FRAME_IS_OO_DEFINE)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "this command may only be called from within the context of" " an ::oo::define or ::oo::objdefine command", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return NULL; } 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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return NULL; } return object; } /* |
︙ | ︙ | |||
736 737 738 739 740 741 742 | } oPtr = (Object *) Tcl_GetObjectFromObj(interp, className); iPtr->varFramePtr = savedFramePtr; if (oPtr == NULL) { return NULL; } if (oPtr->classPtr == NULL) { | | | 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 | } 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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS", TclGetString(className), NULL); return NULL; } return oPtr->classPtr; } |
︙ | ︙ | |||
769 770 771 772 773 774 775 | * current name (post-execution) has to be * used. This matters, because the object * could have been renamed... */ const char *typeOfSubject) /* Part of the message, saying whether it was * an object, class or class-as-object that * was being configured. */ { | | | | | | 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 | * current name (post-execution) has to be * used. This matters, because the object * could have been renamed... */ const char *typeOfSubject) /* Part of the message, saying whether it was * an object, class or class-as-object that * was being configured. */ { size_t length; Tcl_Obj *realNameObj = Tcl_ObjectDeleted((Tcl_Object) oPtr) ? savedNameObj : TclOOObjectName(interp, oPtr); const char *objName = Tcl_GetStringFromObj(realNameObj, &length); size_t limit = OBJNAME_LENGTH_IN_ERRORINFO_LIMIT; int overflow = (length > limit); Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (in definition script for %s \"%.*s%s\" line %d)", typeOfSubject, (int)(overflow ? limit : length), objName, (overflow ? "..." : ""), Tcl_GetErrorLine(interp))); } /* * ---------------------------------------------------------------------- * * TclOODefineObjCmd -- * Implementation of the "oo::define" command. Works by effectively doing * the same as 'namespace eval', but with extra magic applied so that the * object to be modified is known to the commands in the target * namespace. Also does ensemble-like tricks with dispatch so that error * messages are clearer. * * ---------------------------------------------------------------------- */ int TclOODefineObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Foundation *fPtr = TclOOGetFoundation(interp); int result; Object *oPtr; if (objc < 3) { |
︙ | ︙ | |||
847 848 849 850 851 852 853 | GenerateErrorInfo(interp, oPtr, objNameObj, "class"); } TclDecrRefCount(objNameObj); } else { Tcl_Obj *objPtr, *obj2Ptr, **objs; Interp *iPtr = (Interp *) interp; Tcl_Command cmd; | | | | 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 | GenerateErrorInfo(interp, oPtr, objNameObj, "class"); } TclDecrRefCount(objNameObj); } else { Tcl_Obj *objPtr, *obj2Ptr, **objs; Interp *iPtr = (Interp *) interp; Tcl_Command cmd; size_t dummy; /* * More than one argument: fire them through the ensemble processing * engine so that everything appears to be good and proper in error * messages. Note that we cannot just concatenate and send through * Tcl_EvalObjEx, as that doesn't do ensemble processing, and we * cannot go through Tcl_EvalObjv without the extra work to pre-find * the command, as that finds command names in the wrong namespace at * the moment. Ugly! */ if (iPtr->ensembleRewrite.sourceObjs == NULL) { iPtr->ensembleRewrite.sourceObjs = objv; iPtr->ensembleRewrite.numRemovedObjs = 3; iPtr->ensembleRewrite.numInsertedObjs = 1; } else { size_t ni = iPtr->ensembleRewrite.numInsertedObjs; if (ni < 3) { iPtr->ensembleRewrite.numRemovedObjs += 3 - ni; } else { iPtr->ensembleRewrite.numInsertedObjs -= 2; } } |
︙ | ︙ | |||
920 921 922 923 924 925 926 | * ---------------------------------------------------------------------- */ int TclOOObjDefObjCmd( ClientData clientData, Tcl_Interp *interp, | | | 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 | * ---------------------------------------------------------------------- */ int TclOOObjDefObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Foundation *fPtr = TclOOGetFoundation(interp); int result; Object *oPtr; if (objc < 3) { |
︙ | ︙ | |||
961 962 963 964 965 966 967 | GenerateErrorInfo(interp, oPtr, objNameObj, "object"); } TclDecrRefCount(objNameObj); } else { Tcl_Obj *objPtr, *obj2Ptr, **objs; Interp *iPtr = (Interp *) interp; Tcl_Command cmd; | | | | 933 934 935 936 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 | GenerateErrorInfo(interp, oPtr, objNameObj, "object"); } TclDecrRefCount(objNameObj); } else { Tcl_Obj *objPtr, *obj2Ptr, **objs; Interp *iPtr = (Interp *) interp; Tcl_Command cmd; size_t dummy; /* * More than one argument: fire them through the ensemble processing * engine so that everything appears to be good and proper in error * messages. Note that we cannot just concatenate and send through * Tcl_EvalObjEx, as that doesn't do ensemble processing, and we * cannot go through Tcl_EvalObjv without the extra work to pre-find * the command, as that finds command names in the wrong namespace at * the moment. Ugly! */ if (iPtr->ensembleRewrite.sourceObjs == NULL) { iPtr->ensembleRewrite.sourceObjs = objv; iPtr->ensembleRewrite.numRemovedObjs = 3; iPtr->ensembleRewrite.numInsertedObjs = 1; } else { size_t ni = iPtr->ensembleRewrite.numInsertedObjs; if (ni < 3) { iPtr->ensembleRewrite.numRemovedObjs += 3 - ni; } else { iPtr->ensembleRewrite.numInsertedObjs -= 2; } } |
︙ | ︙ | |||
1034 1035 1036 1037 1038 1039 1040 | * ---------------------------------------------------------------------- */ int TclOODefineSelfObjCmd( ClientData clientData, Tcl_Interp *interp, | | | 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 | * ---------------------------------------------------------------------- */ int TclOODefineSelfObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Foundation *fPtr = TclOOGetFoundation(interp); int result; Object *oPtr; if (objc < 2) { |
︙ | ︙ | |||
1075 1076 1077 1078 1079 1080 1081 | GenerateErrorInfo(interp, oPtr, objNameObj, "class object"); } TclDecrRefCount(objNameObj); } else { Tcl_Obj *objPtr, *obj2Ptr, **objs; Interp *iPtr = (Interp *) interp; Tcl_Command cmd; | | | | 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 | GenerateErrorInfo(interp, oPtr, objNameObj, "class object"); } TclDecrRefCount(objNameObj); } else { Tcl_Obj *objPtr, *obj2Ptr, **objs; Interp *iPtr = (Interp *) interp; Tcl_Command cmd; size_t dummy; /* * More than one argument: fire them through the ensemble processing * engine so that everything appears to be good and proper in error * messages. Note that we cannot just concatenate and send through * Tcl_EvalObjEx, as that doesn't do ensemble processing, and we * cannot go through Tcl_EvalObjv without the extra work to pre-find * the command, as that finds command names in the wrong namespace at * the moment. Ugly! */ if (iPtr->ensembleRewrite.sourceObjs == NULL) { iPtr->ensembleRewrite.sourceObjs = objv; iPtr->ensembleRewrite.numRemovedObjs = 2; iPtr->ensembleRewrite.numInsertedObjs = 1; } else { size_t ni = iPtr->ensembleRewrite.numInsertedObjs; if (ni < 2) { iPtr->ensembleRewrite.numRemovedObjs += 2 - ni; } else { iPtr->ensembleRewrite.numInsertedObjs -= 1; } } |
︙ | ︙ | |||
1145 1146 1147 1148 1149 1150 1151 | * ---------------------------------------------------------------------- */ int TclOODefineClassObjCmd( ClientData clientData, Tcl_Interp *interp, | | | > | > | 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 | * ---------------------------------------------------------------------- */ int TclOODefineClassObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Object *oPtr; Class *clsPtr; Foundation *fPtr = TclOOGetFoundation(interp); /* * Parse the context to get the object to operate on. */ 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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", 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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } /* * Parse the argument to get the class to set the object's class to. */ |
︙ | ︙ | |||
1233 1234 1235 1236 1237 1238 1239 | * ---------------------------------------------------------------------- */ int TclOODefineConstructorObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 | * ---------------------------------------------------------------------- */ int TclOODefineConstructorObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Object *oPtr; Class *clsPtr; Tcl_Method method; size_t bodyLength; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "arguments body"); return TCL_ERROR; } /* |
︙ | ︙ | |||
1301 1302 1303 1304 1305 1306 1307 | * ---------------------------------------------------------------------- */ int TclOODefineDeleteMethodObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | | 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 | * ---------------------------------------------------------------------- */ int TclOODefineDeleteMethodObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { int isInstanceDeleteMethod = (clientData != NULL); Object *oPtr; size_t i; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?"); return TCL_ERROR; } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceDeleteMethod && !oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } for (i=1 ; i<objc ; i++) { /* * Delete the method structure from the appropriate hash table. |
︙ | ︙ | |||
1357 1358 1359 1360 1361 1362 1363 | * ---------------------------------------------------------------------- */ int TclOODefineDestructorObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 | * ---------------------------------------------------------------------- */ int TclOODefineDestructorObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { Object *oPtr; Class *clsPtr; Tcl_Method method; size_t bodyLength; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "body"); return TCL_ERROR; } oPtr = (Object *) TclOOGetDefineCmdContext(interp); |
︙ | ︙ | |||
1421 1422 1423 1424 1425 1426 1427 | * ---------------------------------------------------------------------- */ int TclOODefineExportObjCmd( ClientData clientData, Tcl_Interp *interp, | | | > | | 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 1429 1430 1431 1432 | * ---------------------------------------------------------------------- */ int TclOODefineExportObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { int isInstanceExport = (clientData != NULL); Object *oPtr; Method *mPtr; Tcl_HashEntry *hPtr; Class *clsPtr; int isNew, changed = 0; size_t i; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?"); return TCL_ERROR; } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } clsPtr = oPtr->classPtr; if (!isInstanceExport && !clsPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } for (i=1 ; i<objc ; i++) { /* * Exporting is done by adding the PUBLIC_METHOD flag to the method |
︙ | ︙ | |||
1515 1516 1517 1518 1519 1520 1521 | * ---------------------------------------------------------------------- */ int TclOODefineForwardObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 | * ---------------------------------------------------------------------- */ int TclOODefineForwardObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { int isInstanceForward = (clientData != NULL); Object *oPtr; Method *mPtr; int isPublic; Tcl_Obj *prefixObj; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "name cmdName ?arg ...?"); return TCL_ERROR; } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceForward && !oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*") ? PUBLIC_METHOD : 0; /* |
︙ | ︙ | |||
1575 1576 1577 1578 1579 1580 1581 | * ---------------------------------------------------------------------- */ int TclOODefineMethodObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 | * ---------------------------------------------------------------------- */ int TclOODefineMethodObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { int isInstanceMethod = (clientData != NULL); Object *oPtr; int isPublic; if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "name args body"); return TCL_ERROR; } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceMethod && !oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*") ? PUBLIC_METHOD : 0; /* |
︙ | ︙ | |||
1632 1633 1634 1635 1636 1637 1638 | * ---------------------------------------------------------------------- */ int TclOODefineMixinObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | | | 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 | * ---------------------------------------------------------------------- */ int TclOODefineMixinObjCmd( ClientData clientData, Tcl_Interp *interp, const size_t objc, Tcl_Obj *const *objv) { int isInstanceMixin = (clientData != NULL); Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); Class **mixins; size_t i; if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceMixin && !oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } mixins = TclStackAlloc(interp, sizeof(Class *) * (objc-1)); for (i=1 ; i<objc ; i++) { Class *clsPtr = GetClassInOuterContext(interp, objv[i], "may only mix in classes"); if (clsPtr == NULL) { goto freeAndError; } if (!isInstanceMixin && TclOOIsReachable(oPtr->classPtr, clsPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not mix a class into itself", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL); goto freeAndError; } mixins[i-1] = clsPtr; } if (isInstanceMixin) { |
︙ | ︙ | |||
1695 1696 1697 1698 1699 1700 1701 | * ---------------------------------------------------------------------- */ int TclOODefineRenameMethodObjCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 | * ---------------------------------------------------------------------- */ int TclOODefineRenameMethodObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { int isInstanceRenameMethod = (clientData != NULL); Object *oPtr; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "oldName newName"); return TCL_ERROR; } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceRenameMethod && !oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); 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 |
︙ | ︙ | |||
1751 1752 1753 1754 1755 1756 1757 | * ---------------------------------------------------------------------- */ int TclOODefineUnexportObjCmd( ClientData clientData, Tcl_Interp *interp, | | > | | | 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 | * ---------------------------------------------------------------------- */ int TclOODefineUnexportObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv) { int isInstanceUnexport = (clientData != NULL); Object *oPtr; Method *mPtr; Tcl_HashEntry *hPtr; Class *clsPtr; size_t i; int isNew, changed = 0; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?"); return TCL_ERROR; } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } clsPtr = oPtr->classPtr; if (!isInstanceUnexport && !clsPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } for (i=1 ; i<objc ; i++) { /* * Unexporting is done by removing the PUBLIC_METHOD flag from the |
︙ | ︙ | |||
1900 1901 1902 1903 1904 1905 1906 | */ int TclOODefineSlots( Foundation *fPtr) { const struct DeclaredSlot *slotInfoPtr; | | | | > | > | 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 | */ int TclOODefineSlots( Foundation *fPtr) { const struct DeclaredSlot *slotInfoPtr; Tcl_Obj *getName = Tcl_NewStringObj("Get", TCL_STRLEN); Tcl_Obj *setName = Tcl_NewStringObj("Set", TCL_STRLEN); Class *slotCls; slotCls = ((Object *) Tcl_NewObjectInstance(fPtr->interp, (Tcl_Class) fPtr->classCls, "::oo::Slot", NULL, TCL_STRLEN, NULL, 0))->classPtr; if (slotCls == NULL) { return TCL_ERROR; } Tcl_IncrRefCount(getName); Tcl_IncrRefCount(setName); for (slotInfoPtr = slots ; slotInfoPtr->name ; slotInfoPtr++) { Tcl_Object slotObject = Tcl_NewObjectInstance(fPtr->interp, (Tcl_Class) slotCls, slotInfoPtr->name, NULL, TCL_STRLEN, NULL, 0); if (slotObject == NULL) { continue; } Tcl_NewInstanceMethod(fPtr->interp, slotObject, getName, 0, &slotInfoPtr->getterType, NULL); Tcl_NewInstanceMethod(fPtr->interp, slotObject, setName, 0, |
︙ | ︙ | |||
1943 1944 1945 1946 1947 1948 1949 | */ static int ClassFilterGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, | | | | | | | | 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 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 | */ static int ClassFilterGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); Tcl_Obj *resultObj, *filterObj; size_t i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } resultObj = Tcl_NewObj(); FOREACH(filterObj, oPtr->classPtr->filters) { Tcl_ListObjAppendElement(NULL, resultObj, filterObj); } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } static int ClassFilterSet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); size_t 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 (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } else if (Tcl_ListObjGetElements(interp, objv[0], &filterc, &filterv) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
2022 2023 2024 2025 2026 2027 2028 | */ static int ClassMixinGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, | | | | < | | | | | 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 | */ static int ClassMixinGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); Tcl_Obj *resultObj; Class *mixinPtr; size_t i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } resultObj = Tcl_NewObj(); FOREACH(mixinPtr, oPtr->classPtr->mixins) { Tcl_ListObjAppendElement(NULL, resultObj, TclOOObjectName(interp, mixinPtr->thisPtr)); } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } static int ClassMixinSet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); size_t mixinc, i; Tcl_Obj **mixinv; Class **mixins; if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "mixinList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } else if (Tcl_ListObjGetElements(interp, objv[0], &mixinc, &mixinv) != TCL_OK) { return TCL_ERROR; } mixins = TclStackAlloc(interp, sizeof(Class *) * mixinc); for (i=0 ; i<mixinc ; i++) { mixins[i] = GetClassInOuterContext(interp, mixinv[i], "may only mix in classes"); if (mixins[i] == NULL) { goto freeAndError; } if (TclOOIsReachable(oPtr->classPtr, mixins[i])) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not mix a class into itself", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL); goto freeAndError; } } TclOOClassSetMixins(interp, oPtr->classPtr, mixinc, mixins); TclStackFree(interp, mixins); |
︙ | ︙ | |||
2126 2127 2128 2129 2130 2131 2132 | */ static int ClassSuperGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, | | | | | | | | > | 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 | */ static int ClassSuperGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); Tcl_Obj *resultObj; Class *superPtr; size_t i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } resultObj = Tcl_NewObj(); FOREACH(superPtr, oPtr->classPtr->superclasses) { Tcl_ListObjAppendElement(NULL, resultObj, TclOOObjectName(interp, superPtr->thisPtr)); } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } static int ClassSuperSet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); size_t superc, i, j; Tcl_Obj **superv; Class **superclasses, *superPtr; if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "superclassList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } else if (oPtr == oPtr->fPtr->objectCls->thisPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not modify the superclass of the root object", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } else if (Tcl_ListObjGetElements(interp, objv[0], &superc, &superv) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
2225 2226 2227 2228 2229 2230 2231 | 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", | | | > | 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 | 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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS",NULL); goto failedAfterAlloc; } } if (TclOOIsReachable(oPtr->classPtr, superclasses[i])) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to form circular dependency graph", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "CIRCULARITY", NULL); failedAfterAlloc: ckfree((char *) superclasses); return TCL_ERROR; } } } |
︙ | ︙ | |||
2279 2280 2281 2282 2283 2284 2285 | */ static int ClassVarsGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, | | | | | | < | | 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 | */ static int ClassVarsGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); Tcl_Obj *resultObj, *variableObj; size_t i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } resultObj = Tcl_NewObj(); FOREACH(variableObj, oPtr->classPtr->variables) { Tcl_ListObjAppendElement(NULL, resultObj, variableObj); } Tcl_SetObjResult(interp, resultObj); return TCL_OK; } static int ClassVarsSet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); size_t varc, i; Tcl_Obj **varv, *variableObj; if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "filterList"); return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } else if (Tcl_ListObjGetElements(interp, objv[0], &varc, &varv) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
2380 2381 2382 2383 2384 2385 2386 | oPtr->classPtr->variables.list = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj *) * varc); } } oPtr->classPtr->variables.num = 0; if (varc > 0) { | | > | 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 | oPtr->classPtr->variables.list = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj *) * varc); } } oPtr->classPtr->variables.num = 0; if (varc > 0) { int created; size_t n; Tcl_HashTable uniqueTable; Tcl_InitObjHashTable(&uniqueTable); for (i=n=0 ; i<varc ; i++) { Tcl_CreateHashEntry(&uniqueTable, varv[i], &created); if (created) { oPtr->classPtr->variables.list[n++] = varv[i]; |
︙ | ︙ | |||
2421 2422 2423 2424 2425 2426 2427 | */ static int ObjFilterGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, | | | | 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 | */ static int ObjFilterGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); Tcl_Obj *resultObj, *filterObj; size_t i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } else if (oPtr == NULL) { return TCL_ERROR; |
︙ | ︙ | |||
2449 2450 2451 2452 2453 2454 2455 | } static int ObjFilterSet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, | | | | 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 | } static int ObjFilterSet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); size_t filterc; Tcl_Obj **filterv; if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "filterList"); return TCL_ERROR; } else if (oPtr == NULL) { |
︙ | ︙ | |||
2488 2489 2490 2491 2492 2493 2494 | */ static int ObjMixinGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, | | | | 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 | */ static int ObjMixinGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); Tcl_Obj *resultObj; Class *mixinPtr; size_t i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } else if (oPtr == NULL) { return TCL_ERROR; |
︙ | ︙ | |||
2518 2519 2520 2521 2522 2523 2524 | } static int ObjMixinSet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, | | | < | 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 | } static int ObjMixinSet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); size_t mixinc, i; Tcl_Obj **mixinv; Class **mixins; if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "mixinList"); return TCL_ERROR; } else if (oPtr == NULL) { return TCL_ERROR; |
︙ | ︙ | |||
2571 2572 2573 2574 2575 2576 2577 | */ static int ObjVarsGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, | | | | 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 | */ static int ObjVarsGet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); Tcl_Obj *resultObj, *variableObj; size_t i; if (Tcl_ObjectContextSkippedArgs(context) != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } else if (oPtr == NULL) { return TCL_ERROR; |
︙ | ︙ | |||
2599 2600 2601 2602 2603 2604 2605 | } static int ObjVarsSet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, | | | | 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 | } static int ObjVarsSet( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv) { Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); size_t varc, i; Tcl_Obj **varv, *variableObj; if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "variableList"); return TCL_ERROR; } else if (oPtr == NULL) { |
︙ | ︙ | |||
2658 2659 2660 2661 2662 2663 2664 | } else { oPtr->variables.list = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj *) * varc); } } oPtr->variables.num = 0; if (varc > 0) { | | > | 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 | } else { oPtr->variables.list = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj *) * varc); } } oPtr->variables.num = 0; if (varc > 0) { int created; size_t n; Tcl_HashTable uniqueTable; Tcl_InitObjHashTable(&uniqueTable); for (i=n=0 ; i<varc ; i++) { Tcl_CreateHashEntry(&uniqueTable, varv[i], &created); if (created) { oPtr->variables.list[n++] = varv[i]; |
︙ | ︙ |
Changes to generic/tclOOInfo.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "tclInt.h" #include "tclOOInt.h" static inline Class * GetClassFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr); | | | | | < | | | | | | | | | | | | | | | | | | | | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 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 | #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "tclInt.h" #include "tclOOInt.h" static inline Class * GetClassFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr); static Tcl_ObjCmdProc InfoObjectCallCmd; static Tcl_ObjCmdProc InfoObjectClassCmd; static Tcl_ObjCmdProc InfoObjectDefnCmd; static Tcl_ObjCmdProc InfoObjectFiltersCmd; static Tcl_ObjCmdProc InfoObjectForwardCmd; static Tcl_ObjCmdProc InfoObjectIsACmd; static Tcl_ObjCmdProc InfoObjectMethodsCmd; static Tcl_ObjCmdProc InfoObjectMethodTypeCmd; static Tcl_ObjCmdProc InfoObjectMixinsCmd; static Tcl_ObjCmdProc InfoObjectNsCmd; static Tcl_ObjCmdProc InfoObjectVarsCmd; static Tcl_ObjCmdProc InfoObjectVariablesCmd; static Tcl_ObjCmdProc InfoClassCallCmd; static Tcl_ObjCmdProc InfoClassConstrCmd; static Tcl_ObjCmdProc InfoClassDefnCmd; static Tcl_ObjCmdProc InfoClassDestrCmd; static Tcl_ObjCmdProc InfoClassFiltersCmd; static Tcl_ObjCmdProc InfoClassForwardCmd; static Tcl_ObjCmdProc InfoClassInstancesCmd; static Tcl_ObjCmdProc InfoClassMethodsCmd; static Tcl_ObjCmdProc InfoClassMethodTypeCmd; static Tcl_ObjCmdProc InfoClassMixinsCmd; static Tcl_ObjCmdProc InfoClassSubsCmd; static Tcl_ObjCmdProc InfoClassSupersCmd; static Tcl_ObjCmdProc InfoClassVariablesCmd; /* * List of commands that are used to implement the [info object] subcommands. */ static const EnsembleImplMap infoObjectCmds[] = { {"call", InfoObjectCallCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, |
︙ | ︙ | |||
163 164 165 166 167 168 169 | * ---------------------------------------------------------------------- */ static int InfoObjectClassCmd( ClientData clientData, Tcl_Interp *interp, | | | | 163 164 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 192 193 194 195 196 197 198 | * ---------------------------------------------------------------------- */ static int InfoObjectClassCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Object *oPtr; if (objc != 2 && objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "objName ?className?"); return TCL_ERROR; } oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]); if (oPtr == NULL) { return TCL_ERROR; } if (objc == 2) { Tcl_SetObjResult(interp, TclOOObjectName(interp, oPtr->selfCls->thisPtr)); return TCL_OK; } else { Class *mixinPtr, *o2clsPtr; size_t i; o2clsPtr = GetClassFromObj(interp, objv[2]); if (o2clsPtr == NULL) { return TCL_ERROR; } FOREACH(mixinPtr, oPtr->mixins) { |
︙ | ︙ | |||
217 218 219 220 221 222 223 | * ---------------------------------------------------------------------- */ static int InfoObjectDefnCmd( ClientData clientData, Tcl_Interp *interp, | | | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | * ---------------------------------------------------------------------- */ static int InfoObjectDefnCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Object *oPtr; Tcl_HashEntry *hPtr; Proc *procPtr; CompiledLocal *localPtr; Tcl_Obj *resultObjs[2]; |
︙ | ︙ | |||
251 252 253 254 255 256 257 | Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | | 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_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "definition not available for this kind of method", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } resultObjs[0] = Tcl_NewObj(); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_Obj *argObj; argObj = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, argObj, Tcl_NewStringObj(localPtr->name, TCL_STRLEN)); if (localPtr->defValuePtr != NULL) { Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr); } Tcl_ListObjAppendElement(NULL, resultObjs[0], argObj); } } resultObjs[1] = TclOOGetMethodBody(Tcl_GetHashValue(hPtr)); |
︙ | ︙ | |||
291 292 293 294 295 296 297 | * ---------------------------------------------------------------------- */ static int InfoObjectFiltersCmd( ClientData clientData, Tcl_Interp *interp, | | | | 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | * ---------------------------------------------------------------------- */ static int InfoObjectFiltersCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { size_t i; Tcl_Obj *filterObj, *resultObj; Object *oPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "objName"); return TCL_ERROR; } |
︙ | ︙ | |||
330 331 332 333 334 335 336 | * ---------------------------------------------------------------------- */ static int InfoObjectForwardCmd( ClientData clientData, Tcl_Interp *interp, | | | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | * ---------------------------------------------------------------------- */ static int InfoObjectForwardCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Object *oPtr; Tcl_HashEntry *hPtr; Tcl_Obj *prefixObj; if (objc != 3) { |
︙ | ︙ | |||
363 364 365 366 367 368 369 | TclGetString(objv[2]), NULL); return TCL_ERROR; } prefixObj = TclOOGetFwdFromMethod(Tcl_GetHashValue(hPtr)); if (prefixObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "prefix argument list not available for this kind of method", | | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | TclGetString(objv[2]), NULL); return TCL_ERROR; } prefixObj = TclOOGetFwdFromMethod(Tcl_GetHashValue(hPtr)); if (prefixObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "prefix argument list not available for this kind of method", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, prefixObj); return TCL_OK; |
︙ | ︙ | |||
387 388 389 390 391 392 393 | * ---------------------------------------------------------------------- */ static int InfoObjectIsACmd( ClientData clientData, Tcl_Interp *interp, | | | > | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 | * ---------------------------------------------------------------------- */ static int InfoObjectIsACmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { static const char *const categories[] = { "class", "metaclass", "mixin", "object", "typeof", NULL }; enum IsACats { IsClass, IsMetaclass, IsMixin, IsObject, IsType }; Object *oPtr, *o2Ptr; int idx; size_t i; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "category objName ?arg ...?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], categories, "category", 0, &idx) != TCL_OK) { |
︙ | ︙ | |||
455 456 457 458 459 460 461 | } o2Ptr = (Object *) Tcl_GetObjectFromObj(interp, objv[3]); if (o2Ptr == NULL) { return TCL_ERROR; } if (o2Ptr->classPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 | } o2Ptr = (Object *) Tcl_GetObjectFromObj(interp, objv[3]); if (o2Ptr == NULL) { return TCL_ERROR; } if (o2Ptr->classPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "non-classes cannot be mixins", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "NONCLASS", NULL); return TCL_ERROR; } else { Class *mixinPtr; FOREACH(mixinPtr, oPtr->mixins) { if (mixinPtr == o2Ptr->classPtr) { |
︙ | ︙ | |||
481 482 483 484 485 486 487 | } o2Ptr = (Object *) Tcl_GetObjectFromObj(interp, objv[3]); if (o2Ptr == NULL) { return TCL_ERROR; } if (o2Ptr->classPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 | } o2Ptr = (Object *) Tcl_GetObjectFromObj(interp, objv[3]); if (o2Ptr == NULL) { return TCL_ERROR; } if (o2Ptr->classPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "non-classes cannot be types", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "NONCLASS", NULL); return TCL_ERROR; } if (TclOOIsReachable(o2Ptr->classPtr, oPtr->selfCls)) { Tcl_SetObjResult(interp, Tcl_NewLongObj(1)); } else { Tcl_SetObjResult(interp, Tcl_NewLongObj(0)); |
︙ | ︙ | |||
511 512 513 514 515 516 517 | * ---------------------------------------------------------------------- */ static int InfoObjectMethodsCmd( ClientData clientData, Tcl_Interp *interp, | | > | | 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 | * ---------------------------------------------------------------------- */ static int InfoObjectMethodsCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Object *oPtr; int flag = PUBLIC_METHOD, recurse = 0; FOREACH_HASH_DECLS; Tcl_Obj *namePtr, *resultObj; Method *mPtr; static const char *const options[] = { "-all", "-localprivate", "-private", NULL }; enum Options { OPT_ALL, OPT_LOCALPRIVATE, OPT_PRIVATE }; size_t i; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "objName ?-option value ...?"); return TCL_ERROR; } oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]); if (oPtr == NULL) { return TCL_ERROR; } if (objc != 2) { int idx; for (i=2 ; i<objc ; i++) { if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &idx) != TCL_OK) { return TCL_ERROR; } switch ((enum Options) idx) { |
︙ | ︙ | |||
559 560 561 562 563 564 565 | } } } resultObj = Tcl_NewObj(); if (recurse) { const char **names; | | | | 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | } } } resultObj = Tcl_NewObj(); if (recurse) { const char **names; size_t numNames = TclOOGetSortedMethodList(oPtr, flag, &names); for (i=0 ; i<numNames ; i++) { Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(names[i], TCL_STRLEN)); } if (numNames > 0) { ckfree(names); } } else if (oPtr->methodsPtr) { FOREACH_HASH(namePtr, mPtr, oPtr->methodsPtr) { if (mPtr->typePtr != NULL && (mPtr->flags & flag) == flag) { |
︙ | ︙ | |||
593 594 595 596 597 598 599 | * ---------------------------------------------------------------------- */ static int InfoObjectMethodTypeCmd( ClientData clientData, Tcl_Interp *interp, | | | 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 | * ---------------------------------------------------------------------- */ static int InfoObjectMethodTypeCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Object *oPtr; Tcl_HashEntry *hPtr; Method *mPtr; if (objc != 3) { |
︙ | ︙ | |||
632 633 634 635 636 637 638 | * Special entry for visibility control: pretend the method doesnt * exist. */ goto unknownMethod; } | | > | | | 635 636 637 638 639 640 641 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 | * Special entry for visibility control: pretend the method doesnt * exist. */ goto unknownMethod; } Tcl_SetObjResult(interp, Tcl_NewStringObj(mPtr->typePtr->name, TCL_STRLEN)); return TCL_OK; } /* * ---------------------------------------------------------------------- * * InfoObjectMixinsCmd -- * * Implements [info object mixins $objName] * * ---------------------------------------------------------------------- */ static int InfoObjectMixinsCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Class *mixinPtr; Object *oPtr; Tcl_Obj *resultObj; size_t i; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "objName"); return TCL_ERROR; } oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]); if (oPtr == NULL) { |
︙ | ︙ | |||
690 691 692 693 694 695 696 | * ---------------------------------------------------------------------- */ static int InfoObjectNsCmd( ClientData clientData, Tcl_Interp *interp, | | | | | | 694 695 696 697 698 699 700 701 702 703 704 705 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 | * ---------------------------------------------------------------------- */ static int InfoObjectNsCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Object *oPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "objName"); 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_STRLEN)); return TCL_OK; } /* * ---------------------------------------------------------------------- * * InfoObjectVariablesCmd -- * * Implements [info object variables $objName] * * ---------------------------------------------------------------------- */ static int InfoObjectVariablesCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Object *oPtr; Tcl_Obj *variableObj, *resultObj; size_t i; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "objName"); return TCL_ERROR; } oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]); if (oPtr == NULL) { |
︙ | ︙ | |||
761 762 763 764 765 766 767 | * ---------------------------------------------------------------------- */ static int InfoObjectVarsCmd( ClientData clientData, Tcl_Interp *interp, | | | 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 | * ---------------------------------------------------------------------- */ static int InfoObjectVarsCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Object *oPtr; const char *pattern = NULL; FOREACH_HASH_DECLS; VarInHash *vihPtr; Tcl_Obj *nameObj, *resultObj; |
︙ | ︙ | |||
822 823 824 825 826 827 828 | * ---------------------------------------------------------------------- */ static int InfoClassConstrCmd( ClientData clientData, Tcl_Interp *interp, | | | 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 | * ---------------------------------------------------------------------- */ static int InfoClassConstrCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Proc *procPtr; CompiledLocal *localPtr; Tcl_Obj *resultObjs[2]; Class *clsPtr; |
︙ | ︙ | |||
844 845 846 847 848 849 850 | } if (clsPtr->constructorPtr == NULL) { return TCL_OK; } procPtr = TclOOGetProcFromMethod(clsPtr->constructorPtr); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | | 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 | } 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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", NULL); return TCL_ERROR; } resultObjs[0] = Tcl_NewObj(); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_Obj *argObj; argObj = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, argObj, Tcl_NewStringObj(localPtr->name, TCL_STRLEN)); if (localPtr->defValuePtr != NULL) { Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr); } Tcl_ListObjAppendElement(NULL, resultObjs[0], argObj); } } resultObjs[1] = TclOOGetMethodBody(clsPtr->constructorPtr); |
︙ | ︙ | |||
883 884 885 886 887 888 889 | * ---------------------------------------------------------------------- */ static int InfoClassDefnCmd( ClientData clientData, Tcl_Interp *interp, | | | 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 | * ---------------------------------------------------------------------- */ static int InfoClassDefnCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_HashEntry *hPtr; Proc *procPtr; CompiledLocal *localPtr; Tcl_Obj *resultObjs[2]; Class *clsPtr; |
︙ | ︙ | |||
911 912 913 914 915 916 917 | Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | | 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 | Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "definition not available for this kind of method", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } resultObjs[0] = Tcl_NewObj(); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_Obj *argObj; argObj = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, argObj, Tcl_NewStringObj(localPtr->name, TCL_STRLEN)); if (localPtr->defValuePtr != NULL) { Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr); } Tcl_ListObjAppendElement(NULL, resultObjs[0], argObj); } } resultObjs[1] = TclOOGetMethodBody(Tcl_GetHashValue(hPtr)); |
︙ | ︙ | |||
951 952 953 954 955 956 957 | * ---------------------------------------------------------------------- */ static int InfoClassDestrCmd( ClientData clientData, Tcl_Interp *interp, | | | > | 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 990 991 992 993 | * ---------------------------------------------------------------------- */ static int InfoClassDestrCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Proc *procPtr; Class *clsPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "className"); return TCL_ERROR; } clsPtr = GetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } 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_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOOGetMethodBody(clsPtr->destructorPtr)); return TCL_OK; } |
︙ | ︙ | |||
995 996 997 998 999 1000 1001 | * ---------------------------------------------------------------------- */ static int InfoClassFiltersCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 | * ---------------------------------------------------------------------- */ static int InfoClassFiltersCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { size_t i; Tcl_Obj *filterObj, *resultObj; Class *clsPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "className"); return TCL_ERROR; } |
︙ | ︙ | |||
1033 1034 1035 1036 1037 1038 1039 | * ---------------------------------------------------------------------- */ static int InfoClassForwardCmd( ClientData clientData, Tcl_Interp *interp, | | | 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 | * ---------------------------------------------------------------------- */ static int InfoClassForwardCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_HashEntry *hPtr; Tcl_Obj *prefixObj; Class *clsPtr; if (objc != 3) { |
︙ | ︙ | |||
1060 1061 1062 1063 1064 1065 1066 | TclGetString(objv[2]), NULL); return TCL_ERROR; } prefixObj = TclOOGetFwdFromMethod(Tcl_GetHashValue(hPtr)); if (prefixObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "prefix argument list not available for this kind of method", | | | 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 | TclGetString(objv[2]), NULL); return TCL_ERROR; } prefixObj = TclOOGetFwdFromMethod(Tcl_GetHashValue(hPtr)); if (prefixObj == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "prefix argument list not available for this kind of method", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, prefixObj); return TCL_OK; |
︙ | ︙ | |||
1084 1085 1086 1087 1088 1089 1090 | * ---------------------------------------------------------------------- */ static int InfoClassInstancesCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 | * ---------------------------------------------------------------------- */ static int InfoClassInstancesCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Object *oPtr; Class *clsPtr; size_t i; const char *pattern = NULL; Tcl_Obj *resultObj; if (objc != 2 && objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "className ?pattern?"); return TCL_ERROR; } |
︙ | ︙ | |||
1132 1133 1134 1135 1136 1137 1138 | * ---------------------------------------------------------------------- */ static int InfoClassMethodsCmd( ClientData clientData, Tcl_Interp *interp, | | > | | 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 | * ---------------------------------------------------------------------- */ static int InfoClassMethodsCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { int flag = PUBLIC_METHOD, recurse = 0; Tcl_Obj *namePtr, *resultObj; Method *mPtr; Class *clsPtr; static const char *const options[] = { "-all", "-localprivate", "-private", NULL }; enum Options { OPT_ALL, OPT_LOCALPRIVATE, OPT_PRIVATE }; size_t i; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "className ?-option value ...?"); return TCL_ERROR; } clsPtr = GetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } if (objc != 2) { int idx; for (i=2 ; i<objc ; i++) { if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &idx) != TCL_OK) { return TCL_ERROR; } switch ((enum Options) idx) { |
︙ | ︙ | |||
1179 1180 1181 1182 1183 1184 1185 | } } } resultObj = Tcl_NewObj(); if (recurse) { const char **names; | | | | 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 | } } } resultObj = Tcl_NewObj(); if (recurse) { const char **names; size_t numNames = TclOOGetSortedClassMethodList(clsPtr, flag, &names); for (i=0 ; i<numNames ; i++) { Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(names[i], TCL_STRLEN)); } if (numNames > 0) { ckfree(names); } } else { FOREACH_HASH_DECLS; |
︙ | ︙ | |||
1215 1216 1217 1218 1219 1220 1221 | * ---------------------------------------------------------------------- */ static int InfoClassMethodTypeCmd( ClientData clientData, Tcl_Interp *interp, | | | 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 | * ---------------------------------------------------------------------- */ static int InfoClassMethodTypeCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_HashEntry *hPtr; Method *mPtr; Class *clsPtr; if (objc != 3) { |
︙ | ︙ | |||
1249 1250 1251 1252 1253 1254 1255 | /* * Special entry for visibility control: pretend the method doesnt * exist. */ goto unknownMethod; } | | > | | | 1257 1258 1259 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 1289 1290 1291 1292 1293 1294 1295 | /* * Special entry for visibility control: pretend the method doesnt * exist. */ goto unknownMethod; } Tcl_SetObjResult(interp, Tcl_NewStringObj(mPtr->typePtr->name, TCL_STRLEN)); return TCL_OK; } /* * ---------------------------------------------------------------------- * * InfoClassMixinsCmd -- * * Implements [info class mixins $clsName] * * ---------------------------------------------------------------------- */ static int InfoClassMixinsCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Class *clsPtr, *mixinPtr; Tcl_Obj *resultObj; size_t i; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "className"); return TCL_ERROR; } clsPtr = GetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { |
︙ | ︙ | |||
1306 1307 1308 1309 1310 1311 1312 | * ---------------------------------------------------------------------- */ static int InfoClassSubsCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 | * ---------------------------------------------------------------------- */ static int InfoClassSubsCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Class *clsPtr, *subclassPtr; Tcl_Obj *resultObj; size_t i; const char *pattern = NULL; if (objc != 2 && objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "className ?pattern?"); return TCL_ERROR; } clsPtr = GetClassFromObj(interp, objv[1]); |
︙ | ︙ | |||
1361 1362 1363 1364 1365 1366 1367 | * ---------------------------------------------------------------------- */ static int InfoClassSupersCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 | * ---------------------------------------------------------------------- */ static int InfoClassSupersCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Class *clsPtr, *superPtr; Tcl_Obj *resultObj; size_t i; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "className"); return TCL_ERROR; } clsPtr = GetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { |
︙ | ︙ | |||
1400 1401 1402 1403 1404 1405 1406 | * ---------------------------------------------------------------------- */ static int InfoClassVariablesCmd( ClientData clientData, Tcl_Interp *interp, | | | | 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 | * ---------------------------------------------------------------------- */ static int InfoClassVariablesCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Class *clsPtr; Tcl_Obj *variableObj, *resultObj; size_t i; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "className"); return TCL_ERROR; } clsPtr = GetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { |
︙ | ︙ | |||
1438 1439 1440 1441 1442 1443 1444 | * ---------------------------------------------------------------------- */ static int InfoObjectCallCmd( ClientData clientData, Tcl_Interp *interp, | | | 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 | * ---------------------------------------------------------------------- */ static int InfoObjectCallCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Object *oPtr; CallContext *contextPtr; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "objName methodName"); |
︙ | ︙ | |||
1460 1461 1462 1463 1464 1465 1466 | /* * Get the call context and render its call chain. */ contextPtr = TclOOGetCallContext(oPtr, objv[2], PUBLIC_METHOD, NULL); if (contextPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 | /* * Get the call context and render its call chain. */ contextPtr = TclOOGetCallContext(oPtr, objv[2], PUBLIC_METHOD, NULL); if (contextPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot construct any call chain", TCL_STRLEN)); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOORenderCallChain(interp, contextPtr->callPtr)); TclOODeleteContext(contextPtr); return TCL_OK; } |
︙ | ︙ | |||
1483 1484 1485 1486 1487 1488 1489 | * ---------------------------------------------------------------------- */ static int InfoClassCallCmd( ClientData clientData, Tcl_Interp *interp, | | | 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 | * ---------------------------------------------------------------------- */ static int InfoClassCallCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Class *clsPtr; CallChain *callPtr; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "className methodName"); |
︙ | ︙ | |||
1505 1506 1507 1508 1509 1510 1511 | /* * Get an render the stereotypical call chain. */ callPtr = TclOOGetStereotypeCallChain(clsPtr, objv[2], PUBLIC_METHOD); if (callPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 | /* * 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_STRLEN)); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOORenderCallChain(interp, callPtr)); TclOODeleteChain(callPtr); return TCL_OK; } |
︙ | ︙ |
Changes to generic/tclOOInt.h.
︙ | ︙ | |||
133 134 135 136 137 138 139 | * * The "num" field always counts the number of listType_t elements used in the * "list" field. When a "size" field exists, it describes how many elements * are present in the list; when absent, exactly "num" elements are present. */ #define LIST_STATIC(listType_t) \ | | | | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | * * The "num" field always counts the number of listType_t elements used in the * "list" field. When a "size" field exists, it describes how many elements * are present in the list; when absent, exactly "num" elements are present. */ #define LIST_STATIC(listType_t) \ struct { size_t num; listType_t *list; } #define LIST_DYNAMIC(listType_t) \ struct { size_t num, size; listType_t *list; } /* * Now, the definition of what an object actually is. */ typedef struct Object { struct Foundation *fPtr; /* The basis for the object system. Putting |
︙ | ︙ | |||
342 343 344 345 346 347 348 | * chain; it is in the call context. */ int objectEpoch; /* Local (object structure) epoch counter * snapshot. */ int epoch; /* Global (class structure) epoch counter * snapshot. */ int flags; /* Assorted flags, see below. */ int refCount; /* Reference count. */ | | | | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 | * chain; it is in the call context. */ int objectEpoch; /* Local (object structure) epoch counter * snapshot. */ int epoch; /* Global (class structure) epoch counter * snapshot. */ int flags; /* Assorted flags, see below. */ int refCount; /* Reference count. */ size_t numChain; /* Size of the call chain. */ struct MInvoke *chain; /* Array of call chain entries. May point to * staticChain if the number of entries is * small. */ struct MInvoke staticChain[CALL_CHAIN_STATIC_SIZE]; } CallChain; typedef struct CallContext { Object *oPtr; /* The object associated with this call. */ int index; /* Index into the call chain of the currently * executing method implementation. */ size_t skip; /* Current number of arguments to skip; can * vary depending on whether it is a direct * method call or a continuation via the * [next] command. */ CallChain *callPtr; /* The actual call chain. */ } CallContext; /* |
︙ | ︙ | |||
388 389 390 391 392 393 394 | /* *---------------------------------------------------------------- * Commands relating to OO support. *---------------------------------------------------------------- */ MODULE_SCOPE int TclOOInit(Tcl_Interp *interp); | | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | < < | | | 388 389 390 391 392 393 394 395 396 397 398 399 400 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 438 439 440 441 442 443 444 445 | /* *---------------------------------------------------------------- * Commands relating to OO support. *---------------------------------------------------------------- */ MODULE_SCOPE int TclOOInit(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc TclOODefineObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOObjDefObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineConstructorObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineDeleteMethodObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineDestructorObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineExportObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineForwardObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineMethodObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineRenameMethodObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineUnexportObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineClassObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineSelfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOUnknownDefinition; MODULE_SCOPE Tcl_ObjCmdProc TclOOCopyObjectCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOONextObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOONextToObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOSelfObjCmd; /* * Method implementations (in tclOOBasic.c). */ MODULE_SCOPE Tcl_MethodCallProc TclOO_Class_Constructor; MODULE_SCOPE Tcl_MethodCallProc TclOO_Class_Create; MODULE_SCOPE Tcl_MethodCallProc TclOO_Class_CreateNs; MODULE_SCOPE Tcl_MethodCallProc TclOO_Class_New; MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_Destroy; MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_Eval; MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_LinkVar; MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_Unknown; MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_VarName; /* * Private definitions, some of which perhaps ought to be exposed properly or * maybe just put in the internal stubs table. */ 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 int TclNRNewObjectInstance(Tcl_Interp *interp, Tcl_Class cls, const char *nameStr, const char *nsNameStr, size_t objc, Tcl_Obj *const *objv, size_t skip, Tcl_Object *objectPtr); MODULE_SCOPE int TclOODefineSlots(Foundation *fPtr); MODULE_SCOPE void TclOODeleteChain(CallChain *callPtr); MODULE_SCOPE void TclOODeleteChainCache(Tcl_HashTable *tablePtr); MODULE_SCOPE void TclOODeleteContext(CallContext *contextPtr); MODULE_SCOPE void TclOODelMethodRef(Method *method); MODULE_SCOPE CallContext *TclOOGetCallContext(Object *oPtr, |
︙ | ︙ | |||
505 506 507 508 509 510 511 | MODULE_SCOPE Tcl_Obj * TclOOGetMethodBody(Method *mPtr); MODULE_SCOPE int TclOOGetSortedClassMethodList(Class *clsPtr, int flags, const char ***stringsPtr); MODULE_SCOPE int TclOOGetSortedMethodList(Object *oPtr, int flags, const char ***stringsPtr); MODULE_SCOPE int TclOOInit(Tcl_Interp *interp); MODULE_SCOPE void TclOOInitInfo(Tcl_Interp *interp); | | < < | | | 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | MODULE_SCOPE Tcl_Obj * TclOOGetMethodBody(Method *mPtr); MODULE_SCOPE int TclOOGetSortedClassMethodList(Class *clsPtr, int flags, const char ***stringsPtr); MODULE_SCOPE int TclOOGetSortedMethodList(Object *oPtr, int flags, const char ***stringsPtr); MODULE_SCOPE int TclOOInit(Tcl_Interp *interp); MODULE_SCOPE void TclOOInitInfo(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc TclOOInvokeContext; MODULE_SCOPE int TclNRObjectContextInvokeNext(Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv, size_t skip); MODULE_SCOPE void TclOONewBasicMethod(Tcl_Interp *interp, Class *clsPtr, const DeclaredClassMethod *dcm); MODULE_SCOPE Tcl_Obj * TclOOObjectName(Tcl_Interp *interp, Object *oPtr); MODULE_SCOPE void TclOORemoveFromInstances(Object *oPtr, Class *clsPtr); MODULE_SCOPE void TclOORemoveFromMixinSubs(Class *subPtr, Class *mixinPtr); MODULE_SCOPE void TclOORemoveFromSubclasses(Class *subPtr, |
︙ | ︙ |
Changes to generic/tclOOIntDecls.h.
︙ | ︙ | |||
34 35 36 37 38 39 40 | /* 4 */ TCLOOAPI Method * TclOONewProcMethod(Tcl_Interp *interp, Class *clsPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, ProcedureMethod **pmPtrPtr); /* 5 */ TCLOOAPI int TclOOObjectCmdCore(Object *oPtr, Tcl_Interp *interp, | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* 4 */ TCLOOAPI Method * TclOONewProcMethod(Tcl_Interp *interp, Class *clsPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, ProcedureMethod **pmPtrPtr); /* 5 */ TCLOOAPI int TclOOObjectCmdCore(Object *oPtr, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv, int publicOnly, Class *startCls); /* 6 */ TCLOOAPI int TclOOIsReachable(Class *targetPtr, Class *startPtr); /* 7 */ TCLOOAPI Method * TclOONewForwardMethod(Tcl_Interp *interp, Class *clsPtr, int isPublic, Tcl_Obj *nameObj, Tcl_Obj *prefixObj); |
︙ | ︙ | |||
67 68 69 70 71 72 73 | ProcErrorProc *errProc, ClientData clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 11 */ TCLOOAPI int TclOOInvokeObject(Tcl_Interp *interp, Tcl_Object object, Tcl_Class startCls, | | | | | | | | | | | | | | 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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | ProcErrorProc *errProc, ClientData clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 11 */ TCLOOAPI int TclOOInvokeObject(Tcl_Interp *interp, Tcl_Object object, Tcl_Class startCls, int publicPrivate, size_t objc, Tcl_Obj *const *objv); /* 12 */ TCLOOAPI void TclOOObjectSetFilters(Object *oPtr, size_t numFilters, Tcl_Obj *const *filters); /* 13 */ TCLOOAPI void TclOOClassSetFilters(Tcl_Interp *interp, Class *classPtr, size_t numFilters, Tcl_Obj *const *filters); /* 14 */ TCLOOAPI void TclOOObjectSetMixins(Object *oPtr, size_t numMixins, Class *const *mixins); /* 15 */ TCLOOAPI void TclOOClassSetMixins(Tcl_Interp *interp, Class *classPtr, size_t numMixins, Class *const *mixins); typedef struct TclOOIntStubs { int magic; void *hooks; Tcl_Object (*tclOOGetDefineCmdContext) (Tcl_Interp *interp); /* 0 */ Tcl_Method (*tclOOMakeProcInstanceMethod) (Tcl_Interp *interp, Object *oPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType *typePtr, ClientData clientData, Proc **procPtrPtr); /* 1 */ Tcl_Method (*tclOOMakeProcMethod) (Tcl_Interp *interp, Class *clsPtr, int flags, Tcl_Obj *nameObj, const char *namePtr, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType *typePtr, ClientData clientData, Proc **procPtrPtr); /* 2 */ Method * (*tclOONewProcInstanceMethod) (Tcl_Interp *interp, Object *oPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, ProcedureMethod **pmPtrPtr); /* 3 */ Method * (*tclOONewProcMethod) (Tcl_Interp *interp, Class *clsPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, ProcedureMethod **pmPtrPtr); /* 4 */ int (*tclOOObjectCmdCore) (Object *oPtr, Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv, int publicOnly, Class *startCls); /* 5 */ int (*tclOOIsReachable) (Class *targetPtr, Class *startPtr); /* 6 */ Method * (*tclOONewForwardMethod) (Tcl_Interp *interp, Class *clsPtr, int isPublic, Tcl_Obj *nameObj, Tcl_Obj *prefixObj); /* 7 */ Method * (*tclOONewForwardInstanceMethod) (Tcl_Interp *interp, Object *oPtr, int isPublic, Tcl_Obj *nameObj, Tcl_Obj *prefixObj); /* 8 */ Tcl_Method (*tclOONewProcInstanceMethodEx) (Tcl_Interp *interp, Tcl_Object oPtr, TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, ClientData clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 9 */ Tcl_Method (*tclOONewProcMethodEx) (Tcl_Interp *interp, Tcl_Class clsPtr, TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, ClientData clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 10 */ int (*tclOOInvokeObject) (Tcl_Interp *interp, Tcl_Object object, Tcl_Class startCls, int publicPrivate, size_t objc, Tcl_Obj *const *objv); /* 11 */ void (*tclOOObjectSetFilters) (Object *oPtr, size_t numFilters, Tcl_Obj *const *filters); /* 12 */ void (*tclOOClassSetFilters) (Tcl_Interp *interp, Class *classPtr, size_t numFilters, Tcl_Obj *const *filters); /* 13 */ void (*tclOOObjectSetMixins) (Object *oPtr, size_t numMixins, Class *const *mixins); /* 14 */ void (*tclOOClassSetMixins) (Tcl_Interp *interp, Class *classPtr, size_t numMixins, Class *const *mixins); /* 15 */ } TclOOIntStubs; #ifdef __cplusplus extern "C" { #endif extern const TclOOIntStubs *tclOOIntStubsPtr; #ifdef __cplusplus |
︙ | ︙ |
Changes to generic/tclOOMethod.c.
︙ | ︙ | |||
59 60 61 62 63 64 65 | * variables be cached? */ } OOResVarInfo; /* * Function declarations for things defined in this file. */ | | | | | | | | | | 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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | * variables be cached? */ } OOResVarInfo; /* * Function declarations for things defined in this file. */ static Tcl_Obj ** InitEnsembleRewrite(Tcl_Interp *interp, size_t objc, Tcl_Obj *const *objv, size_t toRewrite, size_t rewriteLength, Tcl_Obj *const *rewriteObjs, size_t *lengthPtr); static int InvokeProcedureMethod(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv); static int FinalizeForwardCall(ClientData data[], Tcl_Interp *interp, int result); static int FinalizePMCall(ClientData data[], Tcl_Interp *interp, int result); static int PushMethodCallFrame(Tcl_Interp *interp, CallContext *contextPtr, ProcedureMethod *pmPtr, size_t objc, Tcl_Obj *const *objv, PMFrameData *fdPtr); static void DeleteProcedureMethodRecord(ProcedureMethod *pmPtr); static void DeleteProcedureMethod(ClientData clientData); static int CloneProcedureMethod(Tcl_Interp *interp, ClientData clientData, ClientData *newClientData); static void MethodErrorHandler(Tcl_Interp *interp, Tcl_Obj *procNameObj); static void ConstructorErrorHandler(Tcl_Interp *interp, Tcl_Obj *procNameObj); static void DestructorErrorHandler(Tcl_Interp *interp, Tcl_Obj *procNameObj); static Tcl_Obj * RenderDeclarerName(ClientData clientData); static int InvokeForwardMethod(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, size_t objc, Tcl_Obj *const *objv); static void DeleteForwardMethod(ClientData clientData); static int CloneForwardMethod(Tcl_Interp *interp, ClientData clientData, ClientData *newClientData); static int ProcedureMethodVarResolver(Tcl_Interp *interp, const char *varName, Tcl_Namespace *contextNs, int flags, Tcl_Var *varPtr); static int ProcedureMethodCompiledVarResolver(Tcl_Interp *interp, const char *varName, size_t length, Tcl_Namespace *contextNs, Tcl_ResolvedVarInfo **rPtrPtr); /* * The types of methods defined by the core OO system. */ |
︙ | ︙ | |||
299 300 301 302 303 304 305 | TclOONewBasicMethod( Tcl_Interp *interp, Class *clsPtr, /* Class to attach the method to. */ const DeclaredClassMethod *dcm) /* Name of the method, whether it is public, * and the function to implement it. */ { | | | 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | TclOONewBasicMethod( Tcl_Interp *interp, Class *clsPtr, /* Class to attach the method to. */ const DeclaredClassMethod *dcm) /* Name of the method, whether it is public, * and the function to implement it. */ { Tcl_Obj *namePtr = Tcl_NewStringObj(dcm->name, TCL_STRLEN); Tcl_IncrRefCount(namePtr); Tcl_NewMethod(interp, (Tcl_Class) clsPtr, namePtr, (dcm->isPublic ? PUBLIC_METHOD : 0), &dcm->definition, NULL); Tcl_DecrRefCount(namePtr); } |
︙ | ︙ | |||
333 334 335 336 337 338 339 | Tcl_Obj *bodyObj, /* The body of the method, which must not be * NULL. */ ProcedureMethod **pmPtrPtr) /* Place to write pointer to procedure method * structure to allow for deeper tuning of the * structure's contents. NULL if caller is not * interested. */ { | | | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | Tcl_Obj *bodyObj, /* The body of the method, which must not be * NULL. */ ProcedureMethod **pmPtrPtr) /* Place to write pointer to procedure method * structure to allow for deeper tuning of the * structure's contents. NULL if caller is not * interested. */ { size_t argsLen; register ProcedureMethod *pmPtr; Tcl_Method method; if (Tcl_ListObjLength(interp, argsObj, &argsLen) != TCL_OK) { return NULL; } pmPtr = ckalloc(sizeof(ProcedureMethod)); |
︙ | ︙ | |||
385 386 387 388 389 390 391 | Tcl_Obj *bodyObj, /* The body of the method, which must not be * NULL. */ ProcedureMethod **pmPtrPtr) /* Place to write pointer to procedure method * structure to allow for deeper tuning of the * structure's contents. NULL if caller is not * interested. */ { | | | | | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 | Tcl_Obj *bodyObj, /* The body of the method, which must not be * NULL. */ ProcedureMethod **pmPtrPtr) /* Place to write pointer to procedure method * structure to allow for deeper tuning of the * structure's contents. NULL if caller is not * interested. */ { size_t argsLen; /* TCL_STRLEN => delete argsObj before exit */ register ProcedureMethod *pmPtr; const char *procName; Tcl_Method method; if (argsObj == NULL) { argsLen = TCL_STRLEN; argsObj = Tcl_NewObj(); Tcl_IncrRefCount(argsObj); procName = "<destructor>"; } else if (Tcl_ListObjLength(interp, argsObj, &argsLen) != TCL_OK) { return NULL; } else { procName = (nameObj==NULL ? "<constructor>" : TclGetString(nameObj)); } pmPtr = ckalloc(sizeof(ProcedureMethod)); memset(pmPtr, 0, sizeof(ProcedureMethod)); pmPtr->version = TCLOO_PROCEDURE_METHOD_VERSION; pmPtr->flags = flags & USE_DECLARER_NS; pmPtr->refCount = 1; method = TclOOMakeProcMethod(interp, clsPtr, flags, nameObj, procName, argsObj, bodyObj, &procMethodType, pmPtr, &pmPtr->procPtr); if (argsLen == TCL_STRLEN) { Tcl_DecrRefCount(argsObj); } if (method == NULL) { ckfree(pmPtr); } else if (pmPtrPtr != NULL) { *pmPtrPtr = pmPtr; } |
︙ | ︙ | |||
659 660 661 662 663 664 665 | */ static int InvokeProcedureMethod( ClientData clientData, /* Pointer to some per-method context. */ Tcl_Interp *interp, Tcl_ObjectContext context, /* The method calling context. */ | | | 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 | */ static int InvokeProcedureMethod( ClientData clientData, /* Pointer to some per-method context. */ Tcl_Interp *interp, Tcl_ObjectContext context, /* The method calling context. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Arguments as actually seen. */ { ProcedureMethod *pmPtr = clientData; int result; PMFrameData *fdPtr; /* Important data that has to have a lifetime * matched by this function (or rather, by the * call frame's lifetime). */ |
︙ | ︙ | |||
780 781 782 783 784 785 786 | static int PushMethodCallFrame( Tcl_Interp *interp, /* Current interpreter. */ CallContext *contextPtr, /* Current method call context. */ ProcedureMethod *pmPtr, /* Information about this procedure-like * method. */ | | | 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 | static int PushMethodCallFrame( Tcl_Interp *interp, /* Current interpreter. */ CallContext *contextPtr, /* Current method call context. */ ProcedureMethod *pmPtr, /* Information about this procedure-like * method. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv, /* Array of arguments. */ PMFrameData *fdPtr) /* Place to store information about the call * frame. */ { Namespace *nsPtr = (Namespace *) contextPtr->oPtr->namespacePtr; register int result; const char *namePtr; |
︙ | ︙ | |||
988 989 990 991 992 993 994 | { OOResVarInfo *infoPtr = (OOResVarInfo *) rPtr; Interp *iPtr = (Interp *) interp; CallFrame *framePtr = iPtr->varFramePtr; CallContext *contextPtr; Tcl_Obj *variableObj; Tcl_HashEntry *hPtr; | | > | 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 | { OOResVarInfo *infoPtr = (OOResVarInfo *) rPtr; Interp *iPtr = (Interp *) interp; CallFrame *framePtr = iPtr->varFramePtr; CallContext *contextPtr; Tcl_Obj *variableObj; Tcl_HashEntry *hPtr; int i, isNew, cacheIt; size_t varLen, len; const char *match, *varName; /* * Check that the variable is being requested in a context that is also a * method call; if not (i.e. we're evaluating in the object's namespace or * in a procedure of that namespace) then we do nothing. */ |
︙ | ︙ | |||
1085 1086 1087 1088 1089 1090 1091 | ckfree(infoPtr); } static int ProcedureMethodCompiledVarResolver( Tcl_Interp *interp, const char *varName, | | | 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 | ckfree(infoPtr); } static int ProcedureMethodCompiledVarResolver( Tcl_Interp *interp, const char *varName, size_t length, Tcl_Namespace *contextNs, Tcl_ResolvedVarInfo **rPtrPtr) { OOResVarInfo *infoPtr; Tcl_Obj *variableObj = Tcl_NewStringObj(varName, length); /* |
︙ | ︙ | |||
1156 1157 1158 1159 1160 1161 1162 | * suitable formatting contexts. * * ---------------------------------------------------------------------- */ #define LIMIT 60 #define ELLIPSIFY(str,len) \ | | | | 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 | * suitable formatting contexts. * * ---------------------------------------------------------------------- */ #define LIMIT 60 #define ELLIPSIFY(str,len) \ ((len) > LIMIT ? LIMIT : (int)(len)), (str), ((len) > LIMIT ? "..." : "") static void MethodErrorHandler( Tcl_Interp *interp, Tcl_Obj *methodNameObj) { size_t nameLen, objectNameLen; CallContext *contextPtr = ((Interp *) interp)->varFramePtr->clientData; Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; const char *objectName, *kindName, *methodName = Tcl_GetStringFromObj(mPtr->namePtr, &nameLen); Object *declarerPtr; if (mPtr->declaringObjectPtr != NULL) { |
︙ | ︙ | |||
1198 1199 1200 1201 1202 1203 1204 | Tcl_Interp *interp, Tcl_Obj *methodNameObj) { CallContext *contextPtr = ((Interp *) interp)->varFramePtr->clientData; Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; Object *declarerPtr; const char *objectName, *kindName; | | | 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 | Tcl_Interp *interp, Tcl_Obj *methodNameObj) { CallContext *contextPtr = ((Interp *) interp)->varFramePtr->clientData; Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; Object *declarerPtr; const char *objectName, *kindName; size_t objectNameLen; if (mPtr->declaringObjectPtr != NULL) { declarerPtr = mPtr->declaringObjectPtr; kindName = "object"; } else { if (mPtr->declaringClassPtr == NULL) { Tcl_Panic("method not declared in class or object"); |
︙ | ︙ | |||
1227 1228 1229 1230 1231 1232 1233 | Tcl_Interp *interp, Tcl_Obj *methodNameObj) { CallContext *contextPtr = ((Interp *) interp)->varFramePtr->clientData; Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; Object *declarerPtr; const char *objectName, *kindName; | | | 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 | Tcl_Interp *interp, Tcl_Obj *methodNameObj) { CallContext *contextPtr = ((Interp *) interp)->varFramePtr->clientData; Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr; Object *declarerPtr; const char *objectName, *kindName; size_t objectNameLen; if (mPtr->declaringObjectPtr != NULL) { declarerPtr = mPtr->declaringObjectPtr; kindName = "object"; } else { if (mPtr->declaringClassPtr == NULL) { Tcl_Panic("method not declared in class or object"); |
︙ | ︙ | |||
1363 1364 1365 1366 1367 1368 1369 | Tcl_Interp *interp, /* Interpreter for error reporting. */ Object *oPtr, /* The object to attach the method to. */ int flags, /* Whether the method is public or not. */ Tcl_Obj *nameObj, /* The name of the method. */ Tcl_Obj *prefixObj) /* List of arguments that form the command * prefix to forward to. */ { | | | | 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 | Tcl_Interp *interp, /* Interpreter for error reporting. */ Object *oPtr, /* The object to attach the method to. */ int flags, /* Whether the method is public or not. */ Tcl_Obj *nameObj, /* The name of the method. */ Tcl_Obj *prefixObj) /* List of arguments that form the command * prefix to forward to. */ { size_t prefixLen; register ForwardMethod *fmPtr; Tcl_Obj *cmdObj; if (Tcl_ListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) { return NULL; } if (prefixLen < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "method forward prefix must be non-empty", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", NULL); return NULL; } fmPtr = ckalloc(sizeof(ForwardMethod)); fmPtr->prefixObj = prefixObj; Tcl_ListObjIndex(interp, prefixObj, 0, &cmdObj); |
︙ | ︙ | |||
1404 1405 1406 1407 1408 1409 1410 | Tcl_Interp *interp, /* Interpreter for error reporting. */ Class *clsPtr, /* The class to attach the method to. */ int flags, /* Whether the method is public or not. */ Tcl_Obj *nameObj, /* The name of the method. */ Tcl_Obj *prefixObj) /* List of arguments that form the command * prefix to forward to. */ { | | | | 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 | Tcl_Interp *interp, /* Interpreter for error reporting. */ Class *clsPtr, /* The class to attach the method to. */ int flags, /* Whether the method is public or not. */ Tcl_Obj *nameObj, /* The name of the method. */ Tcl_Obj *prefixObj) /* List of arguments that form the command * prefix to forward to. */ { size_t prefixLen; register ForwardMethod *fmPtr; Tcl_Obj *cmdObj; if (Tcl_ListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) { return NULL; } if (prefixLen < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "method forward prefix must be non-empty", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", NULL); return NULL; } fmPtr = ckalloc(sizeof(ForwardMethod)); fmPtr->prefixObj = prefixObj; Tcl_ListObjIndex(interp, prefixObj, 0, &cmdObj); |
︙ | ︙ | |||
1442 1443 1444 1445 1446 1447 1448 | */ static int InvokeForwardMethod( ClientData clientData, /* Pointer to some per-method context. */ Tcl_Interp *interp, Tcl_ObjectContext context, /* The method calling context. */ | | | | 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 | */ static int InvokeForwardMethod( ClientData clientData, /* Pointer to some per-method context. */ Tcl_Interp *interp, Tcl_ObjectContext context, /* The method calling context. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Arguments as actually seen. */ { CallContext *contextPtr = (CallContext *) context; ForwardMethod *fmPtr = clientData; Tcl_Obj **argObjs, **prefixObjs; size_t numPrefixes, len, skip = contextPtr->skip; /* * Build the real list of arguments to use. Note that we know that the * prefixObj field of the ForwardMethod structure holds a reference to a * non-empty list, so there's a whole class of failures ("not a list") we * can ignore here. */ |
︙ | ︙ | |||
1589 1590 1591 1592 1593 1594 1595 | * * ---------------------------------------------------------------------- */ static Tcl_Obj ** InitEnsembleRewrite( Tcl_Interp *interp, /* Place to log the rewrite info. */ | | | | | | | | 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 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 | * * ---------------------------------------------------------------------- */ static Tcl_Obj ** InitEnsembleRewrite( Tcl_Interp *interp, /* Place to log the rewrite info. */ size_t objc, /* Number of real arguments. */ Tcl_Obj *const *objv, /* The real arguments. */ size_t toRewrite, /* Number of real arguments to replace. */ size_t rewriteLength, /* Number of arguments to insert instead. */ Tcl_Obj *const *rewriteObjs,/* Arguments to insert instead. */ size_t *lengthPtr) /* Where to write the resulting length of the * array of rewritten arguments. */ { Interp *iPtr = (Interp *) interp; int isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL); Tcl_Obj **argObjs; size_t len = rewriteLength + objc - toRewrite; argObjs = TclStackAlloc(interp, sizeof(Tcl_Obj *) * len); memcpy(argObjs, rewriteObjs, rewriteLength * sizeof(Tcl_Obj *)); memcpy(argObjs + rewriteLength, objv + toRewrite, sizeof(Tcl_Obj *) * (objc - toRewrite)); /* * Now plumb this into the core ensemble rewrite logging system so that * Tcl_WrongNumArgs() can rewrite its result appropriately. The rules for * how to store the rewrite rules get complex solely because of the case * where an ensemble rewrites itself out of the picture; when that * happens, the quality of the error message rewrite falls drastically * (and unavoidably). */ if (isRootEnsemble) { iPtr->ensembleRewrite.sourceObjs = objv; iPtr->ensembleRewrite.numRemovedObjs = toRewrite; iPtr->ensembleRewrite.numInsertedObjs = rewriteLength; } else { size_t numIns = iPtr->ensembleRewrite.numInsertedObjs; if (numIns < toRewrite) { iPtr->ensembleRewrite.numRemovedObjs += toRewrite - numIns; iPtr->ensembleRewrite.numInsertedObjs += rewriteLength - 1; } else { iPtr->ensembleRewrite.numInsertedObjs += rewriteLength - toRewrite; |
︙ | ︙ |
Changes to generic/tclObj.c.
︙ | ︙ | |||
142 143 144 145 146 147 148 | * to them. */ #define ObjDeletionLock(contextPtr) ((contextPtr)->deletionCount++) #define ObjDeletionUnlock(contextPtr) ((contextPtr)->deletionCount--) #define ObjDeletePending(contextPtr) ((contextPtr)->deletionCount > 0) #define ObjOnStack(contextPtr) ((contextPtr)->deletionStack != NULL) #define PushObjToDelete(contextPtr,objPtr) \ | > | | > | | > > | | > | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | * to them. */ #define ObjDeletionLock(contextPtr) ((contextPtr)->deletionCount++) #define ObjDeletionUnlock(contextPtr) ((contextPtr)->deletionCount--) #define ObjDeletePending(contextPtr) ((contextPtr)->deletionCount > 0) #define ObjOnStack(contextPtr) ((contextPtr)->deletionStack != NULL) #define PushObjToDelete(contextPtr,objPtr) \ do { \ /* The string rep is already invalidated so we can use the bytes \ * value for our pointer chain: push onto the head of the stack. \ */ \ (objPtr)->bytes = (char *) ((contextPtr)->deletionStack); \ (contextPtr)->deletionStack = (objPtr); \ } while (0) #define PopObjToDelete(contextPtr,objPtrVar) \ do { \ (objPtrVar) = (contextPtr)->deletionStack; \ (contextPtr)->deletionStack = (Tcl_Obj *) (objPtrVar)->bytes; \ } while (0) /* * Macro to set up the local reference to the deletion context. */ #ifndef TCL_THREADS static PendingObjData pendingObjData; #define ObjInitDeletionContext(contextPtr) \ |
︙ | ︙ | |||
566 567 568 569 570 571 572 | *---------------------------------------------------------------------- */ ContLineLoc * TclContinuationsEnter( Tcl_Obj *objPtr, int num, | | | | 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 | *---------------------------------------------------------------------- */ ContLineLoc * TclContinuationsEnter( Tcl_Obj *objPtr, int num, ssize_t *loc) { int newEntry; ThreadSpecificData *tsdPtr = TclGetContLineTable(); Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(tsdPtr->lineCLPtr, objPtr, &newEntry); ContLineLoc *clLocPtr = ckalloc(sizeof(ContLineLoc) + num*sizeof(size_t)); if (!newEntry) { /* * We're entering ContLineLoc data for the same value more than one * time. Taking care not to leak the old entry. * * This can happen when literals in a proc body are shared. See for |
︙ | ︙ | |||
600 601 602 603 604 605 606 | * doing. */ ckfree(Tcl_GetHashValue(hPtr)); } clLocPtr->num = num; | | | 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 | * doing. */ ckfree(Tcl_GetHashValue(hPtr)); } clLocPtr->num = num; memcpy(&clLocPtr->loc, loc, num*sizeof(size_t)); clLocPtr->loc[num] = CLL_END; /* Sentinel */ Tcl_SetHashValue(hPtr, clLocPtr); return clLocPtr; } /* |
︙ | ︙ | |||
629 630 631 632 633 634 635 | * TIP #280 *---------------------------------------------------------------------- */ void TclContinuationsEnterDerived( Tcl_Obj *objPtr, | | | | | | 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 | * TIP #280 *---------------------------------------------------------------------- */ void TclContinuationsEnterDerived( Tcl_Obj *objPtr, size_t start, ssize_t *clNext) { size_t length, end, num; ssize_t *wordCLLast = clNext; /* * We have to handle invisible continuations lines here as well, despite * the code we have in TclSubstTokens (TST) for that. Why ? Nesting. If * our script is the sole argument to an 'eval' command, for example, the * scriptCLLocPtr we are using was generated by a previous call to TST, * and while the words we have here may contain continuation lines they |
︙ | ︙ | |||
676 677 678 679 680 681 682 | /* * And generate the table from the slice, if it was not empty. */ num = wordCLLast - clNext; if (num) { | | | 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 | /* * And generate the table from the slice, if it was not empty. */ num = wordCLLast - clNext; if (num) { size_t i; ContLineLoc *clLocPtr = TclContinuationsEnter(objPtr, num, clNext); /* * Re-base the locations. */ for (i=0 ; i<num ; i++) { |
︙ | ︙ | |||
874 875 876 877 878 879 880 | Tcl_Interp *interp, /* Interpreter used for error reporting. */ Tcl_Obj *objPtr) /* Points to the Tcl object onto which the * name of each registered type is appended as * a list element. */ { register Tcl_HashEntry *hPtr; Tcl_HashSearch search; | | | | | 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 | Tcl_Interp *interp, /* Interpreter used for error reporting. */ Tcl_Obj *objPtr) /* Points to the Tcl object onto which the * name of each registered type is appended as * a list element. */ { register Tcl_HashEntry *hPtr; Tcl_HashSearch search; size_t numElems; /* * Get the test for a valid list out of the way first. */ if (TclListObjLength(interp, objPtr, &numElems) != TCL_OK) { return TCL_ERROR; } /* * Type names are NUL-terminated, not counted strings. This code relies on * that. */ Tcl_MutexLock(&tableMutex); for (hPtr = Tcl_FirstHashEntry(&typeTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj( Tcl_GetHashKey(&typeTable, hPtr), TCL_STRLEN)); } Tcl_MutexUnlock(&tableMutex); return TCL_OK; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1010 1011 1012 1013 1014 1015 1016 | Tcl_HashEntry *hPtr; Tcl_HashTable *tablePtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); tablePtr = tsdPtr->objThreadMap; if (tablePtr != NULL) { | | | 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 | Tcl_HashEntry *hPtr; Tcl_HashTable *tablePtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); tablePtr = tsdPtr->objThreadMap; if (tablePtr != NULL) { fprintf(outFile, "total objects: %lu\n", tablePtr->numEntries); for (hPtr = Tcl_FirstHashEntry(tablePtr, &hSearch); hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { ObjData *objData = Tcl_GetHashValue(hPtr); if (objData != NULL) { fprintf(outFile, "key = 0x%p, objPtr = 0x%p, file = %s, line = %d\n", |
︙ | ︙ | |||
1316 1317 1318 1319 1320 1321 1322 | * Skip that possibility so any double free will trigger the panic. */ objPtr->refCount = -1; /* * Invalidate the string rep first so we can use the bytes value for our * pointer chain, and signal an obj deletion (as opposed to shimmering) | | | | 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 | * Skip that possibility so any double free will trigger the panic. */ objPtr->refCount = -1; /* * Invalidate the string rep first so we can use the bytes value for our * pointer chain, and signal an obj deletion (as opposed to shimmering) * with 'length == TCL_STRLEN'. */ TclInvalidateStringRep(objPtr); objPtr->length = TCL_STRLEN; if (ObjDeletePending(context)) { PushObjToDelete(context, objPtr); } else { TCL_DTRACE_OBJ_FREE(objPtr); if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { ObjDeletionLock(context); |
︙ | ︙ | |||
1384 1385 1386 1387 1388 1389 1390 | void TclFreeObj( register Tcl_Obj *objPtr) /* The object to be freed. */ { /* * Invalidate the string rep first so we can use the bytes value for our * pointer chain, and signal an obj deletion (as opposed to shimmering) | | | | 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 | void TclFreeObj( register Tcl_Obj *objPtr) /* The object to be freed. */ { /* * Invalidate the string rep first so we can use the bytes value for our * pointer chain, and signal an obj deletion (as opposed to shimmering) * with 'length == TCL_STRLEN'. */ TclInvalidateStringRep(objPtr); objPtr->length = TCL_STRLEN; if (!objPtr->typePtr || !objPtr->typePtr->freeIntRepProc) { /* * objPtr can be freed safely, as it will not attempt to free any * other objects: it will not cause recursive calls to this function. */ |
︙ | ︙ | |||
1490 1491 1492 1493 1494 1495 1496 | *---------------------------------------------------------------------- */ int TclObjBeingDeleted( Tcl_Obj *objPtr) { | | | 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 | *---------------------------------------------------------------------- */ int TclObjBeingDeleted( Tcl_Obj *objPtr) { return (objPtr->length == TCL_STRLEN); } /* *---------------------------------------------------------------------- * * Tcl_DuplicateObj -- * |
︙ | ︙ | |||
1613 1614 1615 1616 1617 1618 1619 | * NULL. This panic was added in Tcl 8.1. */ Tcl_Panic("UpdateStringProc should not be invoked for type %s", objPtr->typePtr->name); } objPtr->typePtr->updateStringProc(objPtr); | | | 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 | * NULL. This panic was added in Tcl 8.1. */ Tcl_Panic("UpdateStringProc should not be invoked for type %s", objPtr->typePtr->name); } objPtr->typePtr->updateStringProc(objPtr); if (objPtr->bytes == NULL || objPtr->length == TCL_STRLEN || objPtr->bytes[objPtr->length] != '\0') { Tcl_Panic("UpdateStringProc for type '%s' " "failed to create a valid string rep", objPtr->typePtr->name); } return objPtr->bytes; } |
︙ | ︙ | |||
1648 1649 1650 1651 1652 1653 1654 | *---------------------------------------------------------------------- */ char * Tcl_GetStringFromObj( register Tcl_Obj *objPtr, /* Object whose string rep byte pointer should * be returned. */ | | | 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 | *---------------------------------------------------------------------- */ char * Tcl_GetStringFromObj( register Tcl_Obj *objPtr, /* Object whose string rep byte pointer should * be returned. */ register size_t *lengthPtr) /* If non-NULL, the location where the string * rep's byte array length should * be stored. * If NULL, no length is stored. */ { (void) TclGetString(objPtr); if (lengthPtr != NULL) { *lengthPtr = objPtr->length; |
︙ | ︙ | |||
1886 1887 1888 1889 1890 1891 1892 | #ifndef TCL_WIDE_INT_IS_LONG if (objPtr->typePtr == &tclWideIntType) { *boolPtr = (objPtr->internalRep.wideValue != 0); return TCL_OK; } #endif } while ((ParseBoolean(objPtr) == TCL_OK) || (TCL_OK == | | > | 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 | #ifndef TCL_WIDE_INT_IS_LONG if (objPtr->typePtr == &tclWideIntType) { *boolPtr = (objPtr->internalRep.wideValue != 0); return TCL_OK; } #endif } while ((ParseBoolean(objPtr) == TCL_OK) || (TCL_OK == TclParseNumber(interp, objPtr, "boolean value", NULL, TCL_STRLEN, NULL, 0))); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclSetBooleanFromAny -- |
︙ | ︙ | |||
1951 1952 1953 1954 1955 1956 1957 | if (ParseBoolean(objPtr) == TCL_OK) { return TCL_OK; } badBoolean: if (interp != NULL) { | | | | > | 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 | if (ParseBoolean(objPtr) == TCL_OK) { return TCL_OK; } badBoolean: if (interp != NULL) { size_t length; const char *str = Tcl_GetStringFromObj(objPtr, &length); Tcl_Obj *msg; TclNewLiteralStringObj(msg, "expected boolean value but got \""); Tcl_AppendLimitedToObj(msg, str, length, 50, ""); Tcl_AppendToObj(msg, "\"", TCL_STRLEN); Tcl_SetObjResult(interp, msg); Tcl_SetErrorCode(interp, "TCL", "VALUE", "BOOLEAN", NULL); } return TCL_ERROR; } static int ParseBoolean( register Tcl_Obj *objPtr) /* The object to parse/convert. */ { int i, newBool; size_t length; char lowerCase[6]; const char *str = TclGetStringFromObj(objPtr, &length); if ((length == 0) || (length > 5)) { /* * Longest valid boolean string rep. is "false". */ |
︙ | ︙ | |||
2246 2247 2248 2249 2250 2251 2252 | register double *dblPtr) /* Place to store resulting double. */ { do { if (objPtr->typePtr == &tclDoubleType) { if (TclIsNaN(objPtr->internalRep.doubleValue)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 | register double *dblPtr) /* Place to store resulting double. */ { do { if (objPtr->typePtr == &tclDoubleType) { if (TclIsNaN(objPtr->internalRep.doubleValue)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "floating point value is Not a Number", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DOUBLE", "NAN", NULL); } return TCL_ERROR; } *dblPtr = (double) objPtr->internalRep.doubleValue; return TCL_OK; |
︙ | ︙ | |||
2301 2302 2303 2304 2305 2306 2307 | */ static int SetDoubleFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ register Tcl_Obj *objPtr) /* The object to convert. */ { | | | | 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 | */ static int SetDoubleFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ register Tcl_Obj *objPtr) /* The object to convert. */ { return TclParseNumber(interp, objPtr, "floating-point number", NULL, TCL_STRLEN, NULL, 0); } /* *---------------------------------------------------------------------- * * UpdateStringOfDouble -- * |
︙ | ︙ | |||
2331 2332 2333 2334 2335 2336 2337 | */ static void UpdateStringOfDouble( register Tcl_Obj *objPtr) /* Double obj with string rep to update. */ { char buffer[TCL_DOUBLE_SPACE]; | | | 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 | */ static void UpdateStringOfDouble( register Tcl_Obj *objPtr) /* Double obj with string rep to update. */ { char buffer[TCL_DOUBLE_SPACE]; register size_t len; Tcl_PrintDouble(NULL, objPtr->internalRep.doubleValue, buffer); len = strlen(buffer); objPtr->bytes = ckalloc(len + 1); memcpy(objPtr->bytes, buffer, (unsigned) len + 1); objPtr->length = len; |
︙ | ︙ | |||
2467 2468 2469 2470 2471 2472 2473 | long l; if (TclGetLongFromObj(interp, objPtr, &l) != TCL_OK) { return TCL_ERROR; } if ((ULONG_MAX > UINT_MAX) && ((l > UINT_MAX) || (l < -(long)UINT_MAX))) { if (interp != NULL) { | | | | 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 | long l; if (TclGetLongFromObj(interp, objPtr, &l) != TCL_OK) { return TCL_ERROR; } if ((ULONG_MAX > UINT_MAX) && ((l > UINT_MAX) || (l < -(long)UINT_MAX))) { if (interp != NULL) { static const char *s = "integer value too large to represent as non-long integer"; Tcl_SetObjResult(interp, Tcl_NewStringObj(s, TCL_STRLEN)); Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL); } return TCL_ERROR; } *intPtr = (int) l; return TCL_OK; #endif |
︙ | ︙ | |||
2529 2530 2531 2532 2533 2534 2535 | */ static void UpdateStringOfInt( register Tcl_Obj *objPtr) /* Int object whose string rep to update. */ { char buffer[TCL_INTEGER_SPACE]; | | | 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 | */ static void UpdateStringOfInt( register Tcl_Obj *objPtr) /* Int object whose string rep to update. */ { char buffer[TCL_INTEGER_SPACE]; register size_t len; len = TclFormatInt(buffer, objPtr->internalRep.longValue); objPtr->bytes = ckalloc(len + 1); memcpy(objPtr->bytes, buffer, (unsigned) len + 1); objPtr->length = len; } |
︙ | ︙ | |||
2787 2788 2789 2790 2791 2792 2793 | return TCL_OK; } } #ifndef TCL_WIDE_INT_IS_LONG tooLarge: #endif if (interp != NULL) { | | | | | 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 | return TCL_OK; } } #ifndef TCL_WIDE_INT_IS_LONG tooLarge: #endif if (interp != NULL) { static const char *s = "integer value too large to represent"; Tcl_Obj *msg = Tcl_NewStringObj(s, TCL_STRLEN); Tcl_SetObjResult(interp, msg); Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL); } return TCL_ERROR; } } while (TclParseNumber(interp, objPtr, "integer", NULL, TCL_STRLEN, NULL, TCL_PARSE_INTEGER_ONLY)==TCL_OK); return TCL_ERROR; } #ifndef TCL_WIDE_INT_IS_LONG /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
2825 2826 2827 2828 2829 2830 2831 | */ static void UpdateStringOfWideInt( register Tcl_Obj *objPtr) /* Int object whose string rep to update. */ { char buffer[TCL_INTEGER_SPACE+2]; | | | 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 | */ static void UpdateStringOfWideInt( register Tcl_Obj *objPtr) /* Int object whose string rep to update. */ { char buffer[TCL_INTEGER_SPACE+2]; register size_t len; register Tcl_WideInt wideVal = objPtr->internalRep.wideValue; /* * Note that sprintf will generate a compiler warning under Mingw claiming * %I64 is an unknown format specifier. Just ignore this warning. We can't * use %L as the format specifier since that gets printed as a 32 bit * value. |
︙ | ︙ | |||
3084 3085 3086 3087 3088 3089 3090 | } else { *wideIntPtr = (Tcl_WideInt) value; } return TCL_OK; } } if (interp != NULL) { | | | | | 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 | } else { *wideIntPtr = (Tcl_WideInt) value; } return TCL_OK; } } if (interp != NULL) { static const char *s = "integer value too large to represent"; Tcl_Obj *msg = Tcl_NewStringObj(s, TCL_STRLEN); Tcl_SetObjResult(interp, msg); Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL); } return TCL_ERROR; } } while (TclParseNumber(interp, objPtr, "integer", NULL, TCL_STRLEN, NULL, TCL_PARSE_INTEGER_ONLY)==TCL_OK); return TCL_ERROR; } #ifndef TCL_WIDE_INT_IS_LONG /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
3386 3387 3388 3389 3390 3391 3392 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected integer but got \"%s\"", Tcl_GetString(objPtr))); Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL); } return TCL_ERROR; } | | | 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected integer but got \"%s\"", Tcl_GetString(objPtr))); Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL); } return TCL_ERROR; } } while (TclParseNumber(interp, objPtr, "integer", NULL, TCL_STRLEN, NULL, TCL_PARSE_INTEGER_ONLY)==TCL_OK); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3638 3639 3640 3641 3642 3643 3644 | (int) sizeof(mp_int)); UNPACK_BIGNUM(objPtr, *bigPtr); *typePtr = TCL_NUMBER_BIG; *clientDataPtr = bigPtr; return TCL_OK; } | | | | 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 | (int) sizeof(mp_int)); UNPACK_BIGNUM(objPtr, *bigPtr); *typePtr = TCL_NUMBER_BIG; *clientDataPtr = bigPtr; return TCL_OK; } } while (TCL_OK == TclParseNumber(interp, objPtr, "number", NULL, TCL_STRLEN, NULL, 0)); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * Tcl_DbIncrRefCount -- |
︙ | ︙ | |||
3945 3946 3947 3948 3949 3950 3951 | TclCompareObjKeys( void *keyPtr, /* New key to compare. */ Tcl_HashEntry *hPtr) /* Existing key to compare. */ { Tcl_Obj *objPtr1 = keyPtr; Tcl_Obj *objPtr2 = (Tcl_Obj *) hPtr->key.oneWordValue; register const char *p1, *p2; | | | 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 | TclCompareObjKeys( void *keyPtr, /* New key to compare. */ Tcl_HashEntry *hPtr) /* Existing key to compare. */ { Tcl_Obj *objPtr1 = keyPtr; Tcl_Obj *objPtr2 = (Tcl_Obj *) hPtr->key.oneWordValue; register const char *p1, *p2; register size_t l1, l2; /* * If the object pointers are the same then they match. */ if (objPtr1 == objPtr2) { return 1; |
︙ | ︙ | |||
4033 4034 4035 4036 4037 4038 4039 | unsigned int TclHashObjKey( Tcl_HashTable *tablePtr, /* Hash table. */ void *keyPtr) /* Key from which to compute hash value. */ { Tcl_Obj *objPtr = keyPtr; | | | 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 | unsigned int TclHashObjKey( Tcl_HashTable *tablePtr, /* Hash table. */ void *keyPtr) /* Key from which to compute hash value. */ { Tcl_Obj *objPtr = keyPtr; size_t length; const char *string = TclGetStringFromObj(objPtr, &length); unsigned int result = 0; /* * I tried a zillion different hash functions and asked many other people * for advice. Many people had their own favorite functions, all * different, but no-one had much idea why they were good ones. I chose |
︙ | ︙ | |||
4443 4444 4445 4446 4447 4448 4449 | *---------------------------------------------------------------------- */ int Tcl_RepresentationCmd( ClientData clientData, Tcl_Interp *interp, | | | 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 | *---------------------------------------------------------------------- */ int Tcl_RepresentationCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { char ptrBuffer[2*TCL_INTEGER_SPACE+6]; Tcl_Obj *descObj; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "value"); |
︙ | ︙ | |||
4475 4476 4477 4478 4479 4480 4481 | (void *) objv[1]->internalRep.twoPtrValue.ptr1, (void *) objv[1]->internalRep.twoPtrValue.ptr2); Tcl_AppendPrintfToObj(descObj, ", internal representation %s", ptrBuffer); } if (objv[1]->bytes) { | | | | | 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 | (void *) objv[1]->internalRep.twoPtrValue.ptr1, (void *) objv[1]->internalRep.twoPtrValue.ptr2); Tcl_AppendPrintfToObj(descObj, ", internal representation %s", ptrBuffer); } if (objv[1]->bytes) { Tcl_AppendToObj(descObj, ", string representation \"", TCL_STRLEN); Tcl_AppendLimitedToObj(descObj, objv[1]->bytes, objv[1]->length, 16, "..."); Tcl_AppendToObj(descObj, "\"", TCL_STRLEN); } else { Tcl_AppendToObj(descObj, ", no string representation", TCL_STRLEN); } Tcl_SetObjResult(interp, descObj); return TCL_OK; } /* |
︙ | ︙ |
Changes to generic/tclOptimize.c.
︙ | ︙ | |||
227 228 229 230 231 232 233 | case INST_PUSH1: if (nextInst == INST_POP) { blank = size + InstLength(nextInst); } else if (nextInst == INST_CONCAT1 && TclGetUInt1AtPtr(currentInstPtr + size + 1) == 2) { Tcl_Obj *litPtr = TclFetchLiteral(envPtr, TclGetUInt1AtPtr(currentInstPtr + 1)); | | | | 227 228 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 | case INST_PUSH1: if (nextInst == INST_POP) { blank = size + InstLength(nextInst); } else if (nextInst == INST_CONCAT1 && TclGetUInt1AtPtr(currentInstPtr + size + 1) == 2) { Tcl_Obj *litPtr = TclFetchLiteral(envPtr, TclGetUInt1AtPtr(currentInstPtr + 1)); size_t numBytes; (void) Tcl_GetStringFromObj(litPtr, &numBytes); if (numBytes == 0) { blank = size + InstLength(nextInst); } } break; case INST_PUSH4: if (nextInst == INST_POP) { blank = size + 1; } else if (nextInst == INST_CONCAT1 && TclGetUInt1AtPtr(currentInstPtr + size + 1) == 2) { Tcl_Obj *litPtr = TclFetchLiteral(envPtr, TclGetUInt4AtPtr(currentInstPtr + 1)); size_t numBytes; (void) Tcl_GetStringFromObj(litPtr, &numBytes); if (numBytes == 0) { blank = size + InstLength(nextInst); } } break; |
︙ | ︙ |
Changes to generic/tclParse.c.
︙ | ︙ | |||
157 158 159 160 161 162 163 | }; /* * Prototypes for local functions defined in this file: */ static inline int CommandComplete(const char *script, int numBytes); | | | | | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | }; /* * Prototypes for local functions defined in this file: */ static inline int CommandComplete(const char *script, int numBytes); static size_t ParseComment(const char *src, size_t numBytes, Tcl_Parse *parsePtr); static int ParseTokens(const char *src, size_t numBytes, int mask, int flags, Tcl_Parse *parsePtr); static size_t ParseWhiteSpace(const char *src, size_t numBytes, int *incompletePtr, char *typePtr); /* *---------------------------------------------------------------------- * * TclParseInit -- * |
︙ | ︙ | |||
184 185 186 187 188 189 190 | *---------------------------------------------------------------------- */ void TclParseInit( Tcl_Interp *interp, /* Interpreter to use for error reporting */ const char *start, /* Start of string to be parsed. */ | | | | > > > | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | *---------------------------------------------------------------------- */ void TclParseInit( Tcl_Interp *interp, /* Interpreter to use for error reporting */ const char *start, /* Start of string to be parsed. */ size_t numBytes, /* Total number of bytes in string. If * TCL_STRLEN, the script consists of all * bytes up to the first null character. */ Tcl_Parse *parsePtr) /* Points to struct to initialize */ { if (numBytes == TCL_STRLEN) { numBytes = strlen(start); } parsePtr->numWords = 0; parsePtr->tokenPtr = parsePtr->staticTokens; parsePtr->numTokens = 0; parsePtr->tokensAvailable = NUM_STATIC_TOKENS; parsePtr->string = start; parsePtr->end = start + numBytes; parsePtr->term = parsePtr->end; |
︙ | ︙ | |||
230 231 232 233 234 235 236 | int Tcl_ParseCommand( Tcl_Interp *interp, /* Interpreter to use for error reporting; if * NULL, then no error message is provided. */ const char *start, /* First character of string containing one or * more Tcl commands. */ | | | | | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | int Tcl_ParseCommand( Tcl_Interp *interp, /* Interpreter to use for error reporting; if * NULL, then no error message is provided. */ const char *start, /* First character of string containing one or * more Tcl commands. */ register size_t numBytes, /* Total number of bytes in string. If * TCL_STRLEN, the script consists of all * bytes up to the first null character. */ int nested, /* Non-zero means this is a nested command: * close bracket should be considered a * command terminator. If zero, then close * bracket has no special meaning. */ register Tcl_Parse *parsePtr) /* Structure to fill in with information about * the parsed command; any previous |
︙ | ︙ | |||
256 257 258 259 260 261 262 | const char *termPtr; /* Set by Tcl_ParseBraces/QuotedString to * point to char after terminating one. */ int scanned; if ((start == NULL) && (numBytes != 0)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | const char *termPtr; /* Set by Tcl_ParseBraces/QuotedString to * point to char after terminating one. */ int scanned; if ((start == NULL) && (numBytes != 0)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't parse a NULL pointer", TCL_STRLEN)); } return TCL_ERROR; } if (numBytes == TCL_STRLEN) { numBytes = strlen(start); } TclParseInit(interp, start, numBytes, parsePtr); parsePtr->commentStart = NULL; parsePtr->commentSize = 0; parsePtr->commandStart = NULL; parsePtr->commandSize = 0; |
︙ | ︙ | |||
443 444 445 446 447 448 449 | /* * Step through the literal string, parsing and counting list * elements. */ while (nextElem < listEnd) { | | | 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | /* * Step through the literal string, parsing and counting list * elements. */ while (nextElem < listEnd) { size_t size; code = TclFindElement(NULL, nextElem, listEnd - nextElem, &elemStart, &nextElem, &size, &literal); if ((code != TCL_OK) || !literal) { break; } if (elemStart < listEnd) { |
︙ | ︙ | |||
567 568 569 570 571 572 573 | parsePtr->term = src; src++; break; } if (src[-1] == '"') { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | parsePtr->term = src; src++; break; } if (src[-1] == '"') { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "extra characters after close-quote", TCL_STRLEN)); } parsePtr->errorType = TCL_PARSE_QUOTE_EXTRA; } else { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "extra characters after close-brace", TCL_STRLEN)); } parsePtr->errorType = TCL_PARSE_BRACE_EXTRA; } parsePtr->term = src; goto error; } |
︙ | ︙ | |||
634 635 636 637 638 639 640 | * * Side effects: * None. * *---------------------------------------------------------------------- */ | | | | 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 | * * Side effects: * None. * *---------------------------------------------------------------------- */ static size_t ParseWhiteSpace( const char *src, /* First character to parse. */ register size_t numBytes, /* Max number of bytes to scan. */ int *incompletePtr, /* Set this boolean memory to true if parsing * indicates an incomplete command. */ char *typePtr) /* Points to location to store character type * of character that ends run of whitespace */ { register char type = TYPE_NORMAL; register const char *p = src; |
︙ | ︙ | |||
688 689 690 691 692 693 694 | * * Results: * Returns the number of bytes recognized as white space. * *---------------------------------------------------------------------- */ | | | > > > > > > > > > | | | | | > | | 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 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 | * * Results: * Returns the number of bytes recognized as white space. * *---------------------------------------------------------------------- */ size_t TclParseAllWhiteSpace( const char *src, /* First character to parse. */ size_t numBytes) /* Max number of byes to scan */ { int dummy; char type; const char *p = src; if (numBytes == TCL_STRLEN) { while (1) { p += ParseWhiteSpace(p, TCL_STRLEN, &dummy, &type); if (*p != '\n') { break; } p++; } } else { do { int scanned = ParseWhiteSpace(p, numBytes, &dummy, &type); p += scanned; numBytes -= scanned; } while (numBytes && (*p == '\n') && (p++, --numBytes)); } return p - src; } /* *---------------------------------------------------------------------- * * TclParseHex -- * |
︙ | ︙ | |||
728 729 730 731 732 733 734 | * * The digits '0' .. '9' and the letters 'A' .. 'Z' and 'a' .. 'z' occupy * consecutive code points, and '0' < 'A' < 'a'. * *---------------------------------------------------------------------- */ | | | | 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | * * The digits '0' .. '9' and the letters 'A' .. 'Z' and 'a' .. 'z' occupy * consecutive code points, and '0' < 'A' < 'a'. * *---------------------------------------------------------------------- */ size_t TclParseHex( const char *src, /* First character to parse. */ size_t numBytes, /* Max number of byes to scan */ int *resultPtr) /* Points to storage provided by caller where * the character resulting from the * conversion is to be written. */ { int result = 0; register const char *p = src; |
︙ | ︙ | |||
783 784 785 786 787 788 789 | * * Side effects: * None. * *---------------------------------------------------------------------- */ | | | | | 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 | * * Side effects: * None. * *---------------------------------------------------------------------- */ size_t TclParseBackslash( const char *src, /* Points to the backslash character of a a * backslash sequence. */ size_t numBytes, /* Max number of bytes to scan. */ size_t *readPtr, /* NULL, or points to storage where the number * of bytes scanned should be written. */ char *dst) /* NULL, or points to buffer where the UTF-8 * encoding of the backslash sequence is to be * written. At most TCL_UTF_MAX bytes will be * written there. */ { register const char *p = src+1; |
︙ | ︙ | |||
967 968 969 970 971 972 973 | * * Side effects: * None. * *---------------------------------------------------------------------- */ | | | | | 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 | * * Side effects: * None. * *---------------------------------------------------------------------- */ static size_t ParseComment( const char *src, /* First character to parse. */ register size_t numBytes, /* Max number of bytes to scan. */ Tcl_Parse *parsePtr) /* Information about parse in progress. * Updated if parsing indicates an incomplete * command. */ { register const char *p = src; while (numBytes) { char type; size_t scanned; do { scanned = ParseWhiteSpace(p, numBytes, &parsePtr->incomplete, &type); p += scanned; numBytes -= scanned; } while (numBytes && (*p == '\n') && (p++,numBytes--)); |
︙ | ︙ | |||
1055 1056 1057 1058 1059 1060 1061 | * *---------------------------------------------------------------------- */ static int ParseTokens( register const char *src, /* First character to parse. */ | | | 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 | * *---------------------------------------------------------------------- */ static int ParseTokens( register const char *src, /* First character to parse. */ register size_t numBytes, /* Max number of bytes to scan. */ int mask, /* Specifies when to stop parsing. The parse * stops at the first unquoted character whose * CHAR_TYPE contains any of the bits in * mask. */ int flags, /* OR-ed bits indicating what substitutions to * perform: TCL_SUBST_COMMANDS, * TCL_SUBST_VARIABLES, and |
︙ | ︙ | |||
1174 1175 1176 1177 1178 1179 1180 | && (*(nestedPtr->term) == ']') && !(nestedPtr->incomplete)) { break; } if (numBytes == 0) { if (parsePtr->interp != NULL) { Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( | | | 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 | && (*(nestedPtr->term) == ']') && !(nestedPtr->incomplete)) { break; } if (numBytes == 0) { if (parsePtr->interp != NULL) { Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( "missing close-bracket", TCL_STRLEN)); } parsePtr->errorType = TCL_PARSE_MISSING_BRACKET; parsePtr->term = tokenPtr->start; parsePtr->incomplete = 1; TclStackFree(parsePtr->interp, nestedPtr); return TCL_ERROR; } |
︙ | ︙ | |||
1330 1331 1332 1333 1334 1335 1336 | int Tcl_ParseVarName( Tcl_Interp *interp, /* Interpreter to use for error reporting; if * NULL, then no error message is provided. */ const char *start, /* Start of variable substitution string. * First character must be "$". */ | | | | | | 1343 1344 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 1370 1371 1372 1373 1374 1375 1376 1377 | int Tcl_ParseVarName( Tcl_Interp *interp, /* Interpreter to use for error reporting; if * NULL, then no error message is provided. */ const char *start, /* Start of variable substitution string. * First character must be "$". */ register size_t numBytes, /* Total number of bytes in string. If * TCL_STRLEN, the string consists of all * bytes up to the first null character. */ Tcl_Parse *parsePtr, /* Structure to fill in with information about * the variable name. */ int append) /* Non-zero means append tokens to existing * information in parsePtr; zero means ignore * existing tokens in parsePtr and * reinitialize it. */ { Tcl_Token *tokenPtr; register const char *src; unsigned char c; int varIndex, offset; Tcl_UniChar ch; unsigned array; if ((numBytes == 0) || (start == NULL)) { return TCL_ERROR; } if (numBytes == TCL_STRLEN) { numBytes = strlen(start); } if (!append) { TclParseInit(interp, start, numBytes, parsePtr); } |
︙ | ︙ | |||
1410 1411 1412 1413 1414 1415 1416 | while (numBytes && (*src != '}')) { numBytes--; src++; } if (numBytes == 0) { if (parsePtr->interp != NULL) { Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( | | | 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 | while (numBytes && (*src != '}')) { numBytes--; src++; } if (numBytes == 0) { if (parsePtr->interp != NULL) { Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( "missing close-brace for variable name", TCL_STRLEN)); } parsePtr->errorType = TCL_PARSE_MISSING_VAR_BRACE; parsePtr->term = tokenPtr->start-1; parsePtr->incomplete = 1; goto error; } tokenPtr->size = src - tokenPtr->start; |
︙ | ︙ | |||
1478 1479 1480 1481 1482 1483 1484 | if (TCL_OK != ParseTokens(src+1, numBytes-1, TYPE_CLOSE_PAREN, TCL_SUBST_ALL, parsePtr)) { goto error; } if ((parsePtr->term == src+numBytes) || (*parsePtr->term != ')')){ if (parsePtr->interp != NULL) { Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( | | | 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 | if (TCL_OK != ParseTokens(src+1, numBytes-1, TYPE_CLOSE_PAREN, TCL_SUBST_ALL, parsePtr)) { goto error; } if ((parsePtr->term == src+numBytes) || (*parsePtr->term != ')')){ if (parsePtr->interp != NULL) { Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( "missing )", TCL_STRLEN)); } parsePtr->errorType = TCL_PARSE_MISSING_PAREN; parsePtr->term = src; parsePtr->incomplete = 1; goto error; } src = parsePtr->term + 1; |
︙ | ︙ | |||
1545 1546 1547 1548 1549 1550 1551 | * character just after last one in the * variable specifier. */ { register Tcl_Obj *objPtr; int code; Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse)); | | | 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 | * character just after last one in the * variable specifier. */ { register Tcl_Obj *objPtr; int code; Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse)); if (Tcl_ParseVarName(interp, start, TCL_STRLEN, parsePtr, 0) != TCL_OK) { TclStackFree(interp, parsePtr); return NULL; } if (termPtr != NULL) { *termPtr = start + parsePtr->tokenPtr->size; } |
︙ | ︙ | |||
1620 1621 1622 1623 1624 1625 1626 | int Tcl_ParseBraces( Tcl_Interp *interp, /* Interpreter to use for error reporting; if * NULL, then no error message is provided. */ const char *start, /* Start of string enclosed in braces. The * first character must be {'. */ | | | | | > | | 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 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 | int Tcl_ParseBraces( Tcl_Interp *interp, /* Interpreter to use for error reporting; if * NULL, then no error message is provided. */ const char *start, /* Start of string enclosed in braces. The * first character must be {'. */ register size_t numBytes, /* Total number of bytes in string. If * TCL_STRLEN, the string consists of all * bytes up to the first null character. */ register Tcl_Parse *parsePtr, /* Structure to fill in with information about * the string. */ int append, /* Non-zero means append tokens to existing * information in parsePtr; zero means ignore * existing tokens in parsePtr and * reinitialize it. */ const char **termPtr) /* If non-NULL, points to word in which to * store a pointer to the character just after * the terminating '}' if the parse was * successful. */ { Tcl_Token *tokenPtr; register const char *src; int startIndex, level; size_t length; if ((numBytes == 0) || (start == NULL)) { return TCL_ERROR; } if (numBytes == TCL_STRLEN) { numBytes = strlen(start); } if (!append) { TclParseInit(interp, start, numBytes, parsePtr); } |
︙ | ︙ | |||
1752 1753 1754 1755 1756 1757 1758 | * error message in. */ goto error; } Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( | | | 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 | * error message in. */ goto error; } Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( "missing close-brace", TCL_STRLEN)); /* * Guess if the problem is due to comments by searching the source string * for a possible open brace within the context of a comment. Since we * aren't performing a full Tcl parse, just look for an open brace * preceded by a '<whitespace>#' on the same line. */ |
︙ | ︙ | |||
1775 1776 1777 1778 1779 1780 1781 | break; case '\n': openBrace = 0; break; case '#' : if (openBrace && TclIsSpaceProc(src[-1])) { Tcl_AppendToObj(Tcl_GetObjResult(parsePtr->interp), | | > | 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 | break; case '\n': openBrace = 0; break; case '#' : if (openBrace && TclIsSpaceProc(src[-1])) { Tcl_AppendToObj(Tcl_GetObjResult(parsePtr->interp), ": possible unbalanced brace in comment", TCL_STRLEN); goto error; } break; } } } |
︙ | ︙ | |||
1822 1823 1824 1825 1826 1827 1828 | int Tcl_ParseQuotedString( Tcl_Interp *interp, /* Interpreter to use for error reporting; if * NULL, then no error message is provided. */ const char *start, /* Start of the quoted string. The first * character must be '"'. */ | | | | | | | 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 1884 | int Tcl_ParseQuotedString( Tcl_Interp *interp, /* Interpreter to use for error reporting; if * NULL, then no error message is provided. */ const char *start, /* Start of the quoted string. The first * character must be '"'. */ register size_t numBytes, /* Total number of bytes in string. If * TCL_STRLEN, the string consists of all * bytes up to the first null character. */ register Tcl_Parse *parsePtr, /* Structure to fill in with information about * the string. */ int append, /* Non-zero means append tokens to existing * information in parsePtr; zero means ignore * existing tokens in parsePtr and * reinitialize it. */ const char **termPtr) /* If non-NULL, points to word in which to * store a pointer to the character just after * the quoted string's terminating close-quote * if the parse succeeds. */ { if ((numBytes == 0) || (start == NULL)) { return TCL_ERROR; } if (numBytes == TCL_STRLEN) { numBytes = strlen(start); } if (!append) { TclParseInit(interp, start, numBytes, parsePtr); } if (TCL_OK != ParseTokens(start+1, numBytes-1, TYPE_QUOTE, TCL_SUBST_ALL, parsePtr)) { goto error; } if (*parsePtr->term != '"') { if (parsePtr->interp != NULL) { Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( "missing \"", TCL_STRLEN)); } parsePtr->errorType = TCL_PARSE_MISSING_QUOTE; parsePtr->term = start; parsePtr->incomplete = 1; goto error; } if (termPtr != NULL) { |
︙ | ︙ | |||
1904 1905 1906 1907 1908 1909 1910 | *---------------------------------------------------------------------- */ void TclSubstParse( Tcl_Interp *interp, const char *bytes, | | | | 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 | *---------------------------------------------------------------------- */ void TclSubstParse( Tcl_Interp *interp, const char *bytes, size_t numBytes, int flags, Tcl_Parse *parsePtr, Tcl_InterpState *statePtr) { size_t length = numBytes; const char *p = bytes; TclParseInit(interp, p, length, parsePtr); /* * First parse the string rep of objPtr, as if it were enclosed as a * "-quoted word in a normal Tcl command. Honor flags that selectively |
︙ | ︙ | |||
2103 2104 2105 2106 2107 2108 2109 | int TclSubstTokens( Tcl_Interp *interp, /* Interpreter in which to lookup variables, * execute nested commands, and report * errors. */ Tcl_Token *tokenPtr, /* Pointer to first in an array of tokens to * evaluate and concatenate. */ | | | | | 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 | int TclSubstTokens( Tcl_Interp *interp, /* Interpreter in which to lookup variables, * execute nested commands, and report * errors. */ Tcl_Token *tokenPtr, /* Pointer to first in an array of tokens to * evaluate and concatenate. */ size_t count, /* Number of tokens to consider at tokenPtr. * Must be at least 1. */ size_t *tokensLeftPtr, /* If not NULL, points to memory where an * integer representing the number of tokens * left to be substituted will be written */ int line, /* The line the script starts on. */ ssize_t *clNextOuter, /* Information about an outer context for */ const char *outerScript) /* continuation line data. This is set by * EvalEx() to properly handle [...]-nested * commands. The 'outerScript' refers to the * most-outer script containing the embedded * command, which is refered to by 'script'. * The 'clNextOuter' refers to the current * entry in the table of continuation lines in |
︙ | ︙ | |||
2131 2132 2133 2134 2135 2136 2137 | * for the places generating arguments for * which this is true. */ { Tcl_Obj *result; int code = TCL_OK; #define NUM_STATIC_POS 20 int isLiteral, maxNumCL, numCL, i, adjust; | | | 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 | * for the places generating arguments for * which this is true. */ { Tcl_Obj *result; int code = TCL_OK; #define NUM_STATIC_POS 20 int isLiteral, maxNumCL, numCL, i, adjust; ssize_t *clPosition = NULL; Interp *iPtr = (Interp *) interp; int inFile = iPtr->evalFlags & TCL_EVAL_FILE; /* * Each pass through this loop will substitute one token, and its * components, if any. The only thing tricky here is that we go to some * effort to pass Tcl_Obj's through untouched, to avoid string copying and |
︙ | ︙ | |||
2166 2167 2168 2169 2170 2171 2172 | isLiteral = 0; break; } } if (isLiteral) { maxNumCL = NUM_STATIC_POS; | | | 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 | isLiteral = 0; break; } } if (isLiteral) { maxNumCL = NUM_STATIC_POS; clPosition = ckalloc(maxNumCL * sizeof(ssize_t)); } adjust = 0; result = NULL; for (; count>0 && code==TCL_OK ; count--, tokenPtr++) { Tcl_Obj *appendObj = NULL; const char *append = NULL; |
︙ | ︙ | |||
2206 2207 2208 2209 2210 2211 2212 | * everything, just the number of lines we have to add as * correction. */ if ((appendByteLength == 1) && (utfCharBytes[0] == ' ') && (tokenPtr->start[1] == '\n')) { if (isLiteral) { | | | | < | 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 | * everything, just the number of lines we have to add as * correction. */ if ((appendByteLength == 1) && (utfCharBytes[0] == ' ') && (tokenPtr->start[1] == '\n')) { if (isLiteral) { size_t clPos; if (result == 0) { clPos = 0; } else { Tcl_GetStringFromObj(result, &clPos); } if (numCL >= maxNumCL) { maxNumCL *= 2; clPosition = ckrealloc(clPosition, maxNumCL * sizeof(ssize_t)); } clPosition[numCL++] = (ssize_t) clPos; } adjust++; } break; case TCL_TOKEN_COMMAND: { /* TIP #280: Transfer line information to nested command */ |
︙ | ︙ | |||
2486 2487 2488 2489 2490 2491 2492 | */ int TclObjCommandComplete( Tcl_Obj *objPtr) /* Points to object holding script to * check. */ { | | | 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 | */ int TclObjCommandComplete( Tcl_Obj *objPtr) /* Points to object holding script to * check. */ { size_t length; const char *script = Tcl_GetStringFromObj(objPtr, &length); return CommandComplete(script, length); } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
2512 2513 2514 2515 2516 2517 2518 | * *---------------------------------------------------------------------- */ int TclIsLocalScalar( const char *src, | | | 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 | * *---------------------------------------------------------------------- */ int TclIsLocalScalar( const char *src, size_t len) { const char *p; const char *lastChar = src + (len - 1); for (p=src ; p<=lastChar ; p++) { if ((CHAR_TYPE(*p) != TYPE_NORMAL) && (CHAR_TYPE(*p) != TYPE_COMMAND_END)) { |
︙ | ︙ |
Changes to generic/tclPathObj.c.
︙ | ︙ | |||
220 221 222 223 224 225 226 | oldDirSep = dirSep; } again: if (IsSeparatorOrNull(dirSep[2])) { /* * Need to skip '.' in the path. */ | | > | | | | 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 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | oldDirSep = dirSep; } again: if (IsSeparatorOrNull(dirSep[2])) { /* * Need to skip '.' in the path. */ size_t curLen; if (retVal == NULL) { const char *path = TclGetString(pathPtr); retVal = Tcl_NewStringObj(path, dirSep - path); Tcl_IncrRefCount(retVal); } (void) Tcl_GetStringFromObj(retVal, &curLen); if (curLen == 0) { Tcl_AppendToObj(retVal, dirSep, 1); } dirSep += 2; oldDirSep = dirSep; if (dirSep[0] != 0 && dirSep[1] == '.') { goto again; } continue; } if (dirSep[2] == '.' && IsSeparatorOrNull(dirSep[3])) { Tcl_Obj *linkObj; size_t curLen; char *linkStr; /* * Have '..' so need to skip previous directory. */ if (retVal == NULL) { const char *path = TclGetString(pathPtr); retVal = Tcl_NewStringObj(path, dirSep - path); Tcl_IncrRefCount(retVal); } (void) Tcl_GetStringFromObj(retVal, &curLen); if (curLen == 0) { Tcl_AppendToObj(retVal, dirSep, 1); } if (!first || (tclPlatform == TCL_PLATFORM_UNIX)) { linkObj = Tcl_FSLink(retVal, NULL, 0); /* Safety check in case driver caused sharing */ |
︙ | ︙ | |||
399 400 401 402 403 404 405 | } /* * Ensure a windows drive like C:/ has a trailing separator. */ if (tclPlatform == TCL_PLATFORM_WINDOWS) { | | | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 | } /* * Ensure a windows drive like C:/ has a trailing separator. */ if (tclPlatform == TCL_PLATFORM_WINDOWS) { size_t len; const char *path = Tcl_GetStringFromObj(retVal, &len); if (len == 2 && path[0] != 0 && path[1] == ':') { if (Tcl_IsShared(retVal)) { TclDecrRefCount(retVal); retVal = Tcl_DuplicateObj(retVal); Tcl_IncrRefCount(retVal); |
︙ | ︙ | |||
491 492 493 494 495 496 497 | *---------------------------------------------------------------------- */ Tcl_PathType TclFSGetPathType( Tcl_Obj *pathPtr, const Tcl_Filesystem **filesystemPtrPtr, | | | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 | *---------------------------------------------------------------------- */ Tcl_PathType TclFSGetPathType( Tcl_Obj *pathPtr, const Tcl_Filesystem **filesystemPtrPtr, size_t *driveNameLengthPtr) { FsPath *fsPathPtr; if (Tcl_FSConvertToPathType(NULL, pathPtr) != TCL_OK) { return TclGetPathType(pathPtr, filesystemPtrPtr, driveNameLengthPtr, NULL); } |
︙ | ︙ | |||
573 574 575 576 577 578 579 | * Check if the joined-on bit has any directory delimiters in * it. If so, the 'dirname' would be a joining of the main * part with the dirname of the joined-on bit. We could handle * that special case here, but we don't, and instead just use * the standardPath code. */ | | | 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | * Check if the joined-on bit has any directory delimiters in * it. If so, the 'dirname' would be a joining of the main * part with the dirname of the joined-on bit. We could handle * that special case here, but we don't, and instead just use * the standardPath code. */ size_t numBytes; const char *rest = Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &numBytes); if (strchr(rest, '/') != NULL) { goto standardPath; } /* |
︙ | ︙ | |||
611 612 613 614 615 616 617 | /* * Check if the joined-on bit has any directory delimiters in * it. If so, the 'tail' would be only the part following the * last delimiter. We could handle that special case here, but * we don't, and instead just use the standardPath code. */ | | | 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 | /* * Check if the joined-on bit has any directory delimiters in * it. If so, the 'tail' would be only the part following the * last delimiter. We could handle that special case here, but * we don't, and instead just use the standardPath code. */ size_t numBytes; const char *rest = Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &numBytes); if (strchr(rest, '/') != NULL) { goto standardPath; } /* |
︙ | ︙ | |||
640 641 642 643 644 645 646 | Tcl_IncrRefCount(fsPathPtr->normPathPtr); return fsPathPtr->normPathPtr; } case TCL_PATH_EXTENSION: return GetExtension(fsPathPtr->normPathPtr); case TCL_PATH_ROOT: { const char *fileName, *extension; | | | 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 | Tcl_IncrRefCount(fsPathPtr->normPathPtr); return fsPathPtr->normPathPtr; } case TCL_PATH_EXTENSION: return GetExtension(fsPathPtr->normPathPtr); case TCL_PATH_ROOT: { const char *fileName, *extension; size_t length; fileName = Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &length); extension = TclGetExtension(fileName); if (extension == NULL) { /* * There is no extension so the root is the same as the |
︙ | ︙ | |||
683 684 685 686 687 688 689 | /* Relative path */ goto standardPath; } else { /* Absolute path */ goto standardPath; } } else { | | | | | 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 | /* Relative path */ goto standardPath; } else { /* Absolute path */ goto standardPath; } } else { size_t splitElements; Tcl_Obj *splitPtr, *resultPtr; standardPath: resultPtr = NULL; if (portion == TCL_PATH_EXTENSION) { return GetExtension(pathPtr); } else if (portion == TCL_PATH_ROOT) { size_t length; const char *fileName, *extension; fileName = Tcl_GetStringFromObj(pathPtr, &length); extension = TclGetExtension(fileName); if (extension == NULL) { Tcl_IncrRefCount(pathPtr); return pathPtr; } else { Tcl_Obj *root = Tcl_NewStringObj(fileName, length - strlen(extension)); Tcl_IncrRefCount(root); return root; } } /* |
︙ | ︙ | |||
778 779 780 781 782 783 784 | Tcl_Obj *ret; tail = TclGetString(pathPtr); extension = TclGetExtension(tail); if (extension == NULL) { ret = Tcl_NewObj(); } else { | | | 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 | Tcl_Obj *ret; tail = TclGetString(pathPtr); extension = TclGetExtension(tail); if (extension == NULL) { ret = Tcl_NewObj(); } else { ret = Tcl_NewStringObj(extension, TCL_STRLEN); } Tcl_IncrRefCount(ret); return ret; } /* *--------------------------------------------------------------------------- |
︙ | ︙ | |||
825 826 827 828 829 830 831 | Tcl_Obj * Tcl_FSJoinPath( Tcl_Obj *listObj, /* Path elements to join, may have a zero * reference count. */ int elements) /* Number of elements to use (-1 = all) */ { Tcl_Obj *copy, *res; | | | | | | 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 | Tcl_Obj * Tcl_FSJoinPath( Tcl_Obj *listObj, /* Path elements to join, may have a zero * reference count. */ int elements) /* Number of elements to use (-1 = all) */ { Tcl_Obj *copy, *res; size_t objc; Tcl_Obj **objv; if (Tcl_ListObjLength(NULL, listObj, &objc) != TCL_OK) { return NULL; } elements = ((elements >= 0) && (elements <= objc)) ? elements : objc; copy = TclListObjCopy(NULL, listObj); Tcl_ListObjGetElements(NULL, listObj, &objc, &objv); res = TclJoinPath(elements, objv); Tcl_DecrRefCount(copy); return res; } Tcl_Obj * TclJoinPath( size_t elements, Tcl_Obj * const objv[]) { Tcl_Obj *res; size_t i; const Tcl_Filesystem *fsPtr = NULL; res = NULL; for (i = 0; i < elements; i++) { size_t driveNameLength, strEltLen, length; Tcl_PathType type; char *strElt, *ptr; Tcl_Obj *driveName = NULL; Tcl_Obj *elt = objv[i]; /* * This is a special case where we can be much more efficient, where |
︙ | ︙ | |||
875 876 877 878 879 880 881 | && (elt->typePtr == &tclFsPathType) && !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))) { Tcl_Obj *tailObj = objv[i+1]; type = TclGetPathType(tailObj, NULL, NULL, NULL); if (type == TCL_PATH_RELATIVE) { const char *str; | | | 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 | && (elt->typePtr == &tclFsPathType) && !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))) { Tcl_Obj *tailObj = objv[i+1]; type = TclGetPathType(tailObj, NULL, NULL, NULL); if (type == TCL_PATH_RELATIVE) { const char *str; size_t len; str = Tcl_GetStringFromObj(tailObj, &len); if (len == 0) { /* * This happens if we try to handle the root volume '/'. * There's no need to return a special path object, when * the base itself is just fine! |
︙ | ︙ | |||
1073 1074 1075 1076 1077 1078 1079 | res = Tcl_DuplicateObj(res); Tcl_IncrRefCount(res); } } if (length > 0 && ptr[length -1] != '/') { Tcl_AppendToObj(res, &separator, 1); | | | 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 | res = Tcl_DuplicateObj(res); Tcl_IncrRefCount(res); } } if (length > 0 && ptr[length -1] != '/') { Tcl_AppendToObj(res, &separator, 1); (void) Tcl_GetStringFromObj(res, &length); } Tcl_SetObjLength(res, length + (int) strlen(strElt)); ptr = TclGetString(res) + length; for (; *strElt != '\0'; strElt++) { if (*strElt == separator) { while (strElt[1] == separator) { |
︙ | ︙ | |||
1256 1257 1258 1259 1260 1261 1262 | *--------------------------------------------------------------------------- */ Tcl_Obj * TclNewFSPathObj( Tcl_Obj *dirPtr, const char *addStrRep, | | | 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 | *--------------------------------------------------------------------------- */ Tcl_Obj * TclNewFSPathObj( Tcl_Obj *dirPtr, const char *addStrRep, size_t len) { FsPath *fsPathPtr; Tcl_Obj *pathPtr; const char *p; int state = 0, count = 0; /* [Bug 2806250] - this is only a partial solution of the problem. |
︙ | ︙ | |||
1327 1328 1329 1330 1331 1332 1333 | count++; break; case '/': case '\\': case ':': if (count) { PATHFLAGS(pathPtr) |= TCLPATH_NEEDNORM; | | | 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 | count++; break; case '/': case '\\': case ':': if (count) { PATHFLAGS(pathPtr) |= TCLPATH_NEEDNORM; len = 1; } break; default: count = 0; state = 1; } case 1: /* Scanning for next dirsep */ |
︙ | ︙ | |||
1356 1357 1358 1359 1360 1361 1362 | } static Tcl_Obj * AppendPath( Tcl_Obj *head, Tcl_Obj *tail) { | | | 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 | } static Tcl_Obj * AppendPath( Tcl_Obj *head, Tcl_Obj *tail) { size_t numBytes; const char *bytes; Tcl_Obj *copy = Tcl_DuplicateObj(head); /* * This is likely buggy when dealing with virtual filesystem drivers * that use some character other than "/" as a path separator. I know * of no evidence that such a foolish thing exists. This solution was |
︙ | ︙ | |||
1405 1406 1407 1408 1409 1410 1411 | Tcl_Obj * TclFSMakePathRelative( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *pathPtr, /* The path we have. */ Tcl_Obj *cwdPtr) /* Make it relative to this. */ { | | | 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 | Tcl_Obj * TclFSMakePathRelative( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *pathPtr, /* The path we have. */ Tcl_Obj *cwdPtr) /* Make it relative to this. */ { size_t cwdLen, len; const char *tempStr; if (pathPtr->typePtr == &tclFsPathType) { FsPath *fsPathPtr = PATHOBJ(pathPtr); if (PATHFLAGS(pathPtr) != 0 && fsPathPtr->cwdPtr == cwdPtr) { return fsPathPtr->normPathPtr; |
︙ | ︙ | |||
1489 1490 1491 1492 1493 1494 1495 | */ if (pathPtr->typePtr != NULL) { if (pathPtr->bytes == NULL) { if (pathPtr->typePtr->updateStringProc == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 | */ if (pathPtr->typePtr != NULL) { if (pathPtr->bytes == NULL) { if (pathPtr->typePtr->updateStringProc == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't find object string representation", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "WTF", NULL); } return TCL_ERROR; } pathPtr->typePtr->updateStringProc(pathPtr); } |
︙ | ︙ | |||
1710 1711 1712 1713 1714 1715 1716 | Tcl_FSGetTranslatedStringPath( Tcl_Interp *interp, Tcl_Obj *pathPtr) { Tcl_Obj *transPtr = Tcl_FSGetTranslatedPath(interp, pathPtr); if (transPtr != NULL) { | | | | 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 | Tcl_FSGetTranslatedStringPath( Tcl_Interp *interp, Tcl_Obj *pathPtr) { Tcl_Obj *transPtr = Tcl_FSGetTranslatedPath(interp, pathPtr); if (transPtr != NULL) { size_t len; const char *orig = Tcl_GetStringFromObj(transPtr, &len); char *result = ckalloc(len+1); memcpy(result, orig, len+1); TclDecrRefCount(transPtr); return result; } return NULL; } |
︙ | ︙ | |||
1760 1761 1762 1763 1764 1765 1766 | if (PATHFLAGS(pathPtr) != 0) { /* * This is a special path object which is the result of something like * 'file join' */ Tcl_Obj *dir, *copy; | | > | | 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 | if (PATHFLAGS(pathPtr) != 0) { /* * This is a special path object which is the result of something like * 'file join' */ Tcl_Obj *dir, *copy; size_t tailLen, cwdLen; int pathType; pathType = Tcl_FSGetPathType(fsPathPtr->cwdPtr); dir = Tcl_FSGetNormalizedPath(interp, fsPathPtr->cwdPtr); if (dir == NULL) { return NULL; } /* TODO: Figure out why this is needed. */ if (pathPtr->bytes == NULL) { UpdateStringOfFsPath(pathPtr); } (void) Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &tailLen); if (tailLen) { copy = AppendPath(dir, fsPathPtr->normPathPtr); } else { copy = Tcl_DuplicateObj(dir); } Tcl_IncrRefCount(dir); Tcl_IncrRefCount(copy); |
︙ | ︙ | |||
1874 1875 1876 1877 1878 1879 1880 | } FreeFsPathInternalRep(pathPtr); if (SetFsPathFromAny(interp, pathPtr) != TCL_OK) { return NULL; } fsPathPtr = PATHOBJ(pathPtr); } else if (fsPathPtr->normPathPtr == NULL) { | | | 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 | } FreeFsPathInternalRep(pathPtr); if (SetFsPathFromAny(interp, pathPtr) != TCL_OK) { return NULL; } fsPathPtr = PATHOBJ(pathPtr); } else if (fsPathPtr->normPathPtr == NULL) { size_t cwdLen; Tcl_Obj *copy; copy = AppendPath(fsPathPtr->cwdPtr, pathPtr); (void) Tcl_GetStringFromObj(fsPathPtr->cwdPtr, &cwdLen); cwdLen += (Tcl_GetString(copy)[cwdLen] == '/'); |
︙ | ︙ | |||
1982 1983 1984 1985 1986 1987 1988 | /* * Check if path is pure normalized (this can only be the case if it * is an absolute path). */ if (pureNormalized) { | | | 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 | /* * Check if path is pure normalized (this can only be the case if it * is an absolute path). */ if (pureNormalized) { size_t normPathLen, pathLen; const char *normPath; path = TclGetStringFromObj(pathPtr, &pathLen); normPath = TclGetStringFromObj(fsPathPtr->normPathPtr, &normPathLen); if ((pathLen == normPathLen) && !memcmp(path, normPath, pathLen)) { /* * The path was already normalized. Get rid of the duplicate. |
︙ | ︙ | |||
2247 2248 2249 2250 2251 2252 2253 | int Tcl_FSEqualPaths( Tcl_Obj *firstPtr, Tcl_Obj *secondPtr) { const char *firstStr, *secondStr; | | > | 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 | int Tcl_FSEqualPaths( Tcl_Obj *firstPtr, Tcl_Obj *secondPtr) { const char *firstStr, *secondStr; size_t firstLen, secondLen; int tempErrno; if (firstPtr == secondPtr) { return 1; } if (firstPtr == NULL || secondPtr == NULL) { return 0; |
︙ | ︙ | |||
2306 2307 2308 2309 2310 2311 2312 | */ static int SetFsPathFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *pathPtr) /* The object to convert. */ { | | | 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 | */ static int SetFsPathFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *pathPtr) /* The object to convert. */ { size_t len; FsPath *fsPathPtr; Tcl_Obj *transPtr; char *name; if (pathPtr->typePtr == &tclFsPathType) { return TCL_OK; } |
︙ | ︙ | |||
2370 2371 2372 2373 2374 2375 2376 | } dir = TclGetEnv("HOME", &dirString); if (dir == NULL) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "couldn't find HOME environment variable to" | | | 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 | } dir = TclGetEnv("HOME", &dirString); if (dir == NULL) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "couldn't find HOME environment variable to" " expand path", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "HOMELESS", NULL); } return TCL_ERROR; } Tcl_DStringInit(&temp); Tcl_JoinPath(1, &dir, &temp); |
︙ | ︙ | |||
2417 2418 2419 2420 2421 2422 2423 | if (name[split+1] == separator) { /* * Somewhat tricky case like ~//foo/bar. Make use of * Split/Join machinery to get it right. Assumes all paths * beginning with ~ are part of the native filesystem. */ | | | 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 | if (name[split+1] == separator) { /* * Somewhat tricky case like ~//foo/bar. Make use of * Split/Join machinery to get it right. Assumes all paths * beginning with ~ are part of the native filesystem. */ size_t objc; Tcl_Obj **objv; Tcl_Obj *parts = TclpNativeSplitPath(pathPtr, NULL); Tcl_ListObjGetElements(NULL, parts, &objc, &objv); /* * Skip '~'. It's replaced by its expansion. |
︙ | ︙ | |||
2440 2441 2442 2443 2444 2445 2446 | /* * Simple case. "rest" is relative path. Just join it. The * "rest" object will be freed when Tcl_FSJoinToPath returns * (unless something else claims a refCount on it). */ Tcl_Obj *joined; | | | 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 | /* * Simple case. "rest" is relative path. Just join it. The * "rest" object will be freed when Tcl_FSJoinToPath returns * (unless something else claims a refCount on it). */ Tcl_Obj *joined; Tcl_Obj *rest = Tcl_NewStringObj(name+split+1, TCL_STRLEN); Tcl_IncrRefCount(transPtr); joined = Tcl_FSJoinToPath(transPtr, 1, &rest); TclDecrRefCount(transPtr); transPtr = joined; } } |
︙ | ︙ | |||
2595 2596 2597 2598 2599 2600 2601 | */ static void UpdateStringOfFsPath( register Tcl_Obj *pathPtr) /* path obj with string rep to update. */ { FsPath *fsPathPtr = PATHOBJ(pathPtr); | | | 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 | */ static void UpdateStringOfFsPath( register Tcl_Obj *pathPtr) /* path obj with string rep to update. */ { FsPath *fsPathPtr = PATHOBJ(pathPtr); size_t cwdLen; Tcl_Obj *copy; if (PATHFLAGS(pathPtr) == 0 || fsPathPtr->cwdPtr == NULL) { Tcl_Panic("Called UpdateStringOfFsPath with invalid object"); } copy = AppendPath(fsPathPtr->cwdPtr, fsPathPtr->normPathPtr); |
︙ | ︙ | |||
2663 2664 2665 2666 2667 2668 2669 | } else { /* * It is somewhat unusual to reach this code path without the object * being of tclFsPathType. However, we do our best to deal with the * situation. */ | | | 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 | } else { /* * It is somewhat unusual to reach this code path without the object * being of tclFsPathType. However, we do our best to deal with the * situation. */ size_t len; (void) Tcl_GetStringFromObj(pathPtr, &len); if (len == 0) { /* * We reject the empty path "". */ |
︙ | ︙ |
Changes to generic/tclPipe.c.
︙ | ︙ | |||
30 31 32 33 34 35 36 | /* * Declarations for local functions defined in this file: */ static TclFile FileForRedirect(Tcl_Interp *interp, const char *spec, int atOk, const char *arg, const char *nextArg, | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /* * Declarations for local functions defined in this file: */ static TclFile FileForRedirect(Tcl_Interp *interp, const char *spec, int atOk, const char *arg, const char *nextArg, int flags, size_t *skipPtr, int *closePtr, int *releasePtr); /* *---------------------------------------------------------------------- * * FileForRedirect -- * |
︙ | ︙ | |||
69 70 71 72 73 74 75 | const char *arg, /* Pointer to entire argument containing spec: * used for error reporting. */ const char *nextArg, /* Next argument in argc/argv array, if needed * for file name or channel name. May be * NULL. */ int flags, /* Flags to use for opening file or to specify * mode for channel. */ | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | const char *arg, /* Pointer to entire argument containing spec: * used for error reporting. */ const char *nextArg, /* Next argument in argc/argv array, if needed * for file name or channel name. May be * NULL. */ int flags, /* Flags to use for opening file or to specify * mode for channel. */ size_t *skipPtr, /* Filled with 1 if redirection target was in * spec, 2 if it was in nextArg. */ int *closePtr, /* Filled with one if the caller should close * the file when done with it, zero * otherwise. */ int *releasePtr) { int writing = (flags & O_WRONLY); |
︙ | ︙ | |||
343 344 345 346 347 348 349 | p = Tcl_SignalMsg(WSTOPSIG(waitStatus)); Tcl_SetErrorCode(interp, "CHILDSUSP", msg1, Tcl_SignalId(WSTOPSIG(waitStatus)), p, NULL); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "child suspended: %s\n", p)); } else { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | p = Tcl_SignalMsg(WSTOPSIG(waitStatus)); Tcl_SetErrorCode(interp, "CHILDSUSP", msg1, Tcl_SignalId(WSTOPSIG(waitStatus)), p, NULL); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "child suspended: %s\n", p)); } else { Tcl_SetObjResult(interp, Tcl_NewStringObj( "child wait status didn't make sense\n", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "ODDWAITRESULT", msg1, NULL); } } } } |
︙ | ︙ | |||
368 369 370 371 372 373 374 | if (interp != NULL) { int count; Tcl_Obj *objPtr; Tcl_Seek(errorChan, (Tcl_WideInt)0, SEEK_SET); objPtr = Tcl_NewObj(); | | | 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 | if (interp != NULL) { int count; Tcl_Obj *objPtr; Tcl_Seek(errorChan, (Tcl_WideInt)0, SEEK_SET); objPtr = Tcl_NewObj(); count = Tcl_ReadChars(errorChan, objPtr, TCL_STRLEN, 0); if (count < 0) { result = TCL_ERROR; Tcl_DecrRefCount(objPtr); Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error reading stderr output file: %s", Tcl_PosixError(interp))); |
︙ | ︙ | |||
394 395 396 397 398 399 400 | /* * If a child exited abnormally but didn't output any error information at * all, generate an error message here. */ if ((abnormalExit != 0) && (anyErrorInfo == 0) && (interp != NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | /* * If a child exited abnormally but didn't output any error information at * all, generate an error message here. */ if ((abnormalExit != 0) && (anyErrorInfo == 0) && (interp != NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "child process exited abnormally", TCL_STRLEN)); } return result; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
431 432 433 434 435 436 437 | * *---------------------------------------------------------------------- */ int TclCreatePipeline( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ | | | 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | * *---------------------------------------------------------------------- */ int TclCreatePipeline( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ size_t argc, /* Number of entries in argv. */ const char **argv, /* Array of strings describing commands in * pipeline plus I/O redirection with <, <<, * >, etc. Argv[argc] must be NULL. */ Tcl_Pid **pidArrayPtr, /* Word at *pidArrayPtr gets filled in with * address of array of pids for processes in * pipeline (first pid is first process in * pipeline). */ |
︙ | ︙ | |||
466 467 468 469 470 471 472 | * redirection then the file will still be * created but it will never get any data. */ { Tcl_Pid *pidPtr = NULL; /* Points to malloc-ed array holding all the * pids of child processes. */ int numPids; /* Actual number of processes that exist at * *pidPtr right now. */ | | | 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | * redirection then the file will still be * created but it will never get any data. */ { Tcl_Pid *pidPtr = NULL; /* Points to malloc-ed array holding all the * pids of child processes. */ int numPids; /* Actual number of processes that exist at * *pidPtr right now. */ size_t cmdCount; /* Count of number of distinct commands found * in argc/argv. */ const char *inputLiteral = NULL; /* If non-null, then this points to a string * containing input data (specified via <<) to * be piped to the first process in the * pipeline. */ TclFile inputFile = NULL; /* If != NULL, gives file to use as input for |
︙ | ︙ | |||
493 494 495 496 497 498 499 | * commands in pipeline. NULL means use * stderr. */ int errorClose = 0; /* If non-zero, then errorFile should be * closed when cleaning up. */ int errorRelease = 0; const char *p; const char *nextArg; | | > | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | * commands in pipeline. NULL means use * stderr. */ int errorClose = 0; /* If non-zero, then errorFile should be * closed when cleaning up. */ int errorRelease = 0; const char *p; const char *nextArg; int lastBar, lastArg, atOK, flags, needCmd, errorToOutput = 0; Tcl_DString execBuffer; TclFile pipeIn; TclFile curInFile, curOutFile, curErrFile; Tcl_Channel channel; size_t i, j, skip; if (inPipePtr != NULL) { *inPipePtr = NULL; } if (outPipePtr != NULL) { *outPipePtr = NULL; } |
︙ | ︙ | |||
544 545 546 547 548 549 550 | case '|': if (*p == '&') { p++; } if (*p == '\0') { if ((i == (lastBar + 1)) || (i == (argc - 1))) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | case '|': if (*p == '&') { p++; } if (*p == '\0') { if ((i == (lastBar + 1)) || (i == (argc - 1))) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal use of | or |& in command", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "PIPESYNTAX", NULL); goto error; } } lastBar = i; cmdCount++; |
︙ | ︙ | |||
726 727 728 729 730 731 732 | if (needCmd) { /* * We had a bar followed only by redirections. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 | if (needCmd) { /* * We had a bar followed only by redirections. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal use of | or |& in command", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "PIPESYNTAX", NULL); goto error; } if (inputFile == NULL) { if (inputLiteral != NULL) { |
︙ | ︙ | |||
1046 1047 1048 1049 1050 1051 1052 | *---------------------------------------------------------------------- */ Tcl_Channel Tcl_OpenCommandChannel( Tcl_Interp *interp, /* Interpreter for error reporting. Can NOT be * NULL. */ | | | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 | *---------------------------------------------------------------------- */ Tcl_Channel Tcl_OpenCommandChannel( Tcl_Interp *interp, /* Interpreter for error reporting. Can NOT be * NULL. */ size_t argc, /* How many arguments. */ const char **argv, /* Array of arguments for command pipe. */ int flags) /* Or'ed combination of TCL_STDIN, TCL_STDOUT, * TCL_STDERR, and TCL_ENFORCE_MODE. */ { TclFile *inPipePtr, *outPipePtr, *errFilePtr; TclFile inPipe, outPipe, errFile; int numPids; |
︙ | ︙ | |||
1079 1080 1081 1082 1083 1084 1085 | * constraints. */ if (flags & TCL_ENFORCE_MODE) { if ((flags & TCL_STDOUT) && (outPipe == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't read output from command:" | | | | | 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 | * constraints. */ if (flags & TCL_ENFORCE_MODE) { if ((flags & TCL_STDOUT) && (outPipe == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't read output from command:" " standard output was redirected", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "BADREDIRECT", NULL); goto error; } if ((flags & TCL_STDIN) && (inPipe == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't write input to command:" " standard input was redirected", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "BADREDIRECT", NULL); goto error; } } channel = TclpCreateCommandChannel(outPipe, inPipe, errFile, numPids, pidPtr); if (channel == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "pipe for command could not be created", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "NOPIPE", NULL); goto error; } return channel; error: if (numPids > 0) { |
︙ | ︙ |
Changes to generic/tclPkg.c.
︙ | ︙ | |||
55 56 57 58 59 60 61 | static int CheckVersionAndConvert(Tcl_Interp *interp, const char *string, char **internal, int *stable); static int CompareVersions(char *v1i, char *v2i, int *isMajorPtr); static int CheckRequirement(Tcl_Interp *interp, const char *string); | | | | | | | | | 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 | static int CheckVersionAndConvert(Tcl_Interp *interp, const char *string, char **internal, int *stable); static int CompareVersions(char *v1i, char *v2i, int *isMajorPtr); static int CheckRequirement(Tcl_Interp *interp, const char *string); static int CheckAllRequirements(Tcl_Interp *interp, size_t reqc, Tcl_Obj *const reqv[]); static int RequirementSatisfied(char *havei, const char *req); static int SomeRequirementSatisfied(char *havei, size_t reqc, Tcl_Obj *const reqv[]); static void AddRequirementsToResult(Tcl_Interp *interp, size_t reqc, Tcl_Obj *const reqv[]); static void AddRequirementsToDString(Tcl_DString *dstring, size_t reqc, Tcl_Obj *const reqv[]); static Package * FindPackage(Tcl_Interp *interp, const char *name); static const char * PkgRequireCore(Tcl_Interp *interp, const char *name, size_t reqc, Tcl_Obj *const reqv[], void *clientDataPtr); /* * Helper macros. */ #define DupBlock(v,s,len) \ ((v) = ckalloc(len), memcpy((v),(s),(len))) #define DupString(v,s) \ do { \ size_t local__len = (strlen(s) + 1); \ DupBlock((v),(s),local__len); \ } while (0) /* *---------------------------------------------------------------------- * * Tcl_PkgProvideEx -- |
︙ | ︙ | |||
275 276 277 278 279 280 281 | if (version == NULL) { result = PkgRequireCore(interp, name, 0, NULL, clientDataPtr); } else { if (exact && TCL_OK != CheckVersionAndConvert(interp, version, NULL, NULL)) { return NULL; } | | | | | | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | if (version == NULL) { result = PkgRequireCore(interp, name, 0, NULL, clientDataPtr); } else { if (exact && TCL_OK != CheckVersionAndConvert(interp, version, NULL, NULL)) { return NULL; } ov = Tcl_NewStringObj(version, TCL_STRLEN); if (exact) { Tcl_AppendStringsToObj(ov, "-", version, NULL); } Tcl_IncrRefCount(ov); result = PkgRequireCore(interp, name, 1, &ov, clientDataPtr); TclDecrRefCount(ov); } return result; } int Tcl_PkgRequireProc( Tcl_Interp *interp, /* Interpreter in which package is now * available. */ const char *name, /* Name of desired package. */ size_t reqc, /* Requirements constraining the desired * version. */ Tcl_Obj *const reqv[], /* 0 means to use the latest version * available. */ void *clientDataPtr) { const char *result = PkgRequireCore(interp, name, reqc, reqv, clientDataPtr); if (result == NULL) { return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewStringObj(result, TCL_STRLEN)); return TCL_OK; } static const char * PkgRequireCore( Tcl_Interp *interp, /* Interpreter in which package is now * available. */ const char *name, /* Name of desired package. */ size_t reqc, /* Requirements constraining the desired * version. */ Tcl_Obj *const reqv[], /* 0 means to use the latest version * available. */ void *clientDataPtr) { Interp *iPtr = (Interp *) interp; Package *pkgPtr; |
︙ | ︙ | |||
464 465 466 467 468 469 470 | char *versionToProvide = bestPtr->version; script = bestPtr->script; pkgPtr->clientData = versionToProvide; Tcl_Preserve(script); Tcl_Preserve(versionToProvide); | | | 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | char *versionToProvide = bestPtr->version; script = bestPtr->script; pkgPtr->clientData = versionToProvide; Tcl_Preserve(script); Tcl_Preserve(versionToProvide); code = Tcl_EvalEx(interp, script, TCL_STRLEN, TCL_EVAL_GLOBAL); Tcl_Release(script); pkgPtr = FindPackage(interp, name); if (code == TCL_OK) { Tcl_ResetResult(interp); if (pkgPtr->version == NULL) { code = TCL_ERROR; |
︙ | ︙ | |||
560 561 562 563 564 565 566 | if (pass > 1) { break; } script = ((Interp *) interp)->packageUnknown; if (script != NULL) { Tcl_DStringInit(&command); | | | 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 | if (pass > 1) { break; } script = ((Interp *) interp)->packageUnknown; if (script != NULL) { Tcl_DStringInit(&command); Tcl_DStringAppend(&command, script, TCL_STRLEN); Tcl_DStringAppendElement(&command, name); AddRequirementsToDString(&command, reqc, reqv); code = Tcl_EvalEx(interp, Tcl_DStringValue(&command), Tcl_DStringLength(&command), TCL_EVAL_GLOBAL); Tcl_DStringFree(&command); |
︙ | ︙ | |||
710 711 712 713 714 715 716 717 718 719 720 721 | * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_PackageObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | > > | | > | 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 | * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ // TODO - Turn into an ensemble... /* ARGSUSED */ int Tcl_PackageObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *const pkgOptions[] = { "forget", "ifneeded", "names", "prefer", "present", "provide", "require", "unknown", "vcompare", "versions", "vsatisfies", NULL }; enum pkgOptions { PKG_FORGET, PKG_IFNEEDED, PKG_NAMES, PKG_PREFER, PKG_PRESENT, PKG_PROVIDE, PKG_REQUIRE, PKG_UNKNOWN, PKG_VCOMPARE, PKG_VERSIONS, PKG_VSATISFIES }; Interp *iPtr = (Interp *) interp; int optionIndex, exact, satisfies; PkgAvail *availPtr, *prevPtr; Package *pkgPtr; Tcl_HashEntry *hPtr; Tcl_HashSearch search; Tcl_HashTable *tablePtr; const char *version; const char *argv2, *argv3, *argv4; char *iva = NULL, *ivb = NULL; size_t i; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], pkgOptions, "option", 0, |
︙ | ︙ | |||
775 776 777 778 779 780 781 | ckfree(availPtr); } ckfree(pkgPtr); } break; } case PKG_IFNEEDED: { | | > | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 | ckfree(availPtr); } ckfree(pkgPtr); } break; } case PKG_IFNEEDED: { size_t length; int res; char *argv3i, *avi; if ((objc != 4) && (objc != 5)) { Tcl_WrongNumArgs(interp, 2, objv, "package version ?script?"); return TCL_ERROR; } argv3 = TclGetString(objv[3]); |
︙ | ︙ | |||
814 815 816 817 818 819 820 | res = CompareVersions(avi, argv3i, NULL); ckfree(avi); if (res == 0){ if (objc == 4) { ckfree(argv3i); Tcl_SetObjResult(interp, | | | 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 | res = CompareVersions(avi, argv3i, NULL); ckfree(avi); if (res == 0){ if (objc == 4) { ckfree(argv3i); Tcl_SetObjResult(interp, Tcl_NewStringObj(availPtr->script, TCL_STRLEN)); return TCL_OK; } Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC); break; } } ckfree(argv3i); |
︙ | ︙ | |||
856 857 858 859 860 861 862 | resultObj = Tcl_NewObj(); tablePtr = &iPtr->packageTable; for (hPtr = Tcl_FirstHashEntry(tablePtr, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { pkgPtr = Tcl_GetHashValue(hPtr); if ((pkgPtr->version != NULL) || (pkgPtr->availPtr != NULL)) { Tcl_ListObjAppendElement(NULL,resultObj, Tcl_NewStringObj( | | | 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 | resultObj = Tcl_NewObj(); tablePtr = &iPtr->packageTable; for (hPtr = Tcl_FirstHashEntry(tablePtr, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { pkgPtr = Tcl_GetHashValue(hPtr); if ((pkgPtr->version != NULL) || (pkgPtr->availPtr != NULL)) { Tcl_ListObjAppendElement(NULL,resultObj, Tcl_NewStringObj( Tcl_GetHashKey(tablePtr, hPtr), TCL_STRLEN)); } } Tcl_SetObjResult(interp, resultObj); } break; case PKG_PRESENT: { const char *name; |
︙ | ︙ | |||
920 921 922 923 924 925 926 | argv2 = TclGetString(objv[2]); if (objc == 3) { hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2); if (hPtr != NULL) { pkgPtr = Tcl_GetHashValue(hPtr); if (pkgPtr->version != NULL) { Tcl_SetObjResult(interp, | | | 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 | argv2 = TclGetString(objv[2]); if (objc == 3) { hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2); if (hPtr != NULL) { pkgPtr = Tcl_GetHashValue(hPtr); if (pkgPtr->version != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(pkgPtr->version, TCL_STRLEN)); } } return TCL_OK; } argv3 = TclGetString(objv[3]); if (CheckVersionAndConvert(interp, argv3, NULL, NULL) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
960 961 962 963 964 965 966 | return TCL_ERROR; } /* * Create a new-style requirement for the exact version. */ | | | | | 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 990 991 992 993 994 995 996 997 998 999 1000 1001 | return TCL_ERROR; } /* * Create a new-style requirement for the exact version. */ ov = Tcl_NewStringObj(version, TCL_STRLEN); Tcl_AppendStringsToObj(ov, "-", version, NULL); version = NULL; argv3 = TclGetString(objv[3]); Tcl_IncrRefCount(ov); res = Tcl_PkgRequireProc(interp, argv3, 1, &ov, NULL); TclDecrRefCount(ov); return res; } else { if (CheckAllRequirements(interp, objc-3, objv+3) != TCL_OK) { return TCL_ERROR; } return Tcl_PkgRequireProc(interp, argv2, objc-3, objv+3, NULL); } break; case PKG_UNKNOWN: { size_t length; if (objc == 2) { if (iPtr->packageUnknown != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(iPtr->packageUnknown, TCL_STRLEN)); } } else if (objc == 3) { if (iPtr->packageUnknown != NULL) { ckfree(iPtr->packageUnknown); } argv2 = Tcl_GetStringFromObj(objv[2], &length); if (argv2[0] == 0) { |
︙ | ︙ | |||
1034 1035 1036 1037 1038 1039 1040 | } } /* * Always return current value. */ | | | | 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 | } } /* * Always return current value. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( pkgPreferOptions[iPtr->packagePrefer], TCL_STRLEN)); break; } case PKG_VCOMPARE: if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "version1 version2"); return TCL_ERROR; } |
︙ | ︙ | |||
1081 1082 1083 1084 1085 1086 1087 | argv2 = TclGetString(objv[2]); hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2); if (hPtr != NULL) { pkgPtr = Tcl_GetHashValue(hPtr); for (availPtr = pkgPtr->availPtr; availPtr != NULL; availPtr = availPtr->nextPtr) { Tcl_ListObjAppendElement(NULL, resultObj, | | | 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 | argv2 = TclGetString(objv[2]); hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2); if (hPtr != NULL) { pkgPtr = Tcl_GetHashValue(hPtr); for (availPtr = pkgPtr->availPtr; availPtr != NULL; availPtr = availPtr->nextPtr) { Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(availPtr->version, TCL_STRLEN)); } } Tcl_SetObjResult(interp, resultObj); } break; case PKG_VSATISFIES: { char *argv2i = NULL; |
︙ | ︙ | |||
1522 1523 1524 1525 1526 1527 1528 | * *---------------------------------------------------------------------- */ static int CheckAllRequirements( Tcl_Interp *interp, | | | | 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 | * *---------------------------------------------------------------------- */ static int CheckAllRequirements( Tcl_Interp *interp, size_t reqc, /* Requirements to check. */ Tcl_Obj *const reqv[]) { size_t i; for (i = 0; i < reqc; i++) { if ((CheckRequirement(interp, TclGetString(reqv[i])) != TCL_OK)) { return TCL_ERROR; } } return TCL_OK; |
︙ | ︙ | |||
1628 1629 1630 1631 1632 1633 1634 | * *---------------------------------------------------------------------- */ static void AddRequirementsToResult( Tcl_Interp *interp, | | | | 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 | * *---------------------------------------------------------------------- */ static void AddRequirementsToResult( Tcl_Interp *interp, size_t reqc, /* Requirements constraining the desired * version. */ Tcl_Obj *const reqv[]) /* 0 means to use the latest version * available. */ { Tcl_Obj *result = Tcl_GetObjResult(interp); size_t i, length; for (i = 0; i < reqc; i++) { const char *v = Tcl_GetStringFromObj(reqv[i], &length); if ((length & 0x1) && (v[length/2] == '-') && (strncmp(v, v+((length+1)/2), length/2) == 0)) { Tcl_AppendPrintfToObj(result, " exactly %s", v+((length+1)/2)); |
︙ | ︙ | |||
1667 1668 1669 1670 1671 1672 1673 | * *---------------------------------------------------------------------- */ static void AddRequirementsToDString( Tcl_DString *dsPtr, | | | | 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 | * *---------------------------------------------------------------------- */ static void AddRequirementsToDString( Tcl_DString *dsPtr, size_t reqc, /* Requirements constraining the desired * version. */ Tcl_Obj *const reqv[]) /* 0 means to use the latest version * available. */ { size_t i; if (reqc > 0) { for (i = 0; i < reqc; i++) { TclDStringAppendLiteral(dsPtr, " "); TclDStringAppendObj(dsPtr, reqv[i]); } } else { |
︙ | ︙ | |||
1707 1708 1709 1710 1711 1712 1713 | *---------------------------------------------------------------------- */ static int SomeRequirementSatisfied( char *availVersionI, /* Candidate version to check against the * requirements. */ | | | | 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 | *---------------------------------------------------------------------- */ static int SomeRequirementSatisfied( char *availVersionI, /* Candidate version to check against the * requirements. */ size_t reqc, /* Requirements constraining the desired * version. */ Tcl_Obj *const reqv[]) /* 0 means to use the latest version * available. */ { size_t i; for (i = 0; i < reqc; i++) { if (RequirementSatisfied(availVersionI, TclGetString(reqv[i]))) { return 1; } } return 0; |
︙ | ︙ | |||
1845 1846 1847 1848 1849 1850 1851 | * *---------------------------------------------------------------------- */ const char * Tcl_PkgInitStubsCheck( Tcl_Interp *interp, | | | 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 | * *---------------------------------------------------------------------- */ const char * Tcl_PkgInitStubsCheck( Tcl_Interp *interp, const char *version, int exact) { const char *actualVersion = Tcl_PkgPresentEx(interp, "Tcl", version, 0, NULL); if (exact && actualVersion) { const char *p = version; int count = 0; |
︙ | ︙ |
Changes to generic/tclPlatDecls.h.
︙ | ︙ | |||
33 34 35 36 37 38 39 | /* * Exported function declarations: */ #if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ /* 0 */ | | | | | | | | | | 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | /* * Exported function declarations: */ #if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ /* 0 */ TCLAPI TCHAR * Tcl_WinUtfToTChar(const char *str, size_t len, Tcl_DString *dsPtr); /* 1 */ TCLAPI char * Tcl_WinTCharToUtf(const TCHAR *str, size_t len, Tcl_DString *dsPtr); #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ /* 0 */ TCLAPI int Tcl_MacOSXOpenBundleResources(Tcl_Interp *interp, const char *bundleName, int hasResourceFile, size_t maxPathLen, char *libraryPath); /* 1 */ TCLAPI int Tcl_MacOSXOpenVersionedBundleResources( Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, size_t maxPathLen, char *libraryPath); #endif /* MACOSX */ typedef struct TclPlatStubs { int magic; void *hooks; #if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ TCHAR * (*tcl_WinUtfToTChar) (const char *str, size_t len, Tcl_DString *dsPtr); /* 0 */ char * (*tcl_WinTCharToUtf) (const TCHAR *str, size_t len, Tcl_DString *dsPtr); /* 1 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ int (*tcl_MacOSXOpenBundleResources) (Tcl_Interp *interp, const char *bundleName, int hasResourceFile, size_t maxPathLen, char *libraryPath); /* 0 */ int (*tcl_MacOSXOpenVersionedBundleResources) (Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, size_t maxPathLen, char *libraryPath); /* 1 */ #endif /* MACOSX */ } TclPlatStubs; #ifdef __cplusplus extern "C" { #endif extern const TclPlatStubs *tclPlatStubsPtr; |
︙ | ︙ |
Changes to generic/tclProc.c.
︙ | ︙ | |||
38 39 40 41 42 43 44 | static int InitArgsAndLocals(Tcl_Interp *interp, Tcl_Obj *procNameObj, int skip); static void InitResolvedLocals(Tcl_Interp *interp, ByteCode *codePtr, Var *defPtr, Namespace *nsPtr); static void InitLocalCache(Proc *procPtr); static int PushProcCallFrame(ClientData clientData, | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | static int InitArgsAndLocals(Tcl_Interp *interp, Tcl_Obj *procNameObj, int skip); static void InitResolvedLocals(Tcl_Interp *interp, ByteCode *codePtr, Var *defPtr, Namespace *nsPtr); static void InitLocalCache(Proc *procPtr); static int PushProcCallFrame(ClientData clientData, register Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[], int isLambda); static void ProcBodyDup(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr); static void ProcBodyFree(Tcl_Obj *objPtr); static int ProcWrongNumArgs(Tcl_Interp *interp, int skip); static void MakeProcError(Tcl_Interp *interp, Tcl_Obj *procNameObj); static void MakeLambdaError(Tcl_Interp *interp, |
︙ | ︙ | |||
121 122 123 124 125 126 127 | */ /* ARGSUSED */ int Tcl_ProcObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | */ /* ARGSUSED */ int Tcl_ProcObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { register Interp *iPtr = (Interp *) interp; Proc *procPtr; const char *fullName; const char *procName, *procArgs, *procBody; Namespace *nsPtr, *altNsPtr, *cxtNsPtr; |
︙ | ︙ | |||
191 192 193 194 195 196 197 | * current namespace unless the procedure's name included namespace * qualifiers. To create the new command in the right namespace, we * generate a fully qualified name for it. */ Tcl_DStringInit(&ds); if (nsPtr != iPtr->globalNsPtr) { | | | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | * current namespace unless the procedure's name included namespace * qualifiers. To create the new command in the right namespace, we * generate a fully qualified name for it. */ Tcl_DStringInit(&ds); if (nsPtr != iPtr->globalNsPtr) { Tcl_DStringAppend(&ds, nsPtr->fullName, TCL_STRLEN); TclDStringAppendLiteral(&ds, "::"); } Tcl_DStringAppend(&ds, procName, TCL_STRLEN); cmd = Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds), TclObjInterpProc, TclNRInterpProc, procPtr, TclProcDeleteProc); Tcl_DStringFree(&ds); /* * Now initialize the new procedure's cmdPtr field. This will be used |
︙ | ︙ | |||
331 332 333 334 335 336 337 | procArgs = TclGetString(objv[2]); while (*procArgs == ' ') { procArgs++; } if ((procArgs[0] == 'a') && (strncmp(procArgs, "args", 4) == 0)) { | | | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | procArgs = TclGetString(objv[2]); while (*procArgs == ' ') { procArgs++; } if ((procArgs[0] == 'a') && (strncmp(procArgs, "args", 4) == 0)) { size_t numBytes; procArgs +=4; while (*procArgs != '\0') { if (*procArgs != ' ') { goto done; } procArgs++; |
︙ | ︙ | |||
396 397 398 399 400 401 402 | const char *procName, /* Unqualified name of this proc. */ Tcl_Obj *argsPtr, /* Description of arguments. */ Tcl_Obj *bodyPtr, /* Command body. */ Proc **procPtrPtr) /* Returns: pointer to proc data. */ { Interp *iPtr = (Interp *) interp; const char **argArray = NULL; | < | | | 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 | const char *procName, /* Unqualified name of this proc. */ Tcl_Obj *argsPtr, /* Description of arguments. */ Tcl_Obj *bodyPtr, /* Command body. */ Proc **procPtrPtr) /* Returns: pointer to proc data. */ { Interp *iPtr = (Interp *) interp; const char **argArray = NULL; register Proc *procPtr; size_t i, length, numArgs; const char *args, *bytes, *p; register CompiledLocal *localPtr = NULL; Tcl_Obj *defPtr; int result, precompiled = 0; if (bodyPtr->typePtr == &tclProcBodyType) { /* * Because the body is a TclProProcBody, the actual body is already * compiled, and it is not shared with anyone else, so it's OK not to * unshare it (as a matter of fact, it is bad to unshare it, because * there may be no source code). |
︙ | ︙ | |||
488 489 490 491 492 493 494 | if (result != TCL_OK) { goto procError; } if (precompiled) { if (numArgs > procPtr->numArgs) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( | | | | | 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 | if (result != TCL_OK) { goto procError; } if (precompiled) { if (numArgs > procPtr->numArgs) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "procedure \"%s\": arg list contains %lu entries, " "precompiled header expects %lu", procName, numArgs, procPtr->numArgs)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC", "BYTECODELIES", NULL); goto procError; } localPtr = procPtr->firstLocalPtr; } else { procPtr->numArgs = numArgs; procPtr->numCompiledLocals = numArgs; } for (i = 0; i < numArgs; i++) { size_t fieldCount, nameLength, valueLength; const char **fieldValues; /* * Now divide the specifier up into name and default. */ result = Tcl_SplitList(interp, argArray[i], &fieldCount, |
︙ | ︙ | |||
526 527 528 529 530 531 532 | Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC", "FORMALARGUMENTFORMAT", NULL); goto procError; } if ((fieldCount == 0) || (*fieldValues[0] == 0)) { ckfree(fieldValues); Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 | Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC", "FORMALARGUMENTFORMAT", NULL); goto procError; } if ((fieldCount == 0) || (*fieldValues[0] == 0)) { ckfree(fieldValues); Tcl_SetObjResult(interp, Tcl_NewStringObj( "argument with no name", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC", "FORMALARGUMENTFORMAT", NULL); goto procError; } nameLength = strlen(fieldValues[0]); if (fieldCount == 2) { |
︙ | ︙ | |||
591 592 593 594 595 596 597 | if ((localPtr->nameLength != nameLength) || (strcmp(localPtr->name, fieldValues[0])) || (localPtr->frameIndex != i) || !(localPtr->flags & VAR_ARGUMENT) || (localPtr->defValuePtr == NULL && fieldCount == 2) || (localPtr->defValuePtr != NULL && fieldCount != 2)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( | | | | 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 | if ((localPtr->nameLength != nameLength) || (strcmp(localPtr->name, fieldValues[0])) || (localPtr->frameIndex != i) || !(localPtr->flags & VAR_ARGUMENT) || (localPtr->defValuePtr == NULL && fieldCount == 2) || (localPtr->defValuePtr != NULL && fieldCount != 2)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "procedure \"%s\": formal parameter %lu is " "inconsistent with precompiled body", procName, i)); ckfree(fieldValues); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC", "BYTECODELIES", NULL); goto procError; } /* * Compare the default value if any. */ if (localPtr->defValuePtr != NULL) { size_t tmpLength; const char *tmpPtr = TclGetStringFromObj(localPtr->defValuePtr, &tmpLength); if ((valueLength != tmpLength) || strncmp(fieldValues[1], tmpPtr, (size_t) tmpLength)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "procedure \"%s\": formal parameter \"%s\" has " |
︙ | ︙ | |||
948 949 950 951 952 953 954 | } /* ARGSUSED */ int Tcl_UplevelObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 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 | } /* ARGSUSED */ int Tcl_UplevelObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRUplevelObjCmd, dummy, objc, objv); } int TclNRUplevelObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { register Interp *iPtr = (Interp *) interp; CmdFrame *invoker = NULL; int word = 0; int result; |
︙ | ︙ | |||
1104 1105 1106 1107 1108 1109 1110 | ProcWrongNumArgs( Tcl_Interp *interp, int skip) { CallFrame *framePtr = ((Interp *)interp)->varFramePtr; register Proc *procPtr = framePtr->procPtr; register Var *defPtr; | | > | | 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 | ProcWrongNumArgs( Tcl_Interp *interp, int skip) { CallFrame *framePtr = ((Interp *)interp)->varFramePtr; register Proc *procPtr = framePtr->procPtr; register Var *defPtr; int localCt = procPtr->numCompiledLocals; size_t numArgs, i; Tcl_Obj **desiredObjs; const char *final = NULL; /* * Build up desired argument list for Tcl_WrongNumArgs */ numArgs = framePtr->procPtr->numArgs; desiredObjs = TclStackAlloc(interp, (int) sizeof(Tcl_Obj *) * (numArgs+1)); if (framePtr->isProcCallFrame & FRAME_IS_LAMBDA) { desiredObjs[0] = Tcl_NewStringObj("lambdaExpr", TCL_STRLEN); } else { ((Interp *) interp)->ensembleRewrite.numInsertedObjs -= skip - 1; #ifdef AVOID_HACKS_FOR_ITCL desiredObjs[0] = framePtr->objv[skip-1]; #else desiredObjs[0] = Tcl_NewListObj(skip, framePtr->objv); |
︙ | ︙ | |||
1518 1519 1520 1521 1522 1523 1524 | /* * When we get here, the last formal argument remains to be defined: * defPtr and varPtr point to the last argument to be initialized. */ varPtr->flags = 0; if (defPtr && defPtr->flags & VAR_IS_ARGS) { | > > > > > > > > > > > | | | 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 | /* * When we get here, the last formal argument remains to be defined: * defPtr and varPtr point to the last argument to be initialized. */ varPtr->flags = 0; if (defPtr && defPtr->flags & VAR_IS_ARGS) { Tcl_Obj *listPtr; /* * Note that we can get the number of actual arguments (argCt) less * than the current formal argument index (i) if there is a defaulted * argument before 'args' that uses the default. */ if (argCt <= i) { TclNewObj(listPtr); } else { listPtr = Tcl_NewListObj(argCt-i, argObjs+i); } varPtr->value.objPtr = listPtr; Tcl_IncrRefCount(listPtr); /* Local var is a reference. */ } else if (argCt == numArgs) { Tcl_Obj *objPtr = argObjs[i]; varPtr->value.objPtr = objPtr; Tcl_IncrRefCount(objPtr); /* Local var is a reference. */ |
︙ | ︙ | |||
1588 1589 1590 1591 1592 1593 1594 | static int PushProcCallFrame( ClientData clientData, /* Record describing procedure to be * interpreted. */ register Tcl_Interp *interp,/* Interpreter in which procedure was * invoked. */ | | | 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 | static int PushProcCallFrame( ClientData clientData, /* Record describing procedure to be * interpreted. */ register Tcl_Interp *interp,/* Interpreter in which procedure was * invoked. */ size_t objc, /* Count of number of arguments to this * procedure. */ Tcl_Obj *const objv[], /* Argument value objects. */ int isLambda) /* 1 if this is a call by ApplyObjCmd: it * needs special rules for error msg */ { Proc *procPtr = clientData; Namespace *nsPtr = procPtr->cmdPtr->nsPtr; |
︙ | ︙ | |||
1683 1684 1685 1686 1687 1688 1689 | int TclObjInterpProc( ClientData clientData, /* Record describing procedure to be * interpreted. */ register Tcl_Interp *interp,/* Interpreter in which procedure was * invoked. */ | | | | 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 | int TclObjInterpProc( ClientData clientData, /* Record describing procedure to be * interpreted. */ register Tcl_Interp *interp,/* Interpreter in which procedure was * invoked. */ size_t objc, /* Count of number of arguments to this * procedure. */ Tcl_Obj *const objv[]) /* Argument value objects. */ { /* * Not used much in the core; external interface for iTcl */ return Tcl_NRCallObjProc(interp, TclNRInterpProc, clientData, objc, objv); } int TclNRInterpProc( ClientData clientData, /* Record describing procedure to be * interpreted. */ register Tcl_Interp *interp,/* Interpreter in which procedure was * invoked. */ size_t objc, /* Count of number of arguments to this * procedure. */ Tcl_Obj *const objv[]) /* Argument value objects. */ { int result = PushProcCallFrame(clientData, interp, objc, objv, /*isLambda*/ 0); if (result != TCL_OK) { |
︙ | ︙ | |||
1990 1991 1992 1993 1994 1995 1996 | && (codePtr->nsEpoch == nsPtr->resolverEpoch)) { return TCL_OK; } if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) { if ((Interp *) *codePtr->interpHandle != iPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 | && (codePtr->nsEpoch == nsPtr->resolverEpoch)) { return TCL_OK; } if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) { if ((Interp *) *codePtr->interpHandle != iPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "a precompiled script jumped interps", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC", "CROSSINTERPBYTECODE", NULL); return TCL_ERROR; } codePtr->compileEpoch = iPtr->compileEpoch; codePtr->nsPtr = nsPtr; } else { |
︙ | ︙ | |||
2017 2018 2019 2020 2021 2022 2023 | */ Tcl_Obj *message; TclNewLiteralStringObj(message, "Compiling "); Tcl_IncrRefCount(message); Tcl_AppendStringsToObj(message, description, " \"", NULL); | | | 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 | */ Tcl_Obj *message; TclNewLiteralStringObj(message, "Compiling "); Tcl_IncrRefCount(message); Tcl_AppendStringsToObj(message, description, " \"", NULL); Tcl_AppendLimitedToObj(message, procName, TCL_STRLEN, 50, NULL); fprintf(stdout, "%s\"\n", TclGetString(message)); Tcl_DecrRefCount(message); } #endif /* * Plug the current procPtr into the interpreter and coerce the code |
︙ | ︙ | |||
2123 2124 2125 2126 2127 2128 2129 | static void MakeProcError( Tcl_Interp *interp, /* The interpreter in which the procedure was * called. */ Tcl_Obj *procNameObj) /* Name of the procedure. Used for error * messages and trace information. */ { | | > | | 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 | static void MakeProcError( Tcl_Interp *interp, /* The interpreter in which the procedure was * called. */ Tcl_Obj *procNameObj) /* Name of the procedure. Used for error * messages and trace information. */ { int overflow, limit = 60; size_t nameLen; const char *procName = Tcl_GetStringFromObj(procNameObj, &nameLen); overflow = (nameLen > limit); Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (procedure \"%.*s%s\" line %d)", (overflow ? limit : (int) nameLen), procName, (overflow ? "..." : ""), Tcl_GetErrorLine(interp))); } /* *---------------------------------------------------------------------- * * TclProcDeleteProc -- |
︙ | ︙ | |||
2474 2475 2476 2477 2478 2479 2480 | SetLambdaFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ register Tcl_Obj *objPtr) /* The object to convert. */ { Interp *iPtr = (Interp *) interp; const char *name; Tcl_Obj *argsPtr, *bodyPtr, *nsObjPtr, **objv; | | > | 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 | SetLambdaFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ register Tcl_Obj *objPtr) /* The object to convert. */ { Interp *iPtr = (Interp *) interp; const char *name; Tcl_Obj *argsPtr, *bodyPtr, *nsObjPtr, **objv; int isNew, result; size_t objc; CmdFrame *cfPtr = NULL; Proc *procPtr; if (interp == NULL) { return TCL_ERROR; } |
︙ | ︙ | |||
2662 2663 2664 2665 2666 2667 2668 | *---------------------------------------------------------------------- */ int Tcl_ApplyObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 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 | *---------------------------------------------------------------------- */ int Tcl_ApplyObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_NRCallObjProc(interp, TclNRApplyObjCmd, dummy, objc, objv); } int TclNRApplyObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; Proc *procPtr = NULL; Tcl_Obj *lambdaPtr, *nsObjPtr; int result, isRootEnsemble; Tcl_Namespace *nsPtr; |
︙ | ︙ | |||
2820 2821 2822 2823 2824 2825 2826 | static void MakeLambdaError( Tcl_Interp *interp, /* The interpreter in which the procedure was * called. */ Tcl_Obj *procNameObj) /* Name of the procedure. Used for error * messages and trace information. */ { | | > | | | 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 | static void MakeLambdaError( Tcl_Interp *interp, /* The interpreter in which the procedure was * called. */ Tcl_Obj *procNameObj) /* Name of the procedure. Used for error * messages and trace information. */ { int overflow, limit = 60; size_t nameLen; const char *procName = Tcl_GetStringFromObj(procNameObj, &nameLen); overflow = (nameLen > limit); Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (lambda term \"%.*s%s\" line %d)", (overflow ? limit : (int) nameLen), procName, (overflow ? "..." : ""), Tcl_GetErrorLine(interp))); } /* *---------------------------------------------------------------------- * * Tcl_DisassembleObjCmd -- * * Implementation of the "::tcl::unsupported::disassemble" command. This * command is not documented, but will disassemble procedures, lambda * terms and general scripts. Note that will compile terms if necessary * in order to disassemble them. * *---------------------------------------------------------------------- */ int Tcl_DisassembleObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *const types[] = { "lambda", "method", "objmethod", "proc", "script", NULL }; enum Types { DISAS_LAMBDA, DISAS_CLASS_METHOD, DISAS_OBJECT_METHOD, DISAS_PROC, |
︙ | ︙ | |||
3014 3015 3016 3017 3018 3019 3020 | Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[3]), NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 | Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[3]), NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr)); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "body not available for this kind of method", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", "METHODTYPE", NULL); return TCL_ERROR; } if (procPtr->bodyPtr->typePtr != &tclByteCodeType) { Command cmd; |
︙ | ︙ | |||
3050 3051 3052 3053 3054 3055 3056 | /* * Do the actual disassembly. */ if (((ByteCode *) codeObjPtr->internalRep.twoPtrValue.ptr1)->flags & TCL_BYTECODE_PRECOMPILED) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 | /* * Do the actual disassembly. */ if (((ByteCode *) codeObjPtr->internalRep.twoPtrValue.ptr1)->flags & TCL_BYTECODE_PRECOMPILED) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not disassemble prebuilt bytecode", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", "BYTECODE", NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, TclDisassembleByteCodeObj(codeObjPtr)); return TCL_OK; } |
︙ | ︙ |
Changes to generic/tclRegexp.c.
︙ | ︙ | |||
196 197 198 199 200 201 202 | regexp->objPtr = NULL; /* * Convert the string to Unicode and perform the match. */ Tcl_DStringInit(&ds); | | | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | regexp->objPtr = NULL; /* * Convert the string to Unicode and perform the match. */ Tcl_DStringInit(&ds); ustr = Tcl_UtfToUniCharDString(text, TCL_STRLEN, &ds); numChars = Tcl_DStringLength(&ds) / sizeof(Tcl_UniChar); result = RegExpExecUniChar(interp, re, ustr, numChars, -1 /* nmatches */, flags); Tcl_DStringFree(&ds); return result; } |
︙ | ︙ | |||
429 430 431 432 433 434 435 | int nmatches, /* How many subexpression matches (counting * the whole match as subexpression 0) are of * interest. -1 means all of them. */ int flags) /* Regular expression execution flags. */ { TclRegexp *regexpPtr = (TclRegexp *) re; Tcl_UniChar *udata; | | | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | int nmatches, /* How many subexpression matches (counting * the whole match as subexpression 0) are of * interest. -1 means all of them. */ int flags) /* Regular expression execution flags. */ { TclRegexp *regexpPtr = (TclRegexp *) re; Tcl_UniChar *udata; size_t length; int reflags = regexpPtr->flags; #define TCL_REG_GLOBOK_FLAGS \ (TCL_REG_ADVANCED | TCL_REG_NOSUB | TCL_REG_NOCASE) /* * Take advantage of the equivalent glob pattern, if one exists. * This is possible based only on the right mix of incoming flags (0) |
︙ | ︙ | |||
565 566 567 568 569 570 571 | * the interp regexp cache. */ Tcl_Obj *objPtr, /* Object whose string rep contains regular * expression pattern. Internal rep will be * changed to compiled form of this regular * expression. */ int flags) /* Regular expression compilation flags. */ { | | | 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 | * the interp regexp cache. */ Tcl_Obj *objPtr, /* Object whose string rep contains regular * expression pattern. Internal rep will be * changed to compiled form of this regular * expression. */ int flags) /* Regular expression compilation flags. */ { size_t length; TclRegexp *regexpPtr; const char *pattern; /* * This is OK because we only actually interpret this value properly as a * TclRegexp* when the type is tclRegexpType. */ |
︙ | ︙ | |||
678 679 680 681 682 683 684 | * Now append a list of all the bit-flags set for the RE. */ TclNewObj(infoObj); for (inf=infonames ; inf->bit != 0 ; inf++) { if (regexpPtr->re.re_info & inf->bit) { Tcl_ListObjAppendElement(NULL, infoObj, | | | 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 | * Now append a list of all the bit-flags set for the RE. */ TclNewObj(infoObj); for (inf=infonames ; inf->bit != 0 ; inf++) { if (regexpPtr->re.re_info & inf->bit) { Tcl_ListObjAppendElement(NULL, infoObj, Tcl_NewStringObj(inf->text, TCL_STRLEN)); } } Tcl_ListObjAppendElement(NULL, resultObj, infoObj); Tcl_SetObjResult(interp, resultObj); return 0; } |
︙ | ︙ |
Changes to generic/tclResult.c.
︙ | ︙ | |||
437 438 439 440 441 442 443 | * extended. */ const char *element) /* String to convert to list element and add * to result. */ { Interp *iPtr = (Interp *) interp; Tcl_Obj *elementPtr = Tcl_NewStringObj(element, -1); Tcl_Obj *listPtr = Tcl_NewListObj(1, &elementPtr); | | | 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 | * extended. */ const char *element) /* String to convert to list element and add * to result. */ { Interp *iPtr = (Interp *) interp; Tcl_Obj *elementPtr = Tcl_NewStringObj(element, -1); Tcl_Obj *listPtr = Tcl_NewListObj(1, &elementPtr); size_t length; const char *bytes; if (Tcl_IsShared(iPtr->objResultPtr)) { Tcl_SetObjResult(interp, Tcl_DuplicateObj(iPtr->objResultPtr)); } bytes = Tcl_GetStringFromObj(iPtr->objResultPtr, &length); if (TclNeedSpace(bytes, bytes+length)) { |
︙ | ︙ | |||
614 615 616 617 618 619 620 | while (1) { char *elem = va_arg(argList, char *); if (elem == NULL) { break; } | | > | 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | while (1) { char *elem = va_arg(argList, char *); if (elem == NULL) { break; } Tcl_ListObjAppendElement(NULL, errorObj, Tcl_NewStringObj(elem, TCL_STRLEN)); } Tcl_SetObjErrorCode(interp, errorObj); } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
858 859 860 861 862 863 864 | if (iPtr->errorInfo) { Tcl_DecrRefCount(iPtr->errorInfo); iPtr->errorInfo = NULL; } Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORINFO], &valuePtr); if (valuePtr != NULL) { | | | | 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 | if (iPtr->errorInfo) { Tcl_DecrRefCount(iPtr->errorInfo); iPtr->errorInfo = NULL; } Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORINFO], &valuePtr); if (valuePtr != NULL) { size_t infoLen; (void) TclGetStringFromObj(valuePtr, &infoLen); if (infoLen) { iPtr->errorInfo = valuePtr; Tcl_IncrRefCount(iPtr->errorInfo); iPtr->flags |= ERR_ALREADY_LOGGED; } } Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORSTACK], &valuePtr); if (valuePtr != NULL) { size_t len, valueObjc; Tcl_Obj **valueObjv; if (Tcl_IsShared(iPtr->errorStack)) { Tcl_Obj *newObj; newObj = Tcl_DuplicateObj(iPtr->errorStack); Tcl_DecrRefCount(iPtr->errorStack); |
︙ | ︙ | |||
947 948 949 950 951 952 953 | * *---------------------------------------------------------------------- */ int TclMergeReturnOptions( Tcl_Interp *interp, /* Current interpreter. */ | | | < | 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 | * *---------------------------------------------------------------------- */ int TclMergeReturnOptions( Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[], /* Argument objects. */ Tcl_Obj **optionsPtrPtr, /* If not NULL, points to space for a (Tcl_Obj * *) where the pointer to the merged return * options dictionary should be written. */ int *codePtr, /* If not NULL, points to space where the * -code value should be written. */ int *levelPtr) /* If not NULL, points to space where the * -level value should be written. */ { int code = TCL_OK; int level = 1; Tcl_Obj *valuePtr; Tcl_Obj *returnOpts = Tcl_NewObj(); Tcl_Obj **keys = GetKeys(); for (; objc > 1; objv += 2, objc -= 2) { size_t optLen, compareLen; const char *opt = TclGetStringFromObj(objv[0], &optLen); const char *compare = TclGetStringFromObj(keys[KEY_OPTIONS], &compareLen); if ((optLen == compareLen) && (memcmp(opt, compare, optLen) == 0)) { Tcl_DictSearch search; int done = 0; Tcl_Obj *keyPtr; |
︙ | ︙ | |||
1048 1049 1050 1051 1052 1053 1054 | /* * Check for bogus -errorcode value. */ Tcl_DictObjGet(NULL, returnOpts, keys[KEY_ERRORCODE], &valuePtr); if (valuePtr != NULL) { | | | | | | 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 1081 1082 1083 1084 1085 1086 | /* * Check for bogus -errorcode value. */ Tcl_DictObjGet(NULL, returnOpts, keys[KEY_ERRORCODE], &valuePtr); if (valuePtr != NULL) { size_t length; if (TCL_ERROR == Tcl_ListObjLength(NULL, valuePtr, &length)) { /* * Value is not a list, which is illegal for -errorcode. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad -errorcode value: expected a list but got \"%s\"", TclGetString(valuePtr))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_ERRORCODE", NULL); goto error; } } /* * Check for bogus -errorstack value. */ Tcl_DictObjGet(NULL, returnOpts, keys[KEY_ERRORSTACK], &valuePtr); if (valuePtr != NULL) { size_t length; if (TCL_ERROR == Tcl_ListObjLength(NULL, valuePtr, &length)) { /* * Value is not a list, which is illegal for -errorstack. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad -errorstack value: expected a list but got \"%s\"", TclGetString(valuePtr))); |
︙ | ︙ | |||
1238 1239 1240 1241 1242 1243 1244 | */ int Tcl_SetReturnOptions( Tcl_Interp *interp, Tcl_Obj *options) { | | > | 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 | */ int Tcl_SetReturnOptions( Tcl_Interp *interp, Tcl_Obj *options) { int level, code; size_t objc; Tcl_Obj **objv, *mergedOpts; Tcl_IncrRefCount(options); if (TCL_ERROR == TclListObjGetElements(interp, options, &objc, &objv) || (objc % 2)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected dict but got \"%s\"", TclGetString(options))); |
︙ | ︙ |
Changes to generic/tclScan.c.
︙ | ︙ | |||
43 44 45 46 47 48 49 | * Declarations for functions used only in this file. */ static const char * BuildCharSet(CharSet *cset, const char *format); static int CharInSet(CharSet *cset, int ch); static void ReleaseCharSet(CharSet *cset); static int ValidateFormat(Tcl_Interp *interp, const char *format, | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | * Declarations for functions used only in this file. */ static const char * BuildCharSet(CharSet *cset, const char *format); static int CharInSet(CharSet *cset, int ch); static void ReleaseCharSet(CharSet *cset); static int ValidateFormat(Tcl_Interp *interp, const char *format, size_t numVars, size_t *totalVars); /* *---------------------------------------------------------------------- * * BuildCharSet -- * * This function examines a character set format specification and builds |
︙ | ︙ | |||
246 247 248 249 250 251 252 | *---------------------------------------------------------------------- */ static int ValidateFormat( Tcl_Interp *interp, /* Current interpreter. */ const char *format, /* The format string. */ | | | | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | *---------------------------------------------------------------------- */ static int ValidateFormat( Tcl_Interp *interp, /* Current interpreter. */ const char *format, /* The format string. */ size_t numVars, /* The number of variables passed to the scan * command. */ size_t *totalSubs) /* The number of variables that will be * required. */ { int gotXpg, gotSequential, value, i, flags; char *end; Tcl_UniChar ch; int objIndex, xpgSize, nspace = numVars; int *nassign = TclStackAlloc(interp, nspace * sizeof(int)); |
︙ | ︙ | |||
330 331 332 333 334 335 336 | notXpg: gotSequential = 1; if (gotXpg) { mixedXPG: Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot mix \"%\" and \"%n$\" conversion specifiers", | | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | notXpg: gotSequential = 1; if (gotXpg) { mixedXPG: Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot mix \"%\" and \"%n$\" conversion specifiers", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "MIXEDSPECTYPES", NULL); goto error; } xpgCheckDone: /* * Parse any width specifier. |
︙ | ︙ | |||
377 378 379 380 381 382 383 | */ switch (ch) { case 'c': if (flags & SCAN_WIDTH) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "field width may not be specified in %c conversion", | | | > | | | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 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 | */ switch (ch) { case 'c': if (flags & SCAN_WIDTH) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "field width may not be specified in %c conversion", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADWIDTH", NULL); goto error; } /* * Fall through! */ case 'n': case 's': if (flags & (SCAN_LONGER|SCAN_BIG)) { invalidFieldSize: buf[Tcl_UniCharToUtf(ch, buf)] = '\0'; errorMsg = Tcl_NewStringObj( "field size modifier may not be specified in %", TCL_STRLEN); Tcl_AppendToObj(errorMsg, buf, TCL_STRLEN); Tcl_AppendToObj(errorMsg, " conversion", TCL_STRLEN); Tcl_SetObjResult(interp, errorMsg); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADSIZE", NULL); goto error; } /* * Fall through! */ case 'd': case 'e': case 'f': case 'g': case 'i': case 'o': case 'x': case 'b': break; case 'u': if (flags & SCAN_BIG) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unsigned bignum scans are invalid", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL); goto error; } break; /* * Bracket terms need special checking */ |
︙ | ︙ | |||
449 450 451 452 453 454 455 | goto badSet; } format += Tcl_UtfToUniChar(format, &ch); } break; badSet: Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | | | 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | goto badSet; } format += Tcl_UtfToUniChar(format, &ch); } break; badSet: Tcl_SetObjResult(interp, Tcl_NewStringObj( "unmatched [ in format string", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BRACKET", NULL); goto error; default: buf[Tcl_UniCharToUtf(ch, buf)] = '\0'; errorMsg = Tcl_NewStringObj( "bad scan conversion character \"", TCL_STRLEN); Tcl_AppendToObj(errorMsg, buf, TCL_STRLEN); Tcl_AppendToObj(errorMsg, "\"", TCL_STRLEN); Tcl_SetObjResult(interp, errorMsg); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADTYPE", NULL); goto error; } if (!(flags & SCAN_SUPPRESS)) { if (objIndex >= nspace) { /* |
︙ | ︙ | |||
505 506 507 508 509 510 511 | if (totalSubs) { *totalSubs = numVars; } for (i = 0; i < numVars; i++) { if (nassign[i] > 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "variable is assigned by multiple \"%n$\" conversion specifiers", | | | | | | 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 | if (totalSubs) { *totalSubs = numVars; } for (i = 0; i < numVars; i++) { if (nassign[i] > 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "variable is assigned by multiple \"%n$\" conversion specifiers", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "POLYASSIGNED", NULL); goto error; } else if (!xpgSize && (nassign[i] == 0)) { /* * If the space is empty, and xpgSize is 0 (means XPG wasn't used, * and/or numVars != 0), then too many vars were given */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "variable is not assigned by any conversion specifiers", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "UNASSIGNED", NULL); goto error; } } TclStackFree(interp, nassign); return TCL_OK; badIndex: if (gotXpg) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"%n$\" argument index out of range", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "INDEXRANGE", NULL); } else { Tcl_SetObjResult(interp, Tcl_NewStringObj( "different numbers of variable names and field specifiers", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "FIELDVARMISMATCH", NULL); } error: TclStackFree(interp, nassign); return TCL_ERROR; } |
︙ | ︙ | |||
564 565 566 567 568 569 570 | */ /* ARGSUSED */ int Tcl_ScanObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | */ /* ARGSUSED */ int Tcl_ScanObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *format; size_t numVars, nconversions, totalVars = 0, i; int objIndex, offset, result, code; long value; const char *string, *end, *baseString; char op = 0; int width, underflow = 0; Tcl_WideInt wideValue; Tcl_UniChar ch, sch; Tcl_Obj **objs = NULL, *objPtr = NULL; |
︙ | ︙ | |||
922 923 924 925 926 927 928 | if (TclGetString(objPtr)[0] == '-') { wideValue++; /* WIDE_MAX + 1 = WIDE_MIN */ } } if ((flags & SCAN_UNSIGNED) && (wideValue < 0)) { sprintf(buf, "%" TCL_LL_MODIFIER "u", (Tcl_WideUInt)wideValue); | | | | 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 | if (TclGetString(objPtr)[0] == '-') { wideValue++; /* WIDE_MAX + 1 = WIDE_MIN */ } } if ((flags & SCAN_UNSIGNED) && (wideValue < 0)) { sprintf(buf, "%" TCL_LL_MODIFIER "u", (Tcl_WideUInt)wideValue); Tcl_SetStringObj(objPtr, buf, TCL_STRLEN); } else { Tcl_SetWideIntObj(objPtr, wideValue); } } else if (!(flags & SCAN_BIG)) { if (TclGetLongFromObj(NULL, objPtr, &value) != TCL_OK) { if (TclGetString(objPtr)[0] == '-') { value = LONG_MIN; } else { value = LONG_MAX; } } if ((flags & SCAN_UNSIGNED) && (value < 0)) { sprintf(buf, "%lu", value); /* INTL: ISO digit */ Tcl_SetStringObj(objPtr, buf, TCL_STRLEN); } else { Tcl_SetLongObj(objPtr, value); } } objs[objIndex++] = objPtr; break; |
︙ | ︙ |
Changes to generic/tclStrToD.c.
︙ | ︙ | |||
372 373 374 375 376 377 378 | * number in a format recognized by Tcl. * * The arguments bytes, numBytes, and objPtr are the inputs which * determine the string to be parsed. If bytes is non-NULL, it points to * the first byte to be scanned. If bytes is NULL, then objPtr must be * non-NULL, and the string representation of objPtr will be scanned * (generated first, if necessary). The numBytes argument determines the | | | | | 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | * number in a format recognized by Tcl. * * The arguments bytes, numBytes, and objPtr are the inputs which * determine the string to be parsed. If bytes is non-NULL, it points to * the first byte to be scanned. If bytes is NULL, then objPtr must be * non-NULL, and the string representation of objPtr will be scanned * (generated first, if necessary). The numBytes argument determines the * number of bytes to be scanned. If numBytes is TCL_STRLEN, the first * NUL byte encountered will terminate the scan. If numBytes is * non-negative, then no more than numBytes bytes will be scanned. * * The argument flags is an input that controls the numeric formats * recognized by the parser. The flag bits are: * * - TCL_PARSE_INTEGER_ONLY: accept only integer values; reject * strings that denote floating point values (or accept only the * leading portion of them that are integer values). |
︙ | ︙ | |||
467 468 469 470 471 472 473 | Tcl_Interp *interp, /* Used for error reporting. May be NULL. */ Tcl_Obj *objPtr, /* Object to receive the internal rep. */ const char *expected, /* Description of the type of number the * caller expects to be able to parse * ("integer", "boolean value", etc.). */ const char *bytes, /* Pointer to the start of the string to * scan. */ | | | 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | Tcl_Interp *interp, /* Used for error reporting. May be NULL. */ Tcl_Obj *objPtr, /* Object to receive the internal rep. */ const char *expected, /* Description of the type of number the * caller expects to be able to parse * ("integer", "boolean value", etc.). */ const char *bytes, /* Pointer to the start of the string to * scan. */ size_t numBytes, /* Maximum number of bytes to scan, see * above. */ const char **endPtrPtr, /* Place to store pointer to the character * that terminated the scan. */ int flags) /* Flags governing the parse. */ { enum State { INITIAL, SIGNUM, ZERO, ZERO_X, |
︙ | ︙ | |||
1070 1071 1072 1073 1074 1075 1076 | while (len != 0 && TclIsSpaceProc(*p)) { p++; len--; } } if (endPtrPtr == NULL) { | | | 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 | while (len != 0 && TclIsSpaceProc(*p)) { p++; len--; } } if (endPtrPtr == NULL) { if ((len != 0) && ((numBytes != TCL_STRLEN) || (*p != '\0'))) { status = TCL_ERROR; } } else { *endPtrPtr = p; } } |
︙ | ︙ | |||
1309 1310 1311 1312 1313 1314 1315 | if (status != TCL_OK) { if (interp != NULL) { Tcl_Obj *msg = Tcl_ObjPrintf("expected %s but got \"", expected); Tcl_AppendLimitedToObj(msg, bytes, numBytes, 50, ""); | | | 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 | if (status != TCL_OK) { if (interp != NULL) { Tcl_Obj *msg = Tcl_ObjPrintf("expected %s but got \"", expected); Tcl_AppendLimitedToObj(msg, bytes, numBytes, 50, ""); Tcl_AppendToObj(msg, "\"", TCL_STRLEN); Tcl_SetObjResult(interp, msg); Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL); } } /* * Free memory. |
︙ | ︙ | |||
4434 4435 4436 4437 4438 4439 4440 | /* * Infinite values can't convert to bignum. */ if (TclIsInfinite(d)) { if (interp != NULL) { | | | | 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 | /* * Infinite values can't convert to bignum. */ if (TclIsInfinite(d)) { if (interp != NULL) { static const char *s = "integer value too large to represent"; Tcl_SetObjResult(interp, Tcl_NewStringObj(s, TCL_STRLEN)); Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL); } return TCL_ERROR; } fract = frexp(d,&expt); if (expt <= 0) { |
︙ | ︙ |
Changes to generic/tclStringObj.c.
︙ | ︙ | |||
49 50 51 52 53 54 55 | /* * Prototypes for functions defined later in this file: */ static void AppendPrintfToObjVA(Tcl_Obj *objPtr, const char *format, va_list argList); static void AppendUnicodeToUnicodeRep(Tcl_Obj *objPtr, | | > | | | | | | | | | | | 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 | /* * Prototypes for functions defined later in this file: */ static void AppendPrintfToObjVA(Tcl_Obj *objPtr, const char *format, va_list argList); static void AppendUnicodeToUnicodeRep(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t appendNumChars); static void AppendUnicodeToUtfRep(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t numChars); static void AppendUtfToUnicodeRep(Tcl_Obj *objPtr, const char *bytes, size_t numBytes); static void AppendUtfToUtfRep(Tcl_Obj *objPtr, const char *bytes, size_t numBytes); static void DupStringInternalRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr); static int ExtendStringRepWithUnicode(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t numChars); static void ExtendUnicodeRepWithString(Tcl_Obj *objPtr, const char *bytes, size_t numBytes, size_t numAppendChars); static void FillUnicodeRep(Tcl_Obj *objPtr); static void FreeStringInternalRep(Tcl_Obj *objPtr); static void GrowStringBuffer(Tcl_Obj *objPtr, size_t needed, int flag); static void GrowUnicodeBuffer(Tcl_Obj *objPtr, size_t needed); static int SetStringFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static void SetUnicodeObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t numChars); static size_t UnicodeLength(const Tcl_UniChar *unicode); static void UpdateStringOfString(Tcl_Obj *objPtr); /* * The structure below defines the string Tcl object type by means of * functions that can be invoked by generic object code. */ |
︙ | ︙ | |||
101 102 103 104 105 106 107 | * Under normal configurations, what Tcl calls "Unicode" is actually UTF-16 * restricted to the Basic Multilingual Plane (i.e. U+00000 to U+0FFFF). This * can be officially modified by altering the definition of Tcl_UniChar in * tcl.h, but do not do that unless you are sure what you're doing! */ typedef struct { | | | > | | | | | | | | | | | | | | | | 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 154 | * Under normal configurations, what Tcl calls "Unicode" is actually UTF-16 * restricted to the Basic Multilingual Plane (i.e. U+00000 to U+0FFFF). This * can be officially modified by altering the definition of Tcl_UniChar in * tcl.h, but do not do that unless you are sure what you're doing! */ typedef struct { size_t numChars; /* The number of chars in the string. * TCL_STRLEN means this value has not been * calculated, and anything else means that * there is a valid Unicode rep, or that the * number of UTF bytes == the number of * chars. */ size_t allocated; /* The amount of space actually allocated for * the UTF string (minus 1 byte for the * termination char). */ size_t maxChars; /* Max number of chars that can fit in the * space allocated for the unicode array. */ int hasUnicode; /* Boolean determining whether the string has * a Unicode representation. */ Tcl_UniChar unicode[1]; /* The array of Unicode chars. The actual size * of this field depends on the 'maxChars' * field above. */ } String; #define STRING_MAXCHARS \ (((size_t)ULONG_MAX - sizeof(String))/sizeof(Tcl_UniChar)) #define STRING_SIZE(numChars) \ (sizeof(String) + ((numChars) * sizeof(Tcl_UniChar))) #define stringCheckLimits(numChars) \ if ((numChars) > STRING_MAXCHARS) { \ Tcl_Panic("max length for a Tcl unicode value (%lu chars) exceeded", \ STRING_MAXCHARS); \ } #define stringAttemptAlloc(numChars) \ (String *) attemptckalloc(STRING_SIZE(numChars)) #define stringAlloc(numChars) \ (String *) ckalloc(STRING_SIZE(numChars)) #define stringRealloc(ptr, numChars) \ (String *) ckrealloc((ptr), STRING_SIZE(numChars)) #define stringAttemptRealloc(ptr, numChars) \ (String *) attemptckrealloc((ptr), STRING_SIZE(numChars)) #define GET_STRING(objPtr) \ ((String *) (objPtr)->internalRep.twoPtrValue.ptr1) #define SET_STRING(objPtr, stringPtr) \ ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (stringPtr)) /* * TCL STRING GROWTH ALGORITHM * * When growing strings (during an append, for example), the following growth * algorithm is used: * |
︙ | ︙ | |||
180 181 182 183 184 185 186 | #ifndef TCL_MIN_UNICHAR_GROWTH #define TCL_MIN_UNICHAR_GROWTH TCL_MIN_GROWTH/sizeof(Tcl_UniChar) #endif static void GrowStringBuffer( Tcl_Obj *objPtr, | | | | | | > | > > | | | > | > | 182 183 184 185 186 187 188 189 190 191 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 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 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 | #ifndef TCL_MIN_UNICHAR_GROWTH #define TCL_MIN_UNICHAR_GROWTH TCL_MIN_GROWTH/sizeof(Tcl_UniChar) #endif static void GrowStringBuffer( Tcl_Obj *objPtr, size_t needed, int flag) { /* * Pre-conditions: * objPtr->typePtr == &tclStringType * needed > stringPtr->allocated * flag || objPtr->bytes != NULL */ String *stringPtr = GET_STRING(objPtr); char *ptr = NULL; size_t attempt; if (objPtr->bytes == tclEmptyStringRep) { objPtr->bytes = NULL; } if (flag == 0 || stringPtr->allocated > 0) { attempt = 2 * needed; if (attempt+1 > needed) { ptr = attemptckrealloc(objPtr->bytes, attempt + 1); } if (ptr == NULL) { /* * Take care computing the amount of modest growth to avoid * overflow into invalid argument values for attempt. */ size_t limit = INT_MAX - needed; // TODO FIXME size_t extra = needed - objPtr->length + TCL_MIN_GROWTH; int growth = (int) ((extra > limit) ? limit : extra); attempt = needed + growth; if (attempt+1 > needed) { ptr = attemptckrealloc(objPtr->bytes, attempt + 1); } } } if (ptr == NULL) { /* * First allocation - just big enough; or last chance fallback. */ attempt = needed; // TODO Beware the case right at the limit (which should fail...) ptr = ckrealloc(objPtr->bytes, attempt + 1); } objPtr->bytes = ptr; stringPtr->allocated = attempt; } static void GrowUnicodeBuffer( Tcl_Obj *objPtr, size_t needed) { /* * Pre-conditions: * objPtr->typePtr == &tclStringType * needed > stringPtr->maxChars * needed < STRING_MAXCHARS */ String *ptr = NULL, *stringPtr = GET_STRING(objPtr); size_t attempt; if (stringPtr->maxChars > 0) { /* * Subsequent appends - apply the growth algorithm. */ attempt = 2 * needed; if (attempt > needed && attempt <= STRING_MAXCHARS) { ptr = stringAttemptRealloc(stringPtr, attempt); } if (ptr == NULL) { /* * Take care computing the amount of modest growth to avoid * overflow into invalid argument values for attempt. */ unsigned int limit = STRING_MAXCHARS - needed; unsigned int extra = needed - stringPtr->numChars + TCL_MIN_UNICHAR_GROWTH; int growth = (int) ((extra > limit) ? limit : extra); attempt = needed + growth; if (attempt > needed) { ptr = stringAttemptRealloc(stringPtr, attempt); } } } if (ptr == NULL) { /* * First allocation - just big enough; or last chance fallback. */ |
︙ | ︙ | |||
311 312 313 314 315 316 317 | #ifdef TCL_MEM_DEBUG #undef Tcl_NewStringObj Tcl_Obj * Tcl_NewStringObj( const char *bytes, /* Points to the first of the length bytes * used to initialize the new object. */ | | | | | | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | #ifdef TCL_MEM_DEBUG #undef Tcl_NewStringObj Tcl_Obj * Tcl_NewStringObj( const char *bytes, /* Points to the first of the length bytes * used to initialize the new object. */ size_t length) /* The number of bytes to copy from "bytes" * when initializing the new object. If * TCL_STRLEN, use bytes up to the first NUL * byte. */ { return Tcl_DbNewStringObj(bytes, length, "unknown", 0); } #else /* if not TCL_MEM_DEBUG */ Tcl_Obj * Tcl_NewStringObj( const char *bytes, /* Points to the first of the length bytes * used to initialize the new object. */ size_t length) /* The number of bytes to copy from "bytes" * when initializing the new object. If * TCL_STRLEN, use bytes up to the first NUL * byte. */ { Tcl_Obj *objPtr; if (length == TCL_STRLEN) { length = (bytes? strlen(bytes) : 0); } TclNewStringObj(objPtr, bytes, length); return objPtr; } #endif /* TCL_MEM_DEBUG */ |
︙ | ︙ | |||
372 373 374 375 376 377 378 | */ #ifdef TCL_MEM_DEBUG Tcl_Obj * Tcl_DbNewStringObj( const char *bytes, /* Points to the first of the length bytes * used to initialize the new object. */ | | | | | | | 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 | */ #ifdef TCL_MEM_DEBUG Tcl_Obj * Tcl_DbNewStringObj( const char *bytes, /* Points to the first of the length bytes * used to initialize the new object. */ size_t length, /* The number of bytes to copy from "bytes" * when initializing the new object. If * TCL_STRLEN, use bytes up to the first NUL * byte. */ const char *file, /* The name of the source file calling this * function; used for debugging. */ int line) /* Line number in the source file; used for * debugging. */ { Tcl_Obj *objPtr; if (length == TCL_STRLEN) { length = (bytes? strlen(bytes) : 0); } TclDbNewObj(objPtr, file, line); TclInitStringRep(objPtr, bytes, length); return objPtr; } #else /* if not TCL_MEM_DEBUG */ Tcl_Obj * Tcl_DbNewStringObj( const char *bytes, /* Points to the first of the length bytes * used to initialize the new object. */ size_t length, /* The number of bytes to copy from "bytes" * when initializing the new object. If * TCL_STRLEN, use bytes up to the first NUL * byte. */ const char *file, /* The name of the source file calling this * function; used for debugging. */ int line) /* Line number in the source file; used for * debugging. */ { return Tcl_NewStringObj(bytes, length); |
︙ | ︙ | |||
431 432 433 434 435 436 437 | *--------------------------------------------------------------------------- */ Tcl_Obj * Tcl_NewUnicodeObj( const Tcl_UniChar *unicode, /* The unicode string used to initialize the * new object. */ | | | 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | *--------------------------------------------------------------------------- */ Tcl_Obj * Tcl_NewUnicodeObj( const Tcl_UniChar *unicode, /* The unicode string used to initialize the * new object. */ size_t numChars) /* Number of characters in the unicode * string. */ { Tcl_Obj *objPtr; TclNewObj(objPtr); SetUnicodeObj(objPtr, unicode, numChars); return objPtr; |
︙ | ︙ | |||
458 459 460 461 462 463 464 | * Side effects: * Frees old internal rep. Allocates memory for new "String" internal * rep. * *---------------------------------------------------------------------- */ | | | | | | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 | * Side effects: * Frees old internal rep. Allocates memory for new "String" internal * rep. * *---------------------------------------------------------------------- */ size_t Tcl_GetCharLength( Tcl_Obj *objPtr) /* The String object to get the num chars * of. */ { String *stringPtr; size_t numChars; /* * Optimize the case where we're really dealing with a bytearray object * without string representation; we don't need to convert to a string to * perform the get-length operation. */ if (TclIsPureByteArray(objPtr)) { size_t length; (void) Tcl_GetByteArrayFromObj(objPtr, &length); return length; } /* * OK, need to work with the object as a string. */ SetStringFromAny(NULL, objPtr); stringPtr = GET_STRING(objPtr); numChars = stringPtr->numChars; /* * If numChars is unknown, compute it. */ if (numChars == TCL_STRLEN) { TclNumUtfChars(numChars, objPtr->bytes, objPtr->length); stringPtr->numChars = numChars; #if COMPAT if (numChars < objPtr->length) { /* * Since we've just computed the number of chars, and not all UTF |
︙ | ︙ | |||
531 532 533 534 535 536 537 | *---------------------------------------------------------------------- */ Tcl_UniChar Tcl_GetUniChar( Tcl_Obj *objPtr, /* The object to get the Unicode charater * from. */ | | | 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | *---------------------------------------------------------------------- */ Tcl_UniChar Tcl_GetUniChar( Tcl_Obj *objPtr, /* The object to get the Unicode charater * from. */ size_t index) /* Get the index'th Unicode character. */ { String *stringPtr; /* * Optimize the case where we're really dealing with a bytearray object * without string representation; we don't need to convert to a string to * perform the indexing operation. |
︙ | ︙ | |||
559 560 561 562 563 564 565 | stringPtr = GET_STRING(objPtr); if (stringPtr->hasUnicode == 0) { /* * If numChars is unknown, compute it. */ | | | 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | stringPtr = GET_STRING(objPtr); if (stringPtr->hasUnicode == 0) { /* * If numChars is unknown, compute it. */ if (stringPtr->numChars == TCL_STRLEN) { TclNumUtfChars(stringPtr->numChars, objPtr->bytes, objPtr->length); } if (stringPtr->numChars == objPtr->length) { return (Tcl_UniChar) objPtr->bytes[index]; } FillUnicodeRep(objPtr); stringPtr = GET_STRING(objPtr); |
︙ | ︙ | |||
621 622 623 624 625 626 627 | *---------------------------------------------------------------------- */ Tcl_UniChar * Tcl_GetUnicodeFromObj( Tcl_Obj *objPtr, /* The object to find the unicode string * for. */ | | | 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 | *---------------------------------------------------------------------- */ Tcl_UniChar * Tcl_GetUnicodeFromObj( Tcl_Obj *objPtr, /* The object to find the unicode string * for. */ size_t *lengthPtr) /* If non-NULL, the location where the string * rep's unichar length should be stored. If * NULL, no length is stored. */ { String *stringPtr; SetStringFromAny(NULL, objPtr); stringPtr = GET_STRING(objPtr); |
︙ | ︙ | |||
663 664 665 666 667 668 669 | * *---------------------------------------------------------------------- */ Tcl_Obj * Tcl_GetRange( Tcl_Obj *objPtr, /* The Tcl object to find the range of. */ | | | | 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 | * *---------------------------------------------------------------------- */ Tcl_Obj * Tcl_GetRange( Tcl_Obj *objPtr, /* The Tcl object to find the range of. */ size_t first, /* First index of the range. */ size_t last) /* Last index of the range. */ { Tcl_Obj *newObjPtr; /* The Tcl object to find the range of. */ String *stringPtr; /* * Optimize the case where we're really dealing with a bytearray object * without string representation; we don't need to convert to a string to |
︙ | ︙ | |||
693 694 695 696 697 698 699 | stringPtr = GET_STRING(objPtr); if (stringPtr->hasUnicode == 0) { /* * If numChars is unknown, compute it. */ | | | 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 | stringPtr = GET_STRING(objPtr); if (stringPtr->hasUnicode == 0) { /* * If numChars is unknown, compute it. */ if (stringPtr->numChars == TCL_STRLEN) { TclNumUtfChars(stringPtr->numChars, objPtr->bytes, objPtr->length); } if (stringPtr->numChars == objPtr->length) { newObjPtr = Tcl_NewStringObj(objPtr->bytes + first, last-first+1); /* * Since we know the char length of the result, store it. |
︙ | ︙ | |||
741 742 743 744 745 746 747 | */ void Tcl_SetStringObj( Tcl_Obj *objPtr, /* Object whose internal rep to init. */ const char *bytes, /* Points to the first of the length bytes * used to initialize the object. */ | | | | > | | 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 | */ void Tcl_SetStringObj( Tcl_Obj *objPtr, /* Object whose internal rep to init. */ const char *bytes, /* Points to the first of the length bytes * used to initialize the object. */ size_t length) /* The number of bytes to copy from "bytes" * when initializing the object. If * TCL_STRLEN, use bytes up to the first NUL * byte.*/ { if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetStringObj"); } /* * Set the type to NULL and free any internal rep for the old type. */ TclFreeIntRep(objPtr); /* * Free any old string rep, then set the string rep to a copy of the * length bytes starting at "bytes". */ TclInvalidateStringRep(objPtr); if (length == TCL_STRLEN) { length = (bytes? strlen(bytes) : 0); } TclInitStringRep(objPtr, bytes, length); } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
794 795 796 797 798 799 800 | *---------------------------------------------------------------------- */ void Tcl_SetObjLength( Tcl_Obj *objPtr, /* Pointer to object. This object must not * currently be shared. */ | | | | | 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 | *---------------------------------------------------------------------- */ void Tcl_SetObjLength( Tcl_Obj *objPtr, /* Pointer to object. This object must not * currently be shared. */ size_t length) /* Number of bytes desired for string * representation of object, not including * terminating null byte. */ { String *stringPtr; if (length == TCL_STRLEN) { /* * Setting to a negative length is nonsense. This is probably the * result of overflowing the signed integer range. */ Tcl_Panic("Tcl_SetObjLength: negative length requested: " "%lu (integer overflow?)", length); } if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetObjLength"); } if (objPtr->bytes && objPtr->length == length) { return; |
︙ | ︙ | |||
843 844 845 846 847 848 849 | objPtr->length = length; objPtr->bytes[length] = 0; /* * Invalidate the unicode data. */ | | | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 | objPtr->length = length; objPtr->bytes[length] = 0; /* * Invalidate the unicode data. */ stringPtr->numChars = TCL_STRLEN; stringPtr->hasUnicode = 0; } else { /* * Changing length of pure unicode string. */ stringCheckLimits(length); |
︙ | ︙ | |||
899 900 901 902 903 904 905 | *---------------------------------------------------------------------- */ int Tcl_AttemptSetObjLength( Tcl_Obj *objPtr, /* Pointer to object. This object must not * currently be shared. */ | | | | 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 | *---------------------------------------------------------------------- */ int Tcl_AttemptSetObjLength( Tcl_Obj *objPtr, /* Pointer to object. This object must not * currently be shared. */ size_t length) /* Number of bytes desired for string * representation of object, not including * terminating null byte. */ { String *stringPtr; if (length == TCL_STRLEN) { /* * Setting to a negative length is nonsense. This is probably the * result of overflowing the signed integer range. */ return 0; } |
︙ | ︙ | |||
953 954 955 956 957 958 959 | objPtr->length = length; objPtr->bytes[length] = 0; /* * Invalidate the unicode data. */ | | | 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 | objPtr->length = length; objPtr->bytes[length] = 0; /* * Invalidate the unicode data. */ stringPtr->numChars = TCL_STRLEN; stringPtr->hasUnicode = 0; } else { /* * Changing length of pure unicode string. */ if (length > STRING_MAXCHARS) { |
︙ | ︙ | |||
1009 1010 1011 1012 1013 1014 1015 | */ void Tcl_SetUnicodeObj( Tcl_Obj *objPtr, /* The object to set the string of. */ const Tcl_UniChar *unicode, /* The unicode string used to initialize the * object. */ | | | | | | > > > > | | | 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 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 | */ void Tcl_SetUnicodeObj( Tcl_Obj *objPtr, /* The object to set the string of. */ const Tcl_UniChar *unicode, /* The unicode string used to initialize the * object. */ size_t numChars) /* Number of characters in the unicode * string. */ { if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetUnicodeObj"); } TclFreeIntRep(objPtr); SetUnicodeObj(objPtr, unicode, numChars); } static size_t UnicodeLength( const Tcl_UniChar *unicode) { size_t numChars = 0; if (unicode) { while (unicode[numChars] != 0) { size_t oldNumChars = numChars++; if (oldNumChars > numChars) { // TODO Handle overflow better? break; } } } stringCheckLimits(numChars); return numChars; } static void SetUnicodeObj( Tcl_Obj *objPtr, /* The object to set the string of. */ const Tcl_UniChar *unicode, /* The unicode string used to initialize the * object. */ size_t numChars) /* Number of characters in the unicode * string. */ { String *stringPtr; if (numChars == TCL_STRLEN) { numChars = UnicodeLength(unicode); } /* * Allocate enough space for the String structure + Unicode string. */ |
︙ | ︙ | |||
1090 1091 1092 1093 1094 1095 1096 | */ void Tcl_AppendLimitedToObj( Tcl_Obj *objPtr, /* Points to the object to append to. */ const char *bytes, /* Points to the bytes to append to the * object. */ | | | | > | | | | 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 | */ void Tcl_AppendLimitedToObj( Tcl_Obj *objPtr, /* Points to the object to append to. */ const char *bytes, /* Points to the bytes to append to the * object. */ size_t length, /* The number of bytes available to be * appended from "bytes". If TCL_STRLEN, then * all bytes up to a NUL byte are * available. */ size_t limit, /* The maximum number of bytes to append to * the object. */ const char *ellipsis) /* Ellipsis marker string, appended to the * object to indicate not all available bytes * at "bytes" were appended. */ { String *stringPtr; int toCopy = 0; if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_AppendLimitedToObj"); } if (length == TCL_STRLEN) { length = (bytes ? strlen(bytes) : 0); } if (length == 0) { return; } if (length <= limit || limit == INT_MAX) { toCopy = length; } else { if (ellipsis == NULL) { ellipsis = "..."; } toCopy = Tcl_UtfPrev(bytes+limit+1-strlen(ellipsis), bytes) - bytes; } |
︙ | ︙ | |||
1171 1172 1173 1174 1175 1176 1177 | */ void Tcl_AppendToObj( Tcl_Obj *objPtr, /* Points to the object to append to. */ const char *bytes, /* Points to the bytes to append to the * object. */ | | | | > | | | 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 | */ void Tcl_AppendToObj( Tcl_Obj *objPtr, /* Points to the object to append to. */ const char *bytes, /* Points to the bytes to append to the * object. */ size_t length) /* The number of bytes to append from "bytes". * If TCL_STRLEN, then append all bytes up to * NUL byte. */ { // TODO Handle appending more than INT_MAX bytes Tcl_AppendLimitedToObj(objPtr, bytes, length, INT_MAX, NULL); } /* *---------------------------------------------------------------------- * * Tcl_AppendUnicodeToObj -- * * This function appends a Unicode string to an object in the most * efficient manner possible. Length must *not* be TCL_STRLEN. * * Results: * None. * * Side effects: * Invalidates the string rep and creates a new Unicode string. * *---------------------------------------------------------------------- */ void Tcl_AppendUnicodeToObj( Tcl_Obj *objPtr, /* Points to the object to append to. */ const Tcl_UniChar *unicode, /* The unicode string to append to the * object. */ size_t length) /* Number of chars in "unicode". */ { String *stringPtr; if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_AppendUnicodeToObj"); } |
︙ | ︙ | |||
1256 1257 1258 1259 1260 1261 1262 | void Tcl_AppendObjToObj( Tcl_Obj *objPtr, /* Points to the object to append to. */ Tcl_Obj *appendObjPtr) /* Object to append. */ { String *stringPtr; | | | 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 | void Tcl_AppendObjToObj( Tcl_Obj *objPtr, /* Points to the object to append to. */ Tcl_Obj *appendObjPtr) /* Object to append. */ { String *stringPtr; size_t length, numChars, appendNumChars = TCL_STRLEN; const char *bytes; /* * Special case: second object is standard-empty is fast case. We know * that appending nothing to anything leaves that starting anything... */ |
︙ | ︙ | |||
1278 1279 1280 1281 1282 1283 1284 | * it did, then appending the byte arrays together could well lose * information; this is a special-case optimization only. */ if ((TclIsPureByteArray(objPtr) || objPtr->bytes == tclEmptyStringRep) && TclIsPureByteArray(appendObjPtr)) { unsigned char *bytesSrc; | | | 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 | * it did, then appending the byte arrays together could well lose * information; this is a special-case optimization only. */ if ((TclIsPureByteArray(objPtr) || objPtr->bytes == tclEmptyStringRep) && TclIsPureByteArray(appendObjPtr)) { unsigned char *bytesSrc; size_t lengthSrc, lengthTotal; /* * We do not assume that objPtr and appendObjPtr must be distinct! * This makes this code a bit more complex than it otherwise would be, * but in turn makes it much safer. */ |
︙ | ︙ | |||
1339 1340 1341 1342 1343 1344 1345 | * in both objects before appending, then set the combined number of * characters in the final (appended-to) object. */ bytes = TclGetStringFromObj(appendObjPtr, &length); numChars = stringPtr->numChars; | | > | | 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 | * in both objects before appending, then set the combined number of * characters in the final (appended-to) object. */ bytes = TclGetStringFromObj(appendObjPtr, &length); numChars = stringPtr->numChars; if (numChars != TCL_STRLEN && appendObjPtr->typePtr == &tclStringType) { String *appendStringPtr = GET_STRING(appendObjPtr); appendNumChars = appendStringPtr->numChars; } AppendUtfToUtfRep(objPtr, bytes, length); if (numChars != TCL_STRLEN && appendNumChars != TCL_STRLEN #if COMPAT && appendNumChars == length #endif ) { stringPtr->numChars = numChars + appendNumChars; } } |
︙ | ︙ | |||
1376 1377 1378 1379 1380 1381 1382 | *---------------------------------------------------------------------- */ static void AppendUnicodeToUnicodeRep( Tcl_Obj *objPtr, /* Points to the object to append to. */ const Tcl_UniChar *unicode, /* String to append. */ | | | | 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 | *---------------------------------------------------------------------- */ static void AppendUnicodeToUnicodeRep( Tcl_Obj *objPtr, /* Points to the object to append to. */ const Tcl_UniChar *unicode, /* String to append. */ size_t appendNumChars) /* Number of chars of "unicode" to append. */ { String *stringPtr; int numChars; if (appendNumChars == TCL_STRLEN) { appendNumChars = UnicodeLength(unicode); } if (appendNumChars == 0) { return; } SetStringFromAny(NULL, objPtr); |
︙ | ︙ | |||
1403 1404 1405 1406 1407 1408 1409 | * explanation of this growth algorithm. */ numChars = stringPtr->numChars + appendNumChars; stringCheckLimits(numChars); if (numChars > stringPtr->maxChars) { | | | 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 | * explanation of this growth algorithm. */ numChars = stringPtr->numChars + appendNumChars; stringCheckLimits(numChars); if (numChars > stringPtr->maxChars) { ptrdiff_t offset = -1; /* * Protect against case where unicode points into the existing * stringPtr->unicode array. Force it to follow any relocations due to * the reallocs below. */ |
︙ | ︙ | |||
1463 1464 1465 1466 1467 1468 1469 | *---------------------------------------------------------------------- */ static void AppendUnicodeToUtfRep( Tcl_Obj *objPtr, /* Points to the object to append to. */ const Tcl_UniChar *unicode, /* String to convert to UTF. */ | | | | 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 | *---------------------------------------------------------------------- */ static void AppendUnicodeToUtfRep( Tcl_Obj *objPtr, /* Points to the object to append to. */ const Tcl_UniChar *unicode, /* String to convert to UTF. */ size_t numChars) /* Number of chars of "unicode" to convert. */ { String *stringPtr = GET_STRING(objPtr); numChars = ExtendStringRepWithUnicode(objPtr, unicode, numChars); if (stringPtr->numChars != TCL_STRLEN) { stringPtr->numChars += numChars; } #if COMPAT /* * Invalidate the unicode rep. */ |
︙ | ︙ | |||
1504 1505 1506 1507 1508 1509 1510 | *---------------------------------------------------------------------- */ static void AppendUtfToUnicodeRep( Tcl_Obj *objPtr, /* Points to the object to append to. */ const char *bytes, /* String to convert to Unicode. */ | | | | 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 | *---------------------------------------------------------------------- */ static void AppendUtfToUnicodeRep( Tcl_Obj *objPtr, /* Points to the object to append to. */ const char *bytes, /* String to convert to Unicode. */ size_t numBytes) /* Number of bytes of "bytes" to convert. */ { String *stringPtr; if (numBytes == 0) { return; } ExtendUnicodeRepWithString(objPtr, bytes, numBytes, TCL_STRLEN); TclInvalidateStringRep(objPtr); stringPtr = GET_STRING(objPtr); stringPtr->allocated = 0; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1540 1541 1542 1543 1544 1545 1546 | *---------------------------------------------------------------------- */ static void AppendUtfToUtfRep( Tcl_Obj *objPtr, /* Points to the object to append to. */ const char *bytes, /* String to append. */ | | | | | | 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 | *---------------------------------------------------------------------- */ static void AppendUtfToUtfRep( Tcl_Obj *objPtr, /* Points to the object to append to. */ const char *bytes, /* String to append. */ size_t numBytes) /* Number of bytes of "bytes" to append. */ { String *stringPtr; size_t newLength, oldLength; if (numBytes == 0) { return; } /* * Copy the new string onto the end of the old string, then add the * trailing null. */ if (objPtr->bytes == NULL) { objPtr->length = 0; } oldLength = objPtr->length; newLength = numBytes + oldLength; if (newLength < oldLength) { Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); } stringPtr = GET_STRING(objPtr); if (newLength > stringPtr->allocated) { ptrdiff_t offset = -1; /* * Protect against case where unicode points into the existing * stringPtr->unicode array. Force it to follow any relocations due to * the reallocs below. */ |
︙ | ︙ | |||
1598 1599 1600 1601 1602 1603 1604 | } } /* * Invalidate the unicode data. */ | | | 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 | } } /* * Invalidate the unicode data. */ stringPtr->numChars = TCL_STRLEN; stringPtr->hasUnicode = 0; memmove(objPtr->bytes + oldLength, bytes, numBytes); objPtr->bytes[newLength] = 0; objPtr->length = newLength; } |
︙ | ︙ | |||
1639 1640 1641 1642 1643 1644 1645 | while (1) { const char *bytes = va_arg(argList, char *); if (bytes == NULL) { break; } | | | 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 | while (1) { const char *bytes = va_arg(argList, char *); if (bytes == NULL) { break; } Tcl_AppendToObj(objPtr, bytes, TCL_STRLEN); } } /* *---------------------------------------------------------------------- * * Tcl_AppendStringsToObj -- |
︙ | ︙ | |||
1698 1699 1700 1701 1702 1703 1704 | */ int Tcl_AppendFormatToObj( Tcl_Interp *interp, Tcl_Obj *appendObj, const char *format, | | > | | | 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 | */ int Tcl_AppendFormatToObj( Tcl_Interp *interp, Tcl_Obj *appendObj, const char *format, size_t objc, Tcl_Obj *const objv[]) { const char *span = format, *msg, *errCode; size_t numBytes = 0, objIndex = 0; int gotXpg = 0, gotSequential = 0; size_t originalLength, limit; static const char *mixedXPG = "cannot mix \"%\" and \"%n$\" conversion specifiers"; static const char *const badIndex[2] = { "not enough arguments for all format specifiers", "\"%n$\" argument index out of range" }; static const char *overflow = "max size for a Tcl value exceeded"; |
︙ | ︙ | |||
1726 1727 1728 1729 1730 1731 1732 | * Format string is NUL-terminated. */ while (*format != '\0') { char *end; int gotMinus, gotHash, gotZero, gotSpace, gotPlus, sawFlag; int width, gotPrecision, precision, useShort, useWide, useBig; | | > | 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 | * Format string is NUL-terminated. */ while (*format != '\0') { char *end; int gotMinus, gotHash, gotZero, gotSpace, gotPlus, sawFlag; int width, gotPrecision, precision, useShort, useWide, useBig; int newXpg, allocSegment = 0, segmentLimit; size_t numChars, segmentNumBytes; Tcl_Obj *segment; Tcl_UniChar ch; int step = Tcl_UtfToUniChar(format, &ch); format += step; if (ch != '%') { numBytes += step; |
︙ | ︙ | |||
1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 | newXpg = 0; if (isdigit(UCHAR(ch))) { int position = strtoul(format, &end, 10); if (*end == '$') { newXpg = 1; objIndex = position - 1; format = end + 1; step = Tcl_UtfToUniChar(format, &ch); } } if (newXpg) { if (gotSequential) { msg = mixedXPG; errCode = "MIXEDSPECTYPES"; goto errorMsg; } gotXpg = 1; } else { if (gotXpg) { msg = mixedXPG; errCode = "MIXEDSPECTYPES"; goto errorMsg; } gotSequential = 1; } | > > > | > | 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 | newXpg = 0; if (isdigit(UCHAR(ch))) { int position = strtoul(format, &end, 10); if (*end == '$') { newXpg = 1; if (position == 0) { goto badXpgIndex; } objIndex = position - 1; format = end + 1; step = Tcl_UtfToUniChar(format, &ch); } } if (newXpg) { if (gotSequential) { msg = mixedXPG; errCode = "MIXEDSPECTYPES"; goto errorMsg; } gotXpg = 1; } else { if (gotXpg) { msg = mixedXPG; errCode = "MIXEDSPECTYPES"; goto errorMsg; } gotSequential = 1; } if (objIndex >= objc) { badXpgIndex: msg = badIndex[gotXpg]; errCode = gotXpg ? "INDEXRANGE" : "FIELDVARMISMATCH"; goto errorMsg; } /* * Step 2. Set of flags. |
︙ | ︙ | |||
1929 1930 1931 1932 1933 1934 1935 | span = format; /* * Step 6. The actual conversion character. */ segment = objv[objIndex]; | | | 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 | span = format; /* * Step 6. The actual conversion character. */ segment = objv[objIndex]; numChars = TCL_STRLEN; if (ch == 'i') { ch = 'd'; } switch (ch) { case '\0': msg = "format string ended in middle of field specifier"; errCode = "INCOMPLETE"; |
︙ | ︙ | |||
2060 2061 2062 2063 2064 2065 2066 | segmentLimit -= 2; break; } } switch (ch) { case 'd': { | | | 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 | segmentLimit -= 2; break; } } switch (ch) { case 'd': { size_t length; Tcl_Obj *pure; const char *bytes; if (useShort) { pure = Tcl_NewLongObj((long) s); } else if (useWide) { pure = Tcl_NewWideIntObj(w); |
︙ | ︙ | |||
2337 2338 2339 2340 2341 2342 2343 | case 'E': case 'G': case 'X': { Tcl_SetObjLength(segment, Tcl_UtfToUpper(TclGetString(segment))); } } | | | 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 | case 'E': case 'G': case 'X': { Tcl_SetObjLength(segment, Tcl_UtfToUpper(TclGetString(segment))); } } if (width>0 && numChars==TCL_STRLEN) { numChars = Tcl_GetCharLength(segment); } if (!gotMinus && width>0) { if (numChars < width) { limit -= width - numChars; } while (numChars < width) { |
︙ | ︙ | |||
2391 2392 2393 2394 2395 2396 2397 | numBytes = 0; } return TCL_OK; errorMsg: if (interp != NULL) { | | | 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 | numBytes = 0; } return TCL_OK; errorMsg: if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", errCode, NULL); } error: Tcl_SetObjLength(appendObj, originalLength); return TCL_ERROR; } |
︙ | ︙ | |||
2417 2418 2419 2420 2421 2422 2423 | *--------------------------------------------------------------------------- */ Tcl_Obj * Tcl_Format( Tcl_Interp *interp, const char *format, | | | 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 | *--------------------------------------------------------------------------- */ Tcl_Obj * Tcl_Format( Tcl_Interp *interp, const char *format, size_t objc, Tcl_Obj *const objv[]) { int result; Tcl_Obj *objPtr = Tcl_NewObj(); result = Tcl_AppendFormatToObj(interp, objPtr, format, objc, objv); if (result != TCL_OK) { |
︙ | ︙ | |||
2449 2450 2451 2452 2453 2454 2455 | static void AppendPrintfToObjVA( Tcl_Obj *objPtr, const char *format, va_list argList) { | | > | 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 | static void AppendPrintfToObjVA( Tcl_Obj *objPtr, const char *format, va_list argList) { int code; size_t objc; Tcl_Obj **objv, *list = Tcl_NewObj(); const char *p; p = format; Tcl_IncrRefCount(list); while (*p != '\0') { int size = 0, seekingConversion = 1, gotPrecision = 0; |
︙ | ︙ | |||
2504 2505 2506 2507 2508 2509 2510 | q = bytes + TCL_UTF_MAX; while ((bytes < end) && (bytes < q) && ((*bytes & 0xC0) == 0x80)) { bytes++; } Tcl_ListObjAppendElement(NULL, list, | | | 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 | q = bytes + TCL_UTF_MAX; while ((bytes < end) && (bytes < q) && ((*bytes & 0xC0) == 0x80)) { bytes++; } Tcl_ListObjAppendElement(NULL, list, Tcl_NewStringObj(bytes, (size_t)(end - bytes))); break; } case 'c': case 'i': case 'u': case 'd': |
︙ | ︙ | |||
2653 2654 2655 2656 2657 2658 2659 | *--------------------------------------------------------------------------- */ static void ReverseBytes( unsigned char *to, /* Copy bytes into here... */ unsigned char *from, /* ...from here... */ | | | 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 | *--------------------------------------------------------------------------- */ static void ReverseBytes( unsigned char *to, /* Copy bytes into here... */ unsigned char *from, /* ...from here... */ size_t count) /* Until this many are copied, */ /* reversing as you go. */ { unsigned char *src = from + count; if (to == from) { /* Reversing in place */ while (--src > to) { unsigned char c = *src; |
︙ | ︙ | |||
2679 2680 2681 2682 2683 2684 2685 | TclStringObjReverse( Tcl_Obj *objPtr) { String *stringPtr; Tcl_UniChar ch; if (TclIsPureByteArray(objPtr)) { | | | 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 | TclStringObjReverse( Tcl_Obj *objPtr) { String *stringPtr; Tcl_UniChar ch; if (TclIsPureByteArray(objPtr)) { size_t numBytes; unsigned char *from = Tcl_GetByteArrayFromObj(objPtr, &numBytes); if (Tcl_IsShared(objPtr)) { objPtr = Tcl_NewByteArrayObj(NULL, numBytes); } ReverseBytes(Tcl_GetByteArrayFromObj(objPtr, NULL), from, numBytes); return objPtr; |
︙ | ︙ | |||
2732 2733 2734 2735 2736 2737 2738 | if (Tcl_IsShared(objPtr)) { objPtr = Tcl_NewObj(); Tcl_SetObjLength(objPtr, numBytes); } to = objPtr->bytes; | | | | | | | 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 | if (Tcl_IsShared(objPtr)) { objPtr = Tcl_NewObj(); Tcl_SetObjLength(objPtr, numBytes); } to = objPtr->bytes; if (numChars == TCL_STRLEN || numChars < numBytes) { /* * Either numChars == TCL_STRLEN and we don't know how many chars * are represented by objPtr->bytes and we need Pass 1 just in * case, or numChars >= 0 and we know we have fewer chars than * bytes, so we know there's a multibyte character needing Pass 1. * * Pass 1. Reverse the bytes of each multi-byte character. */ int charCount = 0; int bytesLeft = numBytes; while (bytesLeft) { |
︙ | ︙ | |||
2802 2803 2804 2805 2806 2807 2808 | stringPtr->numChars); } static void ExtendUnicodeRepWithString( Tcl_Obj *objPtr, const char *bytes, | | | | | 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 | stringPtr->numChars); } static void ExtendUnicodeRepWithString( Tcl_Obj *objPtr, const char *bytes, size_t numBytes, size_t numAppendChars) { String *stringPtr = GET_STRING(objPtr); int needed, numOrigChars = 0; Tcl_UniChar *dst; if (stringPtr->hasUnicode) { numOrigChars = stringPtr->numChars; } if (numAppendChars == TCL_STRLEN) { TclNumUtfChars(numAppendChars, bytes, numBytes); } needed = numOrigChars + numAppendChars; stringCheckLimits(needed); if (needed > stringPtr->maxChars) { GrowUnicodeBuffer(objPtr, needed); |
︙ | ︙ | |||
2860 2861 2862 2863 2864 2865 2866 | Tcl_Obj *copyPtr) /* Object with internal rep to set. Must not * currently have an internal rep.*/ { String *srcStringPtr = GET_STRING(srcPtr); String *copyStringPtr = NULL; #if COMPAT==0 | | | 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 | Tcl_Obj *copyPtr) /* Object with internal rep to set. Must not * currently have an internal rep.*/ { String *srcStringPtr = GET_STRING(srcPtr); String *copyStringPtr = NULL; #if COMPAT==0 if (srcStringPtr->numChars == TCL_STRLEN) { /* * The String struct in the source value holds zero useful data. Don't * bother copying it. Don't even bother allocating space in which to * copy it. Just let the copy be untyped. */ return; |
︙ | ︙ | |||
2979 2980 2981 2982 2983 2984 2985 | TclFreeIntRep(objPtr); /* * Create a basic String intrep that just points to the UTF-8 string * already in place at objPtr->bytes. */ | | | 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 | TclFreeIntRep(objPtr); /* * Create a basic String intrep that just points to the UTF-8 string * already in place at objPtr->bytes. */ stringPtr->numChars = TCL_STRLEN; stringPtr->allocated = objPtr->length; stringPtr->maxChars = 0; stringPtr->hasUnicode = 0; SET_STRING(objPtr, stringPtr); objPtr->typePtr = &tclStringType; } return TCL_OK; |
︙ | ︙ | |||
3025 3026 3027 3028 3029 3030 3031 | } } static int ExtendStringRepWithUnicode( Tcl_Obj *objPtr, const Tcl_UniChar *unicode, | | | | | 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 | } } static int ExtendStringRepWithUnicode( Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t numChars) { /* * Pre-condition: this is the "string" Tcl_ObjType. */ size_t i, origLength, size = 0; char *dst, buf[TCL_UTF_MAX]; String *stringPtr = GET_STRING(objPtr); if (numChars == TCL_STRLEN) { numChars = UnicodeLength(unicode); } if (numChars == 0) { return 0; } |
︙ | ︙ | |||
3057 3058 3059 3060 3061 3062 3063 | */ if (numChars <= (INT_MAX - size)/TCL_UTF_MAX && stringPtr->allocated >= size + numChars * TCL_UTF_MAX) { goto copyBytes; } | | | | > | | > | 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 | */ if (numChars <= (INT_MAX - size)/TCL_UTF_MAX && stringPtr->allocated >= size + numChars * TCL_UTF_MAX) { goto copyBytes; } for (i = 0; i < numChars; i++) { size_t oldSize = size; size += Tcl_UniCharToUtf((int) unicode[i], buf); if (oldSize > size) { Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); } } /* * Grow space if needed. */ if (size > stringPtr->allocated) { |
︙ | ︙ |
Changes to generic/tclStubInit.c.
︙ | ︙ | |||
232 233 234 235 236 237 238 239 240 241 242 243 244 245 | static int formatInt(char *buffer, int n){ return TclFormatInt(buffer, (long)n); } #define TclFormatInt (int(*)(char *, long))formatInt #endif #endif /* * WARNING: The contents of this file is automatically generated by the * tools/genStubs.tcl script. Any modifications to the function declarations * below should be made in the generic/tcl.decls script. */ | > > > | 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | static int formatInt(char *buffer, int n){ return TclFormatInt(buffer, (long)n); } #define TclFormatInt (int(*)(char *, long))formatInt #endif #else /* UNIX and MAC */ # define TclpLocaltime_unix TclpLocaltime # define TclpGmtime_unix TclpGmtime #endif /* * WARNING: The contents of this file is automatically generated by the * tools/genStubs.tcl script. Any modifications to the function declarations * below should be made in the generic/tcl.decls script. */ |
︙ | ︙ |
Changes to generic/tclTest.c.
︙ | ︙ | |||
146 147 148 149 150 151 152 | static Tcl_ThreadCreateType AsyncThreadProc(ClientData); #endif static void CleanupTestSetassocdataTests( ClientData clientData, Tcl_Interp *interp); static void CmdDelProc1(ClientData clientData); static void CmdDelProc2(ClientData clientData); static int CmdProc1(ClientData clientData, | | > | > | | | | | > | | | | | | | > | > | | > | | > | > | > | > | > | > | > | > | > | | | > | | | | | > | > | | > | | | > | | > | > | > | > | > | | > | > | | > | > | > | > | > | | | | | | | | | > | > | > | > | | > | > | > | > | | | > | > | | | | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 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 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 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 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 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | static Tcl_ThreadCreateType AsyncThreadProc(ClientData); #endif static void CleanupTestSetassocdataTests( ClientData clientData, Tcl_Interp *interp); static void CmdDelProc1(ClientData clientData); static void CmdDelProc2(ClientData clientData); static int CmdProc1(ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv); static int CmdProc2(ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv); static void CmdTraceDeleteProc( ClientData clientData, Tcl_Interp *interp, int level, char *command, Tcl_CmdProc *cmdProc, ClientData cmdClientData, size_t argc, const char *argv[]); static void CmdTraceProc(ClientData clientData, Tcl_Interp *interp, int level, char *command, Tcl_CmdProc *cmdProc, ClientData cmdClientData, size_t argc, const char *argv[]); static int CreatedCommandProc( ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv); static int CreatedCommandProc2( ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv); static void DelCallbackProc(ClientData clientData, Tcl_Interp *interp); static int DelCmdProc(ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv); static void DelDeleteProc(ClientData clientData); static void EncodingFreeProc(ClientData clientData); static int EncodingToUtfProc(ClientData clientData, const char *src, size_t srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, size_t dstLen, size_t *srcReadPtr, size_t *dstWrotePtr, size_t *dstCharsPtr); static int EncodingFromUtfProc(ClientData clientData, const char *src, size_t srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, size_t dstLen, size_t *srcReadPtr, size_t *dstWrotePtr, size_t *dstCharsPtr); static void ExitProcEven(ClientData clientData); static void ExitProcOdd(ClientData clientData); static int GetTimesCmd(ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv); static void MainLoop(void); static int NoopCmd(ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv); static int NoopObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int ObjTraceProc(ClientData clientData, Tcl_Interp *interp, int level, const char *command, Tcl_Command commandToken, size_t objc, Tcl_Obj *const objv[]); static void ObjTraceDeleteProc(ClientData clientData); static void PrintParse(Tcl_Interp *interp, Tcl_Parse *parsePtr); static void SpecialFree(char *blockPtr); static int StaticInitProc(Tcl_Interp *interp); static int TestasyncCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestcmdinfoCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestcmdtokenCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestcmdtraceCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestconcatobjCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestcreatecommandCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestdcallCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestdelCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestdelassocdataCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestdoubledigitsObjCmd(ClientData dummy, Tcl_Interp* interp, size_t objc, Tcl_Obj* const objv[]); static int TestdstringCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestencodingObjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestevalexObjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestevalobjvObjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TesteventObjCmd(ClientData unused, Tcl_Interp *interp, size_t argc, Tcl_Obj *const objv[]); static int TesteventProc(Tcl_Event *event, int flags); static int TesteventDeleteProc(Tcl_Event *event, ClientData clientData); static int TestexithandlerCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestexprlongCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestexprlongobjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestexprdoubleCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestexprdoubleobjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestexprparserObjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestexprstringCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestfileCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestfilelinkCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestfeventCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestgetassocdataCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestgetintCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestgetplatformCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestgetvarfullnameCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestinterpdeleteCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestlinkCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestlocaleCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestmainthreadCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestsetmainloopCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestexitmainloopCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestpanicCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestparseargsCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestparserObjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestparsevarObjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestparsevarnameObjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestregexpObjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestreturnObjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static void TestregexpXflags(const char *string, size_t length, int *cflagsPtr, int *eflagsPtr); static int TestsaveresultCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static void TestsaveresultFree(char *blockPtr); static int TestsetassocdataCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestsetCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int Testset2Cmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestseterrorcodeCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestsetobjerrorcodeCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestsetplatformCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TeststaticpkgCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TesttranslatefilenameCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestupvarCmd(ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv); static int TestWrongNumArgsObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestGetIndexFromObjStructObjCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestChannelCmd(ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv); static int TestChannelEventCmd(ClientData clientData, Tcl_Interp *interp, size_t argc, const char **argv); static int TestFilesystemObjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestSimpleFilesystemObjCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static void TestReport(const char *cmd, Tcl_Obj *arg1, Tcl_Obj *arg2); static Tcl_Obj * TestReportGetNativePath(Tcl_Obj *pathPtr); static Tcl_FSStatProc TestReportStat; static Tcl_FSAccessProc TestReportAccess; static Tcl_FSOpenFileChannelProc TestReportOpenFileChannel; static Tcl_FSMatchInDirectoryProc TestReportMatchInDirectory; |
︙ | ︙ | |||
376 377 378 379 380 381 382 | static Tcl_FSAccessProc SimpleAccess; static Tcl_FSOpenFileChannelProc SimpleOpenFileChannel; static Tcl_FSListVolumesProc SimpleListVolumes; static Tcl_FSPathInFilesystemProc SimplePathInFilesystem; static Tcl_Obj * SimpleRedirect(Tcl_Obj *pathPtr); static Tcl_FSMatchInDirectoryProc SimpleMatchInDirectory; static int TestNumUtfCharsCmd(ClientData clientData, | | | | | | | 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 | static Tcl_FSAccessProc SimpleAccess; static Tcl_FSOpenFileChannelProc SimpleOpenFileChannel; static Tcl_FSListVolumesProc SimpleListVolumes; static Tcl_FSPathInFilesystemProc SimplePathInFilesystem; static Tcl_Obj * SimpleRedirect(Tcl_Obj *pathPtr); static Tcl_FSMatchInDirectoryProc SimpleMatchInDirectory; static int TestNumUtfCharsCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestHashSystemHashCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestNRELevels(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestInterpResolverCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); #if defined(HAVE_CPUID) || defined(__WIN32__) static int TestcpuidCmd(ClientData dummy, Tcl_Interp* interp, size_t objc, Tcl_Obj *const objv[]); #endif static const Tcl_Filesystem testReportingFilesystem = { "reporting", sizeof(Tcl_Filesystem), TCL_FILESYSTEM_VERSION_1, |
︙ | ︙ | |||
500 501 502 503 504 505 506 | int Tcltest_Init( Tcl_Interp *interp) /* Interpreter for application. */ { Tcl_Obj *listPtr; Tcl_Obj **objv; | > | | 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | int Tcltest_Init( Tcl_Interp *interp) /* Interpreter for application. */ { Tcl_Obj *listPtr; Tcl_Obj **objv; size_t objc; int index; static const char *const specialOptions[] = { "-appinitprocerror", "-appinitprocdeleteinterp", "-appinitprocclosestderr", "-appinitprocsetrcfile", NULL }; if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) { return TCL_ERROR; |
︙ | ︙ | |||
758 759 760 761 762 763 764 | */ /* ARGSUSED */ static int TestasyncCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 | */ /* ARGSUSED */ static int TestasyncCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { TestAsyncHandler *asyncPtr, *prevPtr; int id, code; static int nextId = 1; if (argc < 2) { |
︙ | ︙ | |||
838 839 840 841 842 843 844 | for (asyncPtr = firstHandler; asyncPtr != NULL; asyncPtr = asyncPtr->nextPtr) { if (asyncPtr->id == id) { Tcl_AsyncMark(asyncPtr->handler); break; } } | | | 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 | for (asyncPtr = firstHandler; asyncPtr != NULL; asyncPtr = asyncPtr->nextPtr) { if (asyncPtr->id == id) { Tcl_AsyncMark(asyncPtr->handler); break; } } Tcl_SetObjResult(interp, Tcl_NewStringObj(argv[3], TCL_STRLEN)); Tcl_MutexUnlock(&asyncTestMutex); return code; #ifdef TCL_THREADS } else if (strcmp(argv[1], "marklater") == 0) { if (argc != 3) { goto wrongNumArgs; } |
︙ | ︙ | |||
985 986 987 988 989 990 991 | */ /* ARGSUSED */ static int TestcmdinfoCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 | */ /* ARGSUSED */ static int TestcmdinfoCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_CmdInfo info; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option cmdName\"", NULL); |
︙ | ︙ | |||
1056 1057 1058 1059 1060 1061 1062 | } /*ARGSUSED*/ static int CmdProc1( ClientData clientData, /* String to return. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | | | | 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 | } /*ARGSUSED*/ static int CmdProc1( ClientData clientData, /* String to return. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_AppendResult(interp, "CmdProc1 ", (char *) clientData, NULL); return TCL_OK; } /*ARGSUSED*/ static int CmdProc2( ClientData clientData, /* String to return. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_AppendResult(interp, "CmdProc2 ", (char *) clientData, NULL); return TCL_OK; } static void CmdDelProc1( ClientData clientData) /* String to save. */ { Tcl_DStringInit(&delString); Tcl_DStringAppend(&delString, "CmdDelProc1 ", TCL_STRLEN); Tcl_DStringAppend(&delString, (char *) clientData, TCL_STRLEN); } static void CmdDelProc2( ClientData clientData) /* String to save. */ { Tcl_DStringInit(&delString); Tcl_DStringAppend(&delString, "CmdDelProc2 ", TCL_STRLEN); Tcl_DStringAppend(&delString, (char *) clientData, TCL_STRLEN); } /* *---------------------------------------------------------------------- * * TestcmdtokenCmd -- * |
︙ | ︙ | |||
1115 1116 1117 1118 1119 1120 1121 | */ /* ARGSUSED */ static int TestcmdtokenCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 | */ /* ARGSUSED */ static int TestcmdtokenCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_Command token; int *l; char buf[30]; if (argc != 3) { |
︙ | ︙ | |||
1179 1180 1181 1182 1183 1184 1185 | */ /* ARGSUSED */ static int TestcmdtraceCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 | */ /* ARGSUSED */ static int TestcmdtraceCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_DString buffer; int result; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
︙ | ︙ | |||
1276 1277 1278 1279 1280 1281 1282 | Tcl_Interp *interp, /* Current interpreter. */ int level, /* Current trace level. */ char *command, /* The command being traced (after * substitutions). */ Tcl_CmdProc *cmdProc, /* Points to command's command procedure. */ ClientData cmdClientData, /* Client data associated with command * procedure. */ | | | 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 | Tcl_Interp *interp, /* Current interpreter. */ int level, /* Current trace level. */ char *command, /* The command being traced (after * substitutions). */ Tcl_CmdProc *cmdProc, /* Points to command's command procedure. */ ClientData cmdClientData, /* Client data associated with command * procedure. */ size_t argc, /* Number of arguments. */ const char *argv[]) /* Argument strings. */ { Tcl_DString *bufPtr = (Tcl_DString *) clientData; int i; Tcl_DStringAppendElement(bufPtr, command); |
︙ | ︙ | |||
1301 1302 1303 1304 1305 1306 1307 | Tcl_Interp *interp, /* Current interpreter. */ int level, /* Current trace level. */ char *command, /* The command being traced (after * substitutions). */ Tcl_CmdProc *cmdProc, /* Points to command's command procedure. */ ClientData cmdClientData, /* Client data associated with command * procedure. */ | | | | | | | 1344 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 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 | Tcl_Interp *interp, /* Current interpreter. */ int level, /* Current trace level. */ char *command, /* The command being traced (after * substitutions). */ Tcl_CmdProc *cmdProc, /* Points to command's command procedure. */ ClientData cmdClientData, /* Client data associated with command * procedure. */ size_t argc, /* Number of arguments. */ const char *argv[]) /* Argument strings. */ { /* * Remove ourselves to test whether calling Tcl_DeleteTrace within a trace * callback causes the for loop in TclNRExecuteByteCode that calls traces * to reference freed memory. */ Tcl_DeleteTrace(interp, cmdTrace); } static int ObjTraceProc( ClientData clientData, /* unused */ Tcl_Interp *interp, /* Tcl interpreter */ int level, /* Execution level */ const char *command, /* Command being executed */ Tcl_Command token, /* Command information */ size_t objc, /* Parameter count */ Tcl_Obj *const objv[]) /* Parameter list */ { const char *word = Tcl_GetString(objv[0]); if (!strcmp(word, "Error")) { Tcl_SetObjResult(interp, Tcl_NewStringObj(command, TCL_STRLEN)); return TCL_ERROR; } else if (!strcmp(word, "Break")) { return TCL_BREAK; } else if (!strcmp(word, "Continue")) { return TCL_CONTINUE; } else if (!strcmp(word, "Return")) { return TCL_RETURN; |
︙ | ︙ | |||
1374 1375 1376 1377 1378 1379 1380 | *---------------------------------------------------------------------- */ static int TestcreatecommandCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 | *---------------------------------------------------------------------- */ static int TestcreatecommandCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option\"", NULL); return TCL_ERROR; } |
︙ | ︙ | |||
1404 1405 1406 1407 1408 1409 1410 | return TCL_OK; } static int CreatedCommandProc( ClientData clientData, /* String to return. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 | return TCL_OK; } static int CreatedCommandProc( ClientData clientData, /* String to return. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_CmdInfo info; int found; found = Tcl_GetCommandInfo(interp, "test_ns_basic::createdcommand", &info); |
︙ | ︙ | |||
1426 1427 1428 1429 1430 1431 1432 | return TCL_OK; } static int CreatedCommandProc2( ClientData clientData, /* String to return. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 | return TCL_OK; } static int CreatedCommandProc2( ClientData clientData, /* String to return. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_CmdInfo info; int found; found = Tcl_GetCommandInfo(interp, "value:at:", &info); if (!found) { |
︙ | ︙ | |||
1465 1466 1467 1468 1469 1470 1471 | */ /* ARGSUSED */ static int TestdcallCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | | < | < | 1508 1509 1510 1511 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 | */ /* ARGSUSED */ static int TestdcallCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { size_t i; int id; delInterp = Tcl_CreateInterp(); Tcl_DStringInit(&delString); for (i = 1; i < argc; i++) { if (Tcl_GetInt(interp, argv[i], &id) != TCL_OK) { return TCL_ERROR; } if (id < 0) { Tcl_DontCallWhenDeleted(delInterp, DelCallbackProc, INT2PTR(-id)); } else { Tcl_CallWhenDeleted(delInterp, DelCallbackProc, INT2PTR(id)); } } Tcl_DeleteInterp(delInterp); Tcl_DStringResult(interp, &delString); return TCL_OK; } |
︙ | ︙ | |||
1530 1531 1532 1533 1534 1535 1536 | */ /* ARGSUSED */ static int TestdelCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 | */ /* ARGSUSED */ static int TestdelCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { DelCmd *dPtr; Tcl_Interp *slave; if (argc != 4) { Tcl_AppendResult(interp, "wrong # args", NULL); |
︙ | ︙ | |||
1560 1561 1562 1563 1564 1565 1566 | return TCL_OK; } static int DelCmdProc( ClientData clientData, /* String result to return. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 | return TCL_OK; } static int DelCmdProc( ClientData clientData, /* String result to return. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { DelCmd *dPtr = (DelCmd *) clientData; Tcl_AppendResult(interp, dPtr->deleteCmd, NULL); ckfree(dPtr->deleteCmd); ckfree(dPtr); |
︙ | ︙ | |||
1605 1606 1607 1608 1609 1610 1611 | *---------------------------------------------------------------------- */ static int TestdelassocdataCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 | *---------------------------------------------------------------------- */ static int TestdelassocdataCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { if (argc != 2) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], " data_key\"", NULL); return TCL_ERROR; } |
︙ | ︙ | |||
1639 1640 1641 1642 1643 1644 1645 | * type - One of 'shortest', 'Steele', 'e', 'f' * shorten - Indicates that the 'shorten' flag should be passed in. * *----------------------------------------------------------------------------- */ static int | | | | < < | | < | 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 | * type - One of 'shortest', 'Steele', 'e', 'f' * shorten - Indicates that the 'shorten' flag should be passed in. * *----------------------------------------------------------------------------- */ static int TestdoubledigitsObjCmd( ClientData unused, /* NULL */ Tcl_Interp* interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj* const objv[]) /* Parameter vector */ { static const char* options[] = { "shortest", "Steele", "e", "f", NULL |
︙ | ︙ | |||
1689 1690 1691 1692 1693 1694 1695 | || TclIsNaN(objv[1]->internalRep.doubleValue)) { status = TCL_OK; memcpy(&d, &(objv[1]->internalRep.doubleValue), sizeof(double)); } } if (status != TCL_OK || Tcl_GetIntFromObj(interp, objv[2], &ndigits) != TCL_OK | | | | > | 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 | || TclIsNaN(objv[1]->internalRep.doubleValue)) { status = TCL_OK; memcpy(&d, &(objv[1]->internalRep.doubleValue), sizeof(double)); } } if (status != TCL_OK || Tcl_GetIntFromObj(interp, objv[2], &ndigits) != TCL_OK || Tcl_GetIndexFromObjStruct(interp, objv[3], options, sizeof(char *), "conversion type", TCL_EXACT, &type) != TCL_OK) { fprintf(stderr, "bad value? %g\n", d); return TCL_ERROR; } type = types[type]; if (objc > 4) { if (strcmp(Tcl_GetString(objv[4]), "shorten")) { Tcl_SetObjResult(interp, Tcl_NewStringObj("bad flag", TCL_STRLEN)); return TCL_ERROR; } type |= TCL_DD_SHORTEN_FLAG; } str = TclDoubleDigits(d, ndigits, type, &decpt, &signum, &endPtr); strObj = Tcl_NewStringObj(str, endPtr-str); ckfree(str); |
︙ | ︙ | |||
1735 1736 1737 1738 1739 1740 1741 | */ /* ARGSUSED */ static int TestdstringCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 | */ /* ARGSUSED */ static int TestdstringCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { int count; if (argc < 2) { wrongNumArgs: Tcl_AppendResult(interp, "wrong # args", NULL); |
︙ | ︙ | |||
1786 1787 1788 1789 1790 1791 1792 | } else if (strcmp(argv[2], "staticlarge") == 0) { Tcl_AppendResult(interp, "first0 first1 first2 first3 first4 first5 first6 first7 first8 first9\nsecond0 second1 second2 second3 second4 second5 second6 second7 second8 second9\nthird0 third1 third2 third3 third4 third5 third6 third7 third8 third9\nfourth0 fourth1 fourth2 fourth3 fourth4 fourth5 fourth6 fourth7 fourth8 fourth9\nfifth0 fifth1 fifth2 fifth3 fifth4 fifth5 fifth6 fifth7 fifth8 fifth9\nsixth0 sixth1 sixth2 sixth3 sixth4 sixth5 sixth6 sixth7 sixth8 sixth9\nseventh0 seventh1 seventh2 seventh3 seventh4 seventh5 seventh6 seventh7 seventh8 seventh9\n", NULL); } else if (strcmp(argv[2], "free") == 0) { char *s = ckalloc(100); strcpy(s, "This is a malloc-ed string"); Tcl_SetResult(interp, s, TCL_DYNAMIC); } else if (strcmp(argv[2], "special") == 0) { | | | 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 | } else if (strcmp(argv[2], "staticlarge") == 0) { Tcl_AppendResult(interp, "first0 first1 first2 first3 first4 first5 first6 first7 first8 first9\nsecond0 second1 second2 second3 second4 second5 second6 second7 second8 second9\nthird0 third1 third2 third3 third4 third5 third6 third7 third8 third9\nfourth0 fourth1 fourth2 fourth3 fourth4 fourth5 fourth6 fourth7 fourth8 fourth9\nfifth0 fifth1 fifth2 fifth3 fifth4 fifth5 fifth6 fifth7 fifth8 fifth9\nsixth0 sixth1 sixth2 sixth3 sixth4 sixth5 sixth6 sixth7 sixth8 sixth9\nseventh0 seventh1 seventh2 seventh3 seventh4 seventh5 seventh6 seventh7 seventh8 seventh9\n", NULL); } else if (strcmp(argv[2], "free") == 0) { char *s = ckalloc(100); strcpy(s, "This is a malloc-ed string"); Tcl_SetResult(interp, s, TCL_DYNAMIC); } else if (strcmp(argv[2], "special") == 0) { char *s = ((char *) ckalloc(100)) + 16; strcpy(s, "This is a specially-allocated string"); Tcl_SetResult(interp, s, SpecialFree); } else { Tcl_AppendResult(interp, "bad gresult option \"", argv[2], "\": must be staticsmall, staticlarge, free, or special", NULL); return TCL_ERROR; |
︙ | ︙ | |||
1862 1863 1864 1865 1866 1867 1868 | */ /* ARGSUSED */ static int TestencodingObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 | */ /* ARGSUSED */ static int TestencodingObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Encoding encoding; int index; size_t length; const char *string; TclEncoding *encodingPtr; static const char *const optionStrings[] = { "create", "delete", NULL }; enum options { ENC_CREATE, ENC_DELETE |
︙ | ︙ | |||
1927 1928 1929 1930 1931 1932 1933 | return TCL_OK; } static int EncodingToUtfProc( ClientData clientData, /* TclEncoding structure. */ const char *src, /* Source string in specified encoding. */ | | | | | | | | 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 | return TCL_OK; } static int EncodingToUtfProc( ClientData clientData, /* TclEncoding structure. */ const char *src, /* Source string in specified encoding. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Current state. */ char *dst, /* Output buffer. */ size_t dstLen, /* The maximum length of output buffer. */ size_t *srcReadPtr, /* Filled with number of bytes read. */ size_t *dstWrotePtr, /* Filled with number of bytes stored. */ size_t *dstCharsPtr) /* Filled with number of chars stored. */ { size_t len; TclEncoding *encodingPtr; encodingPtr = (TclEncoding *) clientData; Tcl_EvalEx(encodingPtr->interp, encodingPtr->toUtfCmd, -1, TCL_EVAL_GLOBAL); len = strlen(Tcl_GetStringResult(encodingPtr->interp)); if (len > dstLen) { |
︙ | ︙ | |||
1959 1960 1961 1962 1963 1964 1965 | return TCL_OK; } static int EncodingFromUtfProc( ClientData clientData, /* TclEncoding structure. */ const char *src, /* Source string in specified encoding. */ | | | | | | | | 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 | return TCL_OK; } static int EncodingFromUtfProc( ClientData clientData, /* TclEncoding structure. */ const char *src, /* Source string in specified encoding. */ size_t srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Current state. */ char *dst, /* Output buffer. */ size_t dstLen, /* The maximum length of output buffer. */ size_t *srcReadPtr, /* Filled with number of bytes read. */ size_t *dstWrotePtr, /* Filled with number of bytes stored. */ size_t *dstCharsPtr) /* Filled with number of chars stored. */ { size_t len; TclEncoding *encodingPtr; encodingPtr = (TclEncoding *) clientData; Tcl_EvalEx(encodingPtr->interp, encodingPtr->fromUtfCmd, -1, TCL_EVAL_GLOBAL); len = strlen(Tcl_GetStringResult(encodingPtr->interp)); if (len > dstLen) { |
︙ | ︙ | |||
2019 2020 2021 2022 2023 2024 2025 | *---------------------------------------------------------------------- */ static int TestevalexObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 | *---------------------------------------------------------------------- */ static int TestevalexObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { size_t length; int flags; const char *script; flags = 0; if (objc == 3) { const char *global = Tcl_GetStringFromObj(objv[2], &length); if (strcmp(global, "global") != 0) { Tcl_AppendResult(interp, "bad value \"", global, |
︙ | ︙ | |||
2064 2065 2066 2067 2068 2069 2070 | *---------------------------------------------------------------------- */ static int TestevalobjvObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 | *---------------------------------------------------------------------- */ static int TestevalobjvObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int evalGlobal; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "global word ?word ...?"); return TCL_ERROR; |
︙ | ︙ | |||
2113 2114 2115 2116 2117 2118 2119 | *---------------------------------------------------------------------- */ static int TesteventObjCmd( ClientData unused, /* Not used */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 | *---------------------------------------------------------------------- */ static int TesteventObjCmd( ClientData unused, /* Not used */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj *const objv[]) /* Parameter vector */ { static const char *const subcommands[] = { /* Possible subcommands */ "queue", "delete", NULL }; int subCmdIndex; /* Index of the chosen subcommand */ static const char *const positions[] = { /* Possible queue positions */ |
︙ | ︙ | |||
2292 2293 2294 2295 2296 2297 2298 | *---------------------------------------------------------------------- */ static int TestexithandlerCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 | *---------------------------------------------------------------------- */ static int TestexithandlerCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { int value; if (argc != 3) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], " create|delete value\"", NULL); |
︙ | ︙ | |||
2368 2369 2370 2371 2372 2373 2374 | *---------------------------------------------------------------------- */ static int TestexprlongCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 | *---------------------------------------------------------------------- */ static int TestexprlongCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { long exprResult; char buf[4 + TCL_INTEGER_SPACE]; int result; if (argc != 2) { |
︙ | ︙ | |||
2411 2412 2413 2414 2415 2416 2417 | *---------------------------------------------------------------------- */ static int TestexprlongobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 | *---------------------------------------------------------------------- */ static int TestexprlongobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { long exprResult; char buf[4 + TCL_INTEGER_SPACE]; int result; if (objc != 2) { |
︙ | ︙ | |||
2453 2454 2455 2456 2457 2458 2459 | *---------------------------------------------------------------------- */ static int TestexprdoubleCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 | *---------------------------------------------------------------------- */ static int TestexprdoubleCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { double exprResult; char buf[4 + TCL_DOUBLE_SPACE]; int result; if (argc != 2) { |
︙ | ︙ | |||
2497 2498 2499 2500 2501 2502 2503 | *---------------------------------------------------------------------- */ static int TestexprdoubleobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 | *---------------------------------------------------------------------- */ static int TestexprdoubleobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument objects. */ { double exprResult; char buf[4 + TCL_DOUBLE_SPACE]; int result; if (objc != 2) { |
︙ | ︙ | |||
2539 2540 2541 2542 2543 2544 2545 | *---------------------------------------------------------------------- */ static int TestexprstringCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 | *---------------------------------------------------------------------- */ static int TestexprstringCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { if (argc != 2) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], " expression\"", NULL); return TCL_ERROR; } |
︙ | ︙ | |||
2571 2572 2573 2574 2575 2576 2577 | *---------------------------------------------------------------------- */ static int TestfilelinkCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 | *---------------------------------------------------------------------- */ static int TestfilelinkCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_Obj *contents; if (objc < 2 || objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "source ?target?"); return TCL_ERROR; |
︙ | ︙ | |||
2638 2639 2640 2641 2642 2643 2644 | *---------------------------------------------------------------------- */ static int TestgetassocdataCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 | *---------------------------------------------------------------------- */ static int TestgetassocdataCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { char *res; if (argc != 2) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], " data_key\"", NULL); |
︙ | ︙ | |||
2676 2677 2678 2679 2680 2681 2682 | *---------------------------------------------------------------------- */ static int TestgetplatformCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 | *---------------------------------------------------------------------- */ static int TestgetplatformCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { static const char *const platformStrings[] = { "unix", "mac", "windows" }; TclPlatformType *platform; platform = TclGetPlatform(); |
︙ | ︙ | |||
2717 2718 2719 2720 2721 2722 2723 | */ /* ARGSUSED */ static int TestinterpdeleteCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 | */ /* ARGSUSED */ static int TestinterpdeleteCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_Interp *slaveToDelete; if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " path\"", NULL); |
︙ | ︙ | |||
2758 2759 2760 2761 2762 2763 2764 | */ /* ARGSUSED */ static int TestlinkCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 | */ /* ARGSUSED */ static int TestlinkCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { static int intVar = 43; static int boolVar = 4; static double realVar = 1.23; static Tcl_WideInt wideVar = Tcl_LongAsWide(79); static char *stringVar = NULL; |
︙ | ︙ | |||
3013 3014 3015 3016 3017 3018 3019 | stringVar = NULL; } else { stringVar = ckalloc(strlen(argv[5]) + 1); strcpy(stringVar, argv[5]); } } if (argv[6][0] != 0) { | | | 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 | stringVar = NULL; } else { stringVar = ckalloc(strlen(argv[5]) + 1); strcpy(stringVar, argv[5]); } } if (argv[6][0] != 0) { tmp = Tcl_NewStringObj(argv[6], TCL_STRLEN); if (Tcl_GetWideIntFromObj(interp, tmp, &wideVar) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; } Tcl_DecrRefCount(tmp); } if (argv[7][0]) { |
︙ | ︙ | |||
3071 3072 3073 3074 3075 3076 3077 | if (Tcl_GetDouble(interp, argv[14], &d) != TCL_OK) { return TCL_ERROR; } floatVar = (float) d; } if (argv[15][0]) { Tcl_WideInt w; | | | 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 | if (Tcl_GetDouble(interp, argv[14], &d) != TCL_OK) { return TCL_ERROR; } floatVar = (float) d; } if (argv[15][0]) { Tcl_WideInt w; tmp = Tcl_NewStringObj(argv[15], TCL_STRLEN); if (Tcl_GetWideIntFromObj(interp, tmp, &w) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; } Tcl_DecrRefCount(tmp); uwideVar = (Tcl_WideUInt) w; } |
︙ | ︙ | |||
3121 3122 3123 3124 3125 3126 3127 | } else { stringVar = ckalloc(strlen(argv[5]) + 1); strcpy(stringVar, argv[5]); } Tcl_UpdateLinkedVar(interp, "string"); } if (argv[6][0] != 0) { | | | 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 | } else { stringVar = ckalloc(strlen(argv[5]) + 1); strcpy(stringVar, argv[5]); } Tcl_UpdateLinkedVar(interp, "string"); } if (argv[6][0] != 0) { tmp = Tcl_NewStringObj(argv[6], TCL_STRLEN); if (Tcl_GetWideIntFromObj(interp, tmp, &wideVar) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; } Tcl_DecrRefCount(tmp); Tcl_UpdateLinkedVar(interp, "wide"); } |
︙ | ︙ | |||
3188 3189 3190 3191 3192 3193 3194 | return TCL_ERROR; } floatVar = (float) d; Tcl_UpdateLinkedVar(interp, "float"); } if (argv[15][0]) { Tcl_WideInt w; | | | 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 | return TCL_ERROR; } floatVar = (float) d; Tcl_UpdateLinkedVar(interp, "float"); } if (argv[15][0]) { Tcl_WideInt w; tmp = Tcl_NewStringObj(argv[15], TCL_STRLEN); if (Tcl_GetWideIntFromObj(interp, tmp, &w) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; } Tcl_DecrRefCount(tmp); uwideVar = (Tcl_WideUInt) w; Tcl_UpdateLinkedVar(interp, "uwide"); |
︙ | ︙ | |||
3226 3227 3228 3229 3230 3231 3232 | *---------------------------------------------------------------------- */ static int TestlocaleCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 | *---------------------------------------------------------------------- */ static int TestlocaleCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { int index; const char *locale; static const char *const optionStrings[] = { "ctype", "numeric", "time", "collate", "monetary", |
︙ | ︙ | |||
3262 3263 3264 3265 3266 3267 3268 | if (objc == 3) { locale = Tcl_GetString(objv[2]); } else { locale = NULL; } locale = setlocale(lcTypes[index], locale); if (locale) { | | | 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 | if (objc == 3) { locale = Tcl_GetString(objv[2]); } else { locale = NULL; } locale = setlocale(lcTypes[index], locale); if (locale) { Tcl_SetStringObj(Tcl_GetObjResult(interp), locale, TCL_STRLEN); } return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3313 3314 3315 3316 3317 3318 3319 | *---------------------------------------------------------------------- */ static int TestparserObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | | 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 | *---------------------------------------------------------------------- */ static int TestparserObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { const char *script; int length; size_t dummy; Tcl_Parse parse; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "script length"); return TCL_ERROR; } script = Tcl_GetStringFromObj(objv[1], &dummy); if (Tcl_GetIntFromObj(interp, objv[2], &length)) { return TCL_ERROR; } if (length == 0) { length = (int) dummy; } if (Tcl_ParseCommand(interp, script, length, 0, &parse) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (remainder of script: \""); Tcl_AddErrorInfo(interp, parse.term); Tcl_AddErrorInfo(interp, "\")"); return TCL_ERROR; } |
︙ | ︙ | |||
3369 3370 3371 3372 3373 3374 3375 | *---------------------------------------------------------------------- */ static int TestexprparserObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | | 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 | *---------------------------------------------------------------------- */ static int TestexprparserObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { const char *script; int length; size_t dummy; Tcl_Parse parse; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "expr length"); return TCL_ERROR; } script = Tcl_GetStringFromObj(objv[1], &dummy); if (Tcl_GetIntFromObj(interp, objv[2], &length)) { return TCL_ERROR; } if (length == 0) { length = (int) dummy; } parse.commentStart = NULL; parse.commentSize = 0; parse.commandStart = NULL; parse.commandSize = 0; if (Tcl_ParseExpr(interp, script, length, &parse) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (remainder of expr: \""); |
︙ | ︙ | |||
3435 3436 3437 3438 3439 3440 3441 | Tcl_Interp *interp, /* Interpreter whose result is to be set to * the contents of a parse structure. */ Tcl_Parse *parsePtr) /* Parse structure to print out. */ { Tcl_Obj *objPtr; const char *typeString; Tcl_Token *tokenPtr; | | | 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 | Tcl_Interp *interp, /* Interpreter whose result is to be set to * the contents of a parse structure. */ Tcl_Parse *parsePtr) /* Parse structure to print out. */ { Tcl_Obj *objPtr; const char *typeString; Tcl_Token *tokenPtr; size_t i; objPtr = Tcl_GetObjResult(interp); if (parsePtr->commentSize > 0) { Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(parsePtr->commentStart, parsePtr->commentSize)); } else { |
︙ | ︙ | |||
3484 3485 3486 3487 3488 3489 3490 | typeString = "operator"; break; default: typeString = "??"; break; } Tcl_ListObjAppendElement(NULL, objPtr, | | | | < | | | | 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 | typeString = "operator"; break; default: typeString = "??"; break; } Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(typeString, TCL_STRLEN)); Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(tokenPtr->start, tokenPtr->size)); Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewLongObj(tokenPtr->numComponents)); } Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj( parsePtr->commandStart + parsePtr->commandSize, TCL_STRLEN)); } /* *---------------------------------------------------------------------- * * TestparsevarObjCmd -- * * This procedure implements the "testparsevar" command. It is used for * testing Tcl_ParseVar. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int TestparsevarObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { const char *value, *name, *termPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "varName"); return TCL_ERROR; |
︙ | ︙ | |||
3557 3558 3559 3560 3561 3562 3563 | *---------------------------------------------------------------------- */ static int TestparsevarnameObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | | 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 | *---------------------------------------------------------------------- */ static int TestparsevarnameObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { const char *script; int append, length; size_t dummy; Tcl_Parse parse; if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "script length append"); return TCL_ERROR; } script = Tcl_GetStringFromObj(objv[1], &dummy); if (Tcl_GetIntFromObj(interp, objv[2], &length)) { return TCL_ERROR; } if (length == 0) { length = (int) dummy; } if (Tcl_GetIntFromObj(interp, objv[3], &append)) { return TCL_ERROR; } if (Tcl_ParseVarName(interp, script, length, &parse, append) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (remainder of script: \""); Tcl_AddErrorInfo(interp, parse.term); |
︙ | ︙ | |||
3622 3623 3624 3625 3626 3627 3628 | */ /* ARGSUSED */ static int TestregexpObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | < | > | 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 | */ /* ARGSUSED */ static int TestregexpObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int i, ii, indices, match, about, hasxflags, cflags, eflags; size_t stringLength; Tcl_RegExp regExpr; const char *string; Tcl_Obj *objPtr; Tcl_RegExpInfo info; static const char *const options[] = { "-indices", "-nocase", "-about", "-expanded", "-line", "-linestop", "-lineanchor", |
︙ | ︙ | |||
3853 3854 3855 3856 3857 3858 3859 | * regexec flags word, as appropriate. * *---------------------------------------------------------------------- */ static void TestregexpXflags( | | | > | | 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 | * regexec flags word, as appropriate. * *---------------------------------------------------------------------- */ static void TestregexpXflags( const char *string, /* The string of flags. */ size_t length, /* The length of the string in bytes. */ int *cflagsPtr, /* compile flags word */ int *eflagsPtr) /* exec flags word */ { size_t i; int cflags, eflags; cflags = *cflagsPtr; eflags = *eflagsPtr; for (i = 0; i < length; i++) { switch (string[i]) { case 'a': cflags |= REG_ADVF; |
︙ | ︙ | |||
3946 3947 3948 3949 3950 3951 3952 | */ /* ARGSUSED */ static int TestreturnObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 | */ /* ARGSUSED */ static int TestreturnObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return TCL_RETURN; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
3974 3975 3976 3977 3978 3979 3980 | *---------------------------------------------------------------------- */ static int TestsetassocdataCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 | *---------------------------------------------------------------------- */ static int TestsetassocdataCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { char *buf, *oldData; Tcl_InterpDeleteProc *procPtr; if (argc != 3) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], |
︙ | ︙ | |||
4026 4027 4028 4029 4030 4031 4032 | *---------------------------------------------------------------------- */ static int TestsetplatformCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 | *---------------------------------------------------------------------- */ static int TestsetplatformCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { size_t length; TclPlatformType *platform; platform = TclGetPlatform(); |
︙ | ︙ | |||
4075 4076 4077 4078 4079 4080 4081 | *---------------------------------------------------------------------- */ static int TeststaticpkgCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 | *---------------------------------------------------------------------- */ static int TeststaticpkgCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { int safe, loaded; if (argc != 4) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], " pkgName safe loaded\"", NULL); |
︙ | ︙ | |||
4126 4127 4128 4129 4130 4131 4132 | *---------------------------------------------------------------------- */ static int TesttranslatefilenameCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 | *---------------------------------------------------------------------- */ static int TesttranslatefilenameCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_DString buffer; const char *result; if (argc != 2) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", |
︙ | ︙ | |||
4168 4169 4170 4171 4172 4173 4174 | */ /* ARGSUSED */ static int TestupvarCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 | */ /* ARGSUSED */ static int TestupvarCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { int flags = 0; if ((argc != 5) && (argc != 6)) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], " level name ?name2? dest global\"", NULL); |
︙ | ︙ | |||
4221 4222 4223 4224 4225 4226 4227 | */ /* ARGSUSED */ static int TestseterrorcodeCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 | */ /* ARGSUSED */ static int TestseterrorcodeCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { if (argc > 6) { Tcl_AppendResult(interp, "too many args", NULL); return TCL_ERROR; } switch (argc) { |
︙ | ︙ | |||
4274 4275 4276 4277 4278 4279 4280 | */ /* ARGSUSED */ static int TestsetobjerrorcodeCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 | */ /* ARGSUSED */ static int TestsetobjerrorcodeCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_SetObjErrorCode(interp, Tcl_ConcatObj(objc - 1, objv + 1)); return TCL_ERROR; } /* |
︙ | ︙ | |||
4303 4304 4305 4306 4307 4308 4309 | */ /* ARGSUSED */ static int TestfeventCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 | */ /* ARGSUSED */ static int TestfeventCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { static Tcl_Interp *interp2 = NULL; int code; Tcl_Channel chan; if (argc < 2) { |
︙ | ︙ | |||
4375 4376 4377 4378 4379 4380 4381 | *---------------------------------------------------------------------- */ static int TestpanicCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 | *---------------------------------------------------------------------- */ static int TestpanicCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { const char *argString; /* * Put the arguments into a var args structure * Append all of the arguments together separated by spaces */ argString = Tcl_Merge(argc-1, argv+1); Tcl_Panic("%s", argString); ckfree(argString); return TCL_OK; } static int TestfileCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ Tcl_Obj *const argv[]) /* The argument objects. */ { int force, i, j, result; Tcl_Obj *error = NULL; const char *subcmd; if (argc < 3) { |
︙ | ︙ | |||
4478 4479 4480 4481 4482 4483 4484 | *---------------------------------------------------------------------- */ static int TestgetvarfullnameCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 | *---------------------------------------------------------------------- */ static int TestgetvarfullnameCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { const char *name, *arg; int flags = 0; Tcl_Namespace *namespacePtr; Tcl_CallFrame *framePtr; Tcl_Var variable; |
︙ | ︙ | |||
4556 4557 4558 4559 4560 4561 4562 | *---------------------------------------------------------------------- */ static int GetTimesCmd( ClientData unused, /* Unused. */ Tcl_Interp *interp, /* The current interpreter. */ | | | 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 | *---------------------------------------------------------------------- */ static int GetTimesCmd( ClientData unused, /* Unused. */ Tcl_Interp *interp, /* The current interpreter. */ size_t argc, /* The number of arguments. */ const char **argv) /* The argument strings. */ { Interp *iPtr = (Interp *) interp; int i, n; double timePer; Tcl_Time start, stop; Tcl_Obj *objPtr, **objv; |
︙ | ︙ | |||
4623 4624 4625 4626 4627 4628 4629 | Tcl_GetTime(&stop); timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec); fprintf(stderr, " %.3f usec per Tcl_DecrRefCount\n", timePer/5000); ckfree(objv); /* TclGetString 100000 times */ fprintf(stderr, "TclGetStringFromObj of \"12345\" 100000 times\n"); | | | 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 | Tcl_GetTime(&stop); timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec); fprintf(stderr, " %.3f usec per Tcl_DecrRefCount\n", timePer/5000); ckfree(objv); /* TclGetString 100000 times */ fprintf(stderr, "TclGetStringFromObj of \"12345\" 100000 times\n"); objPtr = Tcl_NewStringObj("12345", TCL_STRLEN); Tcl_GetTime(&start); for (i = 0; i < 100000; i++) { (void) TclGetString(objPtr); } Tcl_GetTime(&stop); timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec); fprintf(stderr, " %.3f usec per TclGetStringFromObj of \"12345\"\n", |
︙ | ︙ | |||
4735 4736 4737 4738 4739 4740 4741 | *---------------------------------------------------------------------- */ static int NoopCmd( ClientData unused, /* Unused. */ Tcl_Interp *interp, /* The current interpreter. */ | | | 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 | *---------------------------------------------------------------------- */ static int NoopCmd( ClientData unused, /* Unused. */ Tcl_Interp *interp, /* The current interpreter. */ size_t argc, /* The number of arguments. */ const char **argv) /* The argument strings. */ { return TCL_OK; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
4762 4763 4764 4765 4766 4767 4768 | *---------------------------------------------------------------------- */ static int NoopObjCmd( ClientData unused, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 | *---------------------------------------------------------------------- */ static int NoopObjCmd( ClientData unused, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { return TCL_OK; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
4790 4791 4792 4793 4794 4795 4796 | */ /* ARGSUSED */ static int TestsetCmd( ClientData data, /* Additional flags for Get/SetVar2. */ register Tcl_Interp *interp,/* Current interpreter. */ | | | 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 | */ /* ARGSUSED */ static int TestsetCmd( ClientData data, /* Additional flags for Get/SetVar2. */ register Tcl_Interp *interp,/* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { int flags = PTR2INT(data); const char *value; if (argc == 2) { Tcl_AppendResult(interp, "before get", NULL); |
︙ | ︙ | |||
4822 4823 4824 4825 4826 4827 4828 | return TCL_ERROR; } } static int Testset2Cmd( ClientData data, /* Additional flags for Get/SetVar2. */ register Tcl_Interp *interp,/* Current interpreter. */ | | | 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 | return TCL_ERROR; } } static int Testset2Cmd( ClientData data, /* Additional flags for Get/SetVar2. */ register Tcl_Interp *interp,/* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { int flags = PTR2INT(data); const char *value; if (argc == 3) { Tcl_AppendResult(interp, "before get", NULL); |
︙ | ︙ | |||
4873 4874 4875 4876 4877 4878 4879 | */ /* ARGSUSED */ static int TestsaveresultCmd( ClientData dummy, /* Not used. */ register Tcl_Interp *interp,/* Current interpreter. */ | | | 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 | */ /* ARGSUSED */ static int TestsaveresultCmd( ClientData dummy, /* Not used. */ register Tcl_Interp *interp,/* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { int discard, result, index; Tcl_SavedResult state; Tcl_Obj *objPtr; static const char *const optionStrings[] = { "append", "dynamic", "free", "object", "small", NULL |
︙ | ︙ | |||
4921 4922 4923 4924 4925 4926 4927 | Tcl_SetResult(interp, buf, TCL_DYNAMIC); break; } case RESULT_DYNAMIC: Tcl_SetResult(interp, (char *)"dynamic result", TestsaveresultFree); break; case RESULT_OBJECT: | | | 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 | Tcl_SetResult(interp, buf, TCL_DYNAMIC); break; } case RESULT_DYNAMIC: Tcl_SetResult(interp, (char *)"dynamic result", TestsaveresultFree); break; case RESULT_OBJECT: objPtr = Tcl_NewStringObj("object result", TCL_STRLEN); Tcl_SetObjResult(interp, objPtr); break; } Tcl_SaveResult(interp, &state); if (((enum options) index) == RESULT_OBJECT) { |
︙ | ︙ | |||
5000 5001 5002 5003 5004 5005 5006 | *---------------------------------------------------------------------- */ static int TestmainthreadCmd( ClientData dummy, /* Not used. */ register Tcl_Interp *interp,/* Current interpreter. */ | | | 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 | *---------------------------------------------------------------------- */ static int TestmainthreadCmd( ClientData dummy, /* Not used. */ register Tcl_Interp *interp,/* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { if (argc == 1) { Tcl_Obj *idObj = Tcl_NewLongObj((long)(size_t)Tcl_GetCurrentThread()); Tcl_SetObjResult(interp, idObj); return TCL_OK; |
︙ | ︙ | |||
5061 5062 5063 5064 5065 5066 5067 | *---------------------------------------------------------------------- */ static int TestsetmainloopCmd( ClientData dummy, /* Not used. */ register Tcl_Interp *interp,/* Current interpreter. */ | | | 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 | *---------------------------------------------------------------------- */ static int TestsetmainloopCmd( ClientData dummy, /* Not used. */ register Tcl_Interp *interp,/* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { exitMainLoop = 0; Tcl_SetMainLoop(MainLoop); return TCL_OK; } |
︙ | ︙ | |||
5090 5091 5092 5093 5094 5095 5096 | *---------------------------------------------------------------------- */ static int TestexitmainloopCmd( ClientData dummy, /* Not used. */ register Tcl_Interp *interp,/* Current interpreter. */ | | | 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 | *---------------------------------------------------------------------- */ static int TestexitmainloopCmd( ClientData dummy, /* Not used. */ register Tcl_Interp *interp,/* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { exitMainLoop = 1; return TCL_OK; } /* |
︙ | ︙ | |||
5119 5120 5121 5122 5123 5124 5125 | */ /* ARGSUSED */ static int TestChannelCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter for result. */ | | | 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 | */ /* ARGSUSED */ static int TestChannelCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter for result. */ size_t argc, /* Count of additional args. */ const char **argv) /* Additional arg strings. */ { const char *cmdName; /* Sub command. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* The actual channel. */ |
︙ | ︙ | |||
5183 5184 5185 5186 5187 5188 5189 | /* lint */ statePtr = NULL; chan = NULL; } if ((cmdName[0] == 's') && (strncmp(cmdName, "setchannelerror", len) == 0)) { | | | | 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 | /* lint */ statePtr = NULL; chan = NULL; } if ((cmdName[0] == 's') && (strncmp(cmdName, "setchannelerror", len) == 0)) { Tcl_Obj *msg = Tcl_NewStringObj(argv[3], TCL_STRLEN); Tcl_IncrRefCount(msg); Tcl_SetChannelError(chan, msg); Tcl_DecrRefCount(msg); Tcl_GetChannelError(chan, &msg); Tcl_SetObjResult(interp, msg); Tcl_DecrRefCount(msg); return TCL_OK; } if ((cmdName[0] == 's') && (strncmp(cmdName, "setchannelerrorinterp", len) == 0)) { Tcl_Obj *msg = Tcl_NewStringObj(argv[3], TCL_STRLEN); Tcl_IncrRefCount(msg); Tcl_SetChannelErrorInterp(interp, msg); Tcl_DecrRefCount(msg); Tcl_GetChannelErrorInterp(interp, &msg); Tcl_SetObjResult(interp, msg); |
︙ | ︙ | |||
5544 5545 5546 5547 5548 5549 5550 | if (strcmp(argv[3], "-command") != 0) { Tcl_AppendResult(interp, "bad argument \"", argv[3], "\": should be \"-command\"", NULL); return TCL_ERROR; } return TclChannelTransform(interp, chan, | | | 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 | if (strcmp(argv[3], "-command") != 0) { Tcl_AppendResult(interp, "bad argument \"", argv[3], "\": should be \"-command\"", NULL); return TCL_ERROR; } return TclChannelTransform(interp, chan, Tcl_NewStringObj(argv[4], TCL_STRLEN)); } if ((cmdName[0] == 'u') && (strncmp(cmdName, "unstack", len) == 0)) { /* * Syntax: unstack channel */ |
︙ | ︙ | |||
5588 5589 5590 5591 5592 5593 5594 | */ /* ARGSUSED */ static int TestChannelEventCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 | */ /* ARGSUSED */ static int TestChannelEventCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_Obj *resultListPtr; Channel *chanPtr; ChannelState *statePtr; /* state info for channel */ EventScriptRecord *esPtr, *prevEsPtr, *nextEsPtr; const char *cmd; |
︙ | ︙ | |||
5636 5637 5638 5639 5640 5641 5642 | esPtr = ckalloc(sizeof(EventScriptRecord)); esPtr->nextPtr = statePtr->scriptRecordPtr; statePtr->scriptRecordPtr = esPtr; esPtr->chanPtr = chanPtr; esPtr->interp = interp; esPtr->mask = mask; | | | 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 | esPtr = ckalloc(sizeof(EventScriptRecord)); esPtr->nextPtr = statePtr->scriptRecordPtr; statePtr->scriptRecordPtr = esPtr; esPtr->chanPtr = chanPtr; esPtr->interp = interp; esPtr->mask = mask; esPtr->scriptPtr = Tcl_NewStringObj(argv[4], TCL_STRLEN); Tcl_IncrRefCount(esPtr->scriptPtr); Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask, TclChannelEventScriptInvoker, (ClientData) esPtr); return TCL_OK; } |
︙ | ︙ | |||
5703 5704 5705 5706 5707 5708 5709 | } resultListPtr = Tcl_GetObjResult(interp); for (esPtr = statePtr->scriptRecordPtr; esPtr != NULL; esPtr = esPtr->nextPtr) { if (esPtr->mask) { Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj( | | > | | 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 | } resultListPtr = Tcl_GetObjResult(interp); for (esPtr = statePtr->scriptRecordPtr; esPtr != NULL; esPtr = esPtr->nextPtr) { if (esPtr->mask) { Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj( (esPtr->mask == TCL_READABLE) ? "readable" : "writable", TCL_STRLEN)); } else { Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj("none", TCL_STRLEN)); } Tcl_ListObjAppendElement(interp, resultListPtr, esPtr->scriptPtr); } Tcl_SetObjResult(interp, resultListPtr); return TCL_OK; } |
︙ | ︙ | |||
5799 5800 5801 5802 5803 5804 5805 | *---------------------------------------------------------------------- */ static int TestWrongNumArgsObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | | | 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 | *---------------------------------------------------------------------- */ static int TestWrongNumArgsObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int i; size_t length; const char *msg; if (objc < 3) { /* * Don't use Tcl_WrongNumArgs here, as that is the function * we want to test! */ Tcl_AppendResult(interp, "insufficient arguments", NULL); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[1], &i) != TCL_OK) { return TCL_ERROR; } msg = Tcl_GetStringFromObj(objv[2], &length); if (length == 0) { msg = NULL; } if ((size_t) i > objc - 3) { /* * Asked for more arguments than were given. */ Tcl_AppendResult(interp, "insufficient arguments", NULL); return TCL_ERROR; } |
︙ | ︙ | |||
5855 5856 5857 5858 5859 5860 5861 | *---------------------------------------------------------------------- */ static int TestGetIndexFromObjStructObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 | *---------------------------------------------------------------------- */ static int TestGetIndexFromObjStructObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *const ary[] = { "a", "b", "c", "d", "e", "f", NULL, NULL }; int idx,target; |
︙ | ︙ | |||
5909 5910 5911 5912 5913 5914 5915 | *---------------------------------------------------------------------- */ static int TestFilesystemObjCmd( ClientData dummy, Tcl_Interp *interp, | | | | 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 | *---------------------------------------------------------------------- */ static int TestFilesystemObjCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { int res, boolVal; const char *msg; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "boolean"); return TCL_ERROR; } if (Tcl_GetBooleanFromObj(interp, objv[1], &boolVal) != TCL_OK) { return TCL_ERROR; } if (boolVal) { res = Tcl_FSRegister((ClientData)interp, &testReportingFilesystem); msg = (res == TCL_OK) ? "registered" : "failed"; } else { res = Tcl_FSUnregister(&testReportingFilesystem); msg = (res == TCL_OK) ? "unregistered" : "failed"; } Tcl_SetObjResult(interp, Tcl_NewStringObj(msg , TCL_STRLEN)); return res; } static int TestReportInFilesystem( Tcl_Obj *pathPtr, ClientData *clientDataPtr) |
︙ | ︙ | |||
6016 6017 6018 6019 6020 6021 6022 | * API, but there you go. We should convert it to objects. */ Tcl_Obj *savedResult; Tcl_DString ds; Tcl_DStringInit(&ds); | | | 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 | * API, but there you go. We should convert it to objects. */ Tcl_Obj *savedResult; Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, "lappend filesystemReport ", TCL_STRLEN); Tcl_DStringStartSublist(&ds); Tcl_DStringAppendElement(&ds, cmd); if (path != NULL) { Tcl_DStringAppendElement(&ds, Tcl_GetString(path)); } if (arg2 != NULL) { Tcl_DStringAppendElement(&ds, Tcl_GetString(arg2)); |
︙ | ︙ | |||
6285 6286 6287 6288 6289 6290 6291 | * important features. */ static int TestSimpleFilesystemObjCmd( ClientData dummy, Tcl_Interp *interp, | | | | | | 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 | * important features. */ static int TestSimpleFilesystemObjCmd( ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { int res, boolVal; const char *msg; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "boolean"); return TCL_ERROR; } if (Tcl_GetBooleanFromObj(interp, objv[1], &boolVal) != TCL_OK) { return TCL_ERROR; } if (boolVal) { res = Tcl_FSRegister((ClientData)interp, &simpleFilesystem); msg = (res == TCL_OK) ? "registered" : "failed"; } else { res = Tcl_FSUnregister(&simpleFilesystem); msg = (res == TCL_OK) ? "unregistered" : "failed"; } Tcl_SetObjResult(interp, Tcl_NewStringObj(msg , TCL_STRLEN)); return res; } /* * Treats a file name 'simplefs:/foo' by using the file 'foo' in the current * (native) directory. */ static Tcl_Obj * SimpleRedirect( Tcl_Obj *pathPtr) /* Name of file to copy. */ { size_t len; const char *str; Tcl_Obj *origPtr; /* * We assume the same name in the current directory is ok. */ str = Tcl_GetStringFromObj(pathPtr, &len); if (len < 10 || strncmp(str, "simplefs:/", 10)) { /* Probably shouldn't ever reach here */ Tcl_IncrRefCount(pathPtr); return pathPtr; } origPtr = Tcl_NewStringObj(str+10, TCL_STRLEN); Tcl_IncrRefCount(origPtr); return origPtr; } static int SimpleMatchInDirectory( Tcl_Interp *interp, /* Interpreter for error |
︙ | ︙ | |||
6364 6365 6366 6367 6368 6369 6370 | * We assume the same name in the current directory is ok. */ resPtr = Tcl_NewObj(); Tcl_IncrRefCount(resPtr); origPtr = SimpleRedirect(dirPtr); res = Tcl_FSMatchInDirectory(interp, resPtr, origPtr, pattern, types); if (res == TCL_OK) { | | > > | | 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 | * We assume the same name in the current directory is ok. */ resPtr = Tcl_NewObj(); Tcl_IncrRefCount(resPtr); origPtr = SimpleRedirect(dirPtr); res = Tcl_FSMatchInDirectory(interp, resPtr, origPtr, pattern, types); if (res == TCL_OK) { size_t gLength, j; Tcl_ListObjLength(NULL, resPtr, &gLength); for (j = 0; j < gLength; j++) { Tcl_Obj *gElt, *nElt; Tcl_ListObjIndex(NULL, resPtr, j, &gElt); nElt = Tcl_NewStringObj("simplefs:/", 10); Tcl_AppendObjToObj(nElt, gElt); Tcl_ListObjAppendElement(NULL, resultPtr, nElt); } } Tcl_DecrRefCount(origPtr); Tcl_DecrRefCount(resPtr); return res; |
︙ | ︙ | |||
6432 6433 6434 6435 6436 6437 6438 | static Tcl_Obj * SimpleListVolumes(void) { /* Add one new volume */ Tcl_Obj *retVal; | | | | | 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 | static Tcl_Obj * SimpleListVolumes(void) { /* Add one new volume */ Tcl_Obj *retVal; retVal = Tcl_NewStringObj("simplefs:/", TCL_STRLEN); Tcl_IncrRefCount(retVal); return retVal; } /* * Used to check correct string-length determining in Tcl_NumUtfChars */ static int TestNumUtfCharsCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { if (objc > 1) { size_t len = TCL_STRLEN; if (objc > 2) { (void) Tcl_GetStringFromObj(objv[1], &len); } len = Tcl_NumUtfChars(Tcl_GetString(objv[1]), len); Tcl_SetObjResult(interp, Tcl_NewLongObj(len)); } |
︙ | ︙ | |||
6488 6489 6490 6491 6492 6493 6494 | *---------------------------------------------------------------------- */ static int TestcpuidCmd( ClientData dummy, Tcl_Interp* interp, /* Tcl interpreter */ | | | | | 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 | *---------------------------------------------------------------------- */ static int TestcpuidCmd( ClientData dummy, Tcl_Interp* interp, /* Tcl interpreter */ size_t objc, /* Parameter count */ Tcl_Obj *const * objv) /* Parameter vector */ { int status, index, i; unsigned int regs[4]; Tcl_Obj *regsObjs[4]; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "eax"); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[1], &index) != TCL_OK) { return TCL_ERROR; } status = TclWinCPUID((unsigned) index, regs); if (status != TCL_OK) { Tcl_SetObjResult(interp, Tcl_NewStringObj("operation not available", TCL_STRLEN)); return status; } for (i=0 ; i<4 ; ++i) { regsObjs[i] = Tcl_NewLongObj((int) regs[i]); } Tcl_SetObjResult(interp, Tcl_NewListObj(4, regsObjs)); return TCL_OK; } #endif /* * Used to do basic checks of the TCL_HASH_KEY_SYSTEM_HASH flag */ static int TestHashSystemHashCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { static const Tcl_HashKeyType hkType = { TCL_HASH_KEY_TYPE_VERSION, TCL_HASH_KEY_SYSTEM_HASH, NULL, NULL, NULL, NULL }; Tcl_HashTable hash; |
︙ | ︙ | |||
6551 6552 6553 6554 6555 6556 6557 | return TCL_ERROR; } for (i=0 ; i<limit ; i++) { hPtr = Tcl_CreateHashEntry(&hash, INT2PTR(i), &isNew); if (!isNew) { Tcl_SetObjResult(interp, Tcl_NewLongObj(i)); | | > | > | > | 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 | return TCL_ERROR; } for (i=0 ; i<limit ; i++) { hPtr = Tcl_CreateHashEntry(&hash, INT2PTR(i), &isNew); if (!isNew) { Tcl_SetObjResult(interp, Tcl_NewLongObj(i)); Tcl_AppendToObj(Tcl_GetObjResult(interp), " creation problem", TCL_STRLEN); Tcl_DeleteHashTable(&hash); return TCL_ERROR; } Tcl_SetHashValue(hPtr, INT2PTR(i+42)); } if (hash.numEntries != limit) { Tcl_AppendResult(interp, "unexpected maximal size", NULL); Tcl_DeleteHashTable(&hash); return TCL_ERROR; } for (i=0 ; i<limit ; i++) { hPtr = Tcl_FindHashEntry(&hash, (char *) INT2PTR(i)); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewLongObj(i)); Tcl_AppendToObj(Tcl_GetObjResult(interp), " lookup problem", TCL_STRLEN); Tcl_DeleteHashTable(&hash); return TCL_ERROR; } if (PTR2INT(Tcl_GetHashValue(hPtr)) != i+42) { Tcl_SetObjResult(interp, Tcl_NewLongObj(i)); Tcl_AppendToObj(Tcl_GetObjResult(interp), " value problem", TCL_STRLEN); Tcl_DeleteHashTable(&hash); return TCL_ERROR; } Tcl_DeleteHashEntry(hPtr); } if (hash.numEntries != 0) { |
︙ | ︙ | |||
6600 6601 6602 6603 6604 6605 6606 | * Used for testing Tcl_GetInt which is no longer used directly by the * core very much. */ static int TestgetintCmd( ClientData dummy, Tcl_Interp *interp, | | | 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 | * Used for testing Tcl_GetInt which is no longer used directly by the * core very much. */ static int TestgetintCmd( ClientData dummy, Tcl_Interp *interp, size_t argc, const char **argv) { if (argc < 2) { Tcl_AppendResult(interp, "wrong # args", NULL); return TCL_ERROR; } else { int val, i, total=0; |
︙ | ︙ | |||
6624 6625 6626 6627 6628 6629 6630 | } } static int TestNRELevels( ClientData clientData, Tcl_Interp *interp, | | | 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 | } } static int TestNRELevels( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; static ptrdiff_t *refDepth = NULL; ptrdiff_t depth; Tcl_Obj *levels[6]; int i = 0; |
︙ | ︙ | |||
6680 6681 6682 6683 6684 6685 6686 | *---------------------------------------------------------------------- */ static int TestconcatobjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | | | | 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 | *---------------------------------------------------------------------- */ static int TestconcatobjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_Obj *list1Ptr, *list2Ptr, *emptyPtr, *concatPtr, *tmpPtr; int result = TCL_OK; size_t len; Tcl_Obj *objv[3]; /* * Set the start of the error message as obj result; it will be cleared at * the end if no errors were found. */ Tcl_SetObjResult(interp, Tcl_NewStringObj("Tcl_ConcatObj is unsafe:", TCL_STRLEN)); emptyPtr = Tcl_NewObj(); list1Ptr = Tcl_NewStringObj("foo bar sum", TCL_STRLEN); Tcl_ListObjLength(NULL, list1Ptr, &len); if (list1Ptr->bytes != NULL) { ckfree(list1Ptr->bytes); list1Ptr->bytes = NULL; } list2Ptr = Tcl_NewStringObj("eeny meeny", TCL_STRLEN); Tcl_ListObjLength(NULL, list2Ptr, &len); if (list2Ptr->bytes != NULL) { ckfree(list2Ptr->bytes); list2Ptr->bytes = NULL; } /* |
︙ | ︙ | |||
6853 6854 6855 6856 6857 6858 6859 | concatPtr = Tcl_ConcatObj(2, objv); if (concatPtr->refCount != 0) { result = TCL_ERROR; Tcl_AppendResult(interp, "\n\t* (e) concatObj does not have refCount 0", NULL); } if (concatPtr == tmpPtr) { | | | 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 | concatPtr = Tcl_ConcatObj(2, objv); if (concatPtr->refCount != 0) { result = TCL_ERROR; Tcl_AppendResult(interp, "\n\t* (e) concatObj does not have refCount 0", NULL); } if (concatPtr == tmpPtr) { size_t len; result = TCL_ERROR; Tcl_AppendResult(interp, "\n\t* (e) concatObj is not a new obj ", NULL); (void) Tcl_ListObjLength(NULL, concatPtr, &len); switch (tmpPtr->refCount) { |
︙ | ︙ | |||
6885 6886 6887 6888 6889 6890 6891 | concatPtr = Tcl_ConcatObj(2, objv); if (concatPtr->refCount != 0) { result = TCL_ERROR; Tcl_AppendResult(interp, "\n\t* (f) concatObj does not have refCount 0", NULL); } if (concatPtr == tmpPtr) { | | | 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 | concatPtr = Tcl_ConcatObj(2, objv); if (concatPtr->refCount != 0) { result = TCL_ERROR; Tcl_AppendResult(interp, "\n\t* (f) concatObj does not have refCount 0", NULL); } if (concatPtr == tmpPtr) { size_t len; result = TCL_ERROR; Tcl_AppendResult(interp, "\n\t* (f) concatObj is not a new obj ", NULL); (void) Tcl_ListObjLength(NULL, concatPtr, &len); switch (tmpPtr->refCount) { |
︙ | ︙ | |||
6918 6919 6920 6921 6922 6923 6924 | concatPtr = Tcl_ConcatObj(2, objv); if (concatPtr->refCount != 0) { result = TCL_ERROR; Tcl_AppendResult(interp, "\n\t* (g) concatObj does not have refCount 0", NULL); } if (concatPtr == tmpPtr) { | | | 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 | concatPtr = Tcl_ConcatObj(2, objv); if (concatPtr->refCount != 0) { result = TCL_ERROR; Tcl_AppendResult(interp, "\n\t* (g) concatObj does not have refCount 0", NULL); } if (concatPtr == tmpPtr) { size_t len; result = TCL_ERROR; Tcl_AppendResult(interp, "\n\t* (g) concatObj is not a new obj ", NULL); (void) Tcl_ListObjLength(NULL, concatPtr, &len); switch (tmpPtr->refCount) { |
︙ | ︙ | |||
6983 6984 6985 6986 6987 6988 6989 | *---------------------------------------------------------------------- */ static int TestparseargsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 | *---------------------------------------------------------------------- */ static int TestparseargsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Arguments. */ { static int foo = 0; size_t count = objc; Tcl_Obj **remObjv, *result[3]; Tcl_ArgvInfo argTable[] = { {TCL_ARGV_CONSTANT, "-bool", INT2PTR(1), &foo, "booltest", NULL}, TCL_ARGV_AUTO_REST, TCL_ARGV_AUTO_HELP, TCL_ARGV_TABLE_END }; foo = 0; if (Tcl_ParseArgsObjv(interp, argTable, &count, objv, &remObjv)!=TCL_OK) { return TCL_ERROR; } result[0] = Tcl_NewLongObj(foo); result[1] = Tcl_NewWideIntObj(count); result[2] = Tcl_NewListObj(count, remObjv); Tcl_SetObjResult(interp, Tcl_NewListObj(3, result)); ckfree(remObjv); return TCL_OK; } /** |
︙ | ︙ | |||
7141 7142 7143 7144 7145 7146 7147 | return var; } static int InterpCompiledVarResolver( Tcl_Interp *interp, const char *name, | | | | | 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 | return var; } static int InterpCompiledVarResolver( Tcl_Interp *interp, const char *name, size_t length, Tcl_Namespace *context, Tcl_ResolvedVarInfo **rPtr) { if (*name == 'T') { MyResolvedVarInfo *resVarInfo = ckalloc(sizeof(MyResolvedVarInfo)); resVarInfo->vInfo.fetchProc = MyCompiledVarFetch; resVarInfo->vInfo.deleteProc = MyCompiledVarFree; resVarInfo->var = NULL; resVarInfo->nameObj = Tcl_NewStringObj(name, TCL_STRLEN); Tcl_IncrRefCount(resVarInfo->nameObj); *rPtr = &resVarInfo->vInfo; return TCL_OK; } return TCL_CONTINUE; } static int TestInterpResolverCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { static const char *const table[] = { "down", "up", NULL }; int idx; #define RESOLVER_KEY "testInterpResolver" |
︙ | ︙ |
Changes to generic/tclTestObj.c.
︙ | ︙ | |||
26 27 28 29 30 31 32 | */ static int CheckIfVarUnset(Tcl_Interp *interp, Tcl_Obj **varPtr, int varIndex); static int GetVariableIndex(Tcl_Interp *interp, const char *string, int *indexPtr); static void SetVarToObj(Tcl_Obj **varPtr, int varIndex, Tcl_Obj *objPtr); static int TestbignumobjCmd(ClientData dummy, Tcl_Interp *interp, | | | | | | | | | | | | < | 26 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 57 58 59 60 | */ static int CheckIfVarUnset(Tcl_Interp *interp, Tcl_Obj **varPtr, int varIndex); static int GetVariableIndex(Tcl_Interp *interp, const char *string, int *indexPtr); static void SetVarToObj(Tcl_Obj **varPtr, int varIndex, Tcl_Obj *objPtr); static int TestbignumobjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestbooleanobjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestdoubleobjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestindexobjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestintobjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestlistobjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TestobjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int TeststringobjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); typedef struct { size_t numChars; size_t allocated; size_t maxChars; } TestString; #define VARPTR_KEY "TCLOBJTEST_VARPTR" #define NUMBER_OF_OBJECT_VARS 20 static void VarPtrDeleteProc(ClientData clientData, Tcl_Interp *interp) { |
︙ | ︙ | |||
150 151 152 153 154 155 156 | *---------------------------------------------------------------------- */ static int TestbignumobjCmd( ClientData clientData, /* unused */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | *---------------------------------------------------------------------- */ static int TestbignumobjCmd( ClientData clientData, /* unused */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Argument count */ Tcl_Obj *const objv[]) /* Argument vector */ { const char *const subcmds[] = { "set", "get", "mult10", "div10", NULL }; enum options { BIGNUM_SET, BIGNUM_GET, BIGNUM_MULT10, BIGNUM_DIV10 |
︙ | ︙ | |||
187 188 189 190 191 192 193 | if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "var value"); return TCL_ERROR; } string = Tcl_GetString(objv[3]); if (mp_init(&bignumValue) != MP_OKAY) { Tcl_SetObjResult(interp, | | | | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "var value"); return TCL_ERROR; } string = Tcl_GetString(objv[3]); if (mp_init(&bignumValue) != MP_OKAY) { Tcl_SetObjResult(interp, Tcl_NewStringObj("error in mp_init", TCL_STRLEN)); return TCL_ERROR; } if (mp_read_radix(&bignumValue, string, 10) != MP_OKAY) { mp_clear(&bignumValue); Tcl_SetObjResult(interp, Tcl_NewStringObj("error in mp_read_radix", TCL_STRLEN)); return TCL_ERROR; } /* * If the object currently bound to the variable with index varIndex * has ref count 1 (i.e. the object is unshared) we can modify that * object directly. Otherwise, if RC>1 (i.e. the object is shared), |
︙ | ︙ | |||
239 240 241 242 243 244 245 | return TCL_ERROR; } if (mp_init(&newValue) != MP_OKAY || (mp_mul_d(&bignumValue, 10, &newValue) != MP_OKAY)) { mp_clear(&bignumValue); mp_clear(&newValue); Tcl_SetObjResult(interp, | | | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | return TCL_ERROR; } if (mp_init(&newValue) != MP_OKAY || (mp_mul_d(&bignumValue, 10, &newValue) != MP_OKAY)) { mp_clear(&bignumValue); mp_clear(&newValue); Tcl_SetObjResult(interp, Tcl_NewStringObj("error in mp_mul_d", TCL_STRLEN)); return TCL_ERROR; } mp_clear(&bignumValue); if (!Tcl_IsShared(varPtr[varIndex])) { Tcl_SetBignumObj(varPtr[varIndex], &newValue); } else { SetVarToObj(varPtr, varIndex, Tcl_NewBignumObj(&newValue)); |
︙ | ︙ | |||
267 268 269 270 271 272 273 | return TCL_ERROR; } if (mp_init(&newValue) != MP_OKAY || (mp_div_d(&bignumValue, 10, &newValue, NULL) != MP_OKAY)) { mp_clear(&bignumValue); mp_clear(&newValue); Tcl_SetObjResult(interp, | | | 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | return TCL_ERROR; } if (mp_init(&newValue) != MP_OKAY || (mp_div_d(&bignumValue, 10, &newValue, NULL) != MP_OKAY)) { mp_clear(&bignumValue); mp_clear(&newValue); Tcl_SetObjResult(interp, Tcl_NewStringObj("error in mp_div_d", TCL_STRLEN)); return TCL_ERROR; } mp_clear(&bignumValue); if (!Tcl_IsShared(varPtr[varIndex])) { Tcl_SetBignumObj(varPtr[varIndex], &newValue); } else { SetVarToObj(varPtr, varIndex, Tcl_NewBignumObj(&newValue)); |
︙ | ︙ | |||
304 305 306 307 308 309 310 | *---------------------------------------------------------------------- */ static int TestbooleanobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | *---------------------------------------------------------------------- */ static int TestbooleanobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int varIndex, boolValue; const char *index, *subCmd; Tcl_Obj **varPtr; if (objc < 3) { |
︙ | ︙ | |||
404 405 406 407 408 409 410 | *---------------------------------------------------------------------- */ static int TestdoubleobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | *---------------------------------------------------------------------- */ static int TestdoubleobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int varIndex; double doubleValue; const char *index, *subCmd, *string; Tcl_Obj **varPtr; |
︙ | ︙ | |||
522 523 524 525 526 527 528 | *---------------------------------------------------------------------- */ static int TestindexobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 | *---------------------------------------------------------------------- */ static int TestindexobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int allowAbbrev, index, index2, setError, i, result; const char **argv; static const char *const tablePtr[] = {"a", "b", "check", NULL}; /* * Keep this structure declaration in sync with tclIndexObj.c |
︙ | ︙ | |||
563 564 565 566 567 568 569 | if (result == TCL_OK) { Tcl_SetLongObj(Tcl_GetObjResult(interp), index); } return result; } if (objc < 5) { | | | 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 | if (result == TCL_OK) { Tcl_SetLongObj(Tcl_GetObjResult(interp), index); } return result; } if (objc < 5) { Tcl_AppendToObj(Tcl_GetObjResult(interp), "wrong # args", TCL_STRLEN); return TCL_ERROR; } if (Tcl_GetBooleanFromObj(interp, objv[1], &setError) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetBooleanFromObj(interp, objv[2], &allowAbbrev) != TCL_OK) { |
︙ | ︙ | |||
626 627 628 629 630 631 632 | *---------------------------------------------------------------------- */ static int TestintobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 | *---------------------------------------------------------------------- */ static int TestintobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int intValue, varIndex, i; long longValue; const char *index, *subCmd, *string; Tcl_Obj **varPtr; |
︙ | ︙ | |||
721 722 723 724 725 726 727 | if (CheckIfVarUnset(interp, varPtr,varIndex)) { return TCL_ERROR; } if (Tcl_GetLongFromObj(interp, varPtr[varIndex], &longValue) != TCL_OK) { return TCL_ERROR; } Tcl_AppendToObj(Tcl_GetObjResult(interp), | | | | | | | 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 | if (CheckIfVarUnset(interp, varPtr,varIndex)) { return TCL_ERROR; } if (Tcl_GetLongFromObj(interp, varPtr[varIndex], &longValue) != TCL_OK) { return TCL_ERROR; } Tcl_AppendToObj(Tcl_GetObjResult(interp), ((longValue == LONG_MAX)? "1" : "0"), TCL_STRLEN); } else if (strcmp(subCmd, "get") == 0) { if (objc != 3) { goto wrongNumArgs; } if (CheckIfVarUnset(interp, varPtr,varIndex)) { return TCL_ERROR; } Tcl_SetObjResult(interp, varPtr[varIndex]); } else if (strcmp(subCmd, "get2") == 0) { if (objc != 3) { goto wrongNumArgs; } if (CheckIfVarUnset(interp, varPtr,varIndex)) { return TCL_ERROR; } string = Tcl_GetString(varPtr[varIndex]); Tcl_AppendToObj(Tcl_GetObjResult(interp), string, TCL_STRLEN); } else if (strcmp(subCmd, "inttoobigtest") == 0) { /* * If long ints have more bits than ints on this platform, verify that * Tcl_GetIntFromObj returns an error if the long int held in an * integer object's internal representation is too large to fit in an * int. */ if (objc != 3) { goto wrongNumArgs; } #if (INT_MAX == LONG_MAX) /* int is same size as long int */ Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", TCL_STRLEN); #else if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) { Tcl_SetLongObj(varPtr[varIndex], LONG_MAX); } else { SetVarToObj(varPtr, varIndex, Tcl_NewLongObj(LONG_MAX)); } if (Tcl_GetIntFromObj(interp, varPtr[varIndex], &i) != TCL_OK) { Tcl_ResetResult(interp); Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", TCL_STRLEN); return TCL_OK; } Tcl_AppendToObj(Tcl_GetObjResult(interp), "0", TCL_STRLEN); #endif } else if (strcmp(subCmd, "mult10") == 0) { if (objc != 3) { goto wrongNumArgs; } if (CheckIfVarUnset(interp, varPtr,varIndex)) { return TCL_ERROR; |
︙ | ︙ | |||
830 831 832 833 834 835 836 | *----------------------------------------------------------------------------- */ static int TestlistobjCmd( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* Tcl interpreter */ | | | 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 | *----------------------------------------------------------------------------- */ static int TestlistobjCmd( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* Tcl interpreter */ size_t objc, /* Number of arguments */ Tcl_Obj *const objv[]) /* Argument objects */ { /* Subcommands supported by this command */ const char* subcommands[] = { "set", "get", "replace" |
︙ | ︙ | |||
927 928 929 930 931 932 933 | *---------------------------------------------------------------------- */ static int TestobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 | *---------------------------------------------------------------------- */ static int TestobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int varIndex, destIndex, i; const char *index, *subCmd, *string; const Tcl_ObjType *targetType; Tcl_Obj **varPtr; |
︙ | ︙ | |||
1057 1058 1059 1060 1061 1062 1063 | * internal rep. If none exists, return "none". */ if (objc != 3) { goto wrongNumArgs; } if (objv[2]->typePtr == NULL) { | | | | 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 | * internal rep. If none exists, return "none". */ if (objc != 3) { goto wrongNumArgs; } if (objv[2]->typePtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("none", TCL_STRLEN)); } else { typeName = objv[2]->typePtr->name; Tcl_SetObjResult(interp, Tcl_NewStringObj(typeName, TCL_STRLEN)); } } else if (strcmp(subCmd, "refcount") == 0) { if (objc != 3) { goto wrongNumArgs; } index = Tcl_GetString(objv[2]); if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) { |
︙ | ︙ | |||
1086 1087 1088 1089 1090 1091 1092 | if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) { return TCL_ERROR; } if (CheckIfVarUnset(interp, varPtr,varIndex)) { return TCL_ERROR; } if (varPtr[varIndex]->typePtr == NULL) { /* a string! */ | | | | 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 | if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) { return TCL_ERROR; } if (CheckIfVarUnset(interp, varPtr,varIndex)) { return TCL_ERROR; } if (varPtr[varIndex]->typePtr == NULL) { /* a string! */ Tcl_AppendToObj(Tcl_GetObjResult(interp), "string", TCL_STRLEN); } else { Tcl_AppendToObj(Tcl_GetObjResult(interp), varPtr[varIndex]->typePtr->name, TCL_STRLEN); } } else if (strcmp(subCmd, "types") == 0) { if (objc != 2) { goto wrongNumArgs; } if (Tcl_AppendAllObjTypes(interp, Tcl_GetObjResult(interp)) != TCL_OK) { |
︙ | ︙ | |||
1131 1132 1133 1134 1135 1136 1137 | *---------------------------------------------------------------------- */ static int TeststringobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 | *---------------------------------------------------------------------- */ static int TeststringobjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_UniChar *unicode; int varIndex, option, i, length; #define MAX_STRINGS 11 const char *index, *string, *strings[MAX_STRINGS+1]; TestString *strPtr; Tcl_Obj **varPtr; size_t slen; static const char *const options[] = { "append", "appendstrings", "get", "get2", "length", "length2", "set", "set2", "setlength", "maxchars", "getunicode", "appendself", "appendself2", NULL }; if (objc < 3) { |
︙ | ︙ | |||
1183 1184 1185 1186 1187 1188 1189 | * "copy on write" and append to a copy of the object. */ if (Tcl_IsShared(varPtr[varIndex])) { SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex])); } string = Tcl_GetString(objv[3]); | | | 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 | * "copy on write" and append to a copy of the object. */ if (Tcl_IsShared(varPtr[varIndex])) { SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex])); } string = Tcl_GetString(objv[3]); Tcl_AppendToObj(varPtr[varIndex], string, (size_t) length); Tcl_SetObjResult(interp, varPtr[varIndex]); break; case 1: /* appendstrings */ if (objc > (MAX_STRINGS+3)) { goto wrongNumArgs; } if (varPtr[varIndex] == NULL) { |
︙ | ︙ | |||
1231 1232 1233 1234 1235 1236 1237 | if (objc != 3) { goto wrongNumArgs; } if (CheckIfVarUnset(interp, varPtr, varIndex)) { return TCL_ERROR; } string = Tcl_GetString(varPtr[varIndex]); | | | 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 | if (objc != 3) { goto wrongNumArgs; } if (CheckIfVarUnset(interp, varPtr, varIndex)) { return TCL_ERROR; } string = Tcl_GetString(varPtr[varIndex]); Tcl_AppendToObj(Tcl_GetObjResult(interp), string, TCL_STRLEN); break; case 4: /* length */ if (objc != 3) { goto wrongNumArgs; } Tcl_SetLongObj(Tcl_GetObjResult(interp), (varPtr[varIndex] != NULL) ? varPtr[varIndex]->length : -1); |
︙ | ︙ | |||
1268 1269 1270 1271 1272 1273 1274 | * varIndex has ref count 1 (i.e. the object is unshared) we can * modify that object directly. Otherwise, if RC>1 (i.e. the * object is shared), we must create a new object to modify/set * and decrement the old formerly-shared object's ref count. This * is "copy on write". */ | | > | 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 | * varIndex has ref count 1 (i.e. the object is unshared) we can * modify that object directly. Otherwise, if RC>1 (i.e. the * object is shared), we must create a new object to modify/set * and decrement the old formerly-shared object's ref count. This * is "copy on write". */ string = Tcl_GetStringFromObj(objv[3], &slen); length = (int) slen; if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) { Tcl_SetStringObj(varPtr[varIndex], string, length); } else { SetVarToObj(varPtr, varIndex, Tcl_NewStringObj(string, length)); } Tcl_SetObjResult(interp, varPtr[varIndex]); |
︙ | ︙ | |||
1302 1303 1304 1305 1306 1307 1308 | if (objc != 3) { goto wrongNumArgs; } if (varPtr[varIndex] != NULL) { Tcl_ConvertToType(NULL, varPtr[varIndex], Tcl_GetObjType("string")); strPtr = varPtr[varIndex]->internalRep.twoPtrValue.ptr1; | | | 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 | if (objc != 3) { goto wrongNumArgs; } if (varPtr[varIndex] != NULL) { Tcl_ConvertToType(NULL, varPtr[varIndex], Tcl_GetObjType("string")); strPtr = varPtr[varIndex]->internalRep.twoPtrValue.ptr1; length = (int) strPtr->maxChars; } else { length = -1; } Tcl_SetLongObj(Tcl_GetObjResult(interp), length); break; case 10: /* getunicode */ if (objc != 3) { |
︙ | ︙ | |||
1331 1332 1333 1334 1335 1336 1337 | * "copy on write" and append to a copy of the object. */ if (Tcl_IsShared(varPtr[varIndex])) { SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex])); } | | > | | 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 | * "copy on write" and append to a copy of the object. */ if (Tcl_IsShared(varPtr[varIndex])) { SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex])); } string = Tcl_GetStringFromObj(varPtr[varIndex], &slen); length = (int) slen; if (Tcl_GetIntFromObj(interp, objv[3], &i) != TCL_OK) { return TCL_ERROR; } if ((i < 0) || (i > length)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "index value out of range", TCL_STRLEN)); return TCL_ERROR; } Tcl_AppendToObj(varPtr[varIndex], string + i, length - i); Tcl_SetObjResult(interp, varPtr[varIndex]); break; case 12: /* appendself2 */ |
︙ | ︙ | |||
1362 1363 1364 1365 1366 1367 1368 | * "copy on write" and append to a copy of the object. */ if (Tcl_IsShared(varPtr[varIndex])) { SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex])); } | | > | | 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 | * "copy on write" and append to a copy of the object. */ if (Tcl_IsShared(varPtr[varIndex])) { SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex])); } unicode = Tcl_GetUnicodeFromObj(varPtr[varIndex], &slen); length = (int) slen; if (Tcl_GetIntFromObj(interp, objv[3], &i) != TCL_OK) { return TCL_ERROR; } if ((i < 0) || (i > length)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "index value out of range", TCL_STRLEN)); return TCL_ERROR; } Tcl_AppendUnicodeToObj(varPtr[varIndex], unicode + i, length - i); Tcl_SetObjResult(interp, varPtr[varIndex]); break; } |
︙ | ︙ | |||
1446 1447 1448 1449 1450 1451 1452 | int index; if (Tcl_GetInt(interp, string, &index) != TCL_OK) { return TCL_ERROR; } if (index < 0 || index >= NUMBER_OF_OBJECT_VARS) { Tcl_ResetResult(interp); | | > | 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 | int index; if (Tcl_GetInt(interp, string, &index) != TCL_OK) { return TCL_ERROR; } if (index < 0 || index >= NUMBER_OF_OBJECT_VARS) { Tcl_ResetResult(interp); Tcl_AppendToObj(Tcl_GetObjResult(interp), "bad variable index", TCL_STRLEN); return TCL_ERROR; } *indexPtr = index; return TCL_OK; } |
︙ | ︙ | |||
1483 1484 1485 1486 1487 1488 1489 | int varIndex) /* Index of the test variable to check. */ { if (varPtr[varIndex] == NULL) { char buf[32 + TCL_INTEGER_SPACE]; sprintf(buf, "variable %d is unset (NULL)", varIndex); Tcl_ResetResult(interp); | | | 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 | int varIndex) /* Index of the test variable to check. */ { if (varPtr[varIndex] == NULL) { char buf[32 + TCL_INTEGER_SPACE]; sprintf(buf, "variable %d is unset (NULL)", varIndex); Tcl_ResetResult(interp); Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, TCL_STRLEN); return 1; } return 0; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclTestProcBodyObj.c.
︙ | ︙ | |||
40 41 42 43 44 45 46 | int exportIt; /* if 1, export the command */ } CmdTable; /* * Declarations for functions defined in this file. */ | | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | int exportIt; /* if 1, export the command */ } CmdTable; /* * Declarations for functions defined in this file. */ static int ProcBodyTestProcObjCmd(ClientData dummy, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int ProcBodyTestInitInternal(Tcl_Interp *interp, int isSafe); static int RegisterCommand(Tcl_Interp* interp, const char *namespace, const CmdTable *cmdTablePtr); /* * List of commands to create when the package is loaded; must go after the * declarations of the enable command procedure. |
︙ | ︙ | |||
130 131 132 133 134 135 136 | *---------------------------------------------------------------------- */ static int RegisterCommand( Tcl_Interp* interp, /* the Tcl interpreter for which the operation * is performed */ | | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | *---------------------------------------------------------------------- */ static int RegisterCommand( Tcl_Interp* interp, /* the Tcl interpreter for which the operation * is performed */ const char *namespace, /* the namespace in which the command is * registered */ const CmdTable *cmdTablePtr)/* the command to register */ { char buf[128]; if (cmdTablePtr->exportIt) { sprintf(buf, "namespace eval %s { namespace export %s }", |
︙ | ︙ | |||
221 222 223 224 225 226 227 | *---------------------------------------------------------------------- */ static int ProcBodyTestProcObjCmd( ClientData dummy, /* context; not used */ Tcl_Interp *interp, /* the current interpreter */ | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | *---------------------------------------------------------------------- */ static int ProcBodyTestProcObjCmd( ClientData dummy, /* context; not used */ Tcl_Interp *interp, /* the current interpreter */ size_t objc, /* argument count */ Tcl_Obj *const objv[]) /* arguments */ { const char *fullName; Tcl_Command procCmd; Command *cmdPtr; Proc *procPtr = NULL; Tcl_Obj *bodyObjPtr; |
︙ | ︙ |
Changes to generic/tclThreadAlloc.c.
︙ | ︙ | |||
102 103 104 105 106 107 108 | * code in Tcl_CreateInterp(). */ typedef struct Cache { struct Cache *nextPtr; /* Linked list of cache entries */ Tcl_ThreadId owner; /* Which thread's cache is this? */ Tcl_Obj *firstObjPtr; /* List of free objects for thread */ | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | * code in Tcl_CreateInterp(). */ typedef struct Cache { struct Cache *nextPtr; /* Linked list of cache entries */ Tcl_ThreadId owner; /* Which thread's cache is this? */ Tcl_Obj *firstObjPtr; /* List of free objects for thread */ size_t numObjects; /* Number of objects for thread */ int totalAssigned; /* Total space assigned to thread */ Bucket buckets[NBUCKETS]; /* The buckets for this thread */ } Cache; /* * The following array specifies various per-bucket limits and locks. The * values are statically initialized to avoid calculating them repeatedly. |
︙ | ︙ | |||
129 130 131 132 133 134 135 | static Cache * GetCache(void); static void LockBucket(Cache *cachePtr, int bucket); static void UnlockBucket(Cache *cachePtr, int bucket); static void PutBlocks(Cache *cachePtr, int bucket, int numMove); static int GetBlocks(Cache *cachePtr, int bucket); static Block * Ptr2Block(char *ptr); | | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | static Cache * GetCache(void); static void LockBucket(Cache *cachePtr, int bucket); static void UnlockBucket(Cache *cachePtr, int bucket); static void PutBlocks(Cache *cachePtr, int bucket, int numMove); static int GetBlocks(Cache *cachePtr, int bucket); static Block * Ptr2Block(char *ptr); static char * Block2Ptr(Block *blockPtr, int bucket, size_t reqSize); static void MoveObjs(Cache *fromPtr, Cache *toPtr, int numMove); /* * Local variables defined in this file and initialized at startup. */ static Tcl_Mutex *listLockPtr; |
︙ | ︙ | |||
304 305 306 307 308 309 310 | * May allocate more blocks for a bucket. * *---------------------------------------------------------------------- */ char * TclpAlloc( | | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | * May allocate more blocks for a bucket. * *---------------------------------------------------------------------- */ char * TclpAlloc( size_t reqSize) { Cache *cachePtr; Block *blockPtr; register int bucket; size_t size; #ifndef __LP64__ |
︙ | ︙ | |||
438 439 440 441 442 443 444 | * *---------------------------------------------------------------------- */ char * TclpRealloc( char *ptr, | | | 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | * *---------------------------------------------------------------------- */ char * TclpRealloc( char *ptr, size_t reqSize) { Cache *cachePtr; Block *blockPtr; void *newPtr; size_t size, min; int bucket; |
︙ | ︙ | |||
751 752 753 754 755 756 757 | *---------------------------------------------------------------------- */ static char * Block2Ptr( Block *blockPtr, int bucket, | | | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | *---------------------------------------------------------------------- */ static char * Block2Ptr( Block *blockPtr, int bucket, size_t reqSize) { register void *ptr; blockPtr->magicNum1 = blockPtr->magicNum2 = MAGIC; blockPtr->sourceBucket = bucket; blockPtr->blockReqSize = reqSize; ptr = ((void *) (blockPtr + 1)); |
︙ | ︙ |
Changes to generic/tclThreadTest.c.
︙ | ︙ | |||
116 117 118 119 120 121 122 | * Access to the list of threads and to the thread send results is guarded by * this mutex. */ TCL_DECLARE_MUTEX(threadMutex) static int ThreadObjCmd(ClientData clientData, | | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | * Access to the list of threads and to the thread send results is guarded by * this mutex. */ TCL_DECLARE_MUTEX(threadMutex) static int ThreadObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int ThreadCreate(Tcl_Interp *interp, const char *script, int joinable); static int ThreadList(Tcl_Interp *interp); static int ThreadSend(Tcl_Interp *interp, Tcl_ThreadId id, const char *script, int wait); static int ThreadCancel(Tcl_Interp *interp, Tcl_ThreadId id, |
︙ | ︙ | |||
205 206 207 208 209 210 211 | */ /* ARGSUSED */ static int ThreadObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | */ /* ARGSUSED */ static int ThreadObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); int option; static const char *const threadOptions[] = { "cancel", "create", "event", "exit", "id", "join", "names", "send", "wait", "errorproc", |
︙ | ︙ | |||
246 247 248 249 250 251 252 | Tcl_MutexUnlock(&threadMutex); } switch ((enum options)option) { case THREAD_CANCEL: { long id; const char *result; | | > | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | Tcl_MutexUnlock(&threadMutex); } switch ((enum options)option) { case THREAD_CANCEL: { long id; const char *result; int flags; size_t arg; if ((objc < 3) || (objc > 5)) { Tcl_WrongNumArgs(interp, 2, objv, "?-unwind? id ?result?"); return TCL_ERROR; } flags = 0; arg = 2; |
︙ | ︙ | |||
273 274 275 276 277 278 279 | } else { result = NULL; } return ThreadCancel(interp, (Tcl_ThreadId) (size_t) id, result, flags); } case THREAD_CREATE: { const char *script; | | > | 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | } else { result = NULL; } return ThreadCancel(interp, (Tcl_ThreadId) (size_t) id, result, flags); } case THREAD_CREATE: { const char *script; int joinable; size_t len; if (objc == 2) { /* * Neither joinable nor special script */ joinable = 0; |
︙ | ︙ | |||
656 657 658 659 660 661 662 | char buf[TCL_DOUBLE_SPACE+1]; sprintf(buf, "%" TCL_LL_MODIFIER "d", (Tcl_WideInt)(size_t)Tcl_GetCurrentThread()); errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); if (errorProcString == NULL) { errChannel = Tcl_GetStdChannel(TCL_STDERR); | | | | | 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 | char buf[TCL_DOUBLE_SPACE+1]; sprintf(buf, "%" TCL_LL_MODIFIER "d", (Tcl_WideInt)(size_t)Tcl_GetCurrentThread()); errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); if (errorProcString == NULL) { errChannel = Tcl_GetStdChannel(TCL_STDERR); Tcl_WriteChars(errChannel, "Error from thread ", TCL_STRLEN); Tcl_WriteChars(errChannel, buf, TCL_STRLEN); Tcl_WriteChars(errChannel, "\n", 1); Tcl_WriteChars(errChannel, errorInfo, TCL_STRLEN); Tcl_WriteChars(errChannel, "\n", 1); } else { argv[0] = errorProcString; argv[1] = buf; argv[2] = errorInfo; script = Tcl_Merge(3, argv); ThreadSend(interp, errorThreadId, script, 0); |
︙ | ︙ | |||
985 986 987 988 989 990 991 | * Since Tcl_CancelEval can be safely called from any thread, * we do it now. */ Tcl_MutexUnlock(&threadMutex); Tcl_ResetResult(interp); return Tcl_CancelEval(tsdPtr->interp, | | > | 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 | * Since Tcl_CancelEval can be safely called from any thread, * we do it now. */ Tcl_MutexUnlock(&threadMutex); Tcl_ResetResult(interp); return Tcl_CancelEval(tsdPtr->interp, (result != NULL) ? Tcl_NewStringObj(result, TCL_STRLEN) : NULL, 0, flags); } /* *------------------------------------------------------------------------ * * ThreadEventProc -- * |
︙ | ︙ |
Changes to generic/tclTimer.c.
︙ | ︙ | |||
772 773 774 775 776 777 778 779 780 781 782 783 | * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_AfterObjCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Current interpreter. */ | > | | | 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 | * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ // TODO Can this become an ensemble? /* ARGSUSED */ int Tcl_AfterObjCmd( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_WideInt ms = 0; /* Number of milliseconds to wait */ Tcl_Time wakeup; AfterInfo *afterPtr; AfterAssocData *assocPtr; size_t length; int index; static const char *const afterSubCmds[] = { "cancel", "idle", "info", NULL }; enum afterSubCmds {AFTER_CANCEL, AFTER_IDLE, AFTER_INFO}; ThreadSpecificData *tsdPtr = InitTimer(); |
︙ | ︙ | |||
885 886 887 888 889 890 891 | assocPtr->firstAfterPtr = afterPtr; Tcl_SetObjResult(interp, Tcl_ObjPrintf("after#%d", afterPtr->id)); return TCL_OK; } case AFTER_CANCEL: { Tcl_Obj *commandPtr; const char *command, *tempCommand; | | | 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 | assocPtr->firstAfterPtr = afterPtr; Tcl_SetObjResult(interp, Tcl_ObjPrintf("after#%d", afterPtr->id)); return TCL_OK; } case AFTER_CANCEL: { Tcl_Obj *commandPtr; const char *command, *tempCommand; size_t tempLength; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "id|command"); return TCL_ERROR; } if (objc == 3) { commandPtr = objv[2]; |
︙ | ︙ | |||
975 976 977 978 979 980 981 | return TCL_ERROR; } else { Tcl_Obj *resultListPtr = Tcl_NewObj(); Tcl_ListObjAppendElement(interp, resultListPtr, afterPtr->commandPtr); Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj( | | > | 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 | return TCL_ERROR; } else { Tcl_Obj *resultListPtr = Tcl_NewObj(); Tcl_ListObjAppendElement(interp, resultListPtr, afterPtr->commandPtr); Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj( (afterPtr->token == NULL) ? "idle" : "timer", TCL_STRLEN)); Tcl_SetObjResult(interp, resultListPtr); } break; default: Tcl_Panic("Tcl_AfterObjCmd: bad subcommand index to afterSubCmds"); } return TCL_OK; |
︙ | ︙ |
Changes to generic/tclTrace.c.
︙ | ︙ | |||
90 91 92 93 94 95 96 | #define TCL_TRACE_EXEC_DIRECT 0x20 /* * Forward declarations for functions defined in this file: */ typedef int (Tcl_TraceTypeObjCmd)(Tcl_Interp *interp, int optionIndex, | | | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | #define TCL_TRACE_EXEC_DIRECT 0x20 /* * Forward declarations for functions defined in this file: */ typedef int (Tcl_TraceTypeObjCmd)(Tcl_Interp *interp, int optionIndex, size_t objc, Tcl_Obj *const objv[]); static Tcl_TraceTypeObjCmd TraceVariableObjCmd; static Tcl_TraceTypeObjCmd TraceCommandObjCmd; static Tcl_TraceTypeObjCmd TraceExecutionObjCmd; /* * Each subcommand has a number of 'types' to which it can apply. Currently |
︙ | ︙ | |||
117 118 119 120 121 122 123 | }; /* * Declarations for local functions to this file: */ static int CallTraceFunction(Tcl_Interp *interp, Trace *tracePtr, | | > | | | 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 | }; /* * Declarations for local functions to this file: */ static int CallTraceFunction(Tcl_Interp *interp, Trace *tracePtr, Command *cmdPtr, const char *command, size_t numChars, size_t objc, Tcl_Obj *const objv[]); static char * TraceVarProc(ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags); static void TraceCommandProc(ClientData clientData, Tcl_Interp *interp, const char *oldName, const char *newName, int flags); static Tcl_CmdObjTraceProc TraceExecutionProc; static int StringTraceProc(ClientData clientData, Tcl_Interp *interp, int level, const char *command, Tcl_Command commandInfo, size_t objc, Tcl_Obj *const objv[]); static void StringTraceDeleteProc(ClientData clientData); static void DisposeTraceResult(int flags, char *result); static int TraceVarEx(Tcl_Interp *interp, const char *part1, const char *part2, register VarTrace *tracePtr); /* * The following structure holds the client data for string-based |
︙ | ︙ | |||
183 184 185 186 187 188 189 | */ /* ARGSUSED */ int Tcl_TraceObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | */ /* ARGSUSED */ int Tcl_TraceObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int optionIndex; const char *name; const char *flagOps, *p; /* Main sub commands to 'trace' */ static const char *const traceOptions[] = { |
︙ | ︙ | |||
265 266 267 268 269 270 271 | } #ifndef TCL_REMOVE_OBSOLETE_TRACES case TRACE_OLD_VARIABLE: case TRACE_OLD_VDELETE: { Tcl_Obj *copyObjv[6]; Tcl_Obj *opsList; | | > | 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | } #ifndef TCL_REMOVE_OBSOLETE_TRACES case TRACE_OLD_VARIABLE: case TRACE_OLD_VDELETE: { Tcl_Obj *copyObjv[6]; Tcl_Obj *opsList; int code; size_t numFlags; if (objc != 5) { Tcl_WrongNumArgs(interp, 2, objv, "name ops command"); return TCL_ERROR; } opsList = Tcl_NewObj(); |
︙ | ︙ | |||
348 349 350 351 352 353 354 | /* * Build a pair (2-item list) with the ops string as the first obj * element and the tvarPtr->command string as the second obj * element. Append the pair (as an element) to the end of the * result object list. */ | | | | 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | /* * Build a pair (2-item list) with the ops string as the first obj * element and the tvarPtr->command string as the second obj * element. Append the pair (as an element) to the end of the * result object list. */ elemObjPtr = Tcl_NewStringObj(ops, TCL_STRLEN); Tcl_ListObjAppendElement(NULL, pairObjPtr, elemObjPtr); elemObjPtr = Tcl_NewStringObj(tvarPtr->command, TCL_STRLEN); Tcl_ListObjAppendElement(NULL, pairObjPtr, elemObjPtr); Tcl_ListObjAppendElement(interp, resultListPtr, pairObjPtr); } Tcl_SetObjResult(interp, resultListPtr); break; } #endif /* TCL_REMOVE_OBSOLETE_TRACES */ |
︙ | ︙ | |||
392 393 394 395 396 397 398 | *---------------------------------------------------------------------- */ static int TraceExecutionObjCmd( Tcl_Interp *interp, /* Current interpreter. */ int optionIndex, /* Add, info or remove */ | | | | | < > | | 394 395 396 397 398 399 400 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 438 439 440 441 442 443 444 445 446 447 448 449 | *---------------------------------------------------------------------- */ static int TraceExecutionObjCmd( Tcl_Interp *interp, /* Current interpreter. */ int optionIndex, /* Add, info or remove */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int index; const char *name, *command; size_t commandLength, length; enum traceOptions { TRACE_ADD, TRACE_INFO, TRACE_REMOVE }; static const char *const opStrings[] = { "enter", "leave", "enterstep", "leavestep", NULL }; enum operations { TRACE_EXEC_ENTER, TRACE_EXEC_LEAVE, TRACE_EXEC_ENTER_STEP, TRACE_EXEC_LEAVE_STEP }; switch ((enum traceOptions) optionIndex) { case TRACE_ADD: case TRACE_REMOVE: { int flags = 0, result; Tcl_Obj **elemPtrs; size_t i, listLen; if (objc != 6) { Tcl_WrongNumArgs(interp, 3, objv, "name opList command"); return TCL_ERROR; } /* * Make sure the ops argument is a list object; get its length and a * pointer to its array of element pointers. */ result = Tcl_ListObjGetElements(interp, objv[4], &listLen, &elemPtrs); if (result != TCL_OK) { return result; } if (listLen == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad operation list \"\": must be one or more of" " enter, leave, enterstep, or leavestep", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "NOOPS", NULL); return TCL_ERROR; } for (i = 0; i < listLen; i++) { if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings, "operation", TCL_EXACT, &index) != TCL_OK) { |
︙ | ︙ | |||
570 571 572 573 574 575 576 | if (Tcl_FindCommand(interp, name, NULL, TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } resultListPtr = Tcl_NewListObj(0, NULL); FOREACH_COMMAND_TRACE(interp, name, clientData) { | | | 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 | if (Tcl_FindCommand(interp, name, NULL, TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } resultListPtr = Tcl_NewListObj(0, NULL); FOREACH_COMMAND_TRACE(interp, name, clientData) { size_t numOps = 0; Tcl_Obj *opObj, *eachTraceObjPtr, *elemObjPtr; TraceCommandInfo *tcmdPtr = clientData; /* * Build a list with the ops list as the first obj element and the * tcmdPtr->command string as the second obj element. Append this * list (as an element) to the end of the result object list. |
︙ | ︙ | |||
609 610 611 612 613 614 615 | } eachTraceObjPtr = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr); Tcl_DecrRefCount(elemObjPtr); elemObjPtr = NULL; Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, | | | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | } eachTraceObjPtr = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr); Tcl_DecrRefCount(elemObjPtr); elemObjPtr = NULL; Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, Tcl_NewStringObj(tcmdPtr->command, TCL_STRLEN)); Tcl_ListObjAppendElement(interp, resultListPtr, eachTraceObjPtr); } Tcl_SetObjResult(interp, resultListPtr); break; } } return TCL_OK; |
︙ | ︙ | |||
642 643 644 645 646 647 648 | *---------------------------------------------------------------------- */ static int TraceCommandObjCmd( Tcl_Interp *interp, /* Current interpreter. */ int optionIndex, /* Add, info or remove */ | | | | | | | | 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 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 | *---------------------------------------------------------------------- */ static int TraceCommandObjCmd( Tcl_Interp *interp, /* Current interpreter. */ int optionIndex, /* Add, info or remove */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int index; const char *name, *command; size_t commandLength, length; enum traceOptions { TRACE_ADD, TRACE_INFO, TRACE_REMOVE }; static const char *const opStrings[] = { "delete", "rename", NULL }; enum operations { TRACE_CMD_DELETE, TRACE_CMD_RENAME }; switch ((enum traceOptions) optionIndex) { case TRACE_ADD: case TRACE_REMOVE: { int flags = 0, result; size_t i, listLen; Tcl_Obj **elemPtrs; if (objc != 6) { Tcl_WrongNumArgs(interp, 3, objv, "name opList command"); return TCL_ERROR; } /* * Make sure the ops argument is a list object; get its length and a * pointer to its array of element pointers. */ result = Tcl_ListObjGetElements(interp, objv[4], &listLen, &elemPtrs); if (result != TCL_OK) { return result; } if (listLen == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad operation list \"\": must be one or more of" " delete or rename", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "NOOPS", NULL); return TCL_ERROR; } for (i = 0; i < listLen; i++) { if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings, |
︙ | ︙ | |||
773 774 775 776 777 778 779 | name = Tcl_GetString(objv[3]); if (Tcl_FindCommand(interp, name, NULL, TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } resultListPtr = Tcl_NewListObj(0, NULL); FOREACH_COMMAND_TRACE(interp, name, clientData) { | | | 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 | name = Tcl_GetString(objv[3]); if (Tcl_FindCommand(interp, name, NULL, TCL_LEAVE_ERR_MSG) == NULL) { return TCL_ERROR; } resultListPtr = Tcl_NewListObj(0, NULL); FOREACH_COMMAND_TRACE(interp, name, clientData) { size_t numOps = 0; Tcl_Obj *opObj, *eachTraceObjPtr, *elemObjPtr; TraceCommandInfo *tcmdPtr = clientData; /* * Build a list with the ops list as the first obj element and the * tcmdPtr->command string as the second obj element. Append this * list (as an element) to the end of the result object list. |
︙ | ︙ | |||
802 803 804 805 806 807 808 | Tcl_DecrRefCount(elemObjPtr); continue; } eachTraceObjPtr = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr); Tcl_DecrRefCount(elemObjPtr); | | | 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 | Tcl_DecrRefCount(elemObjPtr); continue; } eachTraceObjPtr = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr); Tcl_DecrRefCount(elemObjPtr); elemObjPtr = Tcl_NewStringObj(tcmdPtr->command, TCL_STRLEN); Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr); Tcl_ListObjAppendElement(interp, resultListPtr, eachTraceObjPtr); } Tcl_SetObjResult(interp, resultListPtr); break; } } |
︙ | ︙ | |||
836 837 838 839 840 841 842 | *---------------------------------------------------------------------- */ static int TraceVariableObjCmd( Tcl_Interp *interp, /* Current interpreter. */ int optionIndex, /* Add, info or remove */ | | | | | | | | 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 | *---------------------------------------------------------------------- */ static int TraceVariableObjCmd( Tcl_Interp *interp, /* Current interpreter. */ int optionIndex, /* Add, info or remove */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int index; const char *name, *command; size_t commandLength, length; ClientData clientData; enum traceOptions { TRACE_ADD, TRACE_INFO, TRACE_REMOVE }; static const char *const opStrings[] = { "array", "read", "unset", "write", NULL }; enum operations { TRACE_VAR_ARRAY, TRACE_VAR_READ, TRACE_VAR_UNSET, TRACE_VAR_WRITE }; switch ((enum traceOptions) optionIndex) { case TRACE_ADD: case TRACE_REMOVE: { int flags = 0, result; size_t i, listLen; Tcl_Obj **elemPtrs; if (objc != 6) { Tcl_WrongNumArgs(interp, 3, objv, "name opList command"); return TCL_ERROR; } /* * Make sure the ops argument is a list object; get its length and a * pointer to its array of element pointers. */ result = Tcl_ListObjGetElements(interp, objv[4], &listLen, &elemPtrs); if (result != TCL_OK) { return result; } if (listLen == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad operation list \"\": must be one or more of" " array, read, unset, or write", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "NOOPS", NULL); return TCL_ERROR; } for (i = 0; i < listLen ; i++) { if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings, "operation", TCL_EXACT, &index) != TCL_OK) { |
︙ | ︙ | |||
987 988 989 990 991 992 993 | if (tvarPtr->flags & TCL_TRACE_UNSETS) { TclNewLiteralStringObj(opObjPtr, "unset"); Tcl_ListObjAppendElement(NULL, elemObjPtr, opObjPtr); } eachTraceObjPtr = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr); | | | 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 | if (tvarPtr->flags & TCL_TRACE_UNSETS) { TclNewLiteralStringObj(opObjPtr, "unset"); Tcl_ListObjAppendElement(NULL, elemObjPtr, opObjPtr); } eachTraceObjPtr = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr); elemObjPtr = Tcl_NewStringObj(tvarPtr->command, TCL_STRLEN); Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr); Tcl_ListObjAppendElement(interp, resultListPtr, eachTraceObjPtr); } Tcl_SetObjResult(interp, resultListPtr); break; } |
︙ | ︙ | |||
1127 1128 1129 1130 1131 1132 1133 | tracePtr->refCount = 1; cmdPtr->tracePtr = tracePtr; if (tracePtr->flags & TCL_TRACE_ANY_EXEC) { /* * Bug 3484621: up the interp's epoch if this is a BC'ed command */ | | > | 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 | tracePtr->refCount = 1; cmdPtr->tracePtr = tracePtr; if (tracePtr->flags & TCL_TRACE_ANY_EXEC) { /* * Bug 3484621: up the interp's epoch if this is a BC'ed command */ if ((cmdPtr->compileProc != NULL) && !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)) { Interp *iPtr = (Interp *) interp; iPtr->compileEpoch++; } cmdPtr->flags |= CMD_HAS_EXEC_TRACES; } |
︙ | ︙ | |||
1243 1244 1245 1246 1247 1248 1249 | cmdPtr->flags &= ~CMD_HAS_EXEC_TRACES; /* * Bug 3484621: up the interp's epoch if this is a BC'ed command */ if (cmdPtr->compileProc != NULL) { | < | 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 | cmdPtr->flags &= ~CMD_HAS_EXEC_TRACES; /* * Bug 3484621: up the interp's epoch if this is a BC'ed command */ if (cmdPtr->compileProc != NULL) { iPtr->compileEpoch++; } } } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1413 1414 1415 1416 1417 1418 1419 | */ int TclCheckExecutionTraces( Tcl_Interp *interp, /* The current interpreter. */ const char *command, /* Pointer to beginning of the current command * string. */ | | | | 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 | */ int TclCheckExecutionTraces( Tcl_Interp *interp, /* The current interpreter. */ const char *command, /* Pointer to beginning of the current command * string. */ size_t numChars, /* The number of characters in 'command' which * are part of the command string. */ Command *cmdPtr, /* Points to command's Command struct. */ int code, /* The current result code. */ int traceFlags, /* Current tracing situation. */ size_t objc, /* Number of arguments for the command. */ Tcl_Obj *const objv[]) /* Pointers to Tcl_Obj of each argument. */ { Interp *iPtr = (Interp *) interp; CommandTrace *tracePtr, *lastTracePtr; ActiveCommandTrace active; int curLevel; int traceCode = TCL_OK; |
︙ | ︙ | |||
1519 1520 1521 1522 1523 1524 1525 | */ int TclCheckInterpTraces( Tcl_Interp *interp, /* The current interpreter. */ const char *command, /* Pointer to beginning of the current command * string. */ | | | | | 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 | */ int TclCheckInterpTraces( Tcl_Interp *interp, /* The current interpreter. */ const char *command, /* Pointer to beginning of the current command * string. */ size_t numChars, /* The number of characters in 'command' which * are part of the command string. */ Command *cmdPtr, /* Points to command's Command struct. */ int code, /* The current result code. */ int traceFlags, /* Current tracing situation. */ size_t objc, /* Number of arguments for the command. */ Tcl_Obj *const objv[]) /* Pointers to Tcl_Obj of each argument. */ { Interp *iPtr = (Interp *) interp; Trace *tracePtr, *lastTracePtr; ActiveInterpTrace active; int curLevel; int traceCode = TCL_OK; Tcl_InterpState state = NULL; if ((iPtr->tracePtr == NULL) || (iPtr->flags & INTERP_TRACE_IN_PROGRESS)) { return traceCode; } curLevel = iPtr->numLevels; active.nextPtr = iPtr->activeInterpTracePtr; iPtr->activeInterpTracePtr = &active; |
︙ | ︙ | |||
1666 1667 1668 1669 1670 1671 1672 | static int CallTraceFunction( Tcl_Interp *interp, /* The current interpreter. */ register Trace *tracePtr, /* Describes the trace function to call. */ Command *cmdPtr, /* Points to command's Command struct. */ const char *command, /* Points to the first character of the * command's source before substitutions. */ | | | | | | 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 | static int CallTraceFunction( Tcl_Interp *interp, /* The current interpreter. */ register Trace *tracePtr, /* Describes the trace function to call. */ Command *cmdPtr, /* Points to command's Command struct. */ const char *command, /* Points to the first character of the * command's source before substitutions. */ size_t numChars, /* The number of characters in the command's * source. */ register size_t objc, /* Number of arguments for the command. */ Tcl_Obj *const objv[]) /* Pointers to Tcl_Obj of each argument. */ { Interp *iPtr = (Interp *) interp; char *commandCopy; int traceCode; /* * Copy the command characters into a new string. */ commandCopy = TclStackAlloc(interp, numChars + 1); memcpy(commandCopy, command, numChars); commandCopy[numChars] = '\0'; /* * Call the trace function then free allocated storage. */ traceCode = tracePtr->proc(tracePtr->clientData, (Tcl_Interp *) iPtr, |
︙ | ︙ | |||
1754 1755 1756 1757 1758 1759 1760 | static int TraceExecutionProc( ClientData clientData, Tcl_Interp *interp, int level, const char *command, Tcl_Command cmdInfo, | | | 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 | static int TraceExecutionProc( ClientData clientData, Tcl_Interp *interp, int level, const char *command, Tcl_Command cmdInfo, size_t objc, struct Tcl_Obj *const objv[]) { int call = 0; Interp *iPtr = (Interp *) interp; TraceCommandInfo *tcmdPtr = clientData; int flags = tcmdPtr->curFlags; int code = tcmdPtr->curCode; |
︙ | ︙ | |||
1991 1992 1993 1994 1995 1996 1997 | if (tvarPtr->length != (size_t) 0) { /* * Generate a command to execute by appending list elements for * the two variable names and the operation. */ Tcl_DStringInit(&cmd); | | | 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 | if (tvarPtr->length != (size_t) 0) { /* * Generate a command to execute by appending list elements for * the two variable names and the operation. */ Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, tvarPtr->command, tvarPtr->length); Tcl_DStringAppendElement(&cmd, name1); Tcl_DStringAppendElement(&cmd, (name2 ? name2 : "")); #ifndef TCL_REMOVE_OBSOLETE_TRACES if (tvarPtr->flags & TCL_TRACE_OLD_STYLE) { if (flags & TCL_TRACE_ARRAY) { TclDStringAppendLiteral(&cmd, " a"); } else if (flags & TCL_TRACE_READS) { |
︙ | ︙ | |||
2254 2255 2256 2257 2258 2259 2260 | static int StringTraceProc( ClientData clientData, Tcl_Interp *interp, int level, const char *command, Tcl_Command commandInfo, | | | | | 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 | static int StringTraceProc( ClientData clientData, Tcl_Interp *interp, int level, const char *command, Tcl_Command commandInfo, size_t objc, Tcl_Obj *const *objv) { StringTraceData *data = clientData; Command *cmdPtr = (Command *) commandInfo; const char **argv; /* Args to pass to string trace proc */ size_t i; /* * This is a bit messy because we have to emulate the old trace interface, * which uses strings for everything. */ argv = (const char **) TclStackAlloc(interp, (objc + 1) * sizeof(const char *)); for (i = 0; i < objc; i++) { argv[i] = Tcl_GetString(objv[i]); } argv[objc] = 0; /* * Invoke the command function. Note that we cast away const-ness on two |
︙ | ︙ | |||
2719 2720 2721 2722 2723 2724 2725 | break; } if (disposeFlags & TCL_TRACE_RESULT_OBJECT) { Tcl_SetObjResult((Tcl_Interp *)iPtr, (Tcl_Obj *) result); } else { Tcl_SetObjResult((Tcl_Interp *)iPtr, | | | 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 | break; } if (disposeFlags & TCL_TRACE_RESULT_OBJECT) { Tcl_SetObjResult((Tcl_Interp *)iPtr, (Tcl_Obj *) result); } else { Tcl_SetObjResult((Tcl_Interp *)iPtr, Tcl_NewStringObj(result, TCL_STRLEN)); } Tcl_AddErrorInfo((Tcl_Interp *)iPtr, ""); Tcl_AppendObjToErrorInfo((Tcl_Interp *)iPtr, Tcl_ObjPrintf( "\n (%s trace on \"%s%s%s%s\")", type, part1, (part2 ? "(" : ""), (part2 ? part2 : ""), (part2 ? ")" : "") )); |
︙ | ︙ |
Changes to generic/tclUtf.c.
︙ | ︙ | |||
228 229 230 231 232 233 234 | * *--------------------------------------------------------------------------- */ char * Tcl_UniCharToUtfDString( const Tcl_UniChar *uniStr, /* Unicode string to convert to UTF-8. */ | | | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | * *--------------------------------------------------------------------------- */ char * Tcl_UniCharToUtfDString( const Tcl_UniChar *uniStr, /* Unicode string to convert to UTF-8. */ size_t uniLength, /* Length of Unicode string in Tcl_UniChars * (must be >= 0). */ Tcl_DString *dsPtr) /* UTF-8 representation of string is appended * to this previously initialized DString. */ { const Tcl_UniChar *w, *wEnd; char *p, *string; int oldLength; |
︙ | ︙ | |||
390 391 392 393 394 395 396 | * *--------------------------------------------------------------------------- */ Tcl_UniChar * Tcl_UtfToUniCharDString( const char *src, /* UTF-8 string to convert to Unicode. */ | | | | | | | | 390 391 392 393 394 395 396 397 398 399 400 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 | * *--------------------------------------------------------------------------- */ Tcl_UniChar * Tcl_UtfToUniCharDString( const char *src, /* UTF-8 string to convert to Unicode. */ size_t length, /* Length of UTF-8 string in bytes, or * TCL_STRLEN for strlen(). */ Tcl_DString *dsPtr) /* Unicode representation of string is * appended to this previously initialized * DString. */ { Tcl_UniChar *w, *wString; const char *p, *end; size_t oldLength; if (length == TCL_STRLEN) { length = strlen(src); } /* * Unicode string length in Tcl_UniChars will be <= UTF-8 string length in * bytes. */ oldLength = Tcl_DStringLength(dsPtr); /* TODO: fix overreach! */ Tcl_DStringSetLength(dsPtr, (oldLength + length + 1) * sizeof(Tcl_UniChar)); wString = (Tcl_UniChar *) (Tcl_DStringValue(dsPtr) + oldLength); w = wString; end = src + length; for (p = src; p < end; ) { p += TclUtfToUniChar(p, w); w++; } *w = '\0'; Tcl_DStringSetLength(dsPtr, oldLength + ((char *) w - (char *) wString)); return wString; } /* *--------------------------------------------------------------------------- * |
︙ | ︙ | |||
451 452 453 454 455 456 457 | *--------------------------------------------------------------------------- */ int Tcl_UtfCharComplete( const char *src, /* String to check if first few bytes contain * a complete UTF-8 character. */ | | | 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | *--------------------------------------------------------------------------- */ int Tcl_UtfCharComplete( const char *src, /* String to check if first few bytes contain * a complete UTF-8 character. */ size_t length) /* Length of above string in bytes. */ { int ch; ch = *((unsigned char *) src); return length >= totalBytes[ch]; } |
︙ | ︙ | |||
477 478 479 480 481 482 483 | * * Side effects: * None. * *--------------------------------------------------------------------------- */ | | | | | | 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 | * * Side effects: * None. * *--------------------------------------------------------------------------- */ size_t Tcl_NumUtfChars( register const char *src, /* The UTF-8 string to measure. */ size_t length) /* The length of the string in bytes, or * TCL_STRLEN for strlen(string). */ { Tcl_UniChar ch; register Tcl_UniChar *chPtr = &ch; register int i; /* * The separate implementations are faster. * * Since this is a time-sensitive function, we also do the check for the * single-byte char case specially. */ i = 0; if (length == TCL_STRLEN) { while (*src != '\0') { src += TclUtfToUniChar(src, chPtr); i++; } } else { register int n; |
︙ | ︙ | |||
698 699 700 701 702 703 704 | * *--------------------------------------------------------------------------- */ Tcl_UniChar Tcl_UniCharAtIndex( register const char *src, /* The UTF-8 string to dereference. */ | | | 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 | * *--------------------------------------------------------------------------- */ Tcl_UniChar Tcl_UniCharAtIndex( register const char *src, /* The UTF-8 string to dereference. */ register size_t index) /* The position of the desired character. */ { Tcl_UniChar ch = 0; while (index >= 0) { index--; src += TclUtfToUniChar(src, &ch); } |
︙ | ︙ | |||
729 730 731 732 733 734 735 | * *--------------------------------------------------------------------------- */ const char * Tcl_UtfAtIndex( register const char *src, /* The UTF-8 string. */ | | | 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 | * *--------------------------------------------------------------------------- */ const char * Tcl_UtfAtIndex( register const char *src, /* The UTF-8 string. */ register size_t index) /* The position of the desired character. */ { Tcl_UniChar ch; while (index > 0) { index--; src += TclUtfToUniChar(src, &ch); } |
︙ | ︙ | |||
766 767 768 769 770 771 772 | * that represent the Unicode character is at least as large as the * source buffer from which the backslashed sequence was extracted, no * buffer overruns should occur. * *--------------------------------------------------------------------------- */ | | | | < | 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 | * that represent the Unicode character is at least as large as the * source buffer from which the backslashed sequence was extracted, no * buffer overruns should occur. * *--------------------------------------------------------------------------- */ size_t Tcl_UtfBackslash( const char *src, /* Points to the backslash character of a * backslash sequence. */ size_t *readPtr, /* Fill in with number of characters read from * src, unless NULL. */ char *dst) /* Filled with the bytes represented by the * backslash sequence. */ { #define LINE_LENGTH 128 size_t numRead, result; result = TclParseBackslash(src, LINE_LENGTH, &numRead, dst); if (numRead == LINE_LENGTH) { /* * We ate a whole line. Pay the price of a strlen() */ |
︙ | ︙ | |||
817 818 819 820 821 822 823 | int Tcl_UtfToUpper( char *str) /* String to convert in place. */ { Tcl_UniChar ch, upChar; char *src, *dst; | | | | 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 | int Tcl_UtfToUpper( char *str) /* String to convert in place. */ { Tcl_UniChar ch, upChar; char *src, *dst; size_t bytes; /* * Iterate over the string until we hit the terminating null. */ src = dst = str; while (*src) { bytes = TclUtfToUniChar(src, &ch); upChar = Tcl_UniCharToUpper(ch); /* * To keep badly formed Utf strings from getting inflated by the * conversion (thereby causing a segfault), only copy the upper case * char to dst if its size is <= the original char. */ if (bytes < UtfCount(upChar)) { memcpy(dst, src, bytes); dst += bytes; } else { dst += Tcl_UniCharToUtf(upChar, dst); } src += bytes; } *dst = '\0'; |
︙ | ︙ | |||
870 871 872 873 874 875 876 | int Tcl_UtfToLower( char *str) /* String to convert in place. */ { Tcl_UniChar ch, lowChar; char *src, *dst; | | | | 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 | int Tcl_UtfToLower( char *str) /* String to convert in place. */ { Tcl_UniChar ch, lowChar; char *src, *dst; size_t bytes; /* * Iterate over the string until we hit the terminating null. */ src = dst = str; while (*src) { bytes = TclUtfToUniChar(src, &ch); lowChar = Tcl_UniCharToLower(ch); /* * To keep badly formed Utf strings from getting inflated by the * conversion (thereby causing a segfault), only copy the lower case * char to dst if its size is <= the original char. */ if (bytes < UtfCount(lowChar)) { memcpy(dst, src, bytes); dst += bytes; } else { dst += Tcl_UniCharToUtf(lowChar, dst); } src += bytes; } *dst = '\0'; |
︙ | ︙ | |||
924 925 926 927 928 929 930 | int Tcl_UtfToTitle( char *str) /* String to convert in place. */ { Tcl_UniChar ch, titleChar, lowChar; char *src, *dst; | | | | | 923 924 925 926 927 928 929 930 931 932 933 934 935 936 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 | int Tcl_UtfToTitle( char *str) /* String to convert in place. */ { Tcl_UniChar ch, titleChar, lowChar; char *src, *dst; size_t bytes; /* * Capitalize the first character and then lowercase the rest of the * characters until we get to a null. */ src = dst = str; if (*src) { bytes = TclUtfToUniChar(src, &ch); titleChar = Tcl_UniCharToTitle(ch); if (bytes < UtfCount(titleChar)) { memcpy(dst, src, bytes); dst += bytes; } else { dst += Tcl_UniCharToUtf(titleChar, dst); } src += bytes; } while (*src) { bytes = TclUtfToUniChar(src, &ch); lowChar = Tcl_UniCharToLower(ch); if (bytes < UtfCount(lowChar)) { memcpy(dst, src, bytes); dst += bytes; } else { dst += Tcl_UniCharToUtf(lowChar, dst); } src += bytes; } *dst = '\0'; |
︙ | ︙ | |||
982 983 984 985 986 987 988 | *---------------------------------------------------------------------- */ int TclpUtfNcmp2( const char *cs, /* UTF string to compare to ct. */ const char *ct, /* UTF string cs is compared to. */ | | | 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 | *---------------------------------------------------------------------- */ int TclpUtfNcmp2( const char *cs, /* UTF string to compare to ct. */ const char *ct, /* UTF string cs is compared to. */ size_t numBytes) /* Number of *bytes* to compare. */ { /* * We can't simply call 'memcmp(cs, ct, numBytes);' because we need to * check for Tcl's \xC0\x80 non-utf-8 null encoding. Otherwise utf-8 lexes * fine in the strcmp manner. */ |
︙ | ︙ | |||
1029 1030 1031 1032 1033 1034 1035 | *---------------------------------------------------------------------- */ int Tcl_UtfNcmp( const char *cs, /* UTF string to compare to ct. */ const char *ct, /* UTF string cs is compared to. */ | | | 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 | *---------------------------------------------------------------------- */ int Tcl_UtfNcmp( const char *cs, /* UTF string to compare to ct. */ const char *ct, /* UTF string cs is compared to. */ size_t numChars) /* Number of UTF chars to compare. */ { Tcl_UniChar ch1, ch2; /* * Cannot use 'memcmp(cs, ct, n);' as byte representation of \u0000 (the * pair of bytes 0xc0,0x80) is larger than byte representation of \u0001 * (the byte 0x01.) |
︙ | ︙ | |||
1077 1078 1079 1080 1081 1082 1083 | *---------------------------------------------------------------------- */ int Tcl_UtfNcasecmp( const char *cs, /* UTF string to compare to ct. */ const char *ct, /* UTF string cs is compared to. */ | | | 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 | *---------------------------------------------------------------------- */ int Tcl_UtfNcasecmp( const char *cs, /* UTF string to compare to ct. */ const char *ct, /* UTF string cs is compared to. */ size_t numChars) /* Number of UTF chars to compare. */ { Tcl_UniChar ch1, ch2; while (numChars-- > 0) { /* * n must be interpreted as chars, not bytes. * This should be called only when both strings are of * at least n chars long (no need for \0 check) |
︙ | ︙ | |||
1281 1282 1283 1284 1285 1286 1287 | *---------------------------------------------------------------------- */ int Tcl_UniCharNcmp( const Tcl_UniChar *ucs, /* Unicode string to compare to uct. */ const Tcl_UniChar *uct, /* Unicode string ucs is compared to. */ | | | 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 | *---------------------------------------------------------------------- */ int Tcl_UniCharNcmp( const Tcl_UniChar *ucs, /* Unicode string to compare to uct. */ const Tcl_UniChar *uct, /* Unicode string ucs is compared to. */ size_t numChars) /* Number of unichars to compare. */ { #ifdef WORDS_BIGENDIAN /* * We are definitely on a big-endian machine; memcmp() is safe */ return memcmp(ucs, uct, numChars*sizeof(Tcl_UniChar)); |
︙ | ︙ | |||
1326 1327 1328 1329 1330 1331 1332 | *---------------------------------------------------------------------- */ int Tcl_UniCharNcasecmp( const Tcl_UniChar *ucs, /* Unicode string to compare to uct. */ const Tcl_UniChar *uct, /* Unicode string ucs is compared to. */ | | | 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 | *---------------------------------------------------------------------- */ int Tcl_UniCharNcasecmp( const Tcl_UniChar *ucs, /* Unicode string to compare to uct. */ const Tcl_UniChar *uct, /* Unicode string ucs is compared to. */ size_t numChars) /* Number of unichars to compare. */ { for ( ; numChars != 0; numChars--, ucs++, uct++) { if (*ucs != *uct) { Tcl_UniChar lcs = Tcl_UniCharToLower(*ucs); Tcl_UniChar lct = Tcl_UniCharToLower(*uct); if (lcs != lct) { |
︙ | ︙ | |||
1821 1822 1823 1824 1825 1826 1827 | * *---------------------------------------------------------------------- */ int TclUniCharMatch( const Tcl_UniChar *string, /* Unicode String. */ | | | | 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 | * *---------------------------------------------------------------------- */ int TclUniCharMatch( const Tcl_UniChar *string, /* Unicode String. */ size_t strLen, /* Length of String */ const Tcl_UniChar *pattern, /* Pattern, which may contain special * characters. */ size_t ptnLen, /* Length of Pattern */ int nocase) /* 0 for case sensitive, 1 for insensitive */ { const Tcl_UniChar *stringEnd, *patternEnd; Tcl_UniChar p; stringEnd = string + strLen; patternEnd = pattern + ptnLen; |
︙ | ︙ |
Changes to generic/tclUtil.c.
︙ | ︙ | |||
360 361 362 363 364 365 366 | /* *---------------------------------------------------------------------- * * TclMaxListLength -- * * Given 'bytes' pointing to 'numBytes' bytes, scan through them and * count the number of whitespace runs that could be list element | | | | | | | | | | | > | | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 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 | /* *---------------------------------------------------------------------- * * TclMaxListLength -- * * Given 'bytes' pointing to 'numBytes' bytes, scan through them and * count the number of whitespace runs that could be list element * separators. If 'numBytes' is TCL_STRLEN, scan to the terminating '\0'. * Not a full list parser. Typically used to get a quick and dirty * overestimate of length size in order to allocate space for an actual * list parser to operate with. * * Results: * Returns the largest number of list elements that could possibly be in * this string, interpreted as a Tcl list. If 'endPtr' is not NULL, * writes a pointer to the end of the string scanned there. * * Side effects: * None. * *---------------------------------------------------------------------- */ size_t TclMaxListLength( const char *bytes, size_t numBytes, const char **endPtr) { int count = 0; if ((numBytes == 0) || ((numBytes == TCL_STRLEN) && (*bytes == '\0'))) { /* Empty string case - quick exit */ goto done; } /* * No list element before leading white space. */ count += 1 - TclIsSpaceProc(*bytes); /* * Count white space runs as potential element separators. */ while (numBytes) { if ((numBytes == TCL_STRLEN) && (*bytes == '\0')) { break; } if (TclIsSpaceProc(*bytes)) { /* * Space run started; bump count. */ count++; do { bytes++; numBytes -= (numBytes != TCL_STRLEN); } while (numBytes && TclIsSpaceProc(*bytes)); if ((numBytes == 0) || ((numBytes == TCL_STRLEN) && (*bytes == '\0'))) { break; } /* * (*bytes) is non-space; return to counting state. */ } bytes++; numBytes -= (numBytes != TCL_STRLEN); } /* * No list element following trailing white space. */ count -= TclIsSpaceProc(bytes[-1]); |
︙ | ︙ | |||
485 486 487 488 489 490 491 | TclFindElement( Tcl_Interp *interp, /* Interpreter to use for error reporting. If * NULL, then no error message is left after * errors. */ const char *list, /* Points to the first byte of a string * containing a Tcl list with zero or more * elements (possibly in braces). */ | | | | | | 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 | TclFindElement( Tcl_Interp *interp, /* Interpreter to use for error reporting. If * NULL, then no error message is left after * errors. */ const char *list, /* Points to the first byte of a string * containing a Tcl list with zero or more * elements (possibly in braces). */ size_t listLength, /* Number of bytes in the list's string. */ const char **elementPtr, /* Where to put address of first significant * character in first element of list. */ const char **nextPtr, /* Fill in with location of character just * after all white space following end of * argument (next arg or end of list). */ size_t *sizePtr, /* If non-zero, fill in with size of * element. */ int *literalPtr) /* If non-zero, fill in with non-zero/zero to * indicate that the substring of *sizePtr * bytes starting at **elementPtr is/is not * the literal list element and therefore * does not/does require a call to * TclCopyAndCollapse() by the caller. */ { const char *p = list; const char *elemStart; /* Points to first byte of first element. */ const char *limit; /* Points just after list's last byte. */ int openBraces = 0; /* Brace nesting level during parse. */ int inQuotes = 0; size_t size = 0; /* lint. */ size_t numChars; int literal = 1; const char *p2; /* * Skim off leading white space and check for an opening brace or quote. * We treat embedded NULLs in the list as bytes belonging to a list * element. |
︙ | ︙ | |||
666 667 668 669 670 671 672 | * End of list: terminate element. */ if (p == limit) { if (openBraces != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 | * End of list: terminate element. */ if (p == limit) { if (openBraces != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unmatched open brace in list", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "BRACE", NULL); } return TCL_ERROR; } else if (inQuotes) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unmatched open quote in list", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "QUOTE", NULL); } return TCL_ERROR; } size = (p - elemStart); } |
︙ | ︙ | |||
717 718 719 720 721 722 723 | * * Side effects: * None. * *---------------------------------------------------------------------- */ | | | | | | > | 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 | * * Side effects: * None. * *---------------------------------------------------------------------- */ size_t TclCopyAndCollapse( size_t count, /* Number of byte to copy from src. */ const char *src, /* Copy from here... */ char *dst) /* ... to here. */ { size_t newCount = 0; while (count > 0) { char c = *src; if (c == '\\') { size_t numRead; size_t backslashCount = TclParseBackslash(src, count, &numRead, dst); dst += backslashCount; newCount += backslashCount; src += numRead; count -= numRead; } else { *dst = c; |
︙ | ︙ | |||
781 782 783 784 785 786 787 | */ int Tcl_SplitList( Tcl_Interp *interp, /* Interpreter to use for error reporting. If * NULL, no error message is left. */ const char *list, /* Pointer to string with list structure. */ | | > | | | 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 | */ int Tcl_SplitList( Tcl_Interp *interp, /* Interpreter to use for error reporting. If * NULL, no error message is left. */ const char *list, /* Pointer to string with list structure. */ size_t *argcPtr, /* Pointer to location to fill in with the * number of elements in the list. */ const char ***argvPtr) /* Pointer to place to store pointer to array * of pointers to list elements. */ { const char **argv, *end, *element; char *p; int result; size_t length, size, i, elSize; /* * Allocate enough space to work in. A (const char *) for each (possible) * list element plus one more for terminating NULL, plus as many bytes as * in the original string value, plus one more for a terminating '\0'. * Space used to hold element separating white space in the original * string gets re-purposed to hold '\0' characters in the argv array. */ size = TclMaxListLength(list, TCL_STRLEN, &end) + 1; length = end - list; argv = ckalloc((size * sizeof(char *)) + length + 1); for (i = 0, p = ((char *) argv) + size*sizeof(char *); *list != 0; i++) { const char *prevList = list; int literal; |
︙ | ︙ | |||
821 822 823 824 825 826 827 | if (*element == 0) { break; } if (i >= size) { ckfree(argv); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 | if (*element == 0) { break; } if (i >= size) { ckfree(argv); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "internal error in Tcl_SplitList", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "INTERNAL", "Tcl_SplitList", NULL); } return TCL_ERROR; } argv[i] = p; if (literal) { |
︙ | ︙ | |||
865 866 867 868 869 870 871 | * * Side effects: * None. * *---------------------------------------------------------------------- */ | | | | | | | | | | | | | | | | > | 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 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 | * * Side effects: * None. * *---------------------------------------------------------------------- */ size_t Tcl_ScanElement( const char *src, /* String to convert to list element. */ int *flagPtr) /* Where to store information to guide * Tcl_ConvertCountedElement. */ { return Tcl_ScanCountedElement(src, TCL_STRLEN, flagPtr); } /* *---------------------------------------------------------------------- * * Tcl_ScanCountedElement -- * * This function is a companion function to Tcl_ConvertCountedElement. It * scans a string to see what needs to be done to it (e.g. add * backslashes or enclosing braces) to make the string into a valid Tcl * list element. If length is TCL_STRLEN, then the string is scanned from * src up to the first null byte. * * Results: * The return value is an overestimate of the number of bytes that will * be needed by Tcl_ConvertCountedElement to produce a valid list element * from src. The word at *flagPtr is filled in with a value needed by * Tcl_ConvertCountedElement when doing the actual conversion. * * Side effects: * None. * *---------------------------------------------------------------------- */ size_t Tcl_ScanCountedElement( const char *src, /* String to convert to Tcl list element. */ size_t length, /* Number of bytes in src, or TCL_STRLEN. */ int *flagPtr) /* Where to store information to guide * Tcl_ConvertElement. */ { char flags = CONVERT_ANY; size_t numBytes = TclScanElement(src, length, &flags); *flagPtr = flags; return numBytes; } /* *---------------------------------------------------------------------- * * TclScanElement -- * * This function is a companion function to TclConvertElement. It scans a * string to see what needs to be done to it (e.g. add backslashes or * enclosing braces) to make the string into a valid Tcl list element. If * length is TCL_STRLEN, then the string is scanned from src up to the * first null byte. A NULL value for src is treated as an empty string. * The incoming value of *flagPtr is a report from the caller what * additional flags it will pass to TclConvertElement(). * * Results: * The recommended formatting mode for the element is determined and a * value is written to *flagPtr indicating that recommendation. This * recommendation is combined with the incoming flag values in *flagPtr * set by the caller to determine how many bytes will be needed by * TclConvertElement() in which to write the formatted element following * the recommendation modified by the flag values. This number of bytes * is the return value of the routine. In some situations it may be an * overestimate, but so long as the caller passes the same flags to * TclConvertElement(), it will be large enough. * * Side effects: * None. * *---------------------------------------------------------------------- */ size_t TclScanElement( const char *src, /* String to convert to Tcl list element. */ size_t length, /* Number of bytes in src, or TCL_STRLEN. */ char *flagPtr) /* Where to store information to guide * Tcl_ConvertElement. */ { const char *p = src; int nestingLevel = 0; /* Brace nesting count */ int forbidNone = 0; /* Do not permit CONVERT_NONE mode. Something * needs protection or escape. */ int requireEscape = 0; /* Force use of CONVERT_ESCAPE mode. For some * reason bare or brace-quoted form fails. */ int extra = 0; /* Count of number of extra bytes needed for * formatted element, assuming we use escape * sequences in formatting. */ size_t bytesNeeded; /* Buffer length computed to complete the * element formatting in the selected mode. */ #if COMPAT int preferEscape = 0; /* Use preferences to track whether to use */ int preferBrace = 0; /* CONVERT_MASK mode. */ int braceCount = 0; /* Count of all braces '{' '}' seen. */ #endif /* COMPAT */ if ((p == NULL) || (length == 0) || ((*p == '\0') && (length == TCL_STRLEN))) { /* * Empty string element must be brace quoted. */ *flagPtr = CONVERT_BRACE; return 2; } |
︙ | ︙ | |||
987 988 989 990 991 992 993 | forbidNone = 1; #if COMPAT preferBrace = 1; #endif /* COMPAT */ } while (length) { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 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 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 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 | forbidNone = 1; #if COMPAT preferBrace = 1; #endif /* COMPAT */ } while (length) { if (CHAR_TYPE(*p) != TYPE_NORMAL) { switch (*p) { case '{': /* TYPE_BRACE */ #if COMPAT braceCount++; #endif /* COMPAT */ extra++; /* Escape '{' => '\{' */ nestingLevel++; break; case '}': /* TYPE_BRACE */ #if COMPAT braceCount++; #endif /* COMPAT */ extra++; /* Escape '}' => '\}' */ nestingLevel--; if (nestingLevel < 0) { /* * Unbalanced braces! Cannot format with brace quoting. */ requireEscape = 1; } break; case ']': /* TYPE_CLOSE_BRACK */ case '"': /* TYPE_SPACE */ #if COMPAT forbidNone = 1; extra++; /* Escapes all just prepend a backslash */ preferEscape = 1; break; #else /* FLOW THROUGH */ #endif /* COMPAT */ case '[': /* TYPE_SUBS */ case '$': /* TYPE_SUBS */ case ';': /* TYPE_COMMAND_END */ case ' ': /* TYPE_SPACE */ case '\f': /* TYPE_SPACE */ case '\n': /* TYPE_COMMAND_END */ case '\r': /* TYPE_SPACE */ case '\t': /* TYPE_SPACE */ case '\v': /* TYPE_SPACE */ forbidNone = 1; extra++; /* Escape sequences all one byte longer. */ #if COMPAT preferBrace = 1; #endif /* COMPAT */ break; case '\\': /* TYPE_SUBS */ extra++; /* Escape '\' => '\\' */ if ((length == 1) || (length == TCL_STRLEN && p[1] == '\0')) { /* * Final backslash. Cannot format with brace quoting. */ requireEscape = 1; break; } if (p[1] == '\n') { extra++; /* Escape newline => '\n', one byte longer */ /* * Backslash newline sequence. Brace quoting not * permitted. */ requireEscape = 1; length -= (length != TCL_STRLEN); p++; break; } if ((p[1] == '{') || (p[1] == '}') || (p[1] == '\\')) { extra++; /* Escape sequences all one byte longer. */ length -= (length != TCL_STRLEN); p++; } forbidNone = 1; #if COMPAT preferBrace = 1; #endif /* COMPAT */ break; case '\0': /* TYPE_SUBS */ if (length == TCL_STRLEN) { goto endOfString; } /* TODO: Panic on improper encoding? */ break; } } length -= (length != TCL_STRLEN); p++; } endOfString: if (nestingLevel != 0) { /* * Unbalanced braces! Cannot format with brace quoting. |
︙ | ︙ | |||
1110 1111 1112 1113 1114 1115 1116 | * Make room to escape leading #, if needed. */ if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) { bytesNeeded++; } *flagPtr = CONVERT_ESCAPE; | | | 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 | * Make room to escape leading #, if needed. */ if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) { bytesNeeded++; } *flagPtr = CONVERT_ESCAPE; return bytesNeeded; } if (*flagPtr & CONVERT_ANY) { /* * The caller has not let us know what flags it will pass to * TclConvertElement() so compute the max size we might need for any * possible choice. Normally the formatting using escape sequences is * the longer one, and a minimum "extra" value of 2 makes sure we |
︙ | ︙ | |||
1158 1159 1160 1161 1162 1163 1164 | * escape the braces. */ if (*flagPtr & TCL_DONT_USE_BRACES) { bytesNeeded += braceCount; } *flagPtr = CONVERT_MASK; | | | 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 | * escape the braces. */ if (*flagPtr & TCL_DONT_USE_BRACES) { bytesNeeded += braceCount; } *flagPtr = CONVERT_MASK; return bytesNeeded; } #endif /* COMPAT */ if (*flagPtr & TCL_DONT_USE_BRACES) { /* * If the caller reports it will direct TclConvertElement() to * use escapes, add the extra bytes needed to have room for them. */ |
︙ | ︙ | |||
1184 1185 1186 1187 1188 1189 1190 | /* * Add 2 bytes for room for the enclosing braces. */ bytesNeeded += 2; } *flagPtr = CONVERT_BRACE; | | < < < < < | 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 | /* * Add 2 bytes for room for the enclosing braces. */ bytesNeeded += 2; } *flagPtr = CONVERT_BRACE; return bytesNeeded; } /* * So far, no need to quote or escape anything. */ if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) { /* * If we need to quote a leading #, make room to enclose in braces. */ bytesNeeded += 2; } *flagPtr = CONVERT_NONE; return bytesNeeded; } /* *---------------------------------------------------------------------- * * Tcl_ConvertElement -- |
︙ | ︙ | |||
1228 1229 1230 1231 1232 1233 1234 | * * Side effects: * None. * *---------------------------------------------------------------------- */ | | | | 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 | * * Side effects: * None. * *---------------------------------------------------------------------- */ size_t Tcl_ConvertElement( const char *src, /* Source information for list element. */ char *dst, /* Place to put list-ified element. */ int flags) /* Flags produced by Tcl_ScanElement. */ { return Tcl_ConvertCountedElement(src, TCL_STRLEN, dst, flags); } /* *---------------------------------------------------------------------- * * Tcl_ConvertCountedElement -- * |
︙ | ︙ | |||
1258 1259 1260 1261 1262 1263 1264 | * * Side effects: * None. * *---------------------------------------------------------------------- */ | | | | > | 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 | * * Side effects: * None. * *---------------------------------------------------------------------- */ size_t Tcl_ConvertCountedElement( register const char *src, /* Source information for list element. */ size_t length, /* Number of bytes in src, or TCL_STRLEN. */ char *dst, /* Place to put list-ified element. */ int flags) /* Flags produced by Tcl_ScanElement. */ { size_t numBytes = TclConvertElement(src, length, dst, flags); dst[numBytes] = '\0'; return numBytes; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1291 1292 1293 1294 1295 1296 1297 | * * Side effects: * None. * *---------------------------------------------------------------------- */ | | | | > | | | | | 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 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 1337 1338 1339 1340 1341 1342 1343 1344 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 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 | * * Side effects: * None. * *---------------------------------------------------------------------- */ size_t TclConvertElement( register const char *src, /* Source information for list element. */ size_t length, /* Number of bytes in src, or TCL_STRLEN. */ char *dst, /* Place to put list-ified element. */ char flags) /* Flags produced by Tcl_ScanElement. */ { char conversion = flags & CONVERT_MASK; char *p = dst; /* * Let the caller demand we use escape sequences rather than braces. */ if ((flags & TCL_DONT_USE_BRACES) && (conversion & CONVERT_BRACE)) { conversion = CONVERT_ESCAPE; } /* * No matter what the caller demands, empty string must be braced! */ if ((src == NULL) || (length == 0) || (*src == '\0' && length == TCL_STRLEN)) { src = tclEmptyStringRep; length = 0; conversion = CONVERT_BRACE; } /* * Escape leading hash as needed and requested. */ if ((*src == '#') && !(flags & TCL_DONT_QUOTE_HASH)) { if (conversion == CONVERT_ESCAPE) { p[0] = '\\'; p[1] = '#'; p += 2; src++; length -= (length != TCL_STRLEN); } else { conversion = CONVERT_BRACE; } } /* * No escape or quoting needed. Copy the literal string value. */ if (conversion == CONVERT_NONE) { if (length == TCL_STRLEN) { /* TODO: INT_MAX overflow? */ while (*src) { *p++ = *src++; } return p - dst; } else { memcpy(dst, src, length); return length; } } /* * Formatted string is original string enclosed in braces. */ if (conversion == CONVERT_BRACE) { *p = '{'; p++; if (length == TCL_STRLEN) { /* TODO: INT_MAX overflow? */ while (*src) { *p++ = *src++; } } else { memcpy(p, src, length); p += length; } *p = '}'; p++; return p - dst; } /* conversion == CONVERT_ESCAPE or CONVERT_MASK */ /* * Formatted string is original string converted to escape sequences. */ for ( ; length; src++, length -= (length != TCL_STRLEN)) { switch (*src) { case ']': case '[': case '$': case ';': case ' ': case '\\': |
︙ | ︙ | |||
1432 1433 1434 1435 1436 1437 1438 | case '\v': *p = '\\'; p++; *p = 'v'; p++; continue; case '\0': | | | 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 | case '\v': *p = '\\'; p++; *p = 'v'; p++; continue; case '\0': if (length == TCL_STRLEN) { return p - dst; } /* * If we reach this point, there's an embedded NULL in the string * range being processed, which should not happen when the * encoding rules for Tcl strings are properly followed. If the |
︙ | ︙ | |||
1474 1475 1476 1477 1478 1479 1480 | * None. * *---------------------------------------------------------------------- */ char * Tcl_Merge( | | | | 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 | * None. * *---------------------------------------------------------------------- */ char * Tcl_Merge( size_t argc, /* How many strings to merge. */ const char *const *argv) /* Array of string values. */ { #define LOCAL_SIZE 64 char localFlags[LOCAL_SIZE]; size_t i, bytesNeeded = 0; char *result, *dst, *flagPtr = NULL; /* * Handle empty list case first, so logic of the general case can be * simpler. */ |
︙ | ︙ | |||
1504 1505 1506 1507 1508 1509 1510 | if (argc <= LOCAL_SIZE) { flagPtr = localFlags; } else { flagPtr = ckalloc(argc); } for (i = 0; i < argc; i++) { flagPtr[i] = ( i ? TCL_DONT_QUOTE_HASH : 0 ); | | < < | < > | | 1506 1507 1508 1509 1510 1511 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 | if (argc <= LOCAL_SIZE) { flagPtr = localFlags; } else { flagPtr = ckalloc(argc); } for (i = 0; i < argc; i++) { flagPtr[i] = ( i ? TCL_DONT_QUOTE_HASH : 0 ); bytesNeeded += TclScanElement(argv[i], TCL_STRLEN, &flagPtr[i]); } // TODO Is this check sensible any more? if (bytesNeeded > INT_MAX - argc + 1) { Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); } bytesNeeded += argc; /* * Pass two: copy into the result area. */ result = ckalloc(bytesNeeded); dst = result; for (i = 0; i < argc; i++) { flagPtr[i] |= ( i ? TCL_DONT_QUOTE_HASH : 0 ); dst += TclConvertElement(argv[i], TCL_STRLEN, dst, flagPtr[i]); *dst = ' '; dst++; } dst[-1] = 0; if (flagPtr != localFlags) { ckfree(flagPtr); |
︙ | ︙ | |||
1555 1556 1557 1558 1559 1560 1561 | * *---------------------------------------------------------------------- */ int TclTrimRight( const char *bytes, /* String to be trimmed... */ | | | | 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 | * *---------------------------------------------------------------------- */ int TclTrimRight( const char *bytes, /* String to be trimmed... */ size_t numBytes, /* ...and its length in bytes */ const char *trim, /* String of trim characters... */ size_t numTrim) /* ...and its length in bytes */ { const char *p = bytes + numBytes; int pInc; if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) { Tcl_Panic("TclTrimRight works only on null-terminated strings"); } |
︙ | ︙ | |||
1581 1582 1583 1584 1585 1586 1587 | /* * Outer loop: iterate over string to be trimmed. */ do { Tcl_UniChar ch1; const char *q = trim; | | | 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 | /* * Outer loop: iterate over string to be trimmed. */ do { Tcl_UniChar ch1; const char *q = trim; size_t bytesLeft = numTrim; p = Tcl_UtfPrev(p, bytes); pInc = TclUtfToUniChar(p, &ch1); /* * Inner loop: scan trim string for match to current character. */ |
︙ | ︙ | |||
1636 1637 1638 1639 1640 1641 1642 | * *---------------------------------------------------------------------- */ int TclTrimLeft( const char *bytes, /* String to be trimmed... */ | | | | 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 | * *---------------------------------------------------------------------- */ int TclTrimLeft( const char *bytes, /* String to be trimmed... */ size_t numBytes, /* ...and its length in bytes */ const char *trim, /* String of trim characters... */ size_t numTrim) /* ...and its length in bytes */ { const char *p = bytes; if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) { Tcl_Panic("TclTrimLeft works only on null-terminated strings"); } |
︙ | ︙ | |||
1660 1661 1662 1663 1664 1665 1666 | /* * Outer loop: iterate over string to be trimmed. */ do { Tcl_UniChar ch1; | | | | 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 | /* * Outer loop: iterate over string to be trimmed. */ do { Tcl_UniChar ch1; size_t pInc = TclUtfToUniChar(p, &ch1); const char *q = trim; size_t bytesLeft = numTrim; /* * Inner loop: scan trim string for match to current character. */ do { Tcl_UniChar ch2; |
︙ | ︙ | |||
1720 1721 1722 1723 1724 1725 1726 | /* The whitespace characters trimmed during [concat] operations */ #define CONCAT_WS " \f\v\r\t\n" #define CONCAT_WS_SIZE (int) (sizeof(CONCAT_WS "") - 1) char * Tcl_Concat( | | | | < < | < > | | 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 | /* The whitespace characters trimmed during [concat] operations */ #define CONCAT_WS " \f\v\r\t\n" #define CONCAT_WS_SIZE (int) (sizeof(CONCAT_WS "") - 1) char * Tcl_Concat( size_t argc, /* Number of strings to concatenate. */ const char *const *argv) /* Array of strings to concatenate. */ { size_t i, needSpace = 0, bytesNeeded = 0; char *result, *p; /* * Dispose of the empty result corner case first to simplify later code. */ if (argc == 0) { result = ckalloc(1); result[0] = '\0'; return result; } /* * First allocate the result buffer at the size required. */ for (i = 0; i < argc; i++) { bytesNeeded += strlen(argv[i]); } // TODO Is this check sensible any more? if (bytesNeeded + argc - 1 < 0) { /* * Panic test could be tighter, but not going to bother for this * legacy routine. */ Tcl_Panic("Tcl_Concat: max size of Tcl value exceeded"); } /* * All element bytes + (argc - 1) spaces + 1 terminating NULL. */ result = ckalloc((unsigned) (bytesNeeded + argc)); for (p = result, i = 0; i < argc; i++) { size_t trim, elemLength; const char *element; element = argv[i]; elemLength = strlen(argv[i]); /* * Trim away the leading whitespace. |
︙ | ︙ | |||
1800 1801 1802 1803 1804 1805 1806 | /* * Append to the result with space if needed. */ if (needSpace) { *p++ = ' '; } | | | 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 | /* * Append to the result with space if needed. */ if (needSpace) { *p++ = ' '; } memcpy(p, element, elemLength); p += elemLength; needSpace = 1; } *p = '\0'; return result; } |
︙ | ︙ | |||
1828 1829 1830 1831 1832 1833 1834 | * A new object is created. * *---------------------------------------------------------------------- */ Tcl_Obj * Tcl_ConcatObj( | | | | | 1826 1827 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 | * A new object is created. * *---------------------------------------------------------------------- */ Tcl_Obj * Tcl_ConcatObj( size_t objc, /* Number of objects to concatenate. */ Tcl_Obj *const objv[]) /* Array of objects to concatenate. */ { size_t i, elemLength, needSpace = 0, bytesNeeded = 0; const char *element; Tcl_Obj *objPtr, *resPtr; /* * Check first to see if all the items are of list type or empty. If so, * we will concat them together as lists, and return a list object. This * is only valid when the lists are in canonical form. */ for (i = 0; i < objc; i++) { size_t length; objPtr = objv[i]; if (TclListObjIsCanonical(objPtr)) { continue; } Tcl_GetStringFromObj(objPtr, &length); if (length > 0) { |
︙ | ︙ | |||
1882 1883 1884 1885 1886 1887 1888 | * * First try to pre-allocate the size required. */ for (i = 0; i < objc; i++) { element = TclGetStringFromObj(objv[i], &elemLength); bytesNeeded += elemLength; | < < < | | 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 | * * First try to pre-allocate the size required. */ for (i = 0; i < objc; i++) { element = TclGetStringFromObj(objv[i], &elemLength); bytesNeeded += elemLength; } /* * Does not matter if this fails, will simply try later to build up the * string with each Append reallocating as needed with the usual string * append algorithm. When that fails it will report the error. */ TclNewObj(resPtr); Tcl_AttemptSetObjLength(resPtr, bytesNeeded + objc - 1); Tcl_SetObjLength(resPtr, 0); for (i = 0; i < objc; i++) { size_t trim; element = TclGetStringFromObj(objv[i], &elemLength); /* * Trim away the leading whitespace. */ |
︙ | ︙ | |||
1993 1994 1995 1996 1997 1998 1999 | int Tcl_StringCaseMatch( const char *str, /* String. */ const char *pattern, /* Pattern, which may contain special * characters. */ int nocase) /* 0 for case sensitive, 1 for insensitive */ { | > | | 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 | int Tcl_StringCaseMatch( const char *str, /* String. */ const char *pattern, /* Pattern, which may contain special * characters. */ int nocase) /* 0 for case sensitive, 1 for insensitive */ { int p; size_t charLen; const char *pstart = pattern; Tcl_UniChar ch1, ch2; while (1) { p = *pattern; /* |
︙ | ︙ | |||
2222 2223 2224 2225 2226 2227 2228 | * *---------------------------------------------------------------------- */ int TclByteArrayMatch( const unsigned char *string,/* String. */ | | | | 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 | * *---------------------------------------------------------------------- */ int TclByteArrayMatch( const unsigned char *string,/* String. */ size_t strLen, /* Length of String */ const unsigned char *pattern, /* Pattern, which may contain special * characters. */ size_t ptnLen, /* Length of Pattern */ int flags) { const unsigned char *stringEnd, *patternEnd; unsigned char p; stringEnd = string + strLen; patternEnd = pattern + ptnLen; |
︙ | ︙ | |||
2403 2404 2405 2406 2407 2408 2409 | int TclStringMatchObj( Tcl_Obj *strObj, /* string object. */ Tcl_Obj *ptnObj, /* pattern object. */ int flags) /* Only TCL_MATCH_NOCASE should be passed, or * 0. */ { | | > | 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 | int TclStringMatchObj( Tcl_Obj *strObj, /* string object. */ Tcl_Obj *ptnObj, /* pattern object. */ int flags) /* Only TCL_MATCH_NOCASE should be passed, or * 0. */ { int match; size_t length, plen; /* * Promote based on the type of incoming object. * XXX: Currently doesn't take advantage of exact-ness that * XXX: TclReToGlob tells us about trivial = nocase ? 0 : TclMatchIsTrivial(TclGetString(ptnObj)); */ |
︙ | ︙ | |||
2480 2481 2482 2483 2484 2485 2486 | * *---------------------------------------------------------------------- */ char * Tcl_DStringAppend( Tcl_DString *dsPtr, /* Structure describing dynamic string. */ | | | | | | | | | 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 | * *---------------------------------------------------------------------- */ char * Tcl_DStringAppend( Tcl_DString *dsPtr, /* Structure describing dynamic string. */ const char *bytes, /* String to append. If length is TCL_STRLEN * then this must be null-terminated. */ size_t length) /* Number of bytes from "bytes" to append. If * TCL_STRLEN, then append all of bytes, up to * NUL at end. */ { int newSize; if (length == TCL_STRLEN) { length = strlen(bytes); } newSize = length + dsPtr->length; /* * Allocate a larger buffer for the string if the current one isn't large * enough. Allocate extra space in the new buffer so that there will be * room to grow before we have to allocate again. */ if (newSize >= dsPtr->spaceAvl) { dsPtr->spaceAvl = newSize * 2; if (dsPtr->string == dsPtr->staticSpace) { char *newString = ckalloc(dsPtr->spaceAvl); memcpy(newString, dsPtr->string, dsPtr->length); dsPtr->string = newString; } else { dsPtr->string = ckrealloc(dsPtr->string, dsPtr->spaceAvl); } } /* |
︙ | ︙ | |||
2537 2538 2539 2540 2541 2542 2543 | */ char * TclDStringAppendObj( Tcl_DString *dsPtr, Tcl_Obj *objPtr) { | | | 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 | */ char * TclDStringAppendObj( Tcl_DString *dsPtr, Tcl_Obj *objPtr) { size_t length; char *bytes = Tcl_GetStringFromObj(objPtr, &length); return Tcl_DStringAppend(dsPtr, bytes, length); } char * TclDStringAppendDString( |
︙ | ︙ | |||
2577 2578 2579 2580 2581 2582 2583 | char * Tcl_DStringAppendElement( Tcl_DString *dsPtr, /* Structure describing dynamic string. */ const char *element) /* String to append. Must be * null-terminated. */ { char *dst = dsPtr->string + dsPtr->length; | | | | | 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 | char * Tcl_DStringAppendElement( Tcl_DString *dsPtr, /* Structure describing dynamic string. */ const char *element) /* String to append. Must be * null-terminated. */ { char *dst = dsPtr->string + dsPtr->length; size_t needSpace = TclNeedSpace(dsPtr->string, dst); char flags = needSpace ? TCL_DONT_QUOTE_HASH : 0; size_t newSize = dsPtr->length + needSpace + TclScanElement(element, TCL_STRLEN, &flags); /* * Allocate a larger buffer for the string if the current one isn't large * enough. Allocate extra space in the new buffer so that there will be * room to grow before we have to allocate again. SPECIAL NOTE: must use * memcpy, not strcpy, to copy the string to a larger buffer, since there * may be embedded NULLs in the string in some cases. |
︙ | ︙ | |||
2621 2622 2623 2624 2625 2626 2627 | * If we need a space to separate this element from preceding stuff, * then this element will not lead a list, and need not have it's * leading '#' quoted. */ flags |= TCL_DONT_QUOTE_HASH; } | | | 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 | * If we need a space to separate this element from preceding stuff, * then this element will not lead a list, and need not have it's * leading '#' quoted. */ flags |= TCL_DONT_QUOTE_HASH; } dsPtr->length += TclConvertElement(element, TCL_STRLEN, dst, flags); dsPtr->string[dsPtr->length] = '\0'; return dsPtr->string; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
2648 2649 2650 2651 2652 2653 2654 | * *---------------------------------------------------------------------- */ void Tcl_DStringSetLength( Tcl_DString *dsPtr, /* Structure describing dynamic string. */ | | | | | 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 | * *---------------------------------------------------------------------- */ void Tcl_DStringSetLength( Tcl_DString *dsPtr, /* Structure describing dynamic string. */ size_t length) /* New length for dynamic string. */ { size_t newsize; if (length == TCL_STRLEN) { length = 0; } if (length >= dsPtr->spaceAvl) { /* * There are two interesting cases here. In the first case, the user * may be trying to allocate a large buffer of a specific size. It * would be wasteful to overallocate that buffer, so we just allocate |
︙ | ︙ | |||
2772 2773 2774 2775 2776 2777 2778 | void Tcl_DStringGetResult( Tcl_Interp *interp, /* Interpreter whose result is to be reset. */ Tcl_DString *dsPtr) /* Dynamic string that is to become the result * of interp. */ { | | | 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 | void Tcl_DStringGetResult( Tcl_Interp *interp, /* Interpreter whose result is to be reset. */ Tcl_DString *dsPtr) /* Dynamic string that is to become the result * of interp. */ { size_t length; char *bytes = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &length); Tcl_DStringFree(dsPtr); Tcl_DStringAppend(dsPtr, bytes, length); Tcl_ResetResult(interp); } |
︙ | ︙ | |||
3260 3261 3262 3263 3264 3265 3266 | * Side effects: * The formatted characters are written into the storage pointer to by * the "buffer" argument. * *---------------------------------------------------------------------- */ | | < | | 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 | * Side effects: * The formatted characters are written into the storage pointer to by * the "buffer" argument. * *---------------------------------------------------------------------- */ size_t TclFormatInt( char *buffer, /* Points to the storage into which the * formatted characters are written. */ long n) /* The integer to format. */ { long intVal; size_t i, numFormatted, j; const char *digits = "0123456789"; /* * Check first whether "n" is zero. */ if (n == 0) { |
︙ | ︙ | |||
3354 3355 3356 3357 3358 3359 3360 | int TclGetIntForIndex( Tcl_Interp *interp, /* Interpreter to use for error reporting. If * NULL, then no error message is left after * errors. */ Tcl_Obj *objPtr, /* Points to an object containing either "end" * or an integer. */ | | | | > > | > | 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 | int TclGetIntForIndex( Tcl_Interp *interp, /* Interpreter to use for error reporting. If * NULL, then no error message is left after * errors. */ Tcl_Obj *objPtr, /* Points to an object containing either "end" * or an integer. */ ssize_t endValue, /* The value to be stored at "indexPtr" if * "objPtr" holds "end". */ ssize_t *indexPtr) /* Location filled in with an integer * representing an index. */ { size_t length; char *opPtr; const char *bytes; int idx; // TODO Lists may be longer than fits in an int if (TclGetIntFromObj(NULL, objPtr, &idx) == TCL_OK) { *indexPtr = (ssize_t) idx; return TCL_OK; } if (SetEndOffsetFromAny(NULL, objPtr) == TCL_OK) { /* * If the object is already an offset from the end of the list, or can * be converted to one, use it. |
︙ | ︙ | |||
3497 3498 3499 3500 3501 3502 3503 | static int SetEndOffsetFromAny( Tcl_Interp *interp, /* Tcl interpreter or NULL */ Tcl_Obj *objPtr) /* Pointer to the object to parse */ { int offset; /* Offset in the "end-offset" expression */ register const char *bytes; /* String rep of the object */ | | | 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 | static int SetEndOffsetFromAny( Tcl_Interp *interp, /* Tcl interpreter or NULL */ Tcl_Obj *objPtr) /* Pointer to the object to parse */ { int offset; /* Offset in the "end-offset" expression */ register const char *bytes; /* String rep of the object */ size_t length; /* Length of the object's string rep */ /* * If it's already the right type, we're fine. */ if (objPtr->typePtr == &tclEndOffsetType) { return TCL_OK; |
︙ | ︙ | |||
3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 | * This is our limited string expression evaluator. Pass everything * after "end-" to Tcl_GetInt, then reverse for offset. */ if (TclIsSpaceProc(bytes[4])) { goto badIndexFormat; } if (Tcl_GetInt(interp, bytes+4, &offset) != TCL_OK) { return TCL_ERROR; } if (bytes[3] == '-') { offset = -offset; } } else { | > | 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 | * This is our limited string expression evaluator. Pass everything * after "end-" to Tcl_GetInt, then reverse for offset. */ if (TclIsSpaceProc(bytes[4])) { goto badIndexFormat; } // TODO might not fit in an int if (Tcl_GetInt(interp, bytes+4, &offset) != TCL_OK) { return TCL_ERROR; } if (bytes[3] == '-') { offset = -offset; } } else { |
︙ | ︙ | |||
3778 3779 3780 3781 3782 3783 3784 | Tcl_MutexLock(&pgvPtr->mutex); pgvPtr->epoch++; epoch = pgvPtr->epoch; Tcl_UtfToExternalDString(pgvPtr->encoding, pgvPtr->value, pgvPtr->numBytes, &native); Tcl_ExternalToUtfDString(current, Tcl_DStringValue(&native), | | | | 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 | Tcl_MutexLock(&pgvPtr->mutex); pgvPtr->epoch++; epoch = pgvPtr->epoch; Tcl_UtfToExternalDString(pgvPtr->encoding, pgvPtr->value, pgvPtr->numBytes, &native); Tcl_ExternalToUtfDString(current, Tcl_DStringValue(&native), Tcl_DStringLength(&native), &newValue); Tcl_DStringFree(&native); ckfree(pgvPtr->value); pgvPtr->value = ckalloc(Tcl_DStringLength(&newValue) + 1); memcpy(pgvPtr->value, Tcl_DStringValue(&newValue), Tcl_DStringLength(&newValue) + 1); Tcl_DStringFree(&newValue); Tcl_FreeEncoding(pgvPtr->encoding); pgvPtr->encoding = current; Tcl_MutexUnlock(&pgvPtr->mutex); } else { Tcl_FreeEncoding(current); } |
︙ | ︙ | |||
3909 3910 3911 3912 3913 3914 3915 | * *---------------------------------------------------------------------- */ const char * Tcl_GetNameOfExecutable(void) { | | > > > > > > > > > > > > > > > > > > > > > > > > > | 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 | * *---------------------------------------------------------------------- */ const char * Tcl_GetNameOfExecutable(void) { size_t numBytes; const char *bytes = Tcl_GetStringFromObj(TclGetObjNameOfExecutable(), &numBytes); if (numBytes == 0) { return NULL; } return bytes; } /* *---------------------------------------------------------------------- * * TclpGetTime -- * * Deprecated synonym for Tcl_GetTime. This function is provided for the * benefit of extensions written before Tcl_GetTime was exported from the * library. * * Results: * None. * * Side effects: * Stores current time in the buffer designated by "timePtr" * *---------------------------------------------------------------------- */ void TclpGetTime( Tcl_Time *timePtr) { Tcl_GetTime(timePtr); } /* *---------------------------------------------------------------------- * * TclGetPlatform -- * * This is a kludge that allows the test library to get access the |
︙ | ︙ | |||
3966 3967 3968 3969 3970 3971 3972 | *---------------------------------------------------------------------- */ int TclReToGlob( Tcl_Interp *interp, const char *reStr, | | | 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 | *---------------------------------------------------------------------- */ int TclReToGlob( Tcl_Interp *interp, const char *reStr, size_t reStrLen, Tcl_DString *dsPtr, int *exactPtr) { int anchorLeft, anchorRight, lastIsStar, numStars; char *dsStr, *dsStrStart; const char *msg, *p, *strEnd, *code; |
︙ | ︙ | |||
4152 4153 4154 4155 4156 4157 4158 | *exactPtr = (anchorLeft && anchorRight); } return TCL_OK; invalidGlob: if (interp != NULL) { | | | 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 | *exactPtr = (anchorLeft && anchorRight); } return TCL_OK; invalidGlob: if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "RE2GLOB", code, NULL); } Tcl_DStringFree(dsPtr); return TCL_ERROR; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclVar.c.
︙ | ︙ | |||
281 282 283 284 285 286 287 | TclVarHashTable *tablePtr, const char *key, int *newPtr) { Tcl_Obj *keyPtr; Var *varPtr; | | | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | TclVarHashTable *tablePtr, const char *key, int *newPtr) { Tcl_Obj *keyPtr; Var *varPtr; keyPtr = Tcl_NewStringObj(key, TCL_STRLEN); Tcl_IncrRefCount(keyPtr); varPtr = VarHashCreateVar(tablePtr, keyPtr, newPtr); Tcl_DecrRefCount(keyPtr); return varPtr; } |
︙ | ︙ | |||
411 412 413 414 415 416 417 | * return error if it doesn't exist. */ Var **arrayPtrPtr) /* If the name refers to an element of an * array, *arrayPtrPtr gets filled in with * address of array variable. Otherwise this * is set to NULL. */ { Var *varPtr; | | < | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | * return error if it doesn't exist. */ Var **arrayPtrPtr) /* If the name refers to an element of an * array, *arrayPtrPtr gets filled in with * address of array variable. Otherwise this * is set to NULL. */ { Var *varPtr; Tcl_Obj *part1Ptr = Tcl_NewStringObj(part1, TCL_STRLEN); if (createPart1) { Tcl_IncrRefCount(part1Ptr); } varPtr = TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2, arrayPtrPtr); TclDecrRefCount(part1Ptr); return varPtr; } |
︙ | ︙ | |||
494 495 496 497 498 499 500 | * address of array variable. Otherwise this * is set to NULL. */ { Tcl_Obj *part2Ptr = NULL; Var *resPtr; if (part2) { | | | 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | * address of array variable. Otherwise this * is set to NULL. */ { Tcl_Obj *part2Ptr = NULL; Var *resPtr; if (part2) { part2Ptr = Tcl_NewStringObj(part2, TCL_STRLEN); if (createPart2) { Tcl_IncrRefCount(part2Ptr); } } resPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, msg, createPart1, createPart2, arrayPtrPtr); |
︙ | ︙ | |||
544 545 546 547 548 549 550 | * address of array variable. Otherwise this * is set to NULL. */ { Interp *iPtr = (Interp *) interp; register Var *varPtr; /* Points to the variable's in-frame Var * structure. */ const char *part1; | | | | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 | * address of array variable. Otherwise this * is set to NULL. */ { Interp *iPtr = (Interp *) interp; register Var *varPtr; /* Points to the variable's in-frame Var * structure. */ const char *part1; size_t len1, len2; int index, parsed = 0; Tcl_Obj *objPtr; const Tcl_ObjType *typePtr = part1Ptr->typePtr; const char *errMsg = NULL; CallFrame *varFramePtr = iPtr->varFramePtr; #if ENABLE_NS_VARNAME_CACHING Namespace *nsPtr; #endif |
︙ | ︙ | |||
655 656 657 658 659 660 661 | noSuchVar, -1); Tcl_SetErrorCode(interp, "TCL", "VALUE", "VARNAME", NULL); } return NULL; } part2 = newPart2 = part1Ptr->internalRep.twoPtrValue.ptr2; if (newPart2) { | | | 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 | noSuchVar, -1); Tcl_SetErrorCode(interp, "TCL", "VALUE", "VARNAME", NULL); } return NULL; } part2 = newPart2 = part1Ptr->internalRep.twoPtrValue.ptr2; if (newPart2) { part2Ptr = Tcl_NewStringObj(newPart2, TCL_STRLEN); if (createPart2) { Tcl_IncrRefCount(part2Ptr); } } part1Ptr = part1Ptr->internalRep.twoPtrValue.ptr1; typePtr = part1Ptr->typePtr; if (typePtr == &localVarNameType) { |
︙ | ︙ | |||
700 701 702 703 704 705 706 | */ part2 = part1 + i + 1; len2 = len1 - i - 2; len1 = i; newPart2 = ckalloc(len2 + 1); | | | | 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 | */ part2 = part1 + i + 1; len2 = len1 - i - 2; len1 = i; newPart2 = ckalloc(len2 + 1); memcpy(newPart2, part2, len2); *(newPart2+len2) = '\0'; part2 = newPart2; part2Ptr = Tcl_NewStringObj(newPart2, TCL_STRLEN); if (createPart2) { Tcl_IncrRefCount(part2Ptr); } /* * Free the internal rep of the original part1Ptr, now renamed * objPtr, and set it to tclParsedVarNameType. |
︙ | ︙ | |||
916 917 918 919 920 921 922 | TclVarHashTable *tablePtr; /* Points to the hashtable, if any, in which * to look up the variable. */ Tcl_Var var; /* Used to search for global names. */ Var *varPtr; /* Points to the Var structure returned for * the variable. */ Namespace *varNsPtr, *cxtNsPtr, *dummy1Ptr, *dummy2Ptr; ResolverScheme *resPtr; | | > | 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 | TclVarHashTable *tablePtr; /* Points to the hashtable, if any, in which * to look up the variable. */ Tcl_Var var; /* Used to search for global names. */ Var *varPtr; /* Points to the Var structure returned for * the variable. */ Namespace *varNsPtr, *cxtNsPtr, *dummy1Ptr, *dummy2Ptr; ResolverScheme *resPtr; int isNew, i, result; size_t varLen; const char *varName = TclGetStringFromObj(varNamePtr, &varLen); varPtr = NULL; varNsPtr = NULL; /* Set non-NULL if a nonlocal variable. */ *indexPtr = -3; if (flags & TCL_GLOBAL_ONLY) { |
︙ | ︙ | |||
1019 1020 1021 1022 1023 1024 1025 | *errMsgPtr = badNamespace; return NULL; } else if (tail == NULL) { *errMsgPtr = missingName; return NULL; } if (tail != varName) { | | | 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 | *errMsgPtr = badNamespace; return NULL; } else if (tail == NULL) { *errMsgPtr = missingName; return NULL; } if (tail != varName) { tailPtr = Tcl_NewStringObj(tail, TCL_STRLEN); } else { tailPtr = varNamePtr; } varPtr = VarHashCreateVar(&varNsPtr->varTable, tailPtr, &isNew); if (lookGlobal) { /* |
︙ | ︙ | |||
1042 1043 1044 1045 1046 1047 1048 | } } else { /* Var wasn't found and not to create it. */ *errMsgPtr = noSuchVar; return NULL; } } } else { /* Local var: look in frame varFramePtr. */ | > | | 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 | } } else { /* Var wasn't found and not to create it. */ *errMsgPtr = noSuchVar; return NULL; } } } else { /* Local var: look in frame varFramePtr. */ size_t localLen; int localCt = varFramePtr->numCompiledLocals; Tcl_Obj **objPtrPtr = &varFramePtr->localCachePtr->varName0; const char *localNameStr; for (i=0 ; i<localCt ; i++, objPtrPtr++) { register Tcl_Obj *objPtr = *objPtrPtr; if (objPtr) { |
︙ | ︙ | |||
1254 1255 1256 1257 1258 1259 1260 | const char *part2, /* If non-NULL, gives the name of an element * in the array part1. */ int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, * TCL_NAMESPACE_ONLY and TCL_LEAVE_ERR_MSG * * bits. */ { Tcl_Obj *resultPtr; | | | | 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 | const char *part2, /* If non-NULL, gives the name of an element * in the array part1. */ int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, * TCL_NAMESPACE_ONLY and TCL_LEAVE_ERR_MSG * * bits. */ { Tcl_Obj *resultPtr; Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, TCL_STRLEN); if (part2) { part2Ptr = Tcl_NewStringObj(part2, TCL_STRLEN); Tcl_IncrRefCount(part2Ptr); } resultPtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags); Tcl_DecrRefCount(part1Ptr); if (part2Ptr) { |
︙ | ︙ | |||
1307 1308 1309 1310 1311 1312 1313 | const char *part1, /* Name of an array (if part2 is non-NULL) or * the name of a variable. */ const char *part2, /* If non-NULL, gives the name of an element * in the array part1. */ int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ { | | > | | 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 | const char *part1, /* Name of an array (if part2 is non-NULL) or * the name of a variable. */ const char *part2, /* If non-NULL, gives the name of an element * in the array part1. */ int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ { Tcl_Obj *resPtr, *part2Ptr = NULL; Tcl_Obj *part1Ptr = Tcl_NewStringObj(part1, TCL_STRLEN); if (part2) { part2Ptr = Tcl_NewStringObj(part2, TCL_STRLEN); Tcl_IncrRefCount(part2Ptr); } resPtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags); Tcl_DecrRefCount(part1Ptr); if (part2Ptr) { |
︙ | ︙ | |||
1490 1491 1492 1493 1494 1495 1496 | */ /* ARGSUSED */ int Tcl_SetObjCmd( ClientData dummy, /* Not used. */ register Tcl_Interp *interp,/* Current interpreter. */ | | | 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 | */ /* ARGSUSED */ int Tcl_SetObjCmd( ClientData dummy, /* Not used. */ register Tcl_Interp *interp,/* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *varValueObj; if (objc == 2) { varValueObj = Tcl_ObjGetVar2(interp, objv[1], NULL,TCL_LEAVE_ERR_MSG); if (varValueObj == NULL) { |
︙ | ︙ | |||
1558 1559 1560 1561 1562 1563 1564 | const char *newValue, /* New value for variable. */ int flags) /* Various flags that tell how to set value: * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_APPEND_VALUE, TCL_LIST_ELEMENT, or * TCL_LEAVE_ERR_MSG. */ { Tcl_Obj *varValuePtr = Tcl_SetVar2Ex(interp, part1, part2, | | | 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 | const char *newValue, /* New value for variable. */ int flags) /* Various flags that tell how to set value: * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_APPEND_VALUE, TCL_LIST_ELEMENT, or * TCL_LEAVE_ERR_MSG. */ { Tcl_Obj *varValuePtr = Tcl_SetVar2Ex(interp, part1, part2, Tcl_NewStringObj(newValue, TCL_STRLEN), flags); if (varValuePtr == NULL) { return NULL; } return TclGetString(varValuePtr); } |
︙ | ︙ | |||
1618 1619 1620 1621 1622 1623 1624 | * in the array part1. */ Tcl_Obj *newValuePtr, /* New value for variable. */ int flags) /* Various flags that tell how to set value: * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_APPEND_VALUE, TCL_LIST_ELEMENT or * TCL_LEAVE_ERR_MSG. */ { | | > | | 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 | * in the array part1. */ Tcl_Obj *newValuePtr, /* New value for variable. */ int flags) /* Various flags that tell how to set value: * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_APPEND_VALUE, TCL_LIST_ELEMENT or * TCL_LEAVE_ERR_MSG. */ { Tcl_Obj *resPtr, *part2Ptr = NULL, *part1Ptr; part1Ptr = Tcl_NewStringObj(part1, TCL_STRLEN); Tcl_IncrRefCount(part1Ptr); if (part2) { part2Ptr = Tcl_NewStringObj(part2, TCL_STRLEN); Tcl_IncrRefCount(part2Ptr); } resPtr = Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, newValuePtr, flags); Tcl_DecrRefCount(part1Ptr); if (part2Ptr) { |
︙ | ︙ | |||
2058 2059 2060 2061 2062 2063 2064 | } else { Tcl_DecrRefCount(varValuePtr); return NULL; } } else { /* Unshared - can Incr in place */ if (TCL_OK == TclIncrObj(interp, varValuePtr, incrPtr)) { | < | 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 | } else { Tcl_DecrRefCount(varValuePtr); return NULL; } } else { /* Unshared - can Incr in place */ if (TCL_OK == TclIncrObj(interp, varValuePtr, incrPtr)) { /* * This seems dumb to write the incremeted value into the var * after we just adjusted the value in place, but the spec for * [incr] requires that write traces fire, and making this call * is the way to make that happen. */ |
︙ | ︙ | |||
2106 2107 2108 2109 2110 2111 2112 | const char *part1, /* Name of variable or array. */ const char *part2, /* Name of element within array or NULL. */ int flags) /* OR-ed combination of any of * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_LEAVE_ERR_MSG. */ { int result; | | > | | 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 | const char *part1, /* Name of variable or array. */ const char *part2, /* Name of element within array or NULL. */ int flags) /* OR-ed combination of any of * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_LEAVE_ERR_MSG. */ { int result; Tcl_Obj *part2Ptr = NULL, *part1Ptr; part1Ptr = Tcl_NewStringObj(part1, TCL_STRLEN); if (part2) { part2Ptr = Tcl_NewStringObj(part2, TCL_STRLEN); } /* * Filter to pass through only the flags this interface supports. */ flags &= (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG); |
︙ | ︙ | |||
2458 2459 2460 2461 2462 2463 2464 | */ /* ARGSUSED */ int Tcl_UnsetObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 | */ /* ARGSUSED */ int Tcl_UnsetObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { register int i, flags = TCL_LEAVE_ERR_MSG; register const char *name; if (objc == 1) { /* |
︙ | ︙ | |||
2526 2527 2528 2529 2530 2531 2532 | */ /* ARGSUSED */ int Tcl_AppendObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 | */ /* ARGSUSED */ int Tcl_AppendObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Var *varPtr, *arrayPtr; register Tcl_Obj *varValuePtr = NULL; /* Initialized to avoid compiler warning. */ int i; |
︙ | ︙ | |||
2592 2593 2594 2595 2596 2597 2598 | */ /* ARGSUSED */ int Tcl_LappendObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 | */ /* ARGSUSED */ int Tcl_LappendObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *varValuePtr, *newValuePtr; size_t numElems; Var *varPtr, *arrayPtr; int result, createdNewObj; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "varName ?value ...?"); return TCL_ERROR; } if (objc == 2) { newValuePtr = Tcl_ObjGetVar2(interp, objv[1], NULL, 0); |
︙ | ︙ | |||
2738 2739 2740 2741 2742 2743 2744 | TclArraySet( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *arrayNameObj, /* The array name. */ Tcl_Obj *arrayElemObj) /* The array elements list or dict. If this is * NULL, create an empty array. */ { Var *varPtr, *arrayPtr; | | > | 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 | TclArraySet( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *arrayNameObj, /* The array name. */ Tcl_Obj *arrayElemObj) /* The array elements list or dict. If this is * NULL, create an empty array. */ { Var *varPtr, *arrayPtr; int result; size_t i; varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL, /*flags*/ TCL_LEAVE_ERR_MSG, /*msg*/ "set", /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr); if (varPtr == NULL) { return TCL_ERROR; } |
︙ | ︙ | |||
2766 2767 2768 2769 2770 2771 2772 2773 | * Install the contents of the dictionary or list into the array. */ if (arrayElemObj->typePtr == &tclDictType) { Tcl_Obj *keyPtr, *valuePtr; Tcl_DictSearch search; int done; | > | | 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 | * Install the contents of the dictionary or list into the array. */ if (arrayElemObj->typePtr == &tclDictType) { Tcl_Obj *keyPtr, *valuePtr; Tcl_DictSearch search; int done; size_t len; if (Tcl_DictObjSize(interp, arrayElemObj, &len) != TCL_OK) { return TCL_ERROR; } if (done == 0) { /* * Empty, so we'll just force the array to be properly existing * instead. */ |
︙ | ︙ | |||
2809 2810 2811 2812 2813 2814 2815 | return TCL_OK; } else { /* * Not a dictionary, so assume (and convert to, for backward- * -compatability reasons) a list. */ | | | | 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 | return TCL_OK; } else { /* * Not a dictionary, so assume (and convert to, for backward- * -compatability reasons) a list. */ size_t elemLen; Tcl_Obj **elemPtrs, *copyListObj; result = TclListObjGetElements(interp, arrayElemObj, &elemLen, &elemPtrs); if (result != TCL_OK) { return result; } if (elemLen & 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "list must have an even number of elements", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "FORMAT", NULL); return TCL_ERROR; } if (elemLen == 0) { goto ensureArray; } |
︙ | ︙ | |||
2903 2904 2905 2906 2907 2908 2909 | */ /* ARGSUSED */ static int ArrayStartSearchCmd( ClientData clientData, Tcl_Interp *interp, | | | 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 | */ /* ARGSUSED */ static int ArrayStartSearchCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; Var *varPtr, *arrayPtr; Tcl_HashEntry *hPtr; Tcl_Obj *varNameObj; int isNew; |
︙ | ︙ | |||
3001 3002 3003 3004 3005 3006 3007 | */ /* ARGSUSED */ static int ArrayAnyMoreCmd( ClientData clientData, Tcl_Interp *interp, | | | 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 | */ /* ARGSUSED */ static int ArrayAnyMoreCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; Var *varPtr, *arrayPtr; Tcl_Obj *varNameObj, *searchObj; int gotValue; ArraySearch *searchPtr; |
︙ | ︙ | |||
3108 3109 3110 3111 3112 3113 3114 | */ /* ARGSUSED */ static int ArrayNextElementCmd( ClientData clientData, Tcl_Interp *interp, | | | 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 | */ /* ARGSUSED */ static int ArrayNextElementCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; Var *varPtr, *arrayPtr; Tcl_Obj *varNameObj, *searchObj; ArraySearch *searchPtr; |
︙ | ︙ | |||
3217 3218 3219 3220 3221 3222 3223 | */ /* ARGSUSED */ static int ArrayDoneSearchCmd( ClientData clientData, Tcl_Interp *interp, | | | 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 | */ /* ARGSUSED */ static int ArrayDoneSearchCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; Var *varPtr, *arrayPtr; Tcl_HashEntry *hPtr; Tcl_Obj *varNameObj, *searchObj; ArraySearch *searchPtr, *prevPtr; |
︙ | ︙ | |||
3325 3326 3327 3328 3329 3330 3331 | */ /* ARGSUSED */ static int ArrayExistsCmd( ClientData clientData, Tcl_Interp *interp, | | | 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 | */ /* ARGSUSED */ static int ArrayExistsCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; Var *varPtr, *arrayPtr; Tcl_Obj *arrayNameObj; int notArray; |
︙ | ︙ | |||
3392 3393 3394 3395 3396 3397 3398 | */ /* ARGSUSED */ static int ArrayGetCmd( ClientData clientData, Tcl_Interp *interp, | | > | | 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 | */ /* ARGSUSED */ static int ArrayGetCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; Var *varPtr, *arrayPtr, *varPtr2; Tcl_Obj *varNameObj, *nameObj, *valueObj, *nameLstObj, *tmpResObj; Tcl_Obj **nameObjPtr, *patternObj; Tcl_HashSearch search; const char *pattern; int result; size_t i, count; switch (objc) { case 2: varNameObj = objv[1]; patternObj = NULL; break; case 3: |
︙ | ︙ | |||
3576 3577 3578 3579 3580 3581 3582 | */ /* ARGSUSED */ static int ArrayNamesCmd( ClientData clientData, Tcl_Interp *interp, | | | 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 | */ /* ARGSUSED */ static int ArrayNamesCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { static const char *const options[] = { "-exact", "-glob", "-regexp", NULL }; enum options { OPT_EXACT, OPT_GLOB, OPT_REGEXP }; Interp *iPtr = (Interp *) interp; |
︙ | ︙ | |||
3768 3769 3770 3771 3772 3773 3774 | */ /* ARGSUSED */ static int ArraySetCmd( ClientData clientData, Tcl_Interp *interp, | | | 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 | */ /* ARGSUSED */ static int ArraySetCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; Var *varPtr, *arrayPtr; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "arrayName list"); |
︙ | ︙ | |||
3825 3826 3827 3828 3829 3830 3831 | */ /* ARGSUSED */ static int ArraySizeCmd( ClientData clientData, Tcl_Interp *interp, | | | 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 | */ /* ARGSUSED */ static int ArraySizeCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; Var *varPtr, *arrayPtr; Tcl_Obj *varNameObj; Tcl_HashSearch search; Var *varPtr2; |
︙ | ︙ | |||
3909 3910 3911 3912 3913 3914 3915 | */ /* ARGSUSED */ static int ArrayStatsCmd( ClientData clientData, Tcl_Interp *interp, | | | 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 | */ /* ARGSUSED */ static int ArrayStatsCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; Var *varPtr, *arrayPtr; Tcl_Obj *varNameObj; char *stats; |
︙ | ︙ | |||
3962 3963 3964 3965 3966 3967 3968 | TclGetString(varNameObj), NULL); return TCL_ERROR; } stats = Tcl_HashStats((Tcl_HashTable *) varPtr->value.tablePtr); if (stats == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 | TclGetString(varNameObj), NULL); return TCL_ERROR; } stats = Tcl_HashStats((Tcl_HashTable *) varPtr->value.tablePtr); if (stats == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "error reading array statistics", TCL_STRLEN)); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewStringObj(stats, TCL_STRLEN)); ckfree(stats); return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3992 3993 3994 3995 3996 3997 3998 | */ /* ARGSUSED */ static int ArrayUnsetCmd( ClientData clientData, Tcl_Interp *interp, | | | 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 | */ /* ARGSUSED */ static int ArrayUnsetCmd( ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Interp *iPtr = (Interp *) interp; Var *varPtr, *arrayPtr, *varPtr2, *protectedVarPtr; Tcl_Obj *varNameObj, *patternObj, *nameObj; Tcl_HashSearch search; const char *pattern; |
︙ | ︙ | |||
4301 4302 4303 4304 4305 4306 4307 | int index) /* If the variable to be linked is an indexed * scalar, this is its index. Otherwise, -1 */ { Tcl_Obj *myNamePtr = NULL; int result; if (myName) { | | | 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 | int index) /* If the variable to be linked is an indexed * scalar, this is its index. Otherwise, -1 */ { Tcl_Obj *myNamePtr = NULL; int result; if (myName) { myNamePtr = Tcl_NewStringObj(myName, TCL_STRLEN); Tcl_IncrRefCount(myNamePtr); } result = TclPtrObjMakeUpvar(interp, otherPtr, myNamePtr, myFlags, index); if (myNamePtr) { Tcl_DecrRefCount(myNamePtr); } return result; |
︙ | ︙ | |||
4385 4386 4387 4388 4389 4390 4391 | TclGetString(myNamePtr), NULL); return TCL_ERROR; } } if (varPtr == otherPtr) { Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_NewStringObj( | | | 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 | TclGetString(myNamePtr), NULL); return TCL_ERROR; } } if (varPtr == otherPtr) { Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_NewStringObj( "can't upvar from variable to itself", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "UPVAR", "SELF", NULL); return TCL_ERROR; } if (TclIsVarTraced(varPtr)) { Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf( "variable \"%s\" has traces: can't use for upvar", myName)); |
︙ | ︙ | |||
4473 4474 4475 4476 4477 4478 4479 | CallFrame *framePtr; Tcl_Obj *part1Ptr, *localNamePtr; if (TclGetFrame(interp, frameName, &framePtr) == -1) { return TCL_ERROR; } | | | | 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 | CallFrame *framePtr; Tcl_Obj *part1Ptr, *localNamePtr; if (TclGetFrame(interp, frameName, &framePtr) == -1) { return TCL_ERROR; } part1Ptr = Tcl_NewStringObj(part1, TCL_STRLEN); Tcl_IncrRefCount(part1Ptr); localNamePtr = Tcl_NewStringObj(localNameStr, TCL_STRLEN); Tcl_IncrRefCount(localNamePtr); result = ObjMakeUpvar(interp, framePtr, part1Ptr, part2, 0, localNamePtr, flags, -1); Tcl_DecrRefCount(part1Ptr); Tcl_DecrRefCount(localNamePtr); return result; |
︙ | ︙ | |||
4528 4529 4530 4531 4532 4533 4534 | /* * Add the full name of the containing namespace (if any), followed by the * "::" separator, then the variable name. */ nsPtr = TclGetVarNsPtr(varPtr); if (nsPtr) { | | | 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 | /* * Add the full name of the containing namespace (if any), followed by the * "::" separator, then the variable name. */ nsPtr = TclGetVarNsPtr(varPtr); if (nsPtr) { Tcl_AppendToObj(objPtr, nsPtr->fullName, TCL_STRLEN); if (nsPtr != iPtr->globalNsPtr) { Tcl_AppendToObj(objPtr, "::", 2); } } if (TclIsVarInHash(varPtr)) { if (!TclIsVarDeadHash(varPtr)) { namePtr = VarHashGetKey(varPtr); |
︙ | ︙ | |||
4569 4570 4571 4572 4573 4574 4575 | *---------------------------------------------------------------------- */ int Tcl_GlobalObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 | *---------------------------------------------------------------------- */ int Tcl_GlobalObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; register Tcl_Obj *objPtr, *tailPtr; const char *varName; register const char *tail; int result, i; |
︙ | ︙ | |||
4613 4614 4615 4616 4617 4618 4619 | if ((*tail == ':') && (tail > varName)) { tail++; } if (tail == varName) { tailPtr = objPtr; } else { | | | 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 | if ((*tail == ':') && (tail > varName)) { tail++; } if (tail == varName) { tailPtr = objPtr; } else { tailPtr = Tcl_NewStringObj(tail, TCL_STRLEN); Tcl_IncrRefCount(tailPtr); } /* * Link to the variable "varName" in the global :: namespace. */ |
︙ | ︙ | |||
4673 4674 4675 4676 4677 4678 4679 | *---------------------------------------------------------------------- */ int Tcl_VariableObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 | *---------------------------------------------------------------------- */ int Tcl_VariableObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; const char *varName, *tail, *cp; Var *varPtr, *arrayPtr; Tcl_Obj *varValuePtr; int i, result; |
︙ | ︙ | |||
4764 4765 4766 4767 4768 4769 4770 | * Create a local link "tail" to the variable "varName" in the * current namespace. */ if (tail == varName) { tailPtr = varNamePtr; } else { | | | 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 | * Create a local link "tail" to the variable "varName" in the * current namespace. */ if (tail == varName) { tailPtr = varNamePtr; } else { tailPtr = Tcl_NewStringObj(tail, TCL_STRLEN); Tcl_IncrRefCount(tailPtr); } result = ObjMakeUpvar(interp, NULL, varNamePtr, /*otherP2*/ NULL, /*otherFlags*/ TCL_NAMESPACE_ONLY, /*myName*/ tailPtr, /*myFlags*/ 0, -1); |
︙ | ︙ | |||
4806 4807 4808 4809 4810 4811 4812 | */ /* ARGSUSED */ int Tcl_UpvarObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 | */ /* ARGSUSED */ int Tcl_UpvarObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { CallFrame *framePtr; int result, hasLevel; Tcl_Obj *levelObj; if (objc < 3) { |
︙ | ︙ | |||
5386 5387 5388 5389 5390 5391 5392 | Tcl_Interp *interp, /* Interpreter in which to record message. */ const char *part1, const char *part2, /* Variable's two-part name. */ const char *operation, /* String describing operation that failed, * e.g. "read", "set", or "unset". */ const char *reason) /* String describing why operation failed. */ { | | | | 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 | Tcl_Interp *interp, /* Interpreter in which to record message. */ const char *part1, const char *part2, /* Variable's two-part name. */ const char *operation, /* String describing operation that failed, * e.g. "read", "set", or "unset". */ const char *reason) /* String describing why operation failed. */ { Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, TCL_STRLEN); if (part2) { part2Ptr = Tcl_NewStringObj(part2, TCL_STRLEN); } TclObjVarErrMsg(interp, part1Ptr, part2Ptr, operation, reason, -1); Tcl_DecrRefCount(part1Ptr); if (part2Ptr) { Tcl_DecrRefCount(part2Ptr); |
︙ | ︙ | |||
5589 5590 5591 5592 5593 5594 5595 | UpdateParsedVarName( Tcl_Obj *objPtr) { Tcl_Obj *arrayPtr = objPtr->internalRep.twoPtrValue.ptr1; char *part2 = objPtr->internalRep.twoPtrValue.ptr2; const char *part1; char *p; | | | | | 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 | UpdateParsedVarName( Tcl_Obj *objPtr) { Tcl_Obj *arrayPtr = objPtr->internalRep.twoPtrValue.ptr1; char *part2 = objPtr->internalRep.twoPtrValue.ptr2; const char *part1; char *p; size_t len1, len2, totalLen; if (arrayPtr == NULL) { /* * This is a parsed scalar name: what is it doing here? */ Tcl_Panic("scalar parsedVarName without a string rep"); } part1 = TclGetStringFromObj(arrayPtr, &len1); len2 = strlen(part2); totalLen = len1 + len2 + 2; p = ckalloc(totalLen + 1); objPtr->bytes = p; objPtr->length = totalLen; memcpy(p, part1, len1); p += len1; *p++ = '('; memcpy(p, part2, len2); p += len2; *p++ = ')'; *p = '\0'; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
5659 5660 5661 5662 5663 5664 5665 | * global namespace), TCL_NAMESPACE_ONLY (look * up only in contextNsPtr, or the current * namespace if contextNsPtr is NULL), and * TCL_LEAVE_ERR_MSG. If both TCL_GLOBAL_ONLY * and TCL_NAMESPACE_ONLY are given, * TCL_GLOBAL_ONLY is ignored. */ { | | | 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 | * global namespace), TCL_NAMESPACE_ONLY (look * up only in contextNsPtr, or the current * namespace if contextNsPtr is NULL), and * TCL_LEAVE_ERR_MSG. If both TCL_GLOBAL_ONLY * and TCL_NAMESPACE_ONLY are given, * TCL_GLOBAL_ONLY is ignored. */ { Tcl_Obj *namePtr = Tcl_NewStringObj(name, TCL_STRLEN); Tcl_Var var; var = ObjFindNamespaceVar(interp, namePtr, contextNsPtr, flags); Tcl_DecrRefCount(namePtr); return var; } |
︙ | ︙ | |||
5755 5756 5757 5758 5759 5760 5761 | * Look for the variable in the variable table of its namespace. Be sure * to check both possible search paths: from the specified namespace * context and from the global namespace. */ varPtr = NULL; if (simpleName != name) { | | | 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 | * Look for the variable in the variable table of its namespace. Be sure * to check both possible search paths: from the specified namespace * context and from the global namespace. */ varPtr = NULL; if (simpleName != name) { simpleNamePtr = Tcl_NewStringObj(simpleName, TCL_STRLEN); } else { simpleNamePtr = namePtr; } for (search = 0; (search < 2) && (varPtr == NULL); search++) { if ((nsPtr[search] != NULL) && (simpleName != NULL)) { varPtr = VarHashFindVar(&nsPtr[search]->varTable, simpleNamePtr); |
︙ | ︙ | |||
5804 5805 5806 5807 5808 5809 5810 | *---------------------------------------------------------------------- */ int TclInfoVarsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 | *---------------------------------------------------------------------- */ int TclInfoVarsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; const char *varName, *pattern, *simplePattern; Tcl_HashSearch search; Var *varPtr; Namespace *nsPtr; |
︙ | ︙ | |||
5848 5849 5850 5851 5852 5853 5854 | &nsPtr, &dummy1NsPtr, &dummy2NsPtr, &simplePattern); if (nsPtr != NULL) { /* We successfully found the pattern's ns. */ specificNsInPattern = (strcmp(simplePattern, pattern) != 0); if (simplePattern == pattern) { simplePatternPtr = objv[1]; } else { | | | 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 | &nsPtr, &dummy1NsPtr, &dummy2NsPtr, &simplePattern); if (nsPtr != NULL) { /* We successfully found the pattern's ns. */ specificNsInPattern = (strcmp(simplePattern, pattern) != 0); if (simplePattern == pattern) { simplePatternPtr = objv[1]; } else { simplePatternPtr = Tcl_NewStringObj(simplePattern,TCL_STRLEN); } Tcl_IncrRefCount(simplePatternPtr); } } else { Tcl_WrongNumArgs(interp, 1, objv, "?pattern?"); return TCL_ERROR; } |
︙ | ︙ | |||
5995 5996 5997 5998 5999 6000 6001 | *---------------------------------------------------------------------- */ int TclInfoGlobalsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 | *---------------------------------------------------------------------- */ int TclInfoGlobalsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { const char *varName, *pattern; Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp); Tcl_HashSearch search; Var *varPtr; Tcl_Obj *listPtr, *varNamePtr, *patternPtr; |
︙ | ︙ | |||
6033 6034 6035 6036 6037 6038 6039 | */ listPtr = Tcl_NewListObj(0, NULL); if (pattern != NULL && TclMatchIsTrivial(pattern)) { if (pattern == TclGetString(objv[1])) { patternPtr = objv[1]; } else { | | | 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 | */ listPtr = Tcl_NewListObj(0, NULL); if (pattern != NULL && TclMatchIsTrivial(pattern)) { if (pattern == TclGetString(objv[1])) { patternPtr = objv[1]; } else { patternPtr = Tcl_NewStringObj(pattern, TCL_STRLEN); } Tcl_IncrRefCount(patternPtr); varPtr = VarHashFindVar(&globalNsPtr->varTable, patternPtr); if (varPtr) { if (!TclIsVarUndefined(varPtr)) { Tcl_ListObjAppendElement(interp, listPtr, |
︙ | ︙ | |||
6088 6089 6090 6091 6092 6093 6094 | *---------------------------------------------------------------------- */ int TclInfoLocalsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 | *---------------------------------------------------------------------- */ int TclInfoLocalsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; Tcl_Obj *patternPtr, *listPtr; if (objc == 1) { patternPtr = NULL; |
︙ | ︙ |
Changes to generic/tclZlib.c.
︙ | ︙ | |||
175 176 177 178 179 180 181 | static Tcl_ObjCmdProc ZlibStreamPutCmd; static void ConvertError(Tcl_Interp *interp, int code, uLong adler); static Tcl_Obj * ConvertErrorToList(int code, uLong adler); static void ExtractHeader(gz_header *headerPtr, Tcl_Obj *dictObj); static int GenerateHeader(Tcl_Interp *interp, Tcl_Obj *dictObj, | | | | | | | | | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | static Tcl_ObjCmdProc ZlibStreamPutCmd; static void ConvertError(Tcl_Interp *interp, int code, uLong adler); static Tcl_Obj * ConvertErrorToList(int code, uLong adler); static void ExtractHeader(gz_header *headerPtr, Tcl_Obj *dictObj); static int GenerateHeader(Tcl_Interp *interp, Tcl_Obj *dictObj, GzipHeader *headerPtr, size_t *extraSizePtr); static int ZlibPushSubcmd(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static inline size_t ResultCopy(ZlibChannelData *cd, char *buf, size_t toRead); static int ResultGenerate(ZlibChannelData *cd, size_t n, int flush, int *errorCodePtr); static Tcl_Channel ZlibStackChannelTransform(Tcl_Interp *interp, int mode, int format, int level, int limit, Tcl_Channel channel, Tcl_Obj *gzipHeaderDictPtr, Tcl_Obj *compDictObj); static void ZlibStreamCleanup(ZlibStreamHandle *zshPtr); static int ZlibStreamSubcmd(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static inline void ZlibTransformEventTimerKill(ZlibChannelData *cd); static void ZlibTransformTimerRun(ClientData clientData); /* * Type of zlib-based compressing and decompressing channels. */ |
︙ | ︙ | |||
255 256 257 258 259 260 261 | * Firstly, the case that is *different* because it's really coming * from the OS and is just being reported via zlib. It should be * really uncommon because Tcl handles all I/O rather than delegating * it to zlib, but proving it can't happen is hard. */ case Z_ERRNO: | | > | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | * Firstly, the case that is *different* because it's really coming * from the OS and is just being reported via zlib. It should be * really uncommon because Tcl handles all I/O rather than delegating * it to zlib, but proving it can't happen is hard. */ case Z_ERRNO: Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_PosixError(interp), TCL_STRLEN)); return; /* * Normal errors/conditions, some of which have additional detail and * some which don't. (This is not defined by array lookup because zlib * error codes are sometimes negative.) */ |
︙ | ︙ | |||
306 307 308 309 310 311 312 | default: codeStr = "UNKNOWN"; codeStr2 = codeStrBuf; sprintf(codeStrBuf, "%d", code); break; } | | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | default: codeStr = "UNKNOWN"; codeStr2 = codeStrBuf; sprintf(codeStrBuf, "%d", code); break; } Tcl_SetObjResult(interp, Tcl_NewStringObj(zError(code), TCL_STRLEN)); /* * Tricky point! We might pass NULL twice here (and will when the error * type is known). */ Tcl_SetErrorCode(interp, "TCL", "ZLIB", codeStr, codeStr2, NULL); |
︙ | ︙ | |||
343 344 345 346 347 348 349 | TclNewLiteralStringObj(objv[2], "BUF"); return Tcl_NewListObj(3, objv); case Z_VERSION_ERROR: TclNewLiteralStringObj(objv[2], "VERSION"); return Tcl_NewListObj(3, objv); case Z_ERRNO: TclNewLiteralStringObj(objv[2], "POSIX"); | | | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | TclNewLiteralStringObj(objv[2], "BUF"); return Tcl_NewListObj(3, objv); case Z_VERSION_ERROR: TclNewLiteralStringObj(objv[2], "VERSION"); return Tcl_NewListObj(3, objv); case Z_ERRNO: TclNewLiteralStringObj(objv[2], "POSIX"); objv[3] = Tcl_NewStringObj(Tcl_ErrnoId(), TCL_STRLEN); return Tcl_NewListObj(4, objv); case Z_NEED_DICT: TclNewLiteralStringObj(objv[2], "NEED_DICT"); objv[3] = Tcl_NewWideIntObj((Tcl_WideInt) adler); return Tcl_NewListObj(4, objv); /* |
︙ | ︙ | |||
398 399 400 401 402 403 404 | static inline int GetValue( Tcl_Interp *interp, Tcl_Obj *dictObj, const char *nameStr, Tcl_Obj **valuePtrPtr) { | | | > | | 399 400 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 | static inline int GetValue( Tcl_Interp *interp, Tcl_Obj *dictObj, const char *nameStr, Tcl_Obj **valuePtrPtr) { Tcl_Obj *name = Tcl_NewStringObj(nameStr, TCL_STRLEN); int result = Tcl_DictObjGet(interp, dictObj, name, valuePtrPtr); TclDecrRefCount(name); return result; } static int GenerateHeader( Tcl_Interp *interp, /* Where to put error messages. */ Tcl_Obj *dictObj, /* The dictionary whose contents are to be * parsed. */ GzipHeader *headerPtr, /* Where to store the parsed-out values. */ size_t *extraSizePtr) /* Variable to add the length of header * strings (filename, comment) to. */ { Tcl_Obj *value; size_t len; int result = TCL_ERROR; const char *valueStr; Tcl_Encoding latin1enc; static const char *const types[] = { "binary", "text" }; /* |
︙ | ︙ | |||
515 516 517 518 519 520 521 | * Side effects: * Updates the dictionary, which must be writable (i.e. refCount < 2). * *---------------------------------------------------------------------- */ #define SetValue(dictObj, key, value) \ | | | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | * Side effects: * Updates the dictionary, which must be writable (i.e. refCount < 2). * *---------------------------------------------------------------------- */ #define SetValue(dictObj, key, value) \ Tcl_DictObjPut(NULL,(dictObj),Tcl_NewStringObj((key),TCL_STRLEN),(value)) static void ExtractHeader( gz_header *headerPtr, /* The gzip header to extract from. */ Tcl_Obj *dictObj) /* The dictionary to store in. */ { Tcl_Encoding latin1enc = NULL; |
︙ | ︙ | |||
537 538 539 540 541 542 543 | latin1enc = Tcl_GetEncoding(NULL, "iso8859-1"); if (latin1enc == NULL) { Tcl_Panic("no latin-1 encoding"); } } | | | | | | | | | | 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 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 | latin1enc = Tcl_GetEncoding(NULL, "iso8859-1"); if (latin1enc == NULL) { Tcl_Panic("no latin-1 encoding"); } } Tcl_ExternalToUtfDString(latin1enc, (char *) headerPtr->comment, TCL_STRLEN, &tmp); SetValue(dictObj, "comment", TclDStringToObj(&tmp)); } SetValue(dictObj, "crc", Tcl_NewLongObj(headerPtr->hcrc!=0)); if (headerPtr->name != Z_NULL) { if (latin1enc == NULL) { /* * RFC 1952 says that header strings are in ISO 8859-1 (LATIN-1). */ latin1enc = Tcl_GetEncoding(NULL, "iso8859-1"); if (latin1enc == NULL) { Tcl_Panic("no latin-1 encoding"); } } Tcl_ExternalToUtfDString(latin1enc, (char *) headerPtr->name, TCL_STRLEN, &tmp); SetValue(dictObj, "filename", TclDStringToObj(&tmp)); } if (headerPtr->os != 255) { SetValue(dictObj, "os", Tcl_NewLongObj(headerPtr->os)); } if (headerPtr->time != 0 /* magic - no time */) { SetValue(dictObj, "time", Tcl_NewLongObj((long) headerPtr->time)); } if (headerPtr->text != Z_UNKNOWN) { SetValue(dictObj, "type", Tcl_NewStringObj( headerPtr->text ? "text" : "binary", TCL_STRLEN)); } if (latin1enc != NULL) { Tcl_FreeEncoding(latin1enc); } } static int SetInflateDictionary( z_streamp strm, Tcl_Obj *compDictObj) { if (compDictObj != NULL) { size_t length; unsigned char *bytes = Tcl_GetByteArrayFromObj(compDictObj, &length); return inflateSetDictionary(strm, bytes, (unsigned) length); } return Z_OK; } static int SetDeflateDictionary( z_streamp strm, Tcl_Obj *compDictObj) { if (compDictObj != NULL) { size_t length; unsigned char *bytes = Tcl_GetByteArrayFromObj(compDictObj, &length); return deflateSetDictionary(strm, bytes, (unsigned) length); } return Z_OK; } |
︙ | ︙ | |||
768 769 770 771 772 773 774 | } Tcl_DStringInit(&cmdname); TclDStringAppendLiteral(&cmdname, "::tcl::zlib::streamcmd_"); TclDStringAppendObj(&cmdname, Tcl_GetObjResult(interp)); if (Tcl_GetCommandInfo(interp, Tcl_DStringValue(&cmdname), &cmdinfo) == 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 | } Tcl_DStringInit(&cmdname); TclDStringAppendLiteral(&cmdname, "::tcl::zlib::streamcmd_"); TclDStringAppendObj(&cmdname, Tcl_GetObjResult(interp)); if (Tcl_GetCommandInfo(interp, Tcl_DStringValue(&cmdname), &cmdinfo) == 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "BUG: Stream command name already exists", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "BUG", "EXISTING_CMD", NULL); Tcl_DStringFree(&cmdname); goto error; } Tcl_ResetResult(interp); /* |
︙ | ︙ | |||
1145 1146 1147 1148 1149 1150 1151 | Tcl_ZlibStream zshandle, /* As obtained from Tcl_ZlibStreamInit */ Tcl_Obj *data, /* Data to compress/decompress */ int flush) /* TCL_ZLIB_NO_FLUSH, TCL_ZLIB_FLUSH, * TCL_ZLIB_FULLFLUSH, or TCL_ZLIB_FINALIZE */ { ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle; char *dataTmp = NULL; | > | | | 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 | Tcl_ZlibStream zshandle, /* As obtained from Tcl_ZlibStreamInit */ Tcl_Obj *data, /* Data to compress/decompress */ int flush) /* TCL_ZLIB_NO_FLUSH, TCL_ZLIB_FLUSH, * TCL_ZLIB_FULLFLUSH, or TCL_ZLIB_FINALIZE */ { ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle; char *dataTmp = NULL; int e; size_t size, outSize; Tcl_Obj *obj; if (zshPtr->streamEnd) { if (zshPtr->interp) { Tcl_SetObjResult(zshPtr->interp, Tcl_NewStringObj( "already past compressed stream end", TCL_STRLEN)); Tcl_SetErrorCode(zshPtr->interp, "TCL", "ZIP", "CLOSED", NULL); } return TCL_ERROR; } if (zshPtr->mode == TCL_ZLIB_STREAM_DEFLATE) { zshPtr->stream.next_in = Tcl_GetByteArrayFromObj(data, &size); |
︙ | ︙ | |||
1266 1267 1268 1269 1270 1271 1272 | *---------------------------------------------------------------------- */ int Tcl_ZlibStreamGet( Tcl_ZlibStream zshandle, /* As obtained from Tcl_ZlibStreamInit */ Tcl_Obj *data, /* A place to append the data. */ | | | | | 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 | *---------------------------------------------------------------------- */ int Tcl_ZlibStreamGet( Tcl_ZlibStream zshandle, /* As obtained from Tcl_ZlibStreamInit */ Tcl_Obj *data, /* A place to append the data. */ size_t count) /* Number of bytes to grab as a maximum, you * may get less! */ { ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle; int e; Tcl_Obj *itemObj; unsigned char *dataPtr, *itemPtr; size_t i, listLen, itemLen, existing, dataPos = 0; /* * Getting beyond the of stream, just return empty string. */ if (zshPtr->streamEnd) { return TCL_OK; |
︙ | ︙ | |||
1377 1378 1379 1380 1381 1382 1383 | * more to inflate. */ if (zshPtr->stream.avail_in > 0) { if (zshPtr->interp) { Tcl_SetObjResult(zshPtr->interp, Tcl_NewStringObj( "unexpected zlib internal state during" | | | 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 | * more to inflate. */ if (zshPtr->stream.avail_in > 0) { if (zshPtr->interp) { Tcl_SetObjResult(zshPtr->interp, Tcl_NewStringObj( "unexpected zlib internal state during" " decompression", TCL_STRLEN)); Tcl_SetErrorCode(zshPtr->interp, "TCL", "ZIP", "STATE", NULL); } Tcl_SetByteArrayLength(data, existing); return TCL_ERROR; } |
︙ | ︙ | |||
1521 1522 1523 1524 1525 1526 1527 | Tcl_ZlibDeflate( Tcl_Interp *interp, int format, Tcl_Obj *data, int level, Tcl_Obj *gzipHeaderDictObj) { | | > | 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 | Tcl_ZlibDeflate( Tcl_Interp *interp, int format, Tcl_Obj *data, int level, Tcl_Obj *gzipHeaderDictObj) { int wbits = 0, e = 0; size_t inLen = 0, extraSize = 0; Byte *inData = NULL; z_stream stream; GzipHeader header; gz_header *headerPtr = NULL; Tcl_Obj *obj; if (!interp) { |
︙ | ︙ | |||
1671 1672 1673 1674 1675 1676 1677 | Tcl_ZlibInflate( Tcl_Interp *interp, int format, Tcl_Obj *data, int bufferSize, Tcl_Obj *gzipHeaderDictObj) { | | > | 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 | Tcl_ZlibInflate( Tcl_Interp *interp, int format, Tcl_Obj *data, int bufferSize, Tcl_Obj *gzipHeaderDictObj) { int wbits = 0, e = 0; size_t inLen = 0, newBufferSize; Byte *inData = NULL, *outData = NULL, *newOutData = NULL; z_stream stream; gz_header header, *headerPtr = NULL; Tcl_Obj *obj; char *nameBuf = NULL, *commentBuf = NULL; if (!interp) { |
︙ | ︙ | |||
1851 1852 1853 1854 1855 1856 1857 | *---------------------------------------------------------------------- */ unsigned int Tcl_ZlibCRC32( unsigned int crc, const unsigned char *buf, | | > | > | | > | 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 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 | *---------------------------------------------------------------------- */ unsigned int Tcl_ZlibCRC32( unsigned int crc, const unsigned char *buf, size_t len) { // TODO handle data where it is longer than UINT_MAX /* Nothing much to do, just wrap the crc32(). */ return crc32(crc, (Bytef *) buf, (unsigned) len); } unsigned int Tcl_ZlibAdler32( unsigned int adler, const unsigned char *buf, size_t len) { // TODO handle data where it is longer than UINT_MAX return adler32(adler, (Bytef *) buf, (unsigned) len); } /* *---------------------------------------------------------------------- * * ZlibCmd -- * * Implementation of the [zlib] command. * *---------------------------------------------------------------------- */ static int ZlibCmd( ClientData notUsed, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { int command, i, option, level = -1; size_t dlen; unsigned start, buffersize = 0; Byte *data; Tcl_Obj *headerDictObj; const char *extraInfoStr = NULL; static const char *const commands[] = { "adler32", "compress", "crc32", "decompress", "deflate", "gunzip", "gzip", "inflate", "push", "stream", |
︙ | ︙ | |||
2121 2122 2123 2124 2125 2126 2127 | * -> channel */ return ZlibPushSubcmd(interp, objc, objv); }; return TCL_ERROR; badLevel: | | > | 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 | * -> channel */ return ZlibPushSubcmd(interp, objc, objv); }; return TCL_ERROR; badLevel: Tcl_SetObjResult(interp, Tcl_NewStringObj("level must be 0 to 9", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMPRESSIONLEVEL", NULL); if (extraInfoStr) { Tcl_AddErrorInfo(interp, extraInfoStr); } return TCL_ERROR; badBuffer: Tcl_SetObjResult(interp, Tcl_ObjPrintf( |
︙ | ︙ | |||
2148 2149 2150 2151 2152 2153 2154 | * *---------------------------------------------------------------------- */ static int ZlibStreamSubcmd( Tcl_Interp *interp, | | | 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 | * *---------------------------------------------------------------------- */ static int ZlibStreamSubcmd( Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { static const char *const stream_formats[] = { "compress", "decompress", "deflate", "gunzip", "gzip", "inflate", NULL }; enum zlibFormats { |
︙ | ︙ | |||
2265 2266 2267 2268 2269 2270 2271 | */ if (levelObj == NULL) { level = Z_DEFAULT_COMPRESSION; } else if (Tcl_GetIntFromObj(interp, levelObj, &level) != TCL_OK) { return TCL_ERROR; } else if (level < 0 || level > 9) { | | > | 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 | */ if (levelObj == NULL) { level = Z_DEFAULT_COMPRESSION; } else if (Tcl_GetIntFromObj(interp, levelObj, &level) != TCL_OK) { return TCL_ERROR; } else if (level < 0 || level > 9) { Tcl_SetObjResult(interp, Tcl_NewStringObj("level must be 0 to 9", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMPRESSIONLEVEL", NULL); Tcl_AddErrorInfo(interp, "\n (in -level option)"); return TCL_ERROR; } /* * Construct the stream now we know its configuration. |
︙ | ︙ | |||
2302 2303 2304 2305 2306 2307 2308 | * *---------------------------------------------------------------------- */ static int ZlibPushSubcmd( Tcl_Interp *interp, | | | 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 | * *---------------------------------------------------------------------- */ static int ZlibPushSubcmd( Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { static const char *const stream_formats[] = { "compress", "decompress", "deflate", "gunzip", "gzip", "inflate", NULL }; enum zlibFormats { |
︙ | ︙ | |||
2324 2325 2326 2327 2328 2329 2330 | }; static const char *const pushDecompressOptions[] = { "-dictionary", "-header", "-level", "-limit", NULL }; const char *const *pushOptions = pushDecompressOptions; enum pushOptions {poDictionary, poHeader, poLevel, poLimit}; Tcl_Obj *headerObj = NULL, *compDictObj = NULL; | | > | 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 | }; static const char *const pushDecompressOptions[] = { "-dictionary", "-header", "-level", "-limit", NULL }; const char *const *pushOptions = pushDecompressOptions; enum pushOptions {poDictionary, poHeader, poLevel, poLimit}; Tcl_Obj *headerObj = NULL, *compDictObj = NULL; int limit = 1; size_t dummy; if (objc < 4) { Tcl_WrongNumArgs(interp, 2, objv, "mode channel ?options...?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[2], stream_formats, "mode", 0, |
︙ | ︙ | |||
2377 2378 2379 2380 2381 2382 2383 | /* * Sanity checks. */ if (mode == TCL_ZLIB_STREAM_DEFLATE && !(chanMode & TCL_WRITABLE)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | > | 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 | /* * Sanity checks. */ if (mode == TCL_ZLIB_STREAM_DEFLATE && !(chanMode & TCL_WRITABLE)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "compression may only be applied to writable channels", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "UNWRITABLE", NULL); return TCL_ERROR; } if (mode == TCL_ZLIB_STREAM_INFLATE && !(chanMode & TCL_READABLE)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "decompression may only be applied to readable channels", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "UNREADABLE", NULL); return TCL_ERROR; } /* * Parse options. */ |
︙ | ︙ | |||
2417 2418 2419 2420 2421 2422 2423 | break; case poLevel: if (Tcl_GetIntFromObj(interp, objv[i], (int*) &level) != TCL_OK) { goto genericOptionError; } if (level < 0 || level > 9) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 | break; case poLevel: if (Tcl_GetIntFromObj(interp, objv[i], (int*) &level) != TCL_OK) { goto genericOptionError; } if (level < 0 || level > 9) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "level must be 0 to 9", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMPRESSIONLEVEL", NULL); goto genericOptionError; } break; case poLimit: if (Tcl_GetIntFromObj(interp, objv[i], (int*) &limit) != TCL_OK) { |
︙ | ︙ | |||
2439 2440 2441 2442 2443 2444 2445 | goto genericOptionError; } break; case poDictionary: if (format == TCL_ZLIB_FORMAT_GZIP) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "a compression dictionary may not be set in the " | | | 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 | goto genericOptionError; } break; case poDictionary: if (format == TCL_ZLIB_FORMAT_GZIP) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "a compression dictionary may not be set in the " "gzip format", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "BADOPT", NULL); goto genericOptionError; } compDictObj = objv[i]; break; } } |
︙ | ︙ | |||
2476 2477 2478 2479 2480 2481 2482 | *---------------------------------------------------------------------- */ static int ZlibStreamCmd( ClientData cd, Tcl_Interp *interp, | | | 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 | *---------------------------------------------------------------------- */ static int ZlibStreamCmd( ClientData cd, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_ZlibStream zstream = cd; int command, count, code; Tcl_Obj *obj; static const char *const cmds[] = { "add", "checksum", "close", "eof", "finalize", "flush", |
︙ | ︙ | |||
2602 2603 2604 2605 2606 2607 2608 | return TCL_OK; } static int ZlibStreamAddCmd( ClientData cd, Tcl_Interp *interp, | | | 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 | return TCL_OK; } static int ZlibStreamAddCmd( ClientData cd, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_ZlibStream zstream = cd; int index, code, buffersize = -1, flush = -1, i; Tcl_Obj *obj, *compDictObj = NULL; static const char *const add_options[] = { "-buffer", "-dictionary", "-finalize", "-flush", "-fullflush", NULL |
︙ | ︙ | |||
2647 2648 2649 2650 2651 2652 2653 | flush = Z_FINISH; } break; case ao_buffer: /* -buffer */ if (i == objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-buffer\" option must be followed by integer " | | | | | | 2660 2661 2662 2663 2664 2665 2666 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 | flush = Z_FINISH; } break; case ao_buffer: /* -buffer */ if (i == objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-buffer\" option must be followed by integer " "decompression buffersize", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[++i], &buffersize) != TCL_OK) { return TCL_ERROR; } if (buffersize < 1 || buffersize > MAX_BUFFER_SIZE) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "buffer size must be 1 to %d", MAX_BUFFER_SIZE)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "BUFFERSIZE", NULL); return TCL_ERROR; } break; case ao_dictionary: if (i == objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-dictionary\" option must be followed by" " compression dictionary bytes", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL); return TCL_ERROR; } compDictObj = objv[++i]; break; } if (flush == -2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-flush\", \"-fullflush\" and \"-finalize\" options" " are mutually exclusive", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "EXCLUSIVE", NULL); return TCL_ERROR; } } if (flush == -1) { flush = 0; } /* * Set the compression dictionary if requested. */ if (compDictObj != NULL) { size_t len; (void) Tcl_GetByteArrayFromObj(compDictObj, &len); if (len == 0) { compDictObj = NULL; } Tcl_ZlibStreamSetCompressionDictionary(zstream, compDictObj); } |
︙ | ︙ | |||
2726 2727 2728 2729 2730 2731 2732 | return code; } static int ZlibStreamPutCmd( ClientData cd, Tcl_Interp *interp, | | | 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 | return code; } static int ZlibStreamPutCmd( ClientData cd, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { Tcl_ZlibStream zstream = cd; int index, flush = -1, i; Tcl_Obj *compDictObj = NULL; static const char *const put_options[] = { "-dictionary", "-finalize", "-flush", "-fullflush", NULL |
︙ | ︙ | |||
2771 2772 2773 2774 2775 2776 2777 | flush = Z_FINISH; } break; case po_dictionary: if (i == objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-dictionary\" option must be followed by" | | | | | | > | 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 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 | flush = Z_FINISH; } break; case po_dictionary: if (i == objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-dictionary\" option must be followed by" " compression dictionary bytes", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL); return TCL_ERROR; } compDictObj = objv[++i]; break; } if (flush == -2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-flush\", \"-fullflush\" and \"-finalize\" options" " are mutually exclusive", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "EXCLUSIVE", NULL); return TCL_ERROR; } } if (flush == -1) { flush = 0; } /* * Set the compression dictionary if requested. */ if (compDictObj != NULL) { size_t len; (void) Tcl_GetByteArrayFromObj(compDictObj, &len); if (len == 0) { compDictObj = NULL; } Tcl_ZlibStreamSetCompressionDictionary(zstream, compDictObj); } /* * Send the data to the stream core, along with any flushing directive. */ return Tcl_ZlibStreamPut(zstream, objv[objc-1], flush); } static int ZlibStreamHeaderCmd( ClientData cd, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]) { ZlibStreamHandle *zshPtr = cd; Tcl_Obj *resultObj; if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); return TCL_ERROR; } else if (zshPtr->mode != TCL_ZLIB_STREAM_INFLATE || zshPtr->format != TCL_ZLIB_FORMAT_GZIP) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "only gunzip streams can produce header information", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "BADOP", NULL); return TCL_ERROR; } TclNewObj(resultObj); ExtractHeader(&zshPtr->gzHeaderPtr->header, resultObj); Tcl_SetObjResult(interp, resultObj); |
︙ | ︙ | |||
2931 2932 2933 2934 2935 2936 2937 | * ZlibTransformInput -- * * Reader filter that does decompression. * *---------------------------------------------------------------------- */ | | | > | | 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 | * ZlibTransformInput -- * * Reader filter that does decompression. * *---------------------------------------------------------------------- */ static ssize_t ZlibTransformInput( ClientData instanceData, char *buf, size_t toRead, int *errorCodePtr) { ZlibChannelData *cd = instanceData; Tcl_DriverInputProc *inProc = Tcl_ChannelInputProc(Tcl_GetChannelType(cd->parent)); size_t copied; ssize_t readBytes, gotBytes; if (cd->mode == TCL_ZLIB_STREAM_DEFLATE) { return inProc(Tcl_GetChannelInstanceData(cd->parent), buf, toRead, errorCodePtr); } gotBytes = 0; |
︙ | ︙ | |||
3080 3081 3082 3083 3084 3085 3086 | * ZlibTransformOutput -- * * Writer filter that does compression. * *---------------------------------------------------------------------- */ | | | > | | 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 | * ZlibTransformOutput -- * * Writer filter that does compression. * *---------------------------------------------------------------------- */ static ssize_t ZlibTransformOutput( ClientData instanceData, const char *buf, size_t toWrite, int *errorCodePtr) { ZlibChannelData *cd = instanceData; Tcl_DriverOutputProc *outProc = Tcl_ChannelOutputProc(Tcl_GetChannelType(cd->parent)); int e; size_t produced; Tcl_Obj *errObj; if (cd->mode == TCL_ZLIB_STREAM_INFLATE) { return outProc(Tcl_GetChannelInstanceData(cd->parent), buf, toWrite, errorCodePtr); } |
︙ | ︙ | |||
3120 3121 3122 3123 3124 3125 3126 | } while (e == Z_OK && produced > 0 && cd->outStream.avail_in > 0); if (e == Z_OK) { return toWrite - cd->outStream.avail_in; } errObj = Tcl_NewListObj(0, NULL); | | > | | 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 | } while (e == Z_OK && produced > 0 && cd->outStream.avail_in > 0); if (e == Z_OK) { return toWrite - cd->outStream.avail_in; } errObj = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(NULL, errObj, Tcl_NewStringObj("-errorcode", TCL_STRLEN)); Tcl_ListObjAppendElement(NULL, errObj, ConvertErrorToList(e, cd->outStream.adler)); Tcl_ListObjAppendElement(NULL, errObj, Tcl_NewStringObj(cd->outStream.msg, TCL_STRLEN)); Tcl_SetChannelError(cd->parent, errObj); *errorCodePtr = EINVAL; return -1; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
3240 3241 3242 3243 3244 3245 3246 | if (optionName && strcmp(optionName, "-limit") == 0) { int newLimit; if (Tcl_GetInt(interp, value, &newLimit) != TCL_OK) { return TCL_ERROR; } else if (newLimit < 1 || newLimit > MAX_BUFFER_SIZE) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 | if (optionName && strcmp(optionName, "-limit") == 0) { int newLimit; if (Tcl_GetInt(interp, value, &newLimit) != TCL_OK) { return TCL_ERROR; } else if (newLimit < 1 || newLimit > MAX_BUFFER_SIZE) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "-limit must be between 1 and 65536", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "READLIMIT", NULL); return TCL_ERROR; } } } if (setOptionProc == NULL) { |
︙ | ︙ | |||
3314 3315 3316 3317 3318 3319 3320 | } sprintf(buf, "%lu", crc); if (optionName == NULL) { Tcl_DStringAppendElement(dsPtr, "-checksum"); Tcl_DStringAppendElement(dsPtr, buf); } else { | | | | 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 | } sprintf(buf, "%lu", crc); if (optionName == NULL) { Tcl_DStringAppendElement(dsPtr, "-checksum"); Tcl_DStringAppendElement(dsPtr, buf); } else { Tcl_DStringAppend(dsPtr, buf, TCL_STRLEN); return TCL_OK; } } if ((cd->format != TCL_ZLIB_FORMAT_GZIP) && (optionName == NULL || strcmp(optionName, "-dictionary") == 0)) { /* * Embedded NUL bytes are ok; they'll be C080-encoded. */ if (optionName == NULL) { Tcl_DStringAppendElement(dsPtr, "-dictionary"); if (cd->compDictObj) { Tcl_DStringAppendElement(dsPtr, Tcl_GetString(cd->compDictObj)); } else { Tcl_DStringAppendElement(dsPtr, ""); } } else { size_t len; const char *str = Tcl_GetStringFromObj(cd->compDictObj, &len); Tcl_DStringAppend(dsPtr, str, len); } } /* |
︙ | ︙ | |||
3644 3645 3646 3647 3648 3649 3650 | chan = Tcl_StackChannel(interp, &zlibChannelType, cd, Tcl_GetChannelMode(channel), channel); if (chan == NULL) { goto error; } cd->chan = chan; cd->parent = Tcl_GetStackedChannel(chan); | | > | 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 | chan = Tcl_StackChannel(interp, &zlibChannelType, cd, Tcl_GetChannelMode(channel), channel); if (chan == NULL) { goto error; } cd->chan = chan; cd->parent = Tcl_GetStackedChannel(chan); Tcl_SetObjResult(interp, Tcl_NewStringObj( Tcl_GetChannelName(chan), TCL_STRLEN)); return chan; error: if (cd->inBuffer) { ckfree(cd->inBuffer); inflateEnd(&cd->inStream); } |
︙ | ︙ | |||
3681 3682 3683 3684 3685 3686 3687 | * * Result: * The number of actually copied bytes, possibly less than 'toRead'. * *---------------------------------------------------------------------- */ | | | | | 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 | * * Result: * The number of actually copied bytes, possibly less than 'toRead'. * *---------------------------------------------------------------------- */ static inline size_t ResultCopy( ZlibChannelData *cd, /* The location of the buffer to read from. */ char *buf, /* The buffer to copy into */ size_t toRead) /* Number of requested bytes */ { size_t have = Tcl_DStringLength(&cd->decompressed); if (have == 0) { /* * Nothing to copy in the case of an empty buffer. */ return 0; |
︙ | ︙ | |||
3741 3742 3743 3744 3745 3746 3747 | * *---------------------------------------------------------------------- */ static int ResultGenerate( ZlibChannelData *cd, | | | 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 | * *---------------------------------------------------------------------- */ static int ResultGenerate( ZlibChannelData *cd, size_t n, int flush, int *errorCodePtr) { #define MAXBUF 1024 unsigned char buf[MAXBUF]; int e, written; Tcl_Obj *errObj; |
︙ | ︙ | |||
3815 3816 3817 3818 3819 3820 3821 | if (cd->inStream.avail_in <= 0 && flush != Z_SYNC_FLUSH) { return TCL_OK; } } handleError: errObj = Tcl_NewListObj(0, NULL); | | > | | 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 | if (cd->inStream.avail_in <= 0 && flush != Z_SYNC_FLUSH) { return TCL_OK; } } handleError: errObj = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(NULL, errObj, Tcl_NewStringObj("-errorcode", TCL_STRLEN)); Tcl_ListObjAppendElement(NULL, errObj, ConvertErrorToList(e, cd->inStream.adler)); Tcl_ListObjAppendElement(NULL, errObj, Tcl_NewStringObj(cd->inStream.msg, TCL_STRLEN)); Tcl_SetChannelError(cd->parent, errObj); *errorCodePtr = EINVAL; return TCL_ERROR; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
3888 3889 3890 3891 3892 3893 3894 | int mode, int format, int level, Tcl_Obj *dictObj, Tcl_ZlibStream *zshandle) { if (interp) { | | > | 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 | int mode, int format, int level, Tcl_Obj *dictObj, Tcl_ZlibStream *zshandle) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL); } return TCL_ERROR; } int Tcl_ZlibStreamClose( |
︙ | ︙ | |||
3956 3957 3958 3959 3960 3961 3962 | Tcl_Interp *interp, int format, Tcl_Obj *data, int level, Tcl_Obj *gzipHeaderDictObj) { if (interp) { | | > | > | 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 | Tcl_Interp *interp, int format, Tcl_Obj *data, int level, Tcl_Obj *gzipHeaderDictObj) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL); } return TCL_ERROR; } int Tcl_ZlibInflate( Tcl_Interp *interp, int format, Tcl_Obj *data, int bufferSize, Tcl_Obj *gzipHeaderDictObj) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL); } return TCL_ERROR; } unsigned int Tcl_ZlibCRC32( |
︙ | ︙ |
Changes to macosx/tclMacOSXBundle.c.
︙ | ︙ | |||
163 164 165 166 167 168 169 | */ int Tcl_MacOSXOpenBundleResources( Tcl_Interp *interp, const char *bundleName, int hasResourceFile, | | | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | */ int Tcl_MacOSXOpenBundleResources( Tcl_Interp *interp, const char *bundleName, int hasResourceFile, size_t maxPathLen, char *libraryPath) { return Tcl_MacOSXOpenVersionedBundleResources(interp, bundleName, NULL, hasResourceFile, maxPathLen, libraryPath); } /* |
︙ | ︙ | |||
197 198 199 200 201 202 203 | int Tcl_MacOSXOpenVersionedBundleResources( Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, | | | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | int Tcl_MacOSXOpenVersionedBundleResources( Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, size_t maxPathLen, char *libraryPath) { #ifdef HAVE_COREFOUNDATION CFBundleRef bundleRef, versionedBundleRef = NULL; CFStringRef bundleNameRef; CFURLRef libURL; |
︙ | ︙ |
Changes to macosx/tclMacOSXFCmd.c.
︙ | ︙ | |||
632 633 634 635 636 637 638 | static int SetOSTypeFromAny( Tcl_Interp *interp, /* Tcl interpreter */ Tcl_Obj *objPtr) /* Pointer to the object to convert */ { const char *string; | > | | 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | static int SetOSTypeFromAny( Tcl_Interp *interp, /* Tcl interpreter */ Tcl_Obj *objPtr) /* Pointer to the object to convert */ { const char *string; size_t length; int result = TCL_OK; Tcl_DString ds; Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman"); string = Tcl_GetStringFromObj(objPtr, &length); Tcl_UtfToExternalDString(encoding, string, length, &ds); if (Tcl_DStringLength(&ds) > 4) { |
︙ | ︙ |
Changes to tests/env.test.
︙ | ︙ | |||
300 301 302 303 304 305 306 307 | } array donesearch env $s return $n } 0 test env-7.2 {[219226]: links to env elements should not be removed by read} { apply {{} { set ::env(test7_2) ok upvar env(test7_2) elem | > > > > > > > > > > > | > > | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | } array donesearch env $s return $n } 0 test env-7.2 {[219226]: links to env elements should not be removed by read} { apply {{} { set ::env(test7_2) ok set ::env(test7_2,trigger) x upvar env(test7_2) elem set ::env(test7_2,trigger) try { return $elem } finally { unset -nocomplain ::env(test7_2) ::env(test7_2,trigger) } }} } ok test env-7.3 {[219226]: links to env elements should not be removed by write} { apply {{} { set ::env(test7_3) ok upvar env(test7_3) elem set ::env(test7_3,trigger) x try { return $elem } finally { unset -nocomplain ::env(test7_3) ::env(test7_3,trigger) } }} } ok # Restore the environment variables at the end of the test. foreach name [array names env] { |
︙ | ︙ |
Changes to tests/io.test.
︙ | ︙ | |||
90 91 92 93 94 95 96 | proc contents {file} { set f [open $file] fconfigure $f -translation binary set a [read $f] close $f return $a } | | | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | proc contents {file} { set f [open $file] fconfigure $f -translation binary set a [read $f] close $f return $a } test io-1.5 {Tcl_WriteChars: CheckChannelErrors} {emptyTest} { # no test, need to cause an async error. } {} set path(test1) [makeFile {} test1] test io-1.6 {Tcl_WriteChars: WriteBytes} { set f [open $path(test1) w] fconfigure $f -encoding binary |
︙ | ︙ | |||
6871 6872 6873 6874 6875 6876 6877 | set listen [socket -server [namespace code FcopyTestAccept] -myaddr 127.0.0.1 0] set in [open $thisScript] ;# 126 K set out [socket 127.0.0.1 [lindex [fconfigure $listen -sockname] 2]] catch {unset fcopyTestDone} close $listen ;# This means the socket open never really succeeds fcopy $in $out -command [namespace code FcopyTestDone] variable fcopyTestDone | | | 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 | set listen [socket -server [namespace code FcopyTestAccept] -myaddr 127.0.0.1 0] set in [open $thisScript] ;# 126 K set out [socket 127.0.0.1 [lindex [fconfigure $listen -sockname] 2]] catch {unset fcopyTestDone} close $listen ;# This means the socket open never really succeeds fcopy $in $out -command [namespace code FcopyTestDone] variable fcopyTestDone if {![info exists fcopyTestDone]} { vwait [namespace which -variable fcopyTestDone] ;# The error occurs here in the b.g. } close $in close $out set fcopyTestDone ;# 1 for error condition } 1 test io-53.6 {CopyData: error during fcopy} {stdio openpipe fcopy} { |
︙ | ︙ | |||
7551 7552 7553 7554 7555 7556 7557 | lappend res [catch {seek $c 0 start}] close $c removeFile cutsplice set res } {0 1 0} | < < | 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 | lappend res [catch {seek $c 0 start}] close $c removeFile cutsplice set res } {0 1 0} test io-70.1 {Transfer channel} {testchannel thread} { set f [makeFile {... dummy ...} cutsplice] set c [open $f r] set res {} lappend res [catch {seek $c 0 start}] testchannel cut $c |
︙ | ︙ | |||
7770 7771 7772 7773 7774 7775 7776 | } [lrange $expected 0 end] } test io-73.1 {channel Tcl_Obj SetChannelFromAny} {} { # Test for Bug 1847044 - don't spoil type unless we have a valid channel catch {close [lreplace [list a] 0 end]} } {1} | < | | 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 | } [lrange $expected 0 end] } test io-73.1 {channel Tcl_Obj SetChannelFromAny} {} { # Test for Bug 1847044 - don't spoil type unless we have a valid channel catch {close [lreplace [list a] 0 end]} } {1} test io-73.2 {channel Tcl_Obj SetChannelFromAny, bug 2407783} -setup { # Invalidate intrep of 'channel' Tcl_Obj when transiting between interpreters. set f [open [info script] r] } -body { interp create foo seek $f 0 set code [catch {interp eval foo [list seek $f 0]} msg] # The string map converts the changing channel handle to a fixed string list $code [string map [list $f @@] $msg] } -cleanup { close $f } -result {1 {can not find channel named "@@"}} # ### ### ### ######### ######### ######### # cleanup foreach file [list fooBar longfile script script2 output test1 pipe my_script \ test2 test3 cat stdout kyrillic.txt utf8-fcopy.txt utf8-rp.txt] { removeFile $file } cleanupTests } namespace delete ::tcl::test::io return |
Changes to unix/Makefile.in.
︙ | ︙ | |||
1188 1189 1190 1191 1192 1193 1194 1195 | tclLoadDl2.o: $(UNIX_DIR)/tclLoadDl2.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDl2.c tclLoadDld.o: $(UNIX_DIR)/tclLoadDld.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDld.c tclLoadDyld.o: $(UNIX_DIR)/tclLoadDyld.c | > > | | 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 | tclLoadDl2.o: $(UNIX_DIR)/tclLoadDl2.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDl2.c tclLoadDld.o: $(UNIX_DIR)/tclLoadDld.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDld.c # Can explicitly list this: we know we'll only ever compile this file with # something that understands deprecated declarations as it is OSX-specific. tclLoadDyld.o: $(UNIX_DIR)/tclLoadDyld.c $(CC) -c $(CC_SWITCHES) -Wno-deprecated-declarations $(UNIX_DIR)/tclLoadDyld.c tclLoadNone.o: $(GENERIC_DIR)/tclLoadNone.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLoadNone.c tclLoadOSF.o: $(UNIX_DIR)/tclLoadOSF.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadOSF.c |
︙ | ︙ |
Changes to unix/dltest/pkga.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | #include "tcl.h" /* * Prototypes for procedures defined later in this file: */ static int Pkga_EqObjCmd(ClientData clientData, | | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include "tcl.h" /* * Prototypes for procedures defined later in this file: */ static int Pkga_EqObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int Pkga_QuoteObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* *---------------------------------------------------------------------- * * Pkga_EqObjCmd -- * * This procedure is invoked to process the "pkga_eq" Tcl command. It |
︙ | ︙ | |||
39 40 41 42 43 44 45 | *---------------------------------------------------------------------- */ static int Pkga_EqObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | *---------------------------------------------------------------------- */ static int Pkga_EqObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int result; const char *str1, *str2; size_t len1, len2; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string1 string2"); return TCL_ERROR; } str1 = Tcl_GetStringFromObj(objv[1], &len1); |
︙ | ︙ | |||
83 84 85 86 87 88 89 | *---------------------------------------------------------------------- */ static int Pkga_QuoteObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | *---------------------------------------------------------------------- */ static int Pkga_QuoteObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings. */ { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "value"); return TCL_ERROR; } Tcl_SetObjResult(interp, objv[1]); |
︙ | ︙ |
Changes to unix/dltest/pkgb.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | #include "tcl.h" /* * Prototypes for procedures defined later in this file: */ static int Pkgb_SubObjCmd(ClientData clientData, | | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include "tcl.h" /* * Prototypes for procedures defined later in this file: */ static int Pkgb_SubObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int Pkgb_UnsafeObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int Pkgb_DemoObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* *---------------------------------------------------------------------- * * Pkgb_SubObjCmd -- * * This procedure is invoked to process the "pkgb_sub" Tcl command. It |
︙ | ︙ | |||
45 46 47 48 49 50 51 | # define Tcl_GetErrorLine(interp) ((interp)->errorLine) #endif static int Pkgb_SubObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | # define Tcl_GetErrorLine(interp) ((interp)->errorLine) #endif static int Pkgb_SubObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int first, second; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "num num"); return TCL_ERROR; |
︙ | ︙ | |||
86 87 88 89 90 91 92 | *---------------------------------------------------------------------- */ static int Pkgb_UnsafeObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | < < < < | 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 | *---------------------------------------------------------------------- */ static int Pkgb_UnsafeObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { return Tcl_EvalEx(interp, "list unsafe command invoked", -1, TCL_EVAL_GLOBAL); } static int Pkgb_DemoObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *first; if (Tcl_ListObjIndex(NULL, Tcl_GetEncodingSearchPath(), 0, &first) == TCL_OK) { Tcl_SetObjResult(interp, first); } return TCL_OK; } /* *---------------------------------------------------------------------- * * Pkgb_Init -- |
︙ | ︙ |
Changes to unix/dltest/pkgc.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | #include "tcl.h" /* * Prototypes for procedures defined later in this file: */ static int Pkgc_SubObjCmd(ClientData clientData, | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include "tcl.h" /* * Prototypes for procedures defined later in this file: */ static int Pkgc_SubObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int Pkgc_UnsafeObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* *---------------------------------------------------------------------- * * Pkgc_SubObjCmd -- * * This procedure is invoked to process the "pkgc_sub" Tcl command. It |
︙ | ︙ | |||
39 40 41 42 43 44 45 | *---------------------------------------------------------------------- */ static int Pkgc_SubObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | *---------------------------------------------------------------------- */ static int Pkgc_SubObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int first, second; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "num num"); return TCL_ERROR; |
︙ | ︙ | |||
77 78 79 80 81 82 83 | *---------------------------------------------------------------------- */ static int Pkgc_UnsafeObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | *---------------------------------------------------------------------- */ static int Pkgc_UnsafeObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_SetObjResult(interp, Tcl_NewStringObj("unsafe command invoked", TCL_STRLEN)); return TCL_OK; } /* *---------------------------------------------------------------------- * * Pkgc_Init -- |
︙ | ︙ |
Changes to unix/dltest/pkgd.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | #include "tcl.h" /* * Prototypes for procedures defined later in this file: */ static int Pkgd_SubObjCmd(ClientData clientData, | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include "tcl.h" /* * Prototypes for procedures defined later in this file: */ static int Pkgd_SubObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int Pkgd_UnsafeObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* *---------------------------------------------------------------------- * * Pkgd_SubObjCmd -- * * This procedure is invoked to process the "pkgd_sub" Tcl command. It |
︙ | ︙ | |||
39 40 41 42 43 44 45 | *---------------------------------------------------------------------- */ static int Pkgd_SubObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | *---------------------------------------------------------------------- */ static int Pkgd_SubObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int first, second; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "num num"); return TCL_ERROR; |
︙ | ︙ | |||
77 78 79 80 81 82 83 | *---------------------------------------------------------------------- */ static int Pkgd_UnsafeObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | > | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | *---------------------------------------------------------------------- */ static int Pkgd_UnsafeObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_SetObjResult(interp, Tcl_NewStringObj("unsafe command invoked", TCL_STRLEN)); return TCL_OK; } /* *---------------------------------------------------------------------- * * Pkgd_Init -- |
︙ | ︙ |
Changes to unix/dltest/pkgua.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | #include "tcl.h" /* * Prototypes for procedures defined later in this file: */ static int PkguaEqObjCmd(ClientData clientData, | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include "tcl.h" /* * Prototypes for procedures defined later in this file: */ static int PkguaEqObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int PkguaQuoteObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); /* * In the following hash table we are going to store a struct that holds all * the command tokens created by Tcl_CreateObjCommand in an interpreter, * indexed by the interpreter. In this way, we can find which command tokens * we have registered in a specific interpreter, in order to unload them. We * need to keep the various command tokens we have registered, as they are the |
︙ | ︙ | |||
115 116 117 118 119 120 121 | *---------------------------------------------------------------------- */ static int PkguaEqObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | *---------------------------------------------------------------------- */ static int PkguaEqObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { int result; const char *str1, *str2; size_t len1, len2; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string1 string2"); return TCL_ERROR; } str1 = Tcl_GetStringFromObj(objv[1], &len1); |
︙ | ︙ | |||
159 160 161 162 163 164 165 | *---------------------------------------------------------------------- */ static int PkguaQuoteObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | *---------------------------------------------------------------------- */ static int PkguaQuoteObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings. */ { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "value"); return TCL_ERROR; } Tcl_SetObjResult(interp, objv[1]); |
︙ | ︙ |
Changes to unix/tclLoadDl.c.
︙ | ︙ | |||
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | /* * First try the full path the user gave us. This is particularly * important if the cwd is inside a vfs, and we are trying to load using a * relative path. */ native = Tcl_FSGetNativePath(pathPtr); /* * Use (RTLD_NOW|RTLD_LOCAL) as default, see [Bug #3216070] */ if (flags & TCL_LOAD_GLOBAL) { dlopenflags |= RTLD_GLOBAL; } else { dlopenflags |= RTLD_LOCAL; } if (flags & TCL_LOAD_LAZY) { dlopenflags |= RTLD_LAZY; | > > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | /* * First try the full path the user gave us. This is particularly * important if the cwd is inside a vfs, and we are trying to load using a * relative path. */ native = Tcl_FSGetNativePath(pathPtr); /* * Use (RTLD_NOW|RTLD_LOCAL) as default, see [Bug #3216070] */ if (flags & TCL_LOAD_GLOBAL) { dlopenflags |= RTLD_GLOBAL; } else { dlopenflags |= RTLD_LOCAL; } if (flags & TCL_LOAD_LAZY) { dlopenflags |= RTLD_LAZY; |
︙ | ︙ | |||
104 105 106 107 108 109 110 | * string the user gave us which hopefully refers to a file on the * binary path. */ Tcl_DString ds; const char *fileName = Tcl_GetString(pathPtr); | | > > | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | * string the user gave us which hopefully refers to a file on the * binary path. */ Tcl_DString ds; const char *fileName = Tcl_GetString(pathPtr); native = Tcl_UtfToExternalDString(NULL, fileName, TCL_STRLEN, &ds); /* * Use (RTLD_NOW|RTLD_LOCAL) as default, see [Bug #3216070] */ handle = dlopen(native, dlopenflags); Tcl_DStringFree(&ds); } if (handle == NULL) { /* * Write the string to a variable first to work around a compiler bug |
︙ | ︙ | |||
173 174 175 176 177 178 179 | /* * Some platforms still add an underscore to the beginning of symbol * names. If we can't find a name without an underscore, try again with * the underscore. */ | | | | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | /* * Some platforms still add an underscore to the beginning of symbol * names. If we can't find a name without an underscore, try again with * the underscore. */ native = Tcl_UtfToExternalDString(NULL, symbol, TCL_STRLEN, &ds); proc = dlsym(handle, native); /* INTL: Native. */ if (proc == NULL) { Tcl_DStringInit(&newName); TclDStringAppendLiteral(&newName, "_"); native = Tcl_DStringAppend(&newName, native, TCL_STRLEN); proc = dlsym(handle, native); /* INTL: Native. */ Tcl_DStringFree(&newName); } Tcl_DStringFree(&ds); if (proc == NULL && interp != NULL) { const char *errorStr = dlerror(); |
︙ | ︙ |
Changes to unix/tclLoadDyld.c.
︙ | ︙ | |||
178 179 180 181 182 183 184 | * First try the full path the user gave us. This is particularly * important if the cwd is inside a vfs, and we are trying to load using a * relative path. */ nativePath = Tcl_FSGetNativePath(pathPtr); nativeFileName = Tcl_UtfToExternalDString(NULL, Tcl_GetString(pathPtr), | | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | * First try the full path the user gave us. This is particularly * important if the cwd is inside a vfs, and we are trying to load using a * relative path. */ nativePath = Tcl_FSGetNativePath(pathPtr); nativeFileName = Tcl_UtfToExternalDString(NULL, Tcl_GetString(pathPtr), TCL_STRLEN, &ds); #if TCL_DYLD_USE_DLFCN /* * Use (RTLD_NOW|RTLD_LOCAL) as default, see [Bug #3216070] */ if (flags & TCL_LOAD_GLOBAL) { |
︙ | ︙ | |||
246 247 248 249 250 251 252 253 254 255 256 257 258 259 | * attempt to load it as a MH_BUNDLE. */ err = NSCreateObjectFileImageFromFile(nativePath, &dyldObjFileImage); if (err == NSObjectFileImageSuccess && dyldObjFileImage) { int nsflags = NSLINKMODULE_OPTION_RETURN_ON_ERROR; if (!(flags & 1)) nsflags |= NSLINKMODULE_OPTION_PRIVATE; if (!(flags & 2)) nsflags |= NSLINKMODULE_OPTION_BINDNOW; module = NSLinkModule(dyldObjFileImage, nativePath, nsflags); NSDestroyObjectFileImage(dyldObjFileImage); if (module) { modulePtr = ckalloc(sizeof(Tcl_DyldModuleHandle)); modulePtr->module = module; | > | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | * attempt to load it as a MH_BUNDLE. */ err = NSCreateObjectFileImageFromFile(nativePath, &dyldObjFileImage); if (err == NSObjectFileImageSuccess && dyldObjFileImage) { int nsflags = NSLINKMODULE_OPTION_RETURN_ON_ERROR; if (!(flags & 1)) nsflags |= NSLINKMODULE_OPTION_PRIVATE; if (!(flags & 2)) nsflags |= NSLINKMODULE_OPTION_BINDNOW; module = NSLinkModule(dyldObjFileImage, nativePath, nsflags); NSDestroyObjectFileImage(dyldObjFileImage); if (module) { modulePtr = ckalloc(sizeof(Tcl_DyldModuleHandle)); modulePtr->module = module; |
︙ | ︙ | |||
288 289 290 291 292 293 294 | *unloadProcPtr = &UnloadFile; *loadHandle = newHandle; result = TCL_OK; } else { Tcl_Obj *errObj = Tcl_NewObj(); if (errMsg != NULL) { | | | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | *unloadProcPtr = &UnloadFile; *loadHandle = newHandle; result = TCL_OK; } else { Tcl_Obj *errObj = Tcl_NewObj(); if (errMsg != NULL) { Tcl_AppendToObj(errObj, errMsg, TCL_STRLEN); } #if TCL_DYLD_USE_NSMODULE if (objFileImageErrMsg) { Tcl_AppendPrintfToObj(errObj, "\nNSCreateObjectFileImageFromFile() error: %s", objFileImageErrMsg); } |
︙ | ︙ | |||
333 334 335 336 337 338 339 | { Tcl_DyldLoadHandle *dyldLoadHandle = loadHandle->clientData; Tcl_PackageInitProc *proc = NULL; const char *errMsg = NULL; Tcl_DString ds; const char *native; | | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 | { Tcl_DyldLoadHandle *dyldLoadHandle = loadHandle->clientData; Tcl_PackageInitProc *proc = NULL; const char *errMsg = NULL; Tcl_DString ds; const char *native; native = Tcl_UtfToExternalDString(NULL, symbol, TCL_STRLEN, &ds); if (dyldLoadHandle->dlHandle) { #if TCL_DYLD_USE_DLFCN proc = dlsym(dyldLoadHandle->dlHandle, native); if (!proc) { errMsg = dlerror(); } #endif /* TCL_DYLD_USE_DLFCN */ } else { #if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) NSSymbol nsSymbol = NULL; Tcl_DString newName; /* * dyld adds an underscore to the beginning of symbol names. */ Tcl_DStringInit(&newName); TclDStringAppendLiteral(&newName, "_"); native = Tcl_DStringAppend(&newName, native, TCL_STRLEN); if (dyldLoadHandle->dyldLibHeader) { nsSymbol = NSLookupSymbolInImage(dyldLoadHandle->dyldLibHeader, native, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); if (nsSymbol) { /* * Until dyld supports unloading of MY_DYLIB binaries, the |
︙ | ︙ | |||
507 508 509 510 511 512 513 | *---------------------------------------------------------------------- */ #ifdef TCL_LOAD_FROM_MEMORY MODULE_SCOPE void * TclpLoadMemoryGetBuffer( Tcl_Interp *interp, /* Used for error reporting. */ | | | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 | *---------------------------------------------------------------------- */ #ifdef TCL_LOAD_FROM_MEMORY MODULE_SCOPE void * TclpLoadMemoryGetBuffer( Tcl_Interp *interp, /* Used for error reporting. */ size_t size) /* Size of desired buffer. */ { void *buffer = NULL; /* * NSCreateObjectFileImageFromMemory is available but always fails * prior to Darwin 7. */ |
︙ | ︙ | |||
554 555 556 557 558 559 560 | #ifdef TCL_LOAD_FROM_MEMORY MODULE_SCOPE int TclpLoadMemory( Tcl_Interp *interp, /* Used for error reporting. */ void *buffer, /* Buffer containing the desired code * (allocated with TclpLoadMemoryGetBuffer). */ | | | | | | 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 | #ifdef TCL_LOAD_FROM_MEMORY MODULE_SCOPE int TclpLoadMemory( Tcl_Interp *interp, /* Used for error reporting. */ void *buffer, /* Buffer containing the desired code * (allocated with TclpLoadMemoryGetBuffer). */ size_t size, /* Allocation size of buffer. */ size_t codeSize, /* Size of code data read into buffer or * TCL_STRLEN if an error occurred and the * buffer should just be freed. */ Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded * file which will be passed back to * (*unloadProcPtr)() to unload the file. */ Tcl_FSUnloadFileProc **unloadProcPtr, /* Filled with address of Tcl_FSUnloadFileProc * function which should be used for this * file. */ |
︙ | ︙ | |||
579 580 581 582 583 584 585 | const char *objFileImageErrMsg = NULL; int nsflags = NSLINKMODULE_OPTION_RETURN_ON_ERROR; /* * Try to create an object file image that we can load from. */ | | | 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 | const char *objFileImageErrMsg = NULL; int nsflags = NSLINKMODULE_OPTION_RETURN_ON_ERROR; /* * Try to create an object file image that we can load from. */ if (codeSize != TCL_STRLEN) { NSObjectFileImageReturnCode err = NSObjectFileImageSuccess; const struct fat_header *fh = buffer; uint32_t ms = 0; #ifndef __LP64__ const struct mach_header *mh = NULL; # define mh_size sizeof(struct mach_header) # define mh_magic MH_MAGIC |
︙ | ︙ | |||
668 669 670 671 672 673 674 | return TCL_ERROR; } /* * Extract the module we want from the image of the object file. */ | > | > > | > | | 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | return TCL_ERROR; } /* * Extract the module we want from the image of the object file. */ if (!(flags & 1)) { nsflags |= NSLINKMODULE_OPTION_PRIVATE; } if (!(flags & 2)) { nsflags |= NSLINKMODULE_OPTION_BINDNOW; } module = NSLinkModule(dyldObjFileImage, "[Memory Based Bundle]", nsflags); NSDestroyObjectFileImage(dyldObjFileImage); if (!module) { NSLinkEditErrors editError; int errorNumber; const char *errorName, *errMsg; NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, TCL_STRLEN)); return TCL_ERROR; } /* * Stash the module reference within the load handle we create and return. */ |
︙ | ︙ |
Changes to unix/tclLoadNext.c.
︙ | ︙ | |||
79 80 81 82 83 84 85 | * Let the OS loader examine the binary search path for whatever * string the user gave us which hopefully refers to a file on the * binary path */ Tcl_DString ds; | | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | * Let the OS loader examine the binary search path for whatever * string the user gave us which hopefully refers to a file on the * binary path */ Tcl_DString ds; native = Tcl_UtfToExternalDString(NULL, fileName, TCL_STRLEN, &ds); files = {native,NULL}; result = rld_load(errorStream, &header, files, NULL); Tcl_DStringFree(&ds); } if (!result) { char *data; |
︙ | ︙ |
Changes to unix/tclLoadOSF.c.
︙ | ︙ | |||
96 97 98 99 100 101 102 | * Let the OS loader examine the binary search path for whatever * string the user gave us which hopefully refers to a file on the * binary path */ Tcl_DString ds; | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | * Let the OS loader examine the binary search path for whatever * string the user gave us which hopefully refers to a file on the * binary path */ Tcl_DString ds; native = Tcl_UtfToExternalDString(NULL, fileName, TCL_STRLEN, &ds); lm = (Tcl_PackageInitProc *) load(native, LDR_NOFLAGS); Tcl_DStringFree(&ds); } if (lm == LDR_NULL_MODULE) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't load file \"%s\": %s", |
︙ | ︙ |
Changes to unix/tclLoadShl.c.
︙ | ︙ | |||
82 83 84 85 86 87 88 | * Let the OS loader examine the binary search path for whatever * string the user gave us which hopefully refers to a file on the * binary path. */ Tcl_DString ds; | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | * Let the OS loader examine the binary search path for whatever * string the user gave us which hopefully refers to a file on the * binary path. */ Tcl_DString ds; native = Tcl_UtfToExternalDString(NULL, fileName, TCL_STRLEN, &ds); handle = shl_load(native, BIND_DEFERRED|BIND_VERBOSE|DYNAMIC_PATH, 0L); Tcl_DStringFree(&ds); } if (handle == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't load file \"%s\": %s", |
︙ | ︙ | |||
136 137 138 139 140 141 142 | * of exported symbols while others don't; try both forms of each name. */ if (shl_findsym(&handle, symbol, (short) TYPE_PROCEDURE, (void *) &proc) != 0) { Tcl_DStringInit(&newName); TclDStringAppendLiteral(&newName, "_"); | | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | * of exported symbols while others don't; try both forms of each name. */ if (shl_findsym(&handle, symbol, (short) TYPE_PROCEDURE, (void *) &proc) != 0) { Tcl_DStringInit(&newName); TclDStringAppendLiteral(&newName, "_"); Tcl_DStringAppend(&newName, symbol, TCL_STRLEN); if (shl_findsym(&handle, Tcl_DStringValue(&newName), (short) TYPE_PROCEDURE, (void *) &proc) != 0) { proc = NULL; } Tcl_DStringFree(&newName); } if (proc == NULL && interp != NULL) { |
︙ | ︙ |
Changes to unix/tclUnixChan.c.
︙ | ︙ | |||
92 93 94 95 96 97 98 | Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL); \ } /* * Static routines for this file: */ | | | < | < | < | < | < | < | < | > > < < < < < < | 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 | Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL); \ } /* * Static routines for this file: */ static Tcl_DriverBlockModeProc FileBlockModeProc; static Tcl_DriverCloseProc FileCloseProc; static Tcl_DriverGetHandleProc FileGetHandleProc; static Tcl_DriverInputProc FileInputProc; static Tcl_DriverOutputProc FileOutputProc; static Tcl_DriverSeekProc FileSeekProc; static Tcl_DriverTruncateProc FileTruncateProc; static Tcl_DriverWideSeekProc FileWideSeekProc; static Tcl_DriverWatchProc FileWatchProc; #ifdef SUPPORTS_TTY static Tcl_DriverGetOptionProc TtyGetOptionProc; static Tcl_DriverSetOptionProc TtySetOptionProc; static void TtyGetAttributes(int fd, TtyAttrs *ttyPtr); static int TtyGetBaud(speed_t speed); static speed_t TtyGetSpeed(int baud); static void TtyInit(int fd); static void TtyModemStatusStr(int status, Tcl_DString *dsPtr); static int TtyParseMode(Tcl_Interp *interp, const char *mode, TtyAttrs *ttyPtr); static void TtySetAttributes(int fd, TtyAttrs *ttyPtr); #endif /* SUPPORTS_TTY */ /* * This structure describes the channel type structure for file based IO: */ static const Tcl_ChannelType fileChannelType = { |
︙ | ︙ | |||
227 228 229 230 231 232 233 | * * Side effects: * Reads input from the input device of the channel. * *---------------------------------------------------------------------- */ | | | | | | | 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 247 248 249 250 251 252 | * * Side effects: * Reads input from the input device of the channel. * *---------------------------------------------------------------------- */ static ssize_t FileInputProc( ClientData instanceData, /* File state. */ char *buf, /* Where to store data read. */ size_t toRead, /* How much space is available in the * buffer? */ int *errorCodePtr) /* Where to store error code. */ { FileState *fsPtr = instanceData; ssize_t bytesRead; /* How many bytes were actually read from the * input device? */ *errorCodePtr = 0; /* * Assume there is always enough input available. This will block * appropriately, and read will unblock as soon as a short read is * possible, if the channel is in blocking mode. If the channel is * nonblocking, the read will never block. */ bytesRead = read(fsPtr->fd, buf, toRead); if (bytesRead != -1) { return bytesRead; } *errorCodePtr = errno; return -1; } /* |
︙ | ︙ | |||
274 275 276 277 278 279 280 | * * Side effects: * Writes output on the output device of the channel. * *---------------------------------------------------------------------- */ | | | | | | | | | | 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 293 294 295 296 297 298 299 | * * Side effects: * Writes output on the output device of the channel. * *---------------------------------------------------------------------- */ static ssize_t FileOutputProc( ClientData instanceData, /* File state. */ const char *buf, /* The data buffer. */ size_t toWrite, /* How many bytes to write? */ int *errorCodePtr) /* Where to store error code. */ { FileState *fsPtr = instanceData; ssize_t written; *errorCodePtr = 0; if (toWrite == 0) { /* * Do not try to write nothing into a file. STREAM based * implementations will considers this as EOF (if there is a pipe * behind the file). [Bug 465765] */ return 0; } written = write(fsPtr->fd, buf, toWrite); if (written != -1) { return written; } *errorCodePtr = errno; return -1; } /* |
︙ | ︙ | |||
577 578 579 580 581 582 583 | Tcl_Interp *interp, /* For error reporting - can be NULL. */ const char *optionName, /* Which option to set? */ const char *value) /* New value for option. */ { FileState *fsPtr = instanceData; unsigned int len, vlen; TtyAttrs tty; | | | 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | Tcl_Interp *interp, /* For error reporting - can be NULL. */ const char *optionName, /* Which option to set? */ const char *value) /* New value for option. */ { FileState *fsPtr = instanceData; unsigned int len, vlen; TtyAttrs tty; size_t argc; const char **argv; struct termios iostate; len = strlen(optionName); vlen = strlen(value); /* |
︙ | ︙ |
Changes to unix/tclUnixCompat.c.
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 | /* * Per-thread private storage used to store values returned from MT-unsafe * library calls. */ #ifdef TCL_THREADS typedef struct { struct passwd pwd; #if defined(HAVE_GETPWNAM_R_5) || defined(HAVE_GETPWUID_R_5) #define NEED_PW_CLEANER 1 char *pbuf; | > > > | | | | | | 43 44 45 46 47 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 | /* * Per-thread private storage used to store values returned from MT-unsafe * library calls. */ #ifdef TCL_THREADS #define STANDARD_BUFFER_SIZE 2048 #define INITIAL_PWGR_BUFFER_SIZE 1024 typedef struct { struct passwd pwd; #if defined(HAVE_GETPWNAM_R_5) || defined(HAVE_GETPWUID_R_5) #define NEED_PW_CLEANER 1 char *pbuf; size_t pbuflen; #else char pbuf[STANDARD_BUFFER_SIZE]; #endif struct group grp; #if defined(HAVE_GETGRNAM_R_5) || defined(HAVE_GETGRGID_R_5) #define NEED_GR_CLEANER 1 char *gbuf; size_t gbuflen; #else char gbuf[STANDARD_BUFFER_SIZE]; #endif #if !defined(HAVE_MTSAFE_GETHOSTBYNAME) || !defined(HAVE_MTSAFE_GETHOSTBYADDR) struct hostent hent; char hbuf[STANDARD_BUFFER_SIZE]; #endif } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; #if ((!defined(HAVE_GETHOSTBYNAME_R) || !defined(HAVE_GETHOSTBYADDR_R)) && \ (!defined(HAVE_MTSAFE_GETHOSTBYNAME) || \ !defined(HAVE_MTSAFE_GETHOSTBYADDR))) || \ |
︙ | ︙ | |||
95 96 97 98 99 100 101 | #undef NEED_COPYGRP #undef NEED_COPYHOSTENT #undef NEED_COPYPWD #undef NEED_COPYSTRING #if !defined(HAVE_GETGRNAM_R_5) && !defined(HAVE_GETGRNAM_R_4) #define NEED_COPYGRP 1 | | > | > | | | | | 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 | #undef NEED_COPYGRP #undef NEED_COPYHOSTENT #undef NEED_COPYPWD #undef NEED_COPYSTRING #if !defined(HAVE_GETGRNAM_R_5) && !defined(HAVE_GETGRNAM_R_4) #define NEED_COPYGRP 1 static int CopyGrp(struct group *tgtPtr, char *buf, size_t buflen); #endif #if !defined(HAVE_GETPWNAM_R_5) && !defined(HAVE_GETPWNAM_R_4) #define NEED_COPYPWD 1 static int CopyPwd(struct passwd *tgtPtr, char *buf, size_t buflen); #endif static ssize_t CopyArray(char **src, int elsize, char *buf, size_t buflen); static int CopyHostent(struct hostent *tgtPtr, char *buf, size_t buflen); static ssize_t CopyString(const char *src, char *buf, size_t buflen); #endif #ifdef NEED_PW_CLEANER static void FreePwBuf(ClientData ignored); #endif #ifdef NEED_GR_CLEANER |
︙ | ︙ | |||
191 192 193 194 195 196 197 | /* * How to allocate a buffer of the right initial size. If you want the * gory detail, see http://www.opengroup.org/austin/docs/austin_328.txt * and weep. */ if (tsdPtr->pbuf == NULL) { | | > > | > | | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | /* * How to allocate a buffer of the right initial size. If you want the * gory detail, see http://www.opengroup.org/austin/docs/austin_328.txt * and weep. */ if (tsdPtr->pbuf == NULL) { long sizeMax = sysconf(_SC_GETPW_R_SIZE_MAX); if (sizeMax < 1) { tsdPtr->pbuflen = INITIAL_PWGR_BUFFER_SIZE; } else { tsdPtr->pbuflen = (size_t) sizeMax; } tsdPtr->pbuf = ckalloc(tsdPtr->pbuflen); Tcl_CreateThreadExitHandler(FreePwBuf, NULL); } while (1) { int e = getpwnam_r(name, &tsdPtr->pwd, tsdPtr->pbuf, tsdPtr->pbuflen, &pwPtr); |
︙ | ︙ | |||
271 272 273 274 275 276 277 | /* * How to allocate a buffer of the right initial size. If you want the * gory detail, see http://www.opengroup.org/austin/docs/austin_328.txt * and weep. */ if (tsdPtr->pbuf == NULL) { | | > > | > | | 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | /* * How to allocate a buffer of the right initial size. If you want the * gory detail, see http://www.opengroup.org/austin/docs/austin_328.txt * and weep. */ if (tsdPtr->pbuf == NULL) { long sizeMax = sysconf(_SC_GETPW_R_SIZE_MAX); if (sizeMax < 1) { tsdPtr->pbuflen = INITIAL_PWGR_BUFFER_SIZE; } else { tsdPtr->pbuflen = (size_t) sizeMax; } tsdPtr->pbuf = ckalloc(tsdPtr->pbuflen); Tcl_CreateThreadExitHandler(FreePwBuf, NULL); } while (1) { int e = getpwuid_r(uid, &tsdPtr->pwd, tsdPtr->pbuf, tsdPtr->pbuflen, &pwPtr); |
︙ | ︙ | |||
374 375 376 377 378 379 380 | /* * How to allocate a buffer of the right initial size. If you want the * gory detail, see http://www.opengroup.org/austin/docs/austin_328.txt * and weep. */ if (tsdPtr->gbuf == NULL) { | | > > | > | | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | /* * How to allocate a buffer of the right initial size. If you want the * gory detail, see http://www.opengroup.org/austin/docs/austin_328.txt * and weep. */ if (tsdPtr->gbuf == NULL) { long sizeMax = sysconf(_SC_GETGR_R_SIZE_MAX); if (sizeMax < 1) { tsdPtr->gbuflen = INITIAL_PWGR_BUFFER_SIZE; } else { tsdPtr->gbuflen = (size_t) sizeMax; } tsdPtr->gbuf = ckalloc(tsdPtr->gbuflen); Tcl_CreateThreadExitHandler(FreeGrBuf, NULL); } while (1) { int e = getgrnam_r(name, &tsdPtr->grp, tsdPtr->gbuf, tsdPtr->gbuflen, &grPtr); |
︙ | ︙ | |||
454 455 456 457 458 459 460 | /* * How to allocate a buffer of the right initial size. If you want the * gory detail, see http://www.opengroup.org/austin/docs/austin_328.txt * and weep. */ if (tsdPtr->gbuf == NULL) { | | > > | > | | 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 | /* * How to allocate a buffer of the right initial size. If you want the * gory detail, see http://www.opengroup.org/austin/docs/austin_328.txt * and weep. */ if (tsdPtr->gbuf == NULL) { long sizeMax = sysconf(_SC_GETGR_R_SIZE_MAX); if (sizeMax < 1) { tsdPtr->gbuflen = INITIAL_PWGR_BUFFER_SIZE; } else { tsdPtr->gbuflen = (size_t) sizeMax; } tsdPtr->gbuf = ckalloc(tsdPtr->gbuflen); Tcl_CreateThreadExitHandler(FreeGrBuf, NULL); } while (1) { int e = getgrgid_r(gid, &tsdPtr->grp, tsdPtr->gbuf, tsdPtr->gbuflen, &grPtr); |
︙ | ︙ | |||
677 678 679 680 681 682 683 | #define NEED_COPYARRAY 1 #define NEED_COPYSTRING 1 static int CopyGrp( struct group *tgtPtr, char *buf, | | | | 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 | #define NEED_COPYARRAY 1 #define NEED_COPYSTRING 1 static int CopyGrp( struct group *tgtPtr, char *buf, size_t buflen) { register char *p = buf; register ssize_t copied, len = 0; /* * Copy username. */ copied = CopyString(tgtPtr->gr_name, p, buflen - len); if (copied == -1) { |
︙ | ︙ | |||
711 712 713 714 715 716 717 | p = buf + len; /* * Copy group members. */ PadBuffer(p, len, sizeof(char *)); | | | 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 | p = buf + len; /* * Copy group members. */ PadBuffer(p, len, sizeof(char *)); copied = CopyArray((char **)tgtPtr->gr_mem, TCL_STRLEN, p, buflen - len); if (copied == -1) { goto range; } tgtPtr->gr_mem = (copied > 0) ? (char **)p : NULL; return 0; |
︙ | ︙ | |||
750 751 752 753 754 755 756 | #define NEED_COPYSTRING 1 #define NEED_COPYARRAY 1 static int CopyHostent( struct hostent *tgtPtr, char *buf, | | | | | 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 | #define NEED_COPYSTRING 1 #define NEED_COPYARRAY 1 static int CopyHostent( struct hostent *tgtPtr, char *buf, size_t buflen) { char *p = buf; ssize_t copied, len = 0; copied = CopyString(tgtPtr->h_name, p, buflen - len); if (copied == -1) { goto range; } tgtPtr->h_name = (copied > 0) ? p : NULL; len += copied; p = buf + len; PadBuffer(p, len, sizeof(char *)); copied = CopyArray(tgtPtr->h_aliases, TCL_STRLEN, p, buflen - len); if (copied == -1) { goto range; } tgtPtr->h_aliases = (copied > 0) ? (char **)p : NULL; len += copied; p += len; |
︙ | ︙ | |||
812 813 814 815 816 817 818 | #ifdef NEED_COPYPWD #define NEED_COPYSTRING 1 static int CopyPwd( struct passwd *tgtPtr, char *buf, | | | | 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 | #ifdef NEED_COPYPWD #define NEED_COPYSTRING 1 static int CopyPwd( struct passwd *tgtPtr, char *buf, size_t buflen) { char *p = buf; ssize_t copied, len = 0; copied = CopyString(tgtPtr->pw_name, p, buflen - len); if (copied == -1) { range: errno = ERANGE; return -1; } |
︙ | ︙ | |||
871 872 873 874 875 876 877 | * Side effects: * None. * *--------------------------------------------------------------------------- */ #ifdef NEED_COPYARRAY | > | | | | | | | | 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 | * Side effects: * None. * *--------------------------------------------------------------------------- */ #ifdef NEED_COPYARRAY static ssize_t CopyArray( char **src, /* Array of elements to copy. */ size_t elsize, /* Size of each element, or TCL_STRLEN to * indicate that they are C strings of dynamic * length. */ char *buf, /* Buffer to copy into. */ size_t buflen) /* Size of buffer. */ { size_t i, j, len = 0; char *p, **new; if (src == NULL) { return 0; } for (i = 0; src[i] != NULL; i++) { /* * Empty loop to count how many. */ } len = sizeof(char *) * (i + 1); /* Leave place for the array. */ if (len > buflen) { return -1; } new = (char **) buf; p = buf + len; for (j = 0; j < i; j++) { size_t sz = (elsize==TCL_STRLEN ? (int) strlen(src[j]) + 1 : elsize); len += sz; if (len > buflen) { return -1; } memcpy(p, src[j], sz); new[j] = p; p = buf + len; } new[j] = NULL; return (ssize_t) len; } #endif /* NEED_COPYARRAY */ /* *--------------------------------------------------------------------------- * * CopyString -- |
︙ | ︙ | |||
935 936 937 938 939 940 941 | * Side effects: * None * *--------------------------------------------------------------------------- */ #ifdef NEED_COPYSTRING | | | | | < < < < < < < < | > | 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 990 991 992 993 | * Side effects: * None * *--------------------------------------------------------------------------- */ #ifdef NEED_COPYSTRING static ssize_t CopyString( const char *src, /* String to copy. */ char *buf, /* Buffer to copy into. */ size_t buflen) /* Size of buffer. */ { size_t len = 0; if (src != NULL) { len = strlen(src) + 1; if (len > buflen) { return -1; } memcpy(buf, src, len); } return (ssize_t) len; } #endif /* NEED_COPYSTRING */ /* *------------------------------------------------------------------------ * * TclWinCPUID -- * * Get CPU ID information on an Intel box under UNIX (either Linux or * Cygwin). * * Results: * Returns TCL_OK if successful, TCL_ERROR if CPUID is not supported. * * Side effects: * If successful, stores EAX, EBX, ECX and EDX registers after the CPUID * instruction in the four integers designated by 'regsPtr' |
︙ | ︙ | |||
1006 1007 1008 1009 1010 1011 1012 | : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3]) : "a"(index)); #endif status = TCL_OK; #endif return status; } | | | 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 | : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3]) : "a"(index)); #endif status = TCL_OK; #endif return status; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to unix/tclUnixFCmd.c.
︙ | ︙ | |||
521 522 523 524 525 526 527 | const Tcl_StatBuf *statBufPtr, /* Used to determine mode and blocksize. */ int dontCopyAtts) /* If flag set, don't copy attributes. */ { int srcFd, dstFd; unsigned blockSize; /* Optimal I/O blocksize for filesystem */ char *buffer; /* Data buffer for copy */ | | | 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 | const Tcl_StatBuf *statBufPtr, /* Used to determine mode and blocksize. */ int dontCopyAtts) /* If flag set, don't copy attributes. */ { int srcFd, dstFd; unsigned blockSize; /* Optimal I/O blocksize for filesystem */ char *buffer; /* Data buffer for copy */ ssize_t nread; #ifdef DJGPP #define BINMODE |O_BINARY #else #define BINMODE #endif /* DJGPP */ |
︙ | ︙ | |||
577 578 579 580 581 582 583 | */ if (blockSize <= 0) { blockSize = DEFAULT_COPY_BLOCK_SIZE; } buffer = ckalloc(blockSize); while (1) { | | | | | | | 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 | */ if (blockSize <= 0) { blockSize = DEFAULT_COPY_BLOCK_SIZE; } buffer = ckalloc(blockSize); while (1) { nread = read(srcFd, buffer, blockSize); if ((nread == -1) || (nread == 0)) { break; } if (write(dstFd, buffer, nread) != nread) { nread = -1; break; } } ckfree(buffer); close(srcFd); if ((close(dstFd) != 0) || (nread == -1)) { unlink(dst); /* INTL: Native. */ return TCL_ERROR; } if (!dontCopyAtts && CopyFileAtts(src, dst, statBufPtr) == TCL_ERROR) { /* * The copy succeeded, but setting the permissions failed, so be in a * consistent state, we remove the file that was created by the copy. |
︙ | ︙ | |||
1472 1473 1474 1475 1476 1477 1478 | int result; const char *native; if (Tcl_GetLongFromObj(NULL, attributePtr, &gid) != TCL_OK) { Tcl_DString ds; struct group *groupPtr = NULL; const char *string; | | | 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 | int result; const char *native; if (Tcl_GetLongFromObj(NULL, attributePtr, &gid) != TCL_OK) { Tcl_DString ds; struct group *groupPtr = NULL; const char *string; size_t length; string = Tcl_GetStringFromObj(attributePtr, &length); native = Tcl_UtfToExternalDString(NULL, string, length, &ds); groupPtr = TclpGetGrNam(native); /* INTL: Native. */ Tcl_DStringFree(&ds); |
︙ | ︙ | |||
1539 1540 1541 1542 1543 1544 1545 | int result; const char *native; if (Tcl_GetLongFromObj(NULL, attributePtr, &uid) != TCL_OK) { Tcl_DString ds; struct passwd *pwPtr = NULL; const char *string; | | | 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 | int result; const char *native; if (Tcl_GetLongFromObj(NULL, attributePtr, &uid) != TCL_OK) { Tcl_DString ds; struct passwd *pwPtr = NULL; const char *string; size_t length; string = Tcl_GetStringFromObj(attributePtr, &length); native = Tcl_UtfToExternalDString(NULL, string, length, &ds); pwPtr = TclpGetPwNam(native); /* INTL: Native. */ Tcl_DStringFree(&ds); |
︙ | ︙ | |||
1911 1912 1913 1914 1915 1916 1917 | int TclpObjNormalizePath( Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint) { const char *currentPathEndPosition; | | | 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 | int TclpObjNormalizePath( Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint) { const char *currentPathEndPosition; size_t pathLen; char cur; const char *path = Tcl_GetStringFromObj(pathPtr, &pathLen); Tcl_DString ds; const char *nativePath; #ifndef NO_REALPATH char normPath[MAXPATHLEN]; #endif |
︙ | ︙ | |||
2142 2143 2144 2145 2146 2147 2148 | Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj) { Tcl_DString template, tmp; const char *string; | > | | 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 | Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj) { Tcl_DString template, tmp; const char *string; int fd; size_t len; /* * We should also check against making more then TMP_MAX of these. */ if (dirObj) { string = Tcl_GetStringFromObj(dirObj, &len); |
︙ | ︙ |
Changes to unix/tclUnixFile.c.
︙ | ︙ | |||
255 256 257 258 259 260 261 | } Tcl_DecrRefCount(tailPtr); Tcl_DecrRefCount(fileNamePtr); } else { DIR *d; Tcl_DirEntry *entryPtr; const char *dirName; | | | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | } Tcl_DecrRefCount(tailPtr); Tcl_DecrRefCount(fileNamePtr); } else { DIR *d; Tcl_DirEntry *entryPtr; const char *dirName; size_t dirLength, nativeDirLen; int matchHidden, matchHiddenPat; Tcl_StatBuf statBuf; Tcl_DString ds; /* native encoding of dir */ Tcl_DString dsOrig; /* utf-8 encoding of dir */ Tcl_DStringInit(&dsOrig); dirName = Tcl_GetStringFromObj(fileNamePtr, &dirLength); |
︙ | ︙ | |||
930 931 932 933 934 935 936 | } /* * Check symbolic link flag first, since we prefer to create these. */ if (linkAction & TCL_CREATE_SYMBOLIC_LINK) { | | | 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | } /* * Check symbolic link flag first, since we prefer to create these. */ if (linkAction & TCL_CREATE_SYMBOLIC_LINK) { size_t targetLen; Tcl_DString ds; Tcl_Obj *transPtr; /* * Now we don't want to link to the absolute, normalized path. * Relative links are quite acceptable (but links to ~user are not * -- these must be expanded first). |
︙ | ︙ | |||
1073 1074 1075 1076 1077 1078 1079 | TclNativeCreateNativeRep( Tcl_Obj *pathPtr) { char *nativePathPtr; const char *str; Tcl_DString ds; Tcl_Obj *validPathPtr; | | | 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 | TclNativeCreateNativeRep( Tcl_Obj *pathPtr) { char *nativePathPtr; const char *str; Tcl_DString ds; Tcl_Obj *validPathPtr; size_t len; if (TclFSCwdIsNative()) { /* * The cwd is native, which means we can use the translated path * without worrying about normalization (this will also usually be * shorter so the utf-to-external conversion will be somewhat faster). */ |
︙ | ︙ | |||
1103 1104 1105 1106 1107 1108 1109 | } str = Tcl_GetStringFromObj(validPathPtr, &len); Tcl_UtfToExternalDString(NULL, str, len, &ds); len = Tcl_DStringLength(&ds) + sizeof(char); Tcl_DecrRefCount(validPathPtr); nativePathPtr = ckalloc(len); | | | 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 | } str = Tcl_GetStringFromObj(validPathPtr, &len); Tcl_UtfToExternalDString(NULL, str, len, &ds); len = Tcl_DStringLength(&ds) + sizeof(char); Tcl_DecrRefCount(validPathPtr); nativePathPtr = ckalloc(len); memcpy(nativePathPtr, Tcl_DStringValue(&ds), len); Tcl_DStringFree(&ds); return nativePathPtr; } /* *--------------------------------------------------------------------------- |
︙ | ︙ |
Changes to unix/tclUnixInit.c.
︙ | ︙ | |||
454 455 456 457 458 459 460 | * *------------------------------------------------------------------------- */ void TclpInitLibraryPath( char **valuePtr, | | | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 | * *------------------------------------------------------------------------- */ void TclpInitLibraryPath( char **valuePtr, size_t *lengthPtr, Tcl_Encoding *encodingPtr) { #define LIBRARY_SIZE 32 Tcl_Obj *pathPtr, *objPtr; const char *str; Tcl_DString buffer; |
︙ | ︙ | |||
477 478 479 480 481 482 483 | str = getenv("TCL_LIBRARY"); /* INTL: Native. */ Tcl_ExternalToUtfDString(NULL, str, -1, &buffer); str = Tcl_DStringValue(&buffer); if ((str != NULL) && (str[0] != '\0')) { Tcl_DString ds; | | | 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | str = getenv("TCL_LIBRARY"); /* INTL: Native. */ Tcl_ExternalToUtfDString(NULL, str, -1, &buffer); str = Tcl_DStringValue(&buffer); if ((str != NULL) && (str[0] != '\0')) { Tcl_DString ds; size_t pathc; const char **pathv; char installLib[LIBRARY_SIZE]; Tcl_DStringInit(&ds); /* * Initialize the substrings used when locating an executable. The |
︙ | ︙ | |||
979 980 981 982 983 984 985 | *---------------------------------------------------------------------- */ int TclpFindVariable( const char *name, /* Name of desired environment variable * (native). */ | | | 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 | *---------------------------------------------------------------------- */ int TclpFindVariable( const char *name, /* Name of desired environment variable * (native). */ size_t *lengthPtr) /* Used to return length of name (for * successful searches) or number of non-NULL * entries in environ (for unsuccessful * searches). */ { int i, result = -1; register const char *env, *p1, *p2; Tcl_DString envString; |
︙ | ︙ |
Changes to unix/tclUnixPipe.c.
︙ | ︙ | |||
44 45 46 47 48 49 50 | * the children at close time. */ } PipeState; /* * Declarations for local functions defined in this file: */ | | | < | < | < | < | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | * the children at close time. */ } PipeState; /* * Declarations for local functions defined in this file: */ static Tcl_DriverBlockModeProc PipeBlockModeProc; static Tcl_DriverClose2Proc PipeClose2Proc; static Tcl_DriverGetHandleProc PipeGetHandleProc; static Tcl_DriverInputProc PipeInputProc; static Tcl_DriverOutputProc PipeOutputProc; static Tcl_DriverWatchProc PipeWatchProc; static void RestoreSignals(void); static int SetupStdFile(TclFile file, int type); /* * This structure describes the channel type structure for command pipe based * I/O: */ |
︙ | ︙ | |||
375 376 377 378 379 380 381 | /* ARGSUSED */ int TclpCreateProcess( Tcl_Interp *interp, /* Interpreter in which to leave errors that * occurred when creating the child process. * Error messages from the child process * itself are sent to errorFile. */ | | | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | /* ARGSUSED */ int TclpCreateProcess( Tcl_Interp *interp, /* Interpreter in which to leave errors that * occurred when creating the child process. * Error messages from the child process * itself are sent to errorFile. */ size_t argc, /* Number of arguments in following array. */ const char **argv, /* Array of argument strings in UTF-8. * argv[0] contains the name of the executable * translated using Tcl_TranslateFileName * call). Additional arguments have not been * converted. */ TclFile inputFile, /* If non-NULL, gives the file to use as input * for the child process. If inputFile file is |
︙ | ︙ | |||
1030 1031 1032 1033 1034 1035 1036 | * * Side effects: * Reads input from the input device of the channel. * *---------------------------------------------------------------------- */ | | | | | | 1026 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 | * * Side effects: * Reads input from the input device of the channel. * *---------------------------------------------------------------------- */ static ssize_t PipeInputProc( ClientData instanceData, /* Pipe state. */ char *buf, /* Where to store data read. */ size_t toRead, /* How much space is available in the * buffer? */ int *errorCodePtr) /* Where to store error code. */ { PipeState *psPtr = instanceData; ssize_t bytesRead; /* How many bytes were actually read from the * input device? */ *errorCodePtr = 0; /* * Assume there is always enough input available. This will block * appropriately, and read will unblock as soon as a short read is * possible, if the channel is in blocking mode. If the channel is * nonblocking, the read will never block. Some OSes can throw an * interrupt error, for which we should immediately retry. [Bug #415131] */ do { bytesRead = read(GetFd(psPtr->inFile), buf, toRead); } while ((bytesRead < 0) && (errno == EINTR)); if (bytesRead < 0) { *errorCodePtr = errno; return -1; } return bytesRead; |
︙ | ︙ | |||
1081 1082 1083 1084 1085 1086 1087 | * * Side effects: * Writes output on the output device of the channel. * *---------------------------------------------------------------------- */ | | | | | | 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 | * * Side effects: * Writes output on the output device of the channel. * *---------------------------------------------------------------------- */ static ssize_t PipeOutputProc( ClientData instanceData, /* Pipe state. */ const char *buf, /* The data buffer. */ size_t toWrite, /* How many bytes to write? */ int *errorCodePtr) /* Where to store error code. */ { PipeState *psPtr = instanceData; ssize_t written; *errorCodePtr = 0; /* * Some OSes can throw an interrupt error, for which we should immediately * retry. [Bug #415131] */ do { written = write(GetFd(psPtr->outFile), buf, toWrite); } while ((written < 0) && (errno == EINTR)); if (written < 0) { *errorCodePtr = errno; return -1; } return written; |
︙ | ︙ | |||
1248 1249 1250 1251 1252 1253 1254 | */ /* ARGSUSED */ int Tcl_PidObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 | */ /* ARGSUSED */ int Tcl_PidObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Tcl_Channel chan; PipeState *pipePtr; int i; Tcl_Obj *resultPtr; |
︙ | ︙ |
Changes to unix/tclUnixSock.c.
︙ | ︙ | |||
109 110 111 112 113 114 115 | /* * Static routines for this file: */ static int CreateClientSocket(Tcl_Interp *interp, TcpState *state); static void TcpAccept(ClientData data, int mask); | | | < | < | < | < < | < | < | | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | /* * Static routines for this file: */ static int CreateClientSocket(Tcl_Interp *interp, TcpState *state); static void TcpAccept(ClientData data, int mask); static Tcl_DriverBlockModeProc TcpBlockModeProc; static Tcl_DriverCloseProc TcpCloseProc; static Tcl_DriverClose2Proc TcpClose2Proc; static Tcl_DriverGetHandleProc TcpGetHandleProc; static Tcl_DriverGetOptionProc TcpGetOptionProc; static Tcl_DriverInputProc TcpInputProc; static Tcl_DriverOutputProc TcpOutputProc; static Tcl_DriverWatchProc TcpWatchProc; static int WaitForConnect(TcpState *statePtr, int *errorCodePtr); /* * This structure describes the channel type structure for TCP socket * based IO: */ |
︙ | ︙ | |||
176 177 178 179 180 181 182 | * *---------------------------------------------------------------------- */ static void InitializeHostName( char **valuePtr, | | | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | * *---------------------------------------------------------------------- */ static void InitializeHostName( char **valuePtr, size_t *lengthPtr, Tcl_Encoding *encodingPtr) { const char *native = NULL; #ifndef NO_UNAME struct utsname u; struct hostent *hp; |
︙ | ︙ | |||
433 434 435 436 437 438 439 | * Side effects: * Reads input from the input device of the channel. * *---------------------------------------------------------------------- */ /* ARGSUSED */ | | | | | | 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 | * Side effects: * Reads input from the input device of the channel. * *---------------------------------------------------------------------- */ /* ARGSUSED */ static ssize_t TcpInputProc( ClientData instanceData, /* Socket state. */ char *buf, /* Where to store data read. */ size_t bufSize, /* How much space is available in the * buffer? */ int *errorCodePtr) /* Where to store error code. */ { TcpState *statePtr = instanceData; ssize_t bytesRead; *errorCodePtr = 0; if (WaitForConnect(statePtr, errorCodePtr) != 0) { return -1; } bytesRead = recv(statePtr->fds.fd, buf, bufSize, 0); if (bytesRead > -1) { return bytesRead; } if (errno == ECONNRESET) { /* * Turn ECONNRESET into a soft EOF condition. */ |
︙ | ︙ | |||
484 485 486 487 488 489 490 | * * Side effects: * Writes output on the output device of the channel. * *---------------------------------------------------------------------- */ | | | | | | 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | * * Side effects: * Writes output on the output device of the channel. * *---------------------------------------------------------------------- */ static ssize_t TcpOutputProc( ClientData instanceData, /* Socket state. */ const char *buf, /* The data buffer. */ size_t toWrite, /* How many bytes to write? */ int *errorCodePtr) /* Where to store error code. */ { TcpState *statePtr = instanceData; ssize_t written; *errorCodePtr = 0; if (WaitForConnect(statePtr, errorCodePtr) != 0) { return -1; } written = send(statePtr->fds.fd, buf, toWrite, 0); if (written > -1) { return written; } *errorCodePtr = errno; return -1; } |
︙ | ︙ |
Changes to unix/tclUnixTest.c.
︙ | ︙ | |||
136 137 138 139 140 141 142 | *---------------------------------------------------------------------- */ static int TestfilehandlerCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | *---------------------------------------------------------------------- */ static int TestfilehandlerCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Pipe *pipePtr; int i, mask, timeout; static int initialized = 0; char buffer[4000]; TclFile file; |
︙ | ︙ | |||
358 359 360 361 362 363 364 | *---------------------------------------------------------------------- */ static int TestfilewaitCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | *---------------------------------------------------------------------- */ static int TestfilewaitCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { int mask, result, timeout; Tcl_Channel channel; int fd; ClientData data; |
︙ | ︙ | |||
427 428 429 430 431 432 433 | *---------------------------------------------------------------------- */ static int TestfindexecutableCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | *---------------------------------------------------------------------- */ static int TestfindexecutableCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_Obj *saveName; if (argc != 2) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], " argv0\"", NULL); |
︙ | ︙ | |||
470 471 472 473 474 475 476 | *---------------------------------------------------------------------- */ static int TestgetopenfileCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 | *---------------------------------------------------------------------- */ static int TestgetopenfileCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { ClientData filePtr; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName forWriting\"", NULL); |
︙ | ︙ | |||
513 514 515 516 517 518 519 | *---------------------------------------------------------------------- */ static int TestsetdefencdirCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | *---------------------------------------------------------------------- */ static int TestsetdefencdirCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Tcl_Obj *searchPath; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "defaultDir"); return TCL_ERROR; } |
︙ | ︙ | |||
553 554 555 556 557 558 559 | *---------------------------------------------------------------------- */ static int TestforkObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 | *---------------------------------------------------------------------- */ static int TestforkObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { pid_t pid; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, ""); return TCL_ERROR; } |
︙ | ︙ | |||
599 600 601 602 603 604 605 | *---------------------------------------------------------------------- */ static int TestgetdefencdirCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 | *---------------------------------------------------------------------- */ static int TestgetdefencdirCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { size_t numDirs; Tcl_Obj *first, *searchPath; if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } |
︙ | ︙ | |||
643 644 645 646 647 648 649 | *---------------------------------------------------------------------- */ static int TestalarmCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 | *---------------------------------------------------------------------- */ static int TestalarmCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { #ifdef SA_RESTART unsigned int sec; struct sigaction action; if (argc > 1) { |
︙ | ︙ | |||
722 723 724 725 726 727 728 | *---------------------------------------------------------------------- */ static int TestgotsigCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 | *---------------------------------------------------------------------- */ static int TestgotsigCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { Tcl_AppendResult(interp, gotsig, NULL); gotsig = "0"; return TCL_OK; } |
︙ | ︙ | |||
753 754 755 756 757 758 759 | *--------------------------------------------------------------------------- */ static int TestchmodCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | > | | 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 | *--------------------------------------------------------------------------- */ static int TestchmodCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { size_t i; int mode; char *rest; if (argc < 2) { usage: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " mode file ?file ...?", NULL); return TCL_ERROR; |
︙ | ︙ |
Changes to unix/tclUnixThrd.c.
︙ | ︙ | |||
65 66 67 68 69 70 71 | */ int TclpThreadCreate( Tcl_ThreadId *idPtr, /* Return, the ID of the thread */ Tcl_ThreadCreateProc *proc, /* Main() function of the thread */ ClientData clientData, /* The one argument to Main() */ | | | | 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 TclpThreadCreate( Tcl_ThreadId *idPtr, /* Return, the ID of the thread */ Tcl_ThreadCreateProc *proc, /* Main() function of the thread */ ClientData clientData, /* The one argument to Main() */ size_t stackSize, /* Size of stack for the new thread */ int flags) /* Flags controlling behaviour of the new * thread. */ { #ifdef TCL_THREADS pthread_attr_t attr; pthread_t theThread; int result; pthread_attr_init(&attr); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE if (stackSize != TCL_THREAD_STACK_DEFAULT) { pthread_attr_setstacksize(&attr, stackSize); #ifdef TCL_THREAD_STACK_MIN } else { /* * Certain systems define a thread stack size that by default is too * small for many operations. The user has the option of defining * TCL_THREAD_STACK_MIN to a value large enough to work for their * needs. This would look like (for 128K min stack): |
︙ | ︙ |
Changes to unix/tclXtTest.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | static Tcl_CmdProc TesteventloopCmd; extern DLLEXPORT Tcl_PackageInitProc Tclxttest_Init; /* * Functions defined in tclXtNotify.c for use by users of the Xt Notifier: */ | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | static Tcl_CmdProc TesteventloopCmd; extern DLLEXPORT Tcl_PackageInitProc Tclxttest_Init; /* * Functions defined in tclXtNotify.c for use by users of the Xt Notifier: */ extern void InitNotifier(void); extern XtAppContext TclSetAppContext(XtAppContext ctx); /* *---------------------------------------------------------------------- * * Tclxttest_Init -- * |
︙ | ︙ | |||
76 77 78 79 80 81 82 | *---------------------------------------------------------------------- */ static int TesteventloopCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | *---------------------------------------------------------------------- */ static int TesteventloopCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { static int *framePtr = NULL;/* Pointer to integer on stack frame of * innermost invocation of the "wait" * subcommand. */ if (argc < 2) { |
︙ | ︙ |
Changes to win/tclAppInit.c.
︙ | ︙ | |||
74 75 76 77 78 79 80 | * * Side effects: * Just about anything, since from here we call arbitrary Tcl code. * *---------------------------------------------------------------------- */ | < > < < < > > > | > < > | | 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 108 109 110 111 112 113 114 115 116 117 118 | * * Side effects: * Just about anything, since from here we call arbitrary Tcl code. * *---------------------------------------------------------------------- */ int #ifdef TCL_BROKEN_MAINARGS main( int argc, /* Number of command-line arguments. */ char *dummy[]) /* Not used. */ #else _tmain( int argc, /* Number of command-line arguments. */ TCHAR *argv[]) /* Values of command-line arguments. */ #endif /* TCL_BROKEN_MAINARGS */ { #ifdef TCL_BROKEN_MAINARGS TCHAR **argv; #else TCHAR *p; #endif /* TCL_BROKEN_MAINARGS */ /* * Set up the default locale to be standard "C" locale so parsing is * performed correctly. */ setlocale(LC_ALL, "C"); /* * Get our args from the c-runtime. Ignore command line. */ #ifdef TCL_BROKEN_MAINARGS setargv(&argc, &argv); #endif /* TCL_BROKEN_MAINARGS */ /* * Forward slashes substituted for backslashes. */ for (p = argv[0]; *p != '\0'; p++) { if (*p == '\\') { |
︙ | ︙ | |||
193 194 195 196 197 198 199 | /* * Specify a user-specific startup file to invoke if the application is * run interactively. Typically the startup file is "~/.apprc" where "app" * is the name of the application. If this line is deleted then no * user-specific startup file will be run under any conditions. */ | | | > | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | /* * Specify a user-specific startup file to invoke if the application is * run interactively. Typically the startup file is "~/.apprc" where "app" * is the name of the application. If this line is deleted then no * user-specific startup file will be run under any conditions. */ (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", TCL_STRLEN), NULL, Tcl_NewStringObj("~/tclshrc.tcl", TCL_STRLEN), TCL_GLOBAL_ONLY); return TCL_OK; } /* *------------------------------------------------------------------------- * * setargv -- |
︙ | ︙ | |||
255 256 257 258 259 260 261 | } if (*p == '\0') { break; } } } | > | > > > | | | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | } if (*p == '\0') { break; } } } /* * Make sure we don't call ckalloc through the (not yet initialized) stub * table. */ #undef Tcl_Alloc #undef Tcl_DbCkalloc argSpace = ckalloc(size * sizeof(char *) + (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR)); argv = (TCHAR **) argSpace; argSpace += size * (sizeof(char *)/sizeof(TCHAR)); size--; |
︙ | ︙ |
Changes to win/tclWin32Dll.c.
︙ | ︙ | |||
82 83 84 85 86 87 88 | MountPointMap *driveLetterLookup = NULL; TCL_DECLARE_MUTEX(mountPointMap) /* * We will need this below. */ | < | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | MountPointMap *driveLetterLookup = NULL; TCL_DECLARE_MUTEX(mountPointMap) /* * We will need this below. */ #if defined(__WIN32__) && !defined(STATIC_BUILD) /* *---------------------------------------------------------------------- * * DllEntryPoint -- * * This wrapper function is used by Borland to invoke the initialization |
︙ | ︙ | |||
149 150 151 152 153 154 155 | * DLL_PROCESS_DETACH is unnecessary as the user should call * Tcl_Finalize explicitly before unloading Tcl. */ } return TRUE; } | < | | 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | * DLL_PROCESS_DETACH is unnecessary as the user should call * Tcl_Finalize explicitly before unloading Tcl. */ } return TRUE; } #endif /* __WIN32__ && !STATIC_BUILD */ /* *---------------------------------------------------------------------- * * TclWinGetTclInstance -- * * Retrieves the global library instance handle. |
︙ | ︙ | |||
354 355 356 357 358 359 360 361 362 363 364 365 366 367 | * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void TclWinResetInterfaces(void) { if (winTCharEncoding != NULL) { Tcl_FreeEncoding(winTCharEncoding); winTCharEncoding = NULL; } | > | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */ void TclWinResetInterfaces(void) { if (winTCharEncoding != NULL) { Tcl_FreeEncoding(winTCharEncoding); winTCharEncoding = NULL; } |
︙ | ︙ | |||
574 575 576 577 578 579 580 | * *--------------------------------------------------------------------------- */ TCHAR * Tcl_WinUtfToTChar( const char *string, /* Source string in UTF-8. */ | | | | | > | 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 | * *--------------------------------------------------------------------------- */ TCHAR * Tcl_WinUtfToTChar( const char *string, /* Source string in UTF-8. */ size_t len, /* Source string length in bytes, or * TCL_STRLEN for strlen(). */ Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { return (TCHAR *) Tcl_UtfToExternalDString(winTCharEncoding, string, len, dsPtr); } char * Tcl_WinTCharToUtf( const TCHAR *string, /* Source string in Unicode when running NT, * ANSI when running 95. */ size_t len, /* Source string length in bytes, or * TCL_STRLEN for platform-specific string * length. */ Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { return Tcl_ExternalToUtfDString(winTCharEncoding, (const char *) string, len, dsPtr); } |
︙ | ︙ |
Changes to win/tclWinChan.c.
︙ | ︙ | |||
67 68 69 70 71 72 73 | * pointer. */ } FileEvent; /* * Static routines for this file: */ | | < < | < < | < < | < | < | < > > | > | | | | | | | > | | 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 94 95 96 97 98 99 | * pointer. */ } FileEvent; /* * Static routines for this file: */ static Tcl_DriverBlockModeProc FileBlockProc; static Tcl_DriverCloseProc FileCloseProc; static Tcl_DriverGetHandleProc FileGetHandleProc; static Tcl_DriverInputProc FileInputProc; static Tcl_DriverOutputProc FileOutputProc; static Tcl_DriverSeekProc FileSeekProc; static Tcl_DriverThreadActionProc FileThreadActionProc; static Tcl_DriverTruncateProc FileTruncateProc; static Tcl_DriverWideSeekProc FileWideSeekProc; static Tcl_DriverWatchProc FileWatchProc; static Tcl_EventCheckProc FileCheckProc; static Tcl_EventProc FileEventProc; static Tcl_EventSetupProc FileSetupProc; static Tcl_ExitProc FileChannelExitHandler; static ThreadSpecificData * FileInit(void); static DWORD FileGetType(HANDLE handle); /* * This structure describes the channel type structure for file based IO. */ static const Tcl_ChannelType fileChannelType = { "file", /* Type name. */ |
︙ | ︙ | |||
662 663 664 665 666 667 668 | * * Side effects: * Reads input from the actual channel. * *---------------------------------------------------------------------- */ | | | | | 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 687 688 689 690 691 692 693 | * * Side effects: * Reads input from the actual channel. * *---------------------------------------------------------------------- */ static ssize_t FileInputProc( ClientData instanceData, /* File state. */ char *buf, /* Where to store data read. */ size_t bufSize, /* Num bytes available in buffer. */ int *errorCode) /* Where to store error code. */ { FileInfo *infoPtr = instanceData; DWORD bytesRead; *errorCode = 0; /* * Note that we will block on reads from a console buffer until a full * line has been entered. The only way I know of to get around this is to * write a console driver. We should probably do this at some point, but * for now, we just block. The same problem exists for files being read * over the network. */ if (ReadFile(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &bytesRead, (LPOVERLAPPED) NULL) != FALSE) { return (ssize_t) bytesRead; } TclWinConvertError(GetLastError()); *errorCode = errno; if (errno == EPIPE) { return 0; } |
︙ | ︙ | |||
713 714 715 716 717 718 719 | * * Side effects: * Writes output on the actual channel. * *---------------------------------------------------------------------- */ | | | | 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 | * * Side effects: * Writes output on the actual channel. * *---------------------------------------------------------------------- */ static ssize_t FileOutputProc( ClientData instanceData, /* File state. */ const char *buf, /* The data buffer. */ size_t toWrite, /* How many bytes to write? */ int *errorCode) /* Where to store error code. */ { FileInfo *infoPtr = instanceData; DWORD bytesWritten; *errorCode = 0; |
︙ | ︙ | |||
741 742 743 744 745 746 747 | if (WriteFile(infoPtr->handle, (LPVOID) buf, (DWORD) toWrite, &bytesWritten, (LPOVERLAPPED) NULL) == FALSE) { TclWinConvertError(GetLastError()); *errorCode = errno; return -1; } infoPtr->dirty = 1; | | | 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 | if (WriteFile(infoPtr->handle, (LPVOID) buf, (DWORD) toWrite, &bytesWritten, (LPOVERLAPPED) NULL) == FALSE) { TclWinConvertError(GetLastError()); *errorCode = errno; return -1; } infoPtr->dirty = 1; return (ssize_t) bytesWritten; } /* *---------------------------------------------------------------------- * * FileWatchProc -- * |
︙ | ︙ |
Changes to win/tclWinConsole.c.
︙ | ︙ | |||
95 96 97 98 99 100 101 | DWORD writeError; /* An error caused by the last background * write. Set to 0 if no error has been * detected. This word is shared with the * writer thread so access must be * synchronized with the writable object. */ char *writeBuf; /* Current background output buffer. Access is * synchronized with the writable object. */ | | | | | | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | DWORD writeError; /* An error caused by the last background * write. Set to 0 if no error has been * detected. This word is shared with the * writer thread so access must be * synchronized with the writable object. */ char *writeBuf; /* Current background output buffer. Access is * synchronized with the writable object. */ size_t writeBufLen; /* Size of write buffer. Access is * synchronized with the writable object. */ size_t toWrite; /* Current amount to be written. Access is * synchronized with the writable object. */ int readFlags; /* Flags that are shared with the reader * thread. Access is synchronized with the * readable object. */ size_t bytesRead; /* Number of bytes in the buffer. */ size_t offset; /* Number of bytes read out of the buffer. */ char buffer[CONSOLE_BUFFER_SIZE]; /* Data consumed by reader thread. */ } ConsoleInfo; typedef struct{ /* * The following pointer refers to the head of the list of consoles that |
︙ | ︙ | |||
137 138 139 140 141 142 143 | * pointer. */ } ConsoleEvent; /* * Declarations for functions used only in this file. */ | | > > > > > > | | | | | | | | < < < < < < < < < | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | * pointer. */ } ConsoleEvent; /* * Declarations for functions used only in this file. */ static Tcl_DriverBlockModeProc ConsoleBlockModeProc; static Tcl_DriverCloseProc ConsoleCloseProc; static Tcl_DriverGetHandleProc ConsoleGetHandleProc; static Tcl_DriverInputProc ConsoleInputProc; static Tcl_DriverOutputProc ConsoleOutputProc; static Tcl_DriverThreadActionProc ConsoleThreadActionProc; static Tcl_DriverWatchProc ConsoleWatchProc; static Tcl_EventCheckProc ConsoleCheckProc; static Tcl_EventProc ConsoleEventProc; static Tcl_EventSetupProc ConsoleSetupProc; static Tcl_ExitProc ConsoleExitHandler; static Tcl_ExitProc ProcExitHandler; static void ConsoleInit(void); static DWORD WINAPI ConsoleReaderThread(LPVOID arg); static DWORD WINAPI ConsoleWriterThread(LPVOID arg); static int WaitForRead(ConsoleInfo *infoPtr, int blocking); static BOOL ReadConsoleBytes(HANDLE hConsole, LPVOID lpBuffer, DWORD nbytes, LPDWORD nbytesread); static BOOL WriteConsoleBytes(HANDLE hConsole, const void *lpBuffer, DWORD nbytes, LPDWORD nbyteswritten); static void StartChannelThread(ConsoleInfo *infoPtr, ConsoleThreadInfo *threadInfoPtr, |
︙ | ︙ | |||
691 692 693 694 695 696 697 | * * Side effects: * Reads input from the actual channel. * *---------------------------------------------------------------------- */ | | | | 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 | * * Side effects: * Reads input from the actual channel. * *---------------------------------------------------------------------- */ static ssize_t ConsoleInputProc( ClientData instanceData, /* Console state. */ char *buf, /* Where to store data read. */ size_t bufSize, /* How much space is available in the * buffer? */ int *errorCode) /* Where to store error code. */ { ConsoleInfo *infoPtr = instanceData; DWORD count, bytesRead = 0; int result; |
︙ | ︙ | |||
777 778 779 780 781 782 783 | * * Side effects: * Writes output on the actual channel. * *---------------------------------------------------------------------- */ | | | | 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | * * Side effects: * Writes output on the actual channel. * *---------------------------------------------------------------------- */ static ssize_t ConsoleOutputProc( ClientData instanceData, /* Console state. */ const char *buf, /* The data buffer. */ size_t toWrite, /* How many bytes to write? */ int *errorCode) /* Where to store error code. */ { ConsoleInfo *infoPtr = instanceData; ConsoleThreadInfo *threadInfo = &infoPtr->reader; DWORD bytesWritten, timeout; *errorCode = 0; |
︙ | ︙ |
Changes to win/tclWinDde.c.
︙ | ︙ | |||
88 89 90 91 92 93 94 | static int ddeIsServer = 0; #define TCL_DDE_VERSION "1.4.0" #define TCL_DDE_PACKAGE_NAME "dde" #define TCL_DDE_SERVICE_NAME TEXT("TclEval") #define TCL_DDE_EXECUTE_RESULT TEXT("$TCLEVAL$EXECUTE$RESULT") | | | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | static int ddeIsServer = 0; #define TCL_DDE_VERSION "1.4.0" #define TCL_DDE_PACKAGE_NAME "dde" #define TCL_DDE_SERVICE_NAME TEXT("TclEval") #define TCL_DDE_EXECUTE_RESULT TEXT("$TCLEVAL$EXECUTE$RESULT") #define DDE_FLAG_ASYNC 1 #define DDE_FLAG_BINARY 2 #define DDE_FLAG_FORCE 4 TCL_DECLARE_MUTEX(ddeMutex) /* * Forward declarations for functions defined later in this file. */ |
︙ | ︙ | |||
117 118 119 120 121 122 123 | LPARAM lParam); static void DeleteProc(ClientData clientData); static Tcl_Obj * ExecuteRemoteObject(RegisteredInterp *riPtr, Tcl_Obj *ddeObjectPtr); static int MakeDdeConnection(Tcl_Interp *interp, const TCHAR *name, HCONV *ddeConvPtr); static void SetDdeError(Tcl_Interp *interp); | | < < | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | LPARAM lParam); static void DeleteProc(ClientData clientData); static Tcl_Obj * ExecuteRemoteObject(RegisteredInterp *riPtr, Tcl_Obj *ddeObjectPtr); static int MakeDdeConnection(Tcl_Interp *interp, const TCHAR *name, HCONV *ddeConvPtr); static void SetDdeError(Tcl_Interp *interp); static Tcl_ObjCmdProc DdeObjCmd; DLLEXPORT int Dde_Init(Tcl_Interp *interp); DLLEXPORT int Dde_SafeInit(Tcl_Interp *interp); /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
271 272 273 274 275 276 277 | * *---------------------------------------------------------------------- */ static const TCHAR * DdeSetServerName( Tcl_Interp *interp, | | | | > | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | * *---------------------------------------------------------------------- */ static const TCHAR * DdeSetServerName( Tcl_Interp *interp, const TCHAR *name, /* The name that will be used to refer to the * interpreter in later "send" commands. Must * be globally unique. */ int flags, /* DDE_FLAG_FORCE or 0 */ Tcl_Obj *handlerPtr) /* Name of the optional proc/command to handle * incoming Dde eval's */ { int suffix; size_t offset; RegisteredInterp *riPtr, *prevPtr; Tcl_DString dString; const TCHAR *actualName; Tcl_Obj *srvListPtr = NULL, **srvPtrPtr = NULL; int n, srvCount = 0, lastSuffix, r = TCL_OK; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); |
︙ | ︙ | |||
340 341 342 343 344 345 346 | srvListPtr = Tcl_GetObjResult(interp); } if (r == TCL_OK) { r = Tcl_ListObjGetElements(interp, srvListPtr, &srvCount, &srvPtrPtr); } if (r != TCL_OK) { | | > | > | > | > | | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | srvListPtr = Tcl_GetObjResult(interp); } if (r == TCL_OK) { r = Tcl_ListObjGetElements(interp, srvListPtr, &srvCount, &srvPtrPtr); } if (r != TCL_OK) { Tcl_WinUtfToTChar(Tcl_GetStringResult(interp), TCL_STRLEN, &dString); OutputDebugString((TCHAR *) Tcl_DStringValue(&dString)); Tcl_DStringFree(&dString); return NULL; } /* * Pick a name to use for the application. Use "name" if it's not * already in use. Otherwise add a suffix such as " #2", trying larger * and larger numbers until we eventually find one that is unique. */ offset = lastSuffix = 0; suffix = 1; while (suffix != lastSuffix) { lastSuffix = suffix; if (suffix > 1) { if (suffix == 2) { Tcl_DStringAppend(&dString, (char *) name, _tcslen(name) * sizeof(TCHAR)); Tcl_DStringAppend(&dString, (char *) TEXT(" #"), 2 * sizeof(TCHAR)); offset = Tcl_DStringLength(&dString); Tcl_DStringSetLength(&dString, offset + sizeof(TCHAR) * TCL_INTEGER_SPACE); actualName = (TCHAR *) Tcl_DStringValue(&dString); } _sntprintf((TCHAR *) (Tcl_DStringValue(&dString) + offset), TCL_INTEGER_SPACE, TEXT("%d"), suffix); } /* * See if the name is already in use, if so increment suffix. */ for (n = 0; n < srvCount; ++n) { Tcl_Obj* namePtr; Tcl_DString ds; const char *nameStr; size_t len; Tcl_ListObjIndex(interp, srvPtrPtr[n], 1, &namePtr); nameStr = Tcl_GetStringFromObj(namePtr, &len); Tcl_WinUtfToTChar(nameStr, len, &ds); if (_tcscmp(actualName, (TCHAR *)Tcl_DStringValue(&ds)) == 0) { suffix++; Tcl_DStringFree(&ds); |
︙ | ︙ | |||
540 541 542 543 544 545 546 | { Tcl_Obj *returnPackagePtr; int result = TCL_OK; if (riPtr->handlerPtr == NULL && Tcl_IsSafe(riPtr->interp)) { Tcl_SetObjResult(riPtr->interp, Tcl_NewStringObj("permission denied: " "a handler procedure must be defined for use in a safe " | | | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | { Tcl_Obj *returnPackagePtr; int result = TCL_OK; if (riPtr->handlerPtr == NULL && Tcl_IsSafe(riPtr->interp)) { Tcl_SetObjResult(riPtr->interp, Tcl_NewStringObj("permission denied: " "a handler procedure must be defined for use in a safe " "interp", TCL_STRLEN)); Tcl_SetErrorCode(riPtr->interp, "TCL", "DDE", "SECURITY_CHECK", NULL); result = TCL_ERROR; } if (riPtr->handlerPtr != NULL) { /* * Add the dde request data to the handler proc list. |
︙ | ︙ | |||
735 736 737 738 739 740 741 | * Empty loop body. */ } if (convPtr != NULL) { char *returnString; | | | | | | | | | | > | | | | 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 | * Empty loop body. */ } if (convPtr != NULL) { char *returnString; len = DdeQueryString(ddeInstance, ddeItem, NULL,0, CP_WINUNICODE); Tcl_DStringInit(&dString); Tcl_DStringSetLength(&dString, (len + 1) * sizeof(TCHAR) - 1); utilString = (TCHAR *) Tcl_DStringValue(&dString); DdeQueryString(ddeInstance, ddeItem, utilString, (DWORD) len + 1, CP_WINUNICODE); if (_tcsicmp(utilString, TCL_DDE_EXECUTE_RESULT) == 0) { if (uFmt == CF_TEXT) { returnString = Tcl_GetStringFromObj( convPtr->returnPackagePtr, &len); } else { returnString = (char *) Tcl_GetUnicodeFromObj( convPtr->returnPackagePtr, &len); len = 2 * len + 1; } ddeReturn = DdeCreateDataHandle(ddeInstance, (BYTE *) returnString, (DWORD) len+1, 0, ddeItem, uFmt, 0); } else { if (Tcl_IsSafe(convPtr->riPtr->interp)) { ddeReturn = NULL; } else { Tcl_DString ds; Tcl_Obj *variableObjPtr; Tcl_Obj *varName; Tcl_WinTCharToUtf(utilString, TCL_STRLEN, &ds); varName = Tcl_NewStringObj(Tcl_DStringValue(&ds), TCL_STRLEN); Tcl_IncrRefCount(varName); variableObjPtr = Tcl_ObjGetVar2( convPtr->riPtr->interp, varName, NULL, TCL_GLOBAL_ONLY); Tcl_DecrRefCount(varName); if (variableObjPtr != NULL) { if (uFmt == CF_TEXT) { returnString = Tcl_GetStringFromObj( variableObjPtr, &len); } else { returnString = (char *) Tcl_GetUnicodeFromObj( variableObjPtr, &len); len = 2 * len + 1; } ddeReturn = DdeCreateDataHandle(ddeInstance, (BYTE *) returnString, (DWORD) len+1, 0, ddeItem, uFmt, 0); } else { ddeReturn = NULL; } Tcl_DStringFree(&ds); } } Tcl_DStringFree(&dString); |
︙ | ︙ | |||
813 814 815 816 817 818 819 | } if (convPtr && !Tcl_IsSafe(convPtr->riPtr->interp)) { Tcl_DString ds; Tcl_Obj *variableObjPtr; Tcl_Obj *varName; | | | | > | | 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 | } if (convPtr && !Tcl_IsSafe(convPtr->riPtr->interp)) { Tcl_DString ds; Tcl_Obj *variableObjPtr; Tcl_Obj *varName; len = DdeQueryString(ddeInstance, ddeItem, NULL,0, CP_WINUNICODE); Tcl_DStringInit(&dString); Tcl_DStringSetLength(&dString, (len + 1) * sizeof(TCHAR) - 1); utilString = (TCHAR *) Tcl_DStringValue(&dString); DdeQueryString(ddeInstance, ddeItem, utilString, (DWORD) len + 1, CP_WINUNICODE); Tcl_WinTCharToUtf(utilString, TCL_STRLEN, &ds); utilString = (TCHAR *) DdeAccessData(hData, &dlen); if (uFmt == CF_TEXT) { variableObjPtr = Tcl_NewStringObj((char *) utilString, TCL_STRLEN); } else { variableObjPtr = Tcl_NewUnicodeObj(utilString, TCL_STRLEN); } varName = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1); Tcl_IncrRefCount(varName); Tcl_ObjSetVar2(convPtr->riPtr->interp, varName, NULL, variableObjPtr, TCL_GLOBAL_ONLY); Tcl_DecrRefCount(varName); |
︙ | ︙ | |||
873 874 875 876 877 878 879 | if (!string[dlen-1]) { dlen--; } ddeObjectPtr = Tcl_NewStringObj(string, dlen); } else { /* unicode */ dlen >>= 1; | | > | 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 | if (!string[dlen-1]) { dlen--; } ddeObjectPtr = Tcl_NewStringObj(string, dlen); } else { /* unicode */ dlen >>= 1; ddeObjectPtr = Tcl_NewUnicodeObj((Tcl_UniChar *) utilString, dlen - 1); } Tcl_IncrRefCount(ddeObjectPtr); DdeUnaccessData(hData); if (convPtr->returnPackagePtr != NULL) { Tcl_DecrRefCount(convPtr->returnPackagePtr); } convPtr->returnPackagePtr = NULL; |
︙ | ︙ | |||
992 993 994 995 996 997 998 | Tcl_Interp *interp, /* Used to report errors. */ const TCHAR *name, /* The connection to use. */ HCONV *ddeConvPtr) { HSZ ddeTopic, ddeService; HCONV ddeConv; | | > | | > | 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 | Tcl_Interp *interp, /* Used to report errors. */ const TCHAR *name, /* The connection to use. */ HCONV *ddeConvPtr) { HSZ ddeTopic, ddeService; HCONV ddeConv; ddeService = DdeCreateStringHandle(ddeInstance, TCL_DDE_SERVICE_NAME, CP_WINUNICODE); ddeTopic = DdeCreateStringHandle(ddeInstance, name, CP_WINUNICODE); ddeConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL); DdeFreeStringHandle(ddeInstance, ddeService); DdeFreeStringHandle(ddeInstance, ddeTopic); if (ddeConv == (HCONV) NULL) { if (interp != NULL) { Tcl_DString dString; Tcl_WinTCharToUtf(name, TCL_STRLEN, &dString); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "no registered server named \"%s\"", Tcl_DStringValue(&dString))); Tcl_DStringFree(&dString); Tcl_SetErrorCode(interp, "TCL", "DDE", "NO_SERVER", NULL); } return TCL_ERROR; } *ddeConvPtr = ddeConv; |
︙ | ︙ | |||
1112 1113 1114 1115 1116 1117 1118 | if ((es->service == (ATOM)0 || es->service == service) && (es->topic == (ATOM)0 || es->topic == topic)) { Tcl_Obj *matchPtr = Tcl_NewListObj(0, NULL); Tcl_Obj *resultPtr = Tcl_GetObjResult(es->interp); GlobalGetAtomName(service, sz, 255); | | | > | | > | 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 | if ((es->service == (ATOM)0 || es->service == service) && (es->topic == (ATOM)0 || es->topic == topic)) { Tcl_Obj *matchPtr = Tcl_NewListObj(0, NULL); Tcl_Obj *resultPtr = Tcl_GetObjResult(es->interp); GlobalGetAtomName(service, sz, 255); Tcl_WinTCharToUtf(sz, TCL_STRLEN, &dString); Tcl_ListObjAppendElement(NULL, matchPtr, Tcl_NewStringObj( Tcl_DStringValue(&dString), TCL_STRLEN)); Tcl_DStringFree(&dString); GlobalGetAtomName(topic, sz, 255); Tcl_WinTCharToUtf(sz, TCL_STRLEN, &dString); Tcl_ListObjAppendElement(NULL, matchPtr, Tcl_NewStringObj( Tcl_DStringValue(&dString), TCL_STRLEN)); Tcl_DStringFree(&dString); /* * Adding the hwnd as a third list element provides a unique * identifier in the case of multiple servers with the name * application and topic names. */ |
︙ | ︙ | |||
1235 1236 1237 1238 1239 1240 1241 | errorCode = "NOCANDO"; break; default: errorMessage = "dde command failed"; errorCode = "FAILED"; } | | | 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 | errorCode = "NOCANDO"; break; default: errorMessage = "dde command failed"; errorCode = "FAILED"; } Tcl_SetObjResult(interp, Tcl_NewStringObj(errorMessage, TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "DDE", errorCode, NULL); } /* *---------------------------------------------------------------------- * * DdeObjCmd -- |
︙ | ︙ | |||
1260 1261 1262 1263 1264 1265 1266 | *---------------------------------------------------------------------- */ static int DdeObjCmd( ClientData clientData, /* Used only for deletion */ Tcl_Interp *interp, /* The interp we are sending from */ | | | 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 | *---------------------------------------------------------------------- */ static int DdeObjCmd( ClientData clientData, /* Used only for deletion */ Tcl_Interp *interp, /* The interp we are sending from */ size_t objc, /* Number of arguments */ Tcl_Obj *const *objv) /* The arguments */ { static const char *const ddeCommands[] = { "servername", "execute", "poke", "request", "services", "eval", (char *) NULL}; enum DdeSubcommands { DDE_SERVERNAME, DDE_EXECUTE, DDE_POKE, DDE_REQUEST, DDE_SERVICES, |
︙ | ︙ | |||
1289 1290 1291 1292 1293 1294 1295 | static const char *const ddeEvalOptions[] = { "-async", NULL }; static const char *const ddeReqOptions[] = { "-binary", NULL }; | > | | 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 | static const char *const ddeEvalOptions[] = { "-async", NULL }; static const char *const ddeReqOptions[] = { "-binary", NULL }; size_t i, length; int index, argIndex; int flags = 0, result = TCL_OK, firstArg = 0; HSZ ddeService = NULL, ddeTopic = NULL, ddeItem = NULL, ddeCookie = NULL; HDDEDATA ddeData = NULL, ddeItemData = NULL, ddeReturn; HCONV hConv = NULL; const TCHAR *serviceName = NULL, *topicName = NULL; const char *string; DWORD ddeResult; |
︙ | ︙ | |||
1465 1466 1467 1468 1469 1470 1471 | } else if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) { ddeService = DdeCreateStringHandle(ddeInstance, (void *) serviceName, CP_WINUNICODE); } if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) { #ifdef UNICODE | > | | > | > | 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 1512 1513 | } else if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) { ddeService = DdeCreateStringHandle(ddeInstance, (void *) serviceName, CP_WINUNICODE); } if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) { #ifdef UNICODE topicName = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 1], &length); #else topicName = Tcl_GetStringFromObj(objv[firstArg + 1], &length); #endif if (length == 0) { topicName = NULL; } else { ddeTopic = DdeCreateStringHandle(ddeInstance, (void *) topicName, CP_WINUNICODE); } } switch ((enum DdeSubcommands) index) { case DDE_SERVERNAME: serviceName = DdeSetServerName(interp, serviceName, flags, handlerPtr); if (serviceName != NULL) { #ifdef UNICODE Tcl_SetObjResult(interp, Tcl_NewUnicodeObj((Tcl_UniChar *) serviceName, TCL_STRLEN)); #else Tcl_SetObjResult(interp, Tcl_NewStringObj( serviceName, TCL_STRLEN)); #endif } else { Tcl_ResetResult(interp); } break; case DDE_EXECUTE: { |
︙ | ︙ | |||
1507 1508 1509 1510 1511 1512 1513 | dataString = Tcl_GetUnicodeFromObj(objv[firstArg + 2], &dataLength); dataLength = (dataLength + 1) * sizeof(Tcl_UniChar); } if (dataLength <= 0) { Tcl_SetObjResult(interp, | | > | | > | > | > | | | | | > | > | | | | | | | | | 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 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 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 | dataString = Tcl_GetUnicodeFromObj(objv[firstArg + 2], &dataLength); dataLength = (dataLength + 1) * sizeof(Tcl_UniChar); } if (dataLength <= 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot execute null data", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL); result = TCL_ERROR; break; } hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL); DdeFreeStringHandle(ddeInstance, ddeService); DdeFreeStringHandle(ddeInstance, ddeTopic); if (hConv == NULL) { SetDdeError(interp); result = TCL_ERROR; break; } ddeData = DdeCreateDataHandle(ddeInstance, (BYTE *) dataString, (DWORD) dataLength, 0, 0, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, 0); if (ddeData != NULL) { if (flags & DDE_FLAG_ASYNC) { DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF, hConv, 0, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult); DdeAbandonTransaction(ddeInstance, hConv, ddeResult); } else { ddeReturn = DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF, hConv, 0, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_EXECUTE, 30000, NULL); if (ddeReturn == 0) { SetDdeError(interp); result = TCL_ERROR; } } DdeFreeDataHandle(ddeData); } else { SetDdeError(interp); result = TCL_ERROR; } break; } case DDE_REQUEST: { #ifdef UNICODE const TCHAR *itemString = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 2], &length); #else const TCHAR *itemString = Tcl_GetStringFromObj(objv[firstArg + 2], &length); #endif if (length == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot request value of null data", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL); result = TCL_ERROR; goto cleanup; } hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL); DdeFreeStringHandle(ddeInstance, ddeService); DdeFreeStringHandle(ddeInstance, ddeTopic); if (hConv == NULL) { SetDdeError(interp); result = TCL_ERROR; } else { Tcl_Obj *returnObjPtr; ddeItem = DdeCreateStringHandle(ddeInstance, (void *) itemString, CP_WINUNICODE); if (ddeItem != NULL) { ddeData = DdeClientTransaction(NULL, 0, hConv, ddeItem, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_REQUEST, 5000, NULL); if (ddeData == NULL) { SetDdeError(interp); result = TCL_ERROR; } else { DWORD tmp; const Tcl_UniChar *dataString = (const Tcl_UniChar *) DdeAccessData(ddeData, &tmp); if (flags & DDE_FLAG_BINARY) { returnObjPtr = Tcl_NewByteArrayObj((BYTE *) dataString, (int) tmp); } else { tmp >>= 1; if (tmp && !dataString[tmp-1]) { --tmp; } returnObjPtr = Tcl_NewUnicodeObj(dataString, (size_t) tmp); } DdeUnaccessData(ddeData); DdeFreeDataHandle(ddeData); Tcl_SetObjResult(interp, returnObjPtr); } } else { SetDdeError(interp); result = TCL_ERROR; } } break; } case DDE_POKE: { #ifdef UNICODE const TCHAR *itemString = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 2], &length); #else const TCHAR *itemString = Tcl_GetStringFromObj(objv[firstArg + 2], &length); #endif BYTE *dataString; if (length == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot have a null item", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL); result = TCL_ERROR; goto cleanup; } if (flags & DDE_FLAG_BINARY) { dataString = (BYTE *) Tcl_GetByteArrayFromObj(objv[firstArg + 3], &length); |
︙ | ︙ | |||
1641 1642 1643 1644 1645 1646 1647 | if (hConv == NULL) { SetDdeError(interp); result = TCL_ERROR; } else { ddeItem = DdeCreateStringHandle(ddeInstance, (void *) itemString, CP_WINUNICODE); if (ddeItem != NULL) { | | > | > | 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 | if (hConv == NULL) { SetDdeError(interp); result = TCL_ERROR; } else { ddeItem = DdeCreateStringHandle(ddeInstance, (void *) itemString, CP_WINUNICODE); if (ddeItem != NULL) { ddeData = DdeClientTransaction(dataString, (DWORD) length, hConv, ddeItem, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_POKE, 5000, NULL); if (ddeData == NULL) { SetDdeError(interp); result = TCL_ERROR; } } else { SetDdeError(interp); result = TCL_ERROR; |
︙ | ︙ | |||
1664 1665 1666 1667 1668 1669 1670 | break; case DDE_EVAL: { RegisteredInterp *riPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (serviceName == NULL) { | | | | 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 | break; case DDE_EVAL: { RegisteredInterp *riPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (serviceName == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "invalid service name \"\"", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "DDE", "NO_SERVER", NULL); result = TCL_ERROR; goto cleanup; } objc -= firstArg + 1; objv += firstArg + 1; |
︙ | ︙ | |||
1713 1714 1715 1716 1717 1718 1719 | * interp is then deleted, the bytecode structure would be * referring to deallocated objects. */ if (Tcl_IsSafe(riPtr->interp) && riPtr->handlerPtr == NULL) { Tcl_SetObjResult(riPtr->interp, Tcl_NewStringObj( "permission denied: a handler procedure must be" | | > | 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 | * interp is then deleted, the bytecode structure would be * referring to deallocated objects. */ if (Tcl_IsSafe(riPtr->interp) && riPtr->handlerPtr == NULL) { Tcl_SetObjResult(riPtr->interp, Tcl_NewStringObj( "permission denied: a handler procedure must be" " defined for use in a safe interp", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "DDE", "SECURITY_CHECK", NULL); result = TCL_ERROR; } if (result == TCL_OK) { if (objc == 1) objPtr = objv[0]; else { objPtr = Tcl_ConcatObj(objc, objv); } if (riPtr->handlerPtr != NULL) { /* add the dde request data to the handler proc list */ /* *result = Tcl_ListObjReplace(sendInterp, objPtr, 0, 0, 1, * &(riPtr->handlerPtr)); */ Tcl_Obj *cmdPtr = Tcl_DuplicateObj(riPtr->handlerPtr); result = Tcl_ListObjAppendElement(sendInterp, cmdPtr, objPtr); if (result == TCL_OK) { objPtr = cmdPtr; } } } |
︙ | ︙ | |||
1782 1783 1784 1785 1786 1787 1788 | /* * This is a non-local request. Send the script to the server and * poll it for a result. */ if (MakeDdeConnection(interp, serviceName, &hConv) != TCL_OK) { invalidServerResponse: | | | | | | | | 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 | /* * This is a non-local request. Send the script to the server and * poll it for a result. */ if (MakeDdeConnection(interp, serviceName, &hConv) != TCL_OK) { invalidServerResponse: Tcl_SetObjResult(interp, Tcl_NewStringObj( "invalid data returned from server", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "DDE", "BAD_RESPONSE", NULL); result = TCL_ERROR; goto cleanup; } objPtr = Tcl_ConcatObj(objc, objv); string = (const char *) Tcl_GetUnicodeFromObj(objPtr, &length); ddeItemData = DdeCreateDataHandle(ddeInstance, (BYTE *) string, (DWORD) 2*length+2, 0, 0, CF_UNICODETEXT, 0); if (flags & DDE_FLAG_ASYNC) { ddeData = DdeClientTransaction((LPBYTE) ddeItemData, 0xFFFFFFFF, hConv, 0, CF_UNICODETEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult); DdeAbandonTransaction(ddeInstance, hConv, ddeResult); } else { ddeData = DdeClientTransaction((LPBYTE) ddeItemData, 0xFFFFFFFF, hConv, 0, CF_UNICODETEXT, XTYP_EXECUTE, 30000, NULL); if (ddeData != 0) { ddeCookie = DdeCreateStringHandle(ddeInstance, |
︙ | ︙ |
Changes to win/tclWinFCmd.c.
︙ | ︙ | |||
343 344 345 346 347 348 349 | nativeDstPath, &nativeDstRest); if ((size == 0) || (size > MAX_PATH)) { return TCL_ERROR; } CharLower(nativeSrcPath); CharLower(nativeDstPath); | | | | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | nativeDstPath, &nativeDstRest); if ((size == 0) || (size > MAX_PATH)) { return TCL_ERROR; } CharLower(nativeSrcPath); CharLower(nativeDstPath); src = Tcl_WinTCharToUtf(nativeSrcPath, TCL_STRLEN, &srcString); dst = Tcl_WinTCharToUtf(nativeDstPath, TCL_STRLEN, &dstString); /* * Check whether the destination path is actually inside the * source path. This is true if the prefix matches, and the next * character is either end-of-string or a directory separator */ |
︙ | ︙ | |||
926 927 928 929 930 931 932 | normSrcPtr = Tcl_FSGetNormalizedPath(NULL,srcPathPtr); normDestPtr = Tcl_FSGetNormalizedPath(NULL,destPathPtr); if ((normSrcPtr == NULL) || (normDestPtr == NULL)) { return TCL_ERROR; } | | | | | 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 | normSrcPtr = Tcl_FSGetNormalizedPath(NULL,srcPathPtr); normDestPtr = Tcl_FSGetNormalizedPath(NULL,destPathPtr); if ((normSrcPtr == NULL) || (normDestPtr == NULL)) { return TCL_ERROR; } Tcl_WinUtfToTChar(Tcl_GetString(normSrcPtr), TCL_STRLEN, &srcString); Tcl_WinUtfToTChar(Tcl_GetString(normDestPtr), TCL_STRLEN, &dstString); ret = TraverseWinTree(TraversalCopy, &srcString, &dstString, &ds); Tcl_DStringFree(&srcString); Tcl_DStringFree(&dstString); if (ret != TCL_OK) { if (!strcmp(Tcl_DStringValue(&ds), TclGetString(normSrcPtr))) { *errorPtr = srcPathPtr; } else if (!strcmp(Tcl_DStringValue(&ds), TclGetString(normDestPtr))) { *errorPtr = destPathPtr; } else { *errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), TCL_STRLEN); } Tcl_DStringFree(&ds); Tcl_IncrRefCount(*errorPtr); } return ret; } |
︙ | ︙ | |||
999 1000 1001 1002 1003 1004 1005 | */ Tcl_DString native; normPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); if (normPtr == NULL) { return TCL_ERROR; } | | | 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | */ Tcl_DString native; normPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); if (normPtr == NULL) { return TCL_ERROR; } Tcl_WinUtfToTChar(Tcl_GetString(normPtr), TCL_STRLEN, &native); ret = DoRemoveDirectory(&native, recursive, &ds); Tcl_DStringFree(&native); } else { ret = DoRemoveJustDirectory(Tcl_FSGetNativePath(pathPtr), 0, &ds); } if (ret != TCL_OK) { |
︙ | ︙ | |||
1123 1124 1125 1126 1127 1128 1129 | * don't want to initialise the errorPtr yet. */ return TCL_ERROR; } end: if (errorPtr != NULL) { | | | | | | 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 | * don't want to initialise the errorPtr yet. */ return TCL_ERROR; } end: if (errorPtr != NULL) { Tcl_WinTCharToUtf(nativePath, TCL_STRLEN, errorPtr); } return TCL_ERROR; } static int DoRemoveDirectory( Tcl_DString *pathPtr, /* Pathname of directory to be removed * (native). */ int recursive, /* If non-zero, removes directories that are * nonempty. Otherwise, will only remove empty * directories. */ Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free DString * filled with UTF-8 name of file causing * error. */ { int res = DoRemoveJustDirectory((const TCHAR *)Tcl_DStringValue(pathPtr), recursive, errorPtr); if ((res == TCL_ERROR) && recursive && (Tcl_GetErrno() == EEXIST)) { /* * The directory is nonempty, but the recursive flag has been * specified, so we recursively remove all the files in the directory. */ return TraverseWinTree(TraversalDelete, pathPtr, NULL, errorPtr); } else { |
︙ | ︙ | |||
1334 1335 1336 1337 1338 1339 1340 | DOTREE_POSTD, errorPtr); } end: if (nativeErrfile != NULL) { TclWinConvertError(GetLastError()); if (errorPtr != NULL) { | | | 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 | DOTREE_POSTD, errorPtr); } end: if (nativeErrfile != NULL) { TclWinConvertError(GetLastError()); if (errorPtr != NULL) { Tcl_WinTCharToUtf(nativeErrfile, TCL_STRLEN, errorPtr); } result = TCL_ERROR; } return result; } |
︙ | ︙ | |||
1399 1400 1401 1402 1403 1404 1405 | /* * There shouldn't be a problem with src, because we already checked it to * get here. */ if (errorPtr != NULL) { | | | 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 | /* * There shouldn't be a problem with src, because we already checked it to * get here. */ if (errorPtr != NULL) { Tcl_WinTCharToUtf(nativeDst, TCL_STRLEN, errorPtr); } return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1454 1455 1456 1457 1458 1459 1460 | if (DoRemoveJustDirectory(nativeSrc, 0, NULL) == TCL_OK) { return TCL_OK; } break; } if (errorPtr != NULL) { | | | 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 | if (DoRemoveJustDirectory(nativeSrc, 0, NULL) == TCL_OK) { return TCL_OK; } break; } if (errorPtr != NULL) { Tcl_WinTCharToUtf(nativeSrc, TCL_STRLEN, errorPtr); } return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1713 1714 1715 1716 1717 1718 1719 | * about the second. * * fprintf(stderr, "%d\n", data.w.cAlternateFileName[0]); * fprintf(stderr, "%d\n", ((WCHAR *) nativeName)[0]); */ Tcl_DStringInit(&dsTemp); | | | | 1713 1714 1715 1716 1717 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 1744 1745 1746 1747 | * about the second. * * fprintf(stderr, "%d\n", data.w.cAlternateFileName[0]); * fprintf(stderr, "%d\n", ((WCHAR *) nativeName)[0]); */ Tcl_DStringInit(&dsTemp); Tcl_WinTCharToUtf(nativeName, TCL_STRLEN, &dsTemp); Tcl_DStringFree(&ds); /* * Deal with issues of tildes being absolute. */ if (Tcl_DStringValue(&dsTemp)[0] == '~') { TclNewLiteralStringObj(tempPath, "./"); Tcl_AppendToObj(tempPath, Tcl_DStringValue(&dsTemp), Tcl_DStringLength(&dsTemp)); Tcl_DStringFree(&dsTemp); } else { tempPath = TclDStringToObj(&dsTemp); } Tcl_ListObjReplace(NULL, splitPath, i, 1, 1, &tempPath); FindClose(handle); } } *attributePtrPtr = Tcl_FSJoinPath(splitPath, TCL_STRLEN); if (splitPath != NULL) { /* * Unfortunately, the object we will return may have its only refCount * as part of the list splitPath. This means if we free splitPath, the * object will disappear. So, we have to be very careful here. * Unfortunately this means we must manipulate the object's refCount |
︙ | ︙ | |||
1952 1953 1954 1955 1956 1957 1958 | buf[2] = '/'; buf[3] = '\0'; for (i = 0; i < 26; i++) { buf[0] = (char) ('a' + i); if (GetVolumeInformationA(buf, NULL, 0, NULL, NULL, NULL, NULL, 0) || (GetLastError() == ERROR_NOT_READY)) { | | | | 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 | buf[2] = '/'; buf[3] = '\0'; for (i = 0; i < 26; i++) { buf[0] = (char) ('a' + i); if (GetVolumeInformationA(buf, NULL, 0, NULL, NULL, NULL, NULL, 0) || (GetLastError() == ERROR_NOT_READY)) { elemPtr = Tcl_NewStringObj(buf, TCL_STRLEN); Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr); } } } else { for (p = buf; *p != '\0'; p += 4) { p[2] = '/'; elemPtr = Tcl_NewStringObj(p, TCL_STRLEN); Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr); } } Tcl_IncrRefCount(resultPtr); return resultPtr; } |
︙ | ︙ |
Changes to win/tclWinFile.c.
︙ | ︙ | |||
160 161 162 163 164 165 166 | static int NativeIsExec(const TCHAR *path); static int NativeReadReparse(const TCHAR *LinkDirectory, REPARSE_DATA_BUFFER *buffer, DWORD desiredAccess); static int NativeWriteReparse(const TCHAR *LinkDirectory, REPARSE_DATA_BUFFER *buffer); static int NativeMatchType(int isDrive, DWORD attr, const TCHAR *nativeName, Tcl_GlobTypeData *types); | | | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | static int NativeIsExec(const TCHAR *path); static int NativeReadReparse(const TCHAR *LinkDirectory, REPARSE_DATA_BUFFER *buffer, DWORD desiredAccess); static int NativeWriteReparse(const TCHAR *LinkDirectory, REPARSE_DATA_BUFFER *buffer); static int NativeMatchType(int isDrive, DWORD attr, const TCHAR *nativeName, Tcl_GlobTypeData *types); static int WinIsDrive(const char *name, size_t nameLen); static int WinIsReserved(const char *path); static Tcl_Obj * WinReadLink(const TCHAR *LinkSource); static Tcl_Obj * WinReadLinkDirectory(const TCHAR *LinkDirectory); static int WinLink(const TCHAR *LinkSource, const TCHAR *LinkTarget, int linkAction); static int WinSymLinkDirectory(const TCHAR *LinkDirectory, const TCHAR *LinkTarget); |
︙ | ︙ | |||
874 875 876 877 878 879 880 | * Convert to WCHAR to get out of ANSI codepage */ MultiByteToWideChar(CP_ACP, 0, name, -1, wName, MAX_PATH); #endif WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, sizeof(name), NULL, NULL); TclWinNoBackslash(name); | | | 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 | * Convert to WCHAR to get out of ANSI codepage */ MultiByteToWideChar(CP_ACP, 0, name, -1, wName, MAX_PATH); #endif WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, sizeof(name), NULL, NULL); TclWinNoBackslash(name); TclSetObjNameOfExecutable(Tcl_NewStringObj(name, TCL_STRLEN), NULL); } /* *---------------------------------------------------------------------- * * TclpMatchInDirectory -- * |
︙ | ︙ | |||
924 925 926 927 928 929 930 | Tcl_Obj *norm = Tcl_FSGetNormalizedPath(NULL, pathPtr); if (norm != NULL) { /* * Match a single file directly. */ | | | | 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 | Tcl_Obj *norm = Tcl_FSGetNormalizedPath(NULL, pathPtr); if (norm != NULL) { /* * Match a single file directly. */ size_t len; DWORD attr; WIN32_FILE_ATTRIBUTE_DATA data; const char *str = Tcl_GetStringFromObj(norm, &len); native = Tcl_FSGetNativePath(pathPtr); if (GetFileAttributesEx(native, GetFileExInfoStandard, &data) != TRUE) { return TCL_OK; } |
︙ | ︙ | |||
1010 1011 1012 1013 1014 1015 1016 | if (strpbrk(pattern, "[]\\") == NULL) { /* * The pattern is a simple one containing just '*' and/or '?'. * This means we can get the OS to help us, by passing it the * pattern. */ | | | | 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 | if (strpbrk(pattern, "[]\\") == NULL) { /* * The pattern is a simple one containing just '*' and/or '?'. * This means we can get the OS to help us, by passing it the * pattern. */ dirName = Tcl_DStringAppend(&dsOrig, pattern, TCL_STRLEN); } else { dirName = TclDStringAppendLiteral(&dsOrig, "*.*"); } native = Tcl_WinUtfToTChar(dirName, TCL_STRLEN, &ds); if ((types == NULL) || (types->type != TCL_GLOB_TYPE_DIR)) { handle = FindFirstFile(native, &data); } else { /* * We can be more efficient, for pure directory requests. */ |
︙ | ︙ | |||
1088 1089 1090 1091 1092 1093 1094 | do { const char *utfname; int checkDrive = 0, isDrive; DWORD attr; native = data.cFileName; attr = data.dwFileAttributes; | | | 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 | do { const char *utfname; int checkDrive = 0, isDrive; DWORD attr; native = data.cFileName; attr = data.dwFileAttributes; utfname = Tcl_WinTCharToUtf(native, TCL_STRLEN, &ds); if (!matchSpecialDots) { /* * If it is exactly '.' or '..' then we ignore it. */ if ((utfname[0] == '.') && (utfname[1] == '\0' |
︙ | ︙ | |||
1165 1166 1167 1168 1169 1170 1171 | * because for NTFS root volumes, the getFileAttributesProc returns a 'hidden' * attribute when it should not. */ static int WinIsDrive( const char *name, /* Name (UTF-8) */ | | | 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 | * because for NTFS root volumes, the getFileAttributesProc returns a 'hidden' * attribute when it should not. */ static int WinIsDrive( const char *name, /* Name (UTF-8) */ size_t len) /* Length of name */ { int remove = 0; while (len > 4) { if ((name[len-1] != '.' || name[len-2] != '.') || (name[len-3] != '/' && name[len-3] != '\\')) { /* |
︙ | ︙ | |||
1441 1442 1443 1444 1445 1446 1447 | WCHAR buf[MAX_PATH]; Tcl_DStringInit(bufferPtr); wDomain = NULL; domain = strchr(name, '@'); if (domain != NULL) { Tcl_DStringInit(&ds); | | | 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 | WCHAR buf[MAX_PATH]; Tcl_DStringInit(bufferPtr); wDomain = NULL; domain = strchr(name, '@'); if (domain != NULL) { Tcl_DStringInit(&ds); wName = Tcl_UtfToUniCharDString(domain + 1, TCL_STRLEN, &ds); badDomain = NetGetDCName(NULL, wName, (LPBYTE *) wDomainPtr); Tcl_DStringFree(&ds); nameLen = domain - name; } if (badDomain == 0) { Tcl_DStringInit(&ds); wName = Tcl_UtfToUniCharDString(name, nameLen, &ds); |
︙ | ︙ | |||
1524 1525 1526 1527 1528 1529 1530 | */ static int NativeAccess( const TCHAR *nativePath, /* Path of file to access, native encoding. */ int mode) /* Permission setting. */ { | < < | | 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 | */ static int NativeAccess( const TCHAR *nativePath, /* Path of file to access, native encoding. */ int mode) /* Permission setting. */ { DWORD attr = GetFileAttributes(nativePath); if (attr == INVALID_FILE_ATTRIBUTES) { /* * File might not exist. */ DWORD lasterror = GetLastError(); |
︙ | ︙ | |||
1548 1549 1550 1551 1552 1553 1554 | /* * File exists, nothing else to check. */ return 0; } | < | | | 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 | /* * File exists, nothing else to check. */ return 0; } if ((mode & W_OK) && (attr & FILE_ATTRIBUTE_READONLY) && !(attr & FILE_ATTRIBUTE_DIRECTORY)) { /* * The attributes say the file is not writable. If the file is a * regular file (i.e., not a directory), then the file is not * writable, full stop. For directories, the read-only bit is * (mostly) ignored by Windows, so we can't ascertain anything about * directory access from the attrib data. However, if we have the * advanced 'getFileSecurityProc', then more robust ACL checks |
︙ | ︙ | |||
1872 1873 1874 1875 1876 1877 1878 | */ native = (WCHAR *) buffer; if ((native[0] != '\0') && (native[1] == ':') && (native[2] == '\\') && (native[3] == '\\')) { native += 2; } | | | 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 | */ native = (WCHAR *) buffer; if ((native[0] != '\0') && (native[1] == ':') && (native[2] == '\\') && (native[3] == '\\')) { native += 2; } Tcl_WinTCharToUtf((TCHAR *) native, TCL_STRLEN, bufferPtr); /* * Convert to forward slashes for easier use in scripts. */ for (p = Tcl_DStringValue(bufferPtr); *p != '\0'; p++) { if (*p == '\\') { |
︙ | ︙ | |||
2053 2054 2055 2056 2057 2058 2059 | int dev; Tcl_DString ds; TCHAR nativeFullPath[MAX_PATH]; TCHAR *nativePart; const char *fullPath; GetFullPathName(nativePath, MAX_PATH, nativeFullPath, &nativePart); | | | 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 | int dev; Tcl_DString ds; TCHAR nativeFullPath[MAX_PATH]; TCHAR *nativePart; const char *fullPath; GetFullPathName(nativePath, MAX_PATH, nativeFullPath, &nativePart); fullPath = Tcl_WinTCharToUtf(nativeFullPath, TCL_STRLEN, &ds); if ((fullPath[0] == '\\') && (fullPath[1] == '\\')) { const char *p; DWORD dw; const TCHAR *nativeVol; Tcl_DString volString; |
︙ | ︙ | |||
2354 2355 2356 2357 2358 2359 2360 | } if (found == 0) { return NULL; } else { Tcl_DString ds; | | | 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 | } if (found == 0) { return NULL; } else { Tcl_DString ds; Tcl_WinTCharToUtf(volType, TCL_STRLEN, &ds); return TclDStringToObj(&ds); } #undef VOL_BUF_SIZE } /* * This define can be turned on to experiment with a different way of |
︙ | ︙ | |||
2671 2672 2673 2674 2675 2676 2677 | int len; char *path; Tcl_Obj *tmpPathPtr; tmpPathPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), nextCheckpoint); | | | 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 | int len; char *path; Tcl_Obj *tmpPathPtr; tmpPathPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), nextCheckpoint); Tcl_AppendToObj(tmpPathPtr, lastValidPathEnd, TCL_STRLEN); path = Tcl_GetStringFromObj(tmpPathPtr, &len); Tcl_SetStringObj(pathPtr, path, len); Tcl_DecrRefCount(tmpPathPtr); } else { /* * End of string was reached above. */ |
︙ | ︙ | |||
2744 2745 2746 2747 2748 2749 2750 | * Path of form /foo/bar which is a path in the root directory of the * current volume. */ const char *drive = Tcl_GetString(useThisCwd); absolutePath = Tcl_NewStringObj(drive,2); | | | 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 | * Path of form /foo/bar which is a path in the root directory of the * current volume. */ const char *drive = Tcl_GetString(useThisCwd); absolutePath = Tcl_NewStringObj(drive,2); Tcl_AppendToObj(absolutePath, path, TCL_STRLEN); Tcl_IncrRefCount(absolutePath); /* * We have a refCount on the cwd. */ } else { /* |
︙ | ︙ | |||
2798 2799 2800 2801 2802 2803 2804 | * could use the '_dgetdcwd' Win32 API to get the drive's cwd. */ absolutePath = Tcl_NewStringObj(path, 2); Tcl_AppendToObj(absolutePath, "/", 1); } Tcl_IncrRefCount(absolutePath); | | | 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 | * could use the '_dgetdcwd' Win32 API to get the drive's cwd. */ absolutePath = Tcl_NewStringObj(path, 2); Tcl_AppendToObj(absolutePath, "/", 1); } Tcl_IncrRefCount(absolutePath); Tcl_AppendToObj(absolutePath, path+2, TCL_STRLEN); } *useThisCwdPtr = useThisCwd; return absolutePath; } /* *--------------------------------------------------------------------------- |
︙ | ︙ | |||
2831 2832 2833 2834 2835 2836 2837 | Tcl_Obj * TclpNativeToNormalized( ClientData clientData) { Tcl_DString ds; Tcl_Obj *objPtr; | | | | 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 | Tcl_Obj * TclpNativeToNormalized( ClientData clientData) { Tcl_DString ds; Tcl_Obj *objPtr; size_t len; char *copy, *p; Tcl_WinTCharToUtf((const TCHAR *) clientData, TCL_STRLEN, &ds); copy = Tcl_DStringValue(&ds); len = Tcl_DStringLength(&ds); /* * Certain native path representations on Windows have this special prefix * to indicate that they are to be treated specially. For example * extremely long paths, or symlinks. |
︙ | ︙ | |||
2864 2865 2866 2867 2868 2869 2870 | for (p = copy; *p != '\0'; p++) { if (*p == '\\') { *p = '/'; } } | | | 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 | for (p = copy; *p != '\0'; p++) { if (*p == '\\') { *p = '/'; } } objPtr = Tcl_NewStringObj(copy, len); Tcl_DStringFree(&ds); return objPtr; } /* *--------------------------------------------------------------------------- |
︙ | ︙ | |||
2893 2894 2895 2896 2897 2898 2899 | ClientData TclNativeCreateNativeRep( Tcl_Obj *pathPtr) { char *nativePathPtr, *str; Tcl_DString ds; Tcl_Obj *validPathPtr; | | | 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 | ClientData TclNativeCreateNativeRep( Tcl_Obj *pathPtr) { char *nativePathPtr, *str; Tcl_DString ds; Tcl_Obj *validPathPtr; size_t len; if (TclFSCwdIsNative()) { /* * The cwd is native, which means we can use the translated path * without worrying about normalization (this will also usually be * shorter so the utf-to-external conversion will be somewhat faster). */ |
︙ | ︙ |
Changes to win/tclWinInit.c.
︙ | ︙ | |||
172 173 174 175 176 177 178 | * *------------------------------------------------------------------------- */ void TclpInitLibraryPath( char **valuePtr, | | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | * *------------------------------------------------------------------------- */ void TclpInitLibraryPath( char **valuePtr, size_t *lengthPtr, Tcl_Encoding *encodingPtr) { #define LIBRARY_SIZE 64 Tcl_Obj *pathPtr; char installLib[LIBRARY_SIZE]; const char *bytes; |
︙ | ︙ | |||
216 217 218 219 220 221 222 | Tcl_ListObjAppendElement(NULL, pathPtr, TclGetProcessGlobalValue(&sourceLibraryDir)); *encodingPtr = NULL; bytes = Tcl_GetStringFromObj(pathPtr, lengthPtr); *valuePtr = ckalloc((*lengthPtr) + 1); | | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | Tcl_ListObjAppendElement(NULL, pathPtr, TclGetProcessGlobalValue(&sourceLibraryDir)); *encodingPtr = NULL; bytes = Tcl_GetStringFromObj(pathPtr, lengthPtr); *valuePtr = ckalloc((*lengthPtr) + 1); memcpy(*valuePtr, bytes, (*lengthPtr)+1); Tcl_DecrRefCount(pathPtr); } /* *--------------------------------------------------------------------------- * * AppendEnvironment -- |
︙ | ︙ | |||
244 245 246 247 248 249 250 | */ static void AppendEnvironment( Tcl_Obj *pathPtr, const char *lib) { | | | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | */ static void AppendEnvironment( Tcl_Obj *pathPtr, const char *lib) { size_t pathc; WCHAR wBuf[MAX_PATH]; char buf[MAX_PATH * TCL_UTF_MAX]; Tcl_Obj *objPtr; Tcl_DString ds; const char **pathv; char *shortlib; |
︙ | ︙ | |||
283 284 285 286 287 288 289 | buf[0] = '\0'; GetEnvironmentVariableA("TCL_LIBRARY", buf, MAX_PATH); } else { ToUtf(wBuf, buf); } if (buf[0] != '\0') { | | | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | buf[0] = '\0'; GetEnvironmentVariableA("TCL_LIBRARY", buf, MAX_PATH); } else { ToUtf(wBuf, buf); } if (buf[0] != '\0') { objPtr = Tcl_NewStringObj(buf, TCL_STRLEN); Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); TclWinNoBackslash(buf); Tcl_SplitPath(buf, &pathc, &pathv); /* * The lstrcmpi() will work even if pathv[pathc-1] is random UTF-8 |
︙ | ︙ | |||
307 308 309 310 311 312 313 | */ pathv[pathc - 1] = shortlib; Tcl_DStringInit(&ds); (void) Tcl_JoinPath(pathc, pathv, &ds); objPtr = TclDStringToObj(&ds); } else { | | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | */ pathv[pathc - 1] = shortlib; Tcl_DStringInit(&ds); (void) Tcl_JoinPath(pathc, pathv, &ds); objPtr = TclDStringToObj(&ds); } else { objPtr = Tcl_NewStringObj(buf, TCL_STRLEN); } Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); ckfree(pathv); } } /* |
︙ | ︙ | |||
580 581 582 583 584 585 586 | */ Tcl_DStringInit(&ds); ptr = Tcl_GetVar2(interp, "env", "HOME", TCL_GLOBAL_ONLY); if (ptr == NULL) { ptr = Tcl_GetVar2(interp, "env", "HOMEDRIVE", TCL_GLOBAL_ONLY); if (ptr != NULL) { | | | > | 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 | */ Tcl_DStringInit(&ds); ptr = Tcl_GetVar2(interp, "env", "HOME", TCL_GLOBAL_ONLY); if (ptr == NULL) { ptr = Tcl_GetVar2(interp, "env", "HOMEDRIVE", TCL_GLOBAL_ONLY); if (ptr != NULL) { Tcl_DStringAppend(&ds, ptr, TCL_STRLEN); } ptr = Tcl_GetVar2(interp, "env", "HOMEPATH", TCL_GLOBAL_ONLY); if (ptr != NULL) { Tcl_DStringAppend(&ds, ptr, TCL_STRLEN); } if (Tcl_DStringLength(&ds) > 0) { Tcl_SetVar2(interp, "env", "HOME", Tcl_DStringValue(&ds), TCL_GLOBAL_ONLY); } else { Tcl_SetVar2(interp, "env", "HOME", "c:\\", TCL_GLOBAL_ONLY); } } /* * Initialize the user name from the environment first, since this is much * faster than asking the system. * Note: cchUserNameLen is number of characters including nul terminator. */ Tcl_DStringInit(&ds); if (TclGetEnv("USERNAME", &ds) == NULL) { if (GetUserName(szUserName, &cchUserNameLen) != 0) { int cbUserNameLen = cchUserNameLen - 1; cbUserNameLen *= sizeof(TCHAR); Tcl_WinTCharToUtf(szUserName, cbUserNameLen, &ds); } } Tcl_SetVar2(interp, "tcl_platform", "user", Tcl_DStringValue(&ds), TCL_GLOBAL_ONLY); Tcl_DStringFree(&ds); |
︙ | ︙ | |||
643 644 645 646 647 648 649 | *---------------------------------------------------------------------- */ int TclpFindVariable( const char *name, /* Name of desired environment variable * (UTF-8). */ | | | > | | | 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 676 677 678 679 680 681 682 683 684 685 686 | *---------------------------------------------------------------------- */ int TclpFindVariable( const char *name, /* Name of desired environment variable * (UTF-8). */ size_t *lengthPtr) /* Used to return length of name (for * successful searches) or number of non-NULL * entries in environ (for unsuccessful * searches). */ { int i, result = -1; size_t length; register const char *env, *p1, *p2; char *envUpper, *nameUpper; Tcl_DString envString; /* * Convert the name to all upper case for the case insensitive comparison. */ length = strlen(name); nameUpper = ckalloc(length + 1); memcpy(nameUpper, name, length+1); Tcl_UtfToUpper(nameUpper); Tcl_DStringInit(&envString); for (i = 0, env = environ[i]; env != NULL; i++, env = environ[i]) { /* * Chop the env string off after the equal sign, then Convert the name * to all upper case, so we do not have to convert all the characters * after the equal sign. */ envUpper = Tcl_ExternalToUtfDString(NULL,env,TCL_STRLEN, &envString); p1 = strchr(envUpper, '='); if (p1 == NULL) { continue; } length = (int) (p1 - envUpper); Tcl_DStringSetLength(&envString, length+1); Tcl_UtfToUpper(envUpper); |
︙ | ︙ |
Changes to win/tclWinLoad.c.
︙ | ︙ | |||
80 81 82 83 84 85 86 | * Let the OS loader examine the binary search path for whatever * string the user gave us which hopefully refers to a file on the * binary path. */ Tcl_DString ds; | | > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | * Let the OS loader examine the binary search path for whatever * string the user gave us which hopefully refers to a file on the * binary path. */ Tcl_DString ds; nativeName = Tcl_WinUtfToTChar(Tcl_GetString(pathPtr), TCL_STRLEN, &ds); hInstance = LoadLibraryEx(nativeName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); Tcl_DStringFree(&ds); } if (hInstance == NULL) { DWORD lastError = GetLastError(); |
︙ | ︙ | |||
106 107 108 109 110 111 112 | case ERROR_MOD_NOT_FOUND: Tcl_SetErrorCode(interp, "WIN_LOAD", "MOD_NOT_FOUND", NULL); goto notFoundMsg; case ERROR_DLL_NOT_FOUND: Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_NOT_FOUND", NULL); notFoundMsg: Tcl_AppendToObj(errMsg, "this library or a dependent library" | | | | | | | 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 | case ERROR_MOD_NOT_FOUND: Tcl_SetErrorCode(interp, "WIN_LOAD", "MOD_NOT_FOUND", NULL); goto notFoundMsg; case ERROR_DLL_NOT_FOUND: Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_NOT_FOUND", NULL); notFoundMsg: Tcl_AppendToObj(errMsg, "this library or a dependent library" " could not be found in library path", TCL_STRLEN); break; case ERROR_PROC_NOT_FOUND: Tcl_SetErrorCode(interp, "WIN_LOAD", "PROC_NOT_FOUND", NULL); Tcl_AppendToObj(errMsg, "A function specified in the import" " table could not be resolved by the system. Windows" " is not telling which one, I'm sorry.", TCL_STRLEN); break; case ERROR_INVALID_DLL: Tcl_SetErrorCode(interp, "WIN_LOAD", "INVALID_DLL", NULL); Tcl_AppendToObj(errMsg, "this library or a dependent library" " is damaged", TCL_STRLEN); break; case ERROR_DLL_INIT_FAILED: Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_INIT_FAILED", NULL); Tcl_AppendToObj(errMsg, "the library initialization" " routine failed", TCL_STRLEN); break; default: TclWinConvertError(lastError); Tcl_AppendToObj(errMsg, Tcl_PosixError(interp), TCL_STRLEN); } Tcl_SetObjResult(interp, errMsg); return TCL_ERROR; } /* * Succeded; package everything up for Tcl. |
︙ | ︙ | |||
182 183 184 185 186 187 188 | proc = (void *) GetProcAddress(hInstance, symbol); if (proc == NULL) { Tcl_DString ds; const char *sym2; Tcl_DStringInit(&ds); TclDStringAppendLiteral(&ds, "_"); | | | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | proc = (void *) GetProcAddress(hInstance, symbol); if (proc == NULL) { Tcl_DString ds; const char *sym2; Tcl_DStringInit(&ds); TclDStringAppendLiteral(&ds, "_"); sym2 = Tcl_DStringAppend(&ds, symbol, TCL_STRLEN); proc = (Tcl_PackageInitProc *) GetProcAddress(hInstance, sym2); Tcl_DStringFree(&ds); } if (proc == NULL && interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cannot find symbol \"%s\"", symbol)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol, NULL); |
︙ | ︙ |
Changes to win/tclWinPipe.c.
︙ | ︙ | |||
125 126 127 128 129 130 131 | * write. Set to 0 if no error has been * detected. This word is shared with the * writer thread so access must be * synchronized with the writable object. */ char *writeBuf; /* Current background output buffer. Access is * synchronized with the writable object. */ | | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | * write. Set to 0 if no error has been * detected. This word is shared with the * writer thread so access must be * synchronized with the writable object. */ char *writeBuf; /* Current background output buffer. Access is * synchronized with the writable object. */ size_t writeBufLen; /* Size of write buffer. Access is * synchronized with the writable object. */ size_t toWrite; /* Current amount to be written. Access is * synchronized with the writable object. */ int readFlags; /* Flags that are shared with the reader * thread. Access is synchronized with the * readable object. */ char extraByte; /* Buffer for extra character consumed by * reader thread. This byte is shared with the * reader thread so access must be |
︙ | ︙ | |||
166 167 168 169 170 171 172 173 174 175 | * exists before dereferencing this * pointer. */ } PipeEvent; /* * Declarations for functions used only in this file. */ static int ApplicationType(Tcl_Interp *interp, const char *fileName, char *fullName); | > > > > > > > > > > > > | < < < < < < < < < < < < < < < | 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 192 193 194 195 196 197 198 199 200 201 202 | * exists before dereferencing this * pointer. */ } PipeEvent; /* * Declarations for functions used only in this file. */ static Tcl_DriverBlockModeProc PipeBlockModeProc; static Tcl_DriverClose2Proc PipeClose2Proc; static Tcl_DriverGetHandleProc PipeGetHandleProc; static Tcl_DriverInputProc PipeInputProc; static Tcl_DriverOutputProc PipeOutputProc; static Tcl_DriverThreadActionProc PipeThreadActionProc; static Tcl_DriverWatchProc PipeWatchProc; static Tcl_EventCheckProc PipeCheckProc; static Tcl_EventProc PipeEventProc; static Tcl_EventSetupProc PipeSetupProc; static int ApplicationType(Tcl_Interp *interp, const char *fileName, char *fullName); static void BuildCommandLine(const char *executable, size_t argc, const char **argv, Tcl_DString *linePtr); static BOOL HasConsole(void); static void PipeInit(void); static DWORD WINAPI PipeReaderThread(LPVOID arg); static DWORD WINAPI PipeWriterThread(LPVOID arg); static int TempFileName(TCHAR name[MAX_PATH]); static int WaitForRead(PipeInfo *infoPtr, int blocking); /* * This structure describes the channel type structure for command pipe based * I/O. */ static const Tcl_ChannelType pipeChannelType = { |
︙ | ︙ | |||
575 576 577 578 579 580 581 | createMode = TRUNCATE_EXISTING; break; default: createMode = OPEN_EXISTING; break; } | | | 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 | createMode = TRUNCATE_EXISTING; break; default: createMode = OPEN_EXISTING; break; } nativePath = Tcl_WinUtfToTChar(path, TCL_STRLEN, &ds); /* * If the file is not being created, use the existing file attributes. */ flags = 0; if (!(mode & O_CREAT)) { |
︙ | ︙ | |||
670 671 672 673 674 675 676 | /* * Write the file out, doing line translations on the way. */ if (contents != NULL) { DWORD result, length; const char *p; | | | | 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 | /* * Write the file out, doing line translations on the way. */ if (contents != NULL) { DWORD result, length; const char *p; size_t toCopy; /* * Convert the contents from UTF to native encoding */ native = Tcl_UtfToExternalDString(NULL,contents,TCL_STRLEN, &dstring); toCopy = Tcl_DStringLength(&dstring); for (p = native; toCopy > 0; p++, toCopy--) { if (*p == '\n') { length = p - native; if (length > 0) { if (!WriteFile(handle, native, length, &result, NULL)) { |
︙ | ︙ | |||
908 909 910 911 912 913 914 | int TclpCreateProcess( Tcl_Interp *interp, /* Interpreter in which to leave errors that * occurred when creating the child process. * Error messages from the child process * itself are sent to errorFile. */ | | | 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 | int TclpCreateProcess( Tcl_Interp *interp, /* Interpreter in which to leave errors that * occurred when creating the child process. * Error messages from the child process * itself are sent to errorFile. */ size_t argc, /* Number of arguments in following array. */ const char **argv, /* Array of argument strings. argv[0] contains * the name of the executable converted to * native format (using the * Tcl_TranslateFileName call). Additional * arguments have not been converted. */ TclFile inputFile, /* If non-NULL, gives the file to use as input * for the child process. If inputFile file is |
︙ | ︙ | |||
1121 1122 1123 1124 1125 1126 1127 | } else { createFlags = DETACHED_PROCESS; } if (applType == APPL_DOS) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "DOS application process not supported on this platform", | | | 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 | } else { createFlags = DETACHED_PROCESS; } if (applType == APPL_DOS) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "DOS application process not supported on this platform", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "DOS_APP", NULL); goto end; } } /* |
︙ | ︙ | |||
1299 1300 1301 1302 1303 1304 1305 | * words, SearchPath will not find the program "a.b.exe" if the arguments * specified "a.b" and ".exe"). So, first look for the file as it is * named. Then manually append the extensions, looking for a match. */ applType = APPL_NONE; Tcl_DStringInit(&nameBuf); | | | | | 1296 1297 1298 1299 1300 1301 1302 1303 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 | * words, SearchPath will not find the program "a.b.exe" if the arguments * specified "a.b" and ".exe"). So, first look for the file as it is * named. Then manually append the extensions, looking for a match. */ applType = APPL_NONE; Tcl_DStringInit(&nameBuf); Tcl_DStringAppend(&nameBuf, originalName, TCL_STRLEN); nameLen = Tcl_DStringLength(&nameBuf); for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) { Tcl_DStringSetLength(&nameBuf, nameLen); Tcl_DStringAppend(&nameBuf, extensions[i], TCL_STRLEN); nativeName = Tcl_WinUtfToTChar(Tcl_DStringValue(&nameBuf), Tcl_DStringLength(&nameBuf), &ds); found = SearchPath(NULL, nativeName, NULL, MAX_PATH, nativeFullPath, &rest); Tcl_DStringFree(&ds); if (found == 0) { continue; } /* * Ignore matches on directories or data files, return if identified a * known type. */ attr = GetFileAttributes(nativeFullPath); if ((attr == 0xffffffff) || (attr & FILE_ATTRIBUTE_DIRECTORY)) { continue; } strcpy(fullName, Tcl_WinTCharToUtf(nativeFullPath, TCL_STRLEN, &ds)); Tcl_DStringFree(&ds); ext = strrchr(fullName, '.'); if ((ext != NULL) && (strcasecmp(ext, ".bat") == 0)) { applType = APPL_DOS; break; } |
︙ | ︙ | |||
1413 1414 1415 1416 1417 1418 1419 | * Replace long path name of executable with short path name for * 16-bit applications. Otherwise the application may not be able to * correctly parse its own command line to separate off the * application name from the arguments. */ GetShortPathName(nativeFullPath, nativeFullPath, MAX_PATH); | | | 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 | * Replace long path name of executable with short path name for * 16-bit applications. Otherwise the application may not be able to * correctly parse its own command line to separate off the * application name from the arguments. */ GetShortPathName(nativeFullPath, nativeFullPath, MAX_PATH); strcpy(fullName, Tcl_WinTCharToUtf(nativeFullPath, TCL_STRLEN, &ds)); Tcl_DStringFree(&ds); } return applType; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1442 1443 1444 1445 1446 1447 1448 | *---------------------------------------------------------------------- */ static void BuildCommandLine( const char *executable, /* Full path of executable (including * extension). Replacement for argv[0]. */ | | | 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 | *---------------------------------------------------------------------- */ static void BuildCommandLine( const char *executable, /* Full path of executable (including * extension). Replacement for argv[0]. */ size_t argc, /* Number of arguments. */ const char **argv, /* Argument strings in UTF. */ Tcl_DString *linePtr) /* Initialized Tcl_DString that receives the * command line (TCHAR). */ { const char *arg, *start, *special; int quote, i; Tcl_DString ds; |
︙ | ︙ | |||
2044 2045 2046 2047 2048 2049 2050 | * * Side effects: * Reads input from the actual channel. * *---------------------------------------------------------------------- */ | | | | 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 | * * Side effects: * Reads input from the actual channel. * *---------------------------------------------------------------------- */ static ssize_t PipeInputProc( ClientData instanceData, /* Pipe state. */ char *buf, /* Where to store data read. */ size_t bufSize, /* How much space is available in the * buffer? */ int *errorCode) /* Where to store error code. */ { PipeInfo *infoPtr = (PipeInfo *) instanceData; WinFile *filePtr = (WinFile*) infoPtr->readFile; DWORD count, bytesRead = 0; int result; |
︙ | ︙ | |||
2138 2139 2140 2141 2142 2143 2144 | * * Side effects: * Writes output on the actual channel. * *---------------------------------------------------------------------- */ | | | | 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 | * * Side effects: * Writes output on the actual channel. * *---------------------------------------------------------------------- */ static ssize_t PipeOutputProc( ClientData instanceData, /* Pipe state. */ const char *buf, /* The data buffer. */ size_t toWrite, /* How many bytes to write? */ int *errorCode) /* Where to store error code. */ { PipeInfo *infoPtr = (PipeInfo *) instanceData; WinFile *filePtr = (WinFile*) infoPtr->writeFile; DWORD bytesWritten, timeout; *errorCode = 0; |
︙ | ︙ | |||
2627 2628 2629 2630 2631 2632 2633 | */ /* ARGSUSED */ int Tcl_PidObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 | */ /* ARGSUSED */ int Tcl_PidObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Tcl_Channel chan; const Tcl_ChannelType *chanTypePtr; PipeInfo *pipePtr; int i; Tcl_Obj *resultPtr; |
︙ | ︙ |
Changes to win/tclWinReg.c.
︙ | ︙ | |||
94 95 96 97 98 99 100 | static DWORD lastType = REG_RESOURCE_LIST; /* * Declarations for functions defined in this file. */ static void AppendSystemError(Tcl_Interp *interp, DWORD error); | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | static DWORD lastType = REG_RESOURCE_LIST; /* * Declarations for functions defined in this file. */ static void AppendSystemError(Tcl_Interp *interp, DWORD error); static int BroadcastValue(Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static DWORD ConvertDWORD(DWORD type, DWORD value); static void DeleteCmd(ClientData clientData); static int DeleteKey(Tcl_Interp *interp, Tcl_Obj *keyNameObj, REGSAM mode); static int DeleteValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj, Tcl_Obj *valueNameObj, REGSAM mode); |
︙ | ︙ | |||
121 122 123 124 125 126 127 | HKEY *keyPtr); static int ParseKeyName(Tcl_Interp *interp, char *name, char **hostNamePtr, HKEY *rootKeyPtr, char **keyNamePtr); static DWORD RecursiveDeleteKey(HKEY hStartKey, const TCHAR * pKeyName, REGSAM mode); static int RegistryObjCmd(ClientData clientData, | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | HKEY *keyPtr); static int ParseKeyName(Tcl_Interp *interp, char *name, char **hostNamePtr, HKEY *rootKeyPtr, char **keyNamePtr); static DWORD RecursiveDeleteKey(HKEY hStartKey, const TCHAR * pKeyName, REGSAM mode); static int RegistryObjCmd(ClientData clientData, Tcl_Interp *interp, size_t objc, Tcl_Obj *const objv[]); static int SetValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj, Tcl_Obj *valueNameObj, Tcl_Obj *dataObj, Tcl_Obj *typeObj, REGSAM mode); DLLEXPORT int Registry_Init(Tcl_Interp *interp); DLLEXPORT int Registry_Unload(Tcl_Interp *interp, int flags); |
︙ | ︙ | |||
190 191 192 193 194 195 196 | Tcl_Command cmd; Tcl_Obj *objv[3]; /* * Unregister the registry package. There is no Tcl_PkgForget() */ | | | | | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | Tcl_Command cmd; Tcl_Obj *objv[3]; /* * Unregister the registry package. There is no Tcl_PkgForget() */ objv[0] = Tcl_NewStringObj("package", TCL_STRLEN); objv[1] = Tcl_NewStringObj("forget", TCL_STRLEN); objv[2] = Tcl_NewStringObj("registry", TCL_STRLEN); Tcl_EvalObjv(interp, 3, objv, TCL_EVAL_GLOBAL); /* * Delete the originally registered command. */ cmd = Tcl_GetAssocData(interp, REGISTRY_ASSOC_KEY, NULL); |
︙ | ︙ | |||
253 254 255 256 257 258 259 | *---------------------------------------------------------------------- */ static int RegistryObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ | | | | | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | *---------------------------------------------------------------------- */ static int RegistryObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument values. */ { size_t n = 1, argc; int index; REGSAM mode = 0; const char *errString = NULL; static const char *const subcommands[] = { "broadcast", "delete", "get", "keys", "set", "type", "values", NULL }; enum SubCmdIdx { |
︙ | ︙ | |||
402 403 404 405 406 407 408 | Tcl_Obj *keyNameObj, /* Name of key to delete. */ REGSAM mode) /* Mode flags to pass. */ { char *tail, *buffer, *hostName, *keyName; const TCHAR *nativeTail; HKEY rootKey, subkey; DWORD result; | | | | | 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 | Tcl_Obj *keyNameObj, /* Name of key to delete. */ REGSAM mode) /* Mode flags to pass. */ { char *tail, *buffer, *hostName, *keyName; const TCHAR *nativeTail; HKEY rootKey, subkey; DWORD result; size_t length; Tcl_DString buf; REGSAM saveMode = mode; /* * Find the parent of the key being deleted and open it. */ keyName = Tcl_GetStringFromObj(keyNameObj, &length); buffer = ckalloc(length + 1); strcpy(buffer, keyName); if (ParseKeyName(interp, buffer, &hostName, &rootKey, &keyName) != TCL_OK) { ckfree(buffer); return TCL_ERROR; } if (*keyName == '\0') { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad key: cannot delete root keys", TCL_STRLEN)); Tcl_SetErrorCode(interp, "WIN_REG", "DEL_ROOT_KEY", NULL); ckfree(buffer); return TCL_ERROR; } tail = strrchr(keyName, '\\'); if (tail) { |
︙ | ︙ | |||
444 445 446 447 448 449 450 | result = OpenSubKey(hostName, rootKey, keyName, mode, 0, &subkey); if (result != ERROR_SUCCESS) { ckfree(buffer); if (result == ERROR_FILE_NOT_FOUND) { return TCL_OK; } Tcl_SetObjResult(interp, | | | | | 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 470 471 472 473 | result = OpenSubKey(hostName, rootKey, keyName, mode, 0, &subkey); if (result != ERROR_SUCCESS) { ckfree(buffer); if (result == ERROR_FILE_NOT_FOUND) { return TCL_OK; } Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to delete key: ", TCL_STRLEN)); AppendSystemError(interp, result); return TCL_ERROR; } /* * Now we recursively delete the key and everything below it. */ nativeTail = Tcl_WinUtfToTChar(tail, TCL_STRLEN, &buf); result = RecursiveDeleteKey(subkey, nativeTail, saveMode); Tcl_DStringFree(&buf); if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to delete key: ", TCL_STRLEN)); AppendSystemError(interp, result); result = TCL_ERROR; } else { result = TCL_OK; } RegCloseKey(subkey); |
︙ | ︙ | |||
496 497 498 499 500 501 502 | Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *keyNameObj, /* Name of key. */ Tcl_Obj *valueNameObj, /* Name of value to delete. */ REGSAM mode) /* Mode flags to pass. */ { HKEY key; char *valueName; | | | 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 | Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *keyNameObj, /* Name of key. */ Tcl_Obj *valueNameObj, /* Name of value to delete. */ REGSAM mode) /* Mode flags to pass. */ { HKEY key; char *valueName; size_t length; DWORD result; Tcl_DString ds; /* * Attempt to open the key for deletion. */ |
︙ | ︙ | |||
652 653 654 655 656 657 658 | REGSAM mode) /* Mode flags to pass. */ { HKEY key; DWORD result, type; Tcl_DString ds; const char *valueName; const TCHAR *nativeValue; | | | 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 | REGSAM mode) /* Mode flags to pass. */ { HKEY key; DWORD result, type; Tcl_DString ds; const char *valueName; const TCHAR *nativeValue; size_t length; /* * Attempt to open the key for reading. */ mode |= KEY_QUERY_VALUE; if (OpenKey(interp, keyNameObj, mode, 0, &key) != TCL_OK) { |
︙ | ︙ | |||
691 692 693 694 695 696 697 | * Set the type into the result. Watch out for unknown types. If we don't * know about the type, just use the numeric value. */ if (type > lastType) { Tcl_SetObjResult(interp, Tcl_NewLongObj((int) type)); } else { | | > | 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 | * Set the type into the result. Watch out for unknown types. If we don't * know about the type, just use the numeric value. */ if (type > lastType) { Tcl_SetObjResult(interp, Tcl_NewLongObj((int) type)); } else { Tcl_SetObjResult(interp, Tcl_NewStringObj( typeNames[type], TCL_STRLEN)); } return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
725 726 727 728 729 730 731 | REGSAM mode) /* Mode flags to pass. */ { HKEY key; const char *valueName; const TCHAR *nativeValue; DWORD result, length, type; Tcl_DString data, buf; | | | 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 | REGSAM mode) /* Mode flags to pass. */ { HKEY key; const char *valueName; const TCHAR *nativeValue; DWORD result, length, type; Tcl_DString data, buf; size_t nameLen; /* * Attempt to open the key for reading. */ mode |= KEY_QUERY_VALUE; if (OpenKey(interp, keyNameObj, mode, 0, &key) != TCL_OK) { |
︙ | ︙ | |||
803 804 805 806 807 808 809 | * terminated by two null characters. Also do a bounds check in case * we get bogus data. */ while ((p < end) && *((Tcl_UniChar *) p) != 0) { Tcl_UniChar *up; | | | > | 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 | * terminated by two null characters. Also do a bounds check in case * we get bogus data. */ while ((p < end) && *((Tcl_UniChar *) p) != 0) { Tcl_UniChar *up; Tcl_WinTCharToUtf((TCHAR *) p, TCL_STRLEN, &buf); Tcl_ListObjAppendElement(interp, resultPtr, Tcl_NewStringObj(Tcl_DStringValue(&buf), Tcl_DStringLength(&buf))); up = (Tcl_UniChar *) p; while (*up++ != 0) {/* empty body */} p = (char *) up; Tcl_DStringFree(&buf); } Tcl_SetObjResult(interp, resultPtr); } else if ((type == REG_SZ) || (type == REG_EXPAND_SZ)) { Tcl_WinTCharToUtf((TCHAR *) Tcl_DStringValue(&data), TCL_STRLEN, &buf); Tcl_DStringResult(interp, &buf); } else { /* * Save binary data as a byte array. */ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj( |
︙ | ︙ | |||
941 942 943 944 945 946 947 | Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *keyNameObj, /* Key to open. */ REGSAM mode, /* Access mode. */ int flags, /* 0 or REG_CREATE. */ HKEY *keyPtr) /* Returned HKEY. */ { char *keyName, *buffer, *hostName; | | | | 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 | Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *keyNameObj, /* Key to open. */ REGSAM mode, /* Access mode. */ int flags, /* 0 or REG_CREATE. */ HKEY *keyPtr) /* Returned HKEY. */ { char *keyName, *buffer, *hostName; size_t length; HKEY rootKey; DWORD result; keyName = Tcl_GetStringFromObj(keyNameObj, &length); buffer = ckalloc(length + 1); strcpy(buffer, keyName); result = ParseKeyName(interp, buffer, &hostName, &rootKey, &keyName); if (result == TCL_OK) { result = OpenSubKey(hostName, rootKey, keyName, mode, flags, keyPtr); if (result != ERROR_SUCCESS) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to open key: ", TCL_STRLEN)); AppendSystemError(interp, result); result = TCL_ERROR; } else { result = TCL_OK; } } |
︙ | ︙ | |||
1001 1002 1003 1004 1005 1006 1007 | Tcl_DString buf; /* * Attempt to open the root key on a remote host if necessary. */ if (hostName) { | | | | 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 | Tcl_DString buf; /* * Attempt to open the root key on a remote host if necessary. */ if (hostName) { hostName = (char *) Tcl_WinUtfToTChar(hostName, TCL_STRLEN, &buf); result = RegConnectRegistry((TCHAR *)hostName, rootKey, &rootKey); Tcl_DStringFree(&buf); if (result != ERROR_SUCCESS) { return result; } } /* * Now open the specified key with the requested permissions. Note that * this key must be closed by the caller. */ keyName = (char *) Tcl_WinUtfToTChar(keyName, TCL_STRLEN, &buf); if (flags & REG_CREATE) { DWORD create; result = RegCreateKeyEx(rootKey, (TCHAR *)keyName, 0, NULL, REG_OPTION_NON_VOLATILE, mode, NULL, keyPtr, &create); } else if (rootKey == HKEY_PERFORMANCE_DATA) { /* |
︙ | ︙ | |||
1116 1117 1118 1119 1120 1121 1122 | } } /* * Look for a matching root name. */ | | | 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 | } } /* * Look for a matching root name. */ rootObj = Tcl_NewStringObj(rootName, TCL_STRLEN); result = Tcl_GetIndexFromObjStruct(interp, rootObj, rootKeyNames, sizeof(char *), "root name", TCL_EXACT, &index); Tcl_DecrRefCount(rootObj); if (result != TCL_OK) { return TCL_ERROR; } *rootKeyPtr = rootKeys[index]; |
︙ | ︙ | |||
1245 1246 1247 1248 1249 1250 1251 | Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *keyNameObj, /* Name of key. */ Tcl_Obj *valueNameObj, /* Name of value to set. */ Tcl_Obj *dataObj, /* Data to be written. */ Tcl_Obj *typeObj, /* Type of data to be written. */ REGSAM mode) /* Mode flags to pass. */ { | | > | 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 | Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *keyNameObj, /* Name of key. */ Tcl_Obj *valueNameObj, /* Name of value to set. */ Tcl_Obj *dataObj, /* Data to be written. */ Tcl_Obj *typeObj, /* Type of data to be written. */ REGSAM mode) /* Mode flags to pass. */ { int type; size_t length; DWORD result; HKEY key; const char *valueName; Tcl_DString nameBuf; if (typeObj == NULL) { type = REG_SZ; |
︙ | ︙ | |||
1282 1283 1284 1285 1286 1287 1288 | } value = ConvertDWORD((DWORD) type, (DWORD) value); result = RegSetValueEx(key, (TCHAR *) valueName, 0, (DWORD) type, (BYTE *) &value, sizeof(DWORD)); } else if (type == REG_MULTI_SZ) { Tcl_DString data, buf; | | | 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 | } value = ConvertDWORD((DWORD) type, (DWORD) value); result = RegSetValueEx(key, (TCHAR *) valueName, 0, (DWORD) type, (BYTE *) &value, sizeof(DWORD)); } else if (type == REG_MULTI_SZ) { Tcl_DString data, buf; size_t objc, i; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, dataObj, &objc, &objv) != TCL_OK) { RegCloseKey(key); Tcl_DStringFree(&nameBuf); return TCL_ERROR; } |
︙ | ︙ | |||
1350 1351 1352 1353 1354 1355 1356 | } Tcl_DStringFree(&nameBuf); RegCloseKey(key); if (result != ERROR_SUCCESS) { Tcl_SetObjResult(interp, | | | 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 | } Tcl_DStringFree(&nameBuf); RegCloseKey(key); if (result != ERROR_SUCCESS) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unable to set value: ", TCL_STRLEN)); AppendSystemError(interp, result); return TCL_ERROR; } return TCL_OK; } /* |
︙ | ︙ | |||
1377 1378 1379 1380 1381 1382 1383 | * *---------------------------------------------------------------------- */ static int BroadcastValue( Tcl_Interp *interp, /* Current interpreter. */ | | | | 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 | * *---------------------------------------------------------------------- */ static int BroadcastValue( Tcl_Interp *interp, /* Current interpreter. */ size_t objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument values. */ { LRESULT result; DWORD_PTR sendResult; UINT timeout = 3000; size_t len; const char *str; Tcl_Obj *objPtr; if (objc == 3) { str = Tcl_GetStringFromObj(objv[1], &len); if ((len < 2) || (*str != '-') || strncmp(str, "-timeout", (size_t) len)) { |
︙ | ︙ | |||
1440 1441 1442 1443 1444 1445 1446 | */ static void AppendSystemError( Tcl_Interp *interp, /* Current interpreter. */ DWORD error) /* Result code from error. */ { | | | | 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 | */ static void AppendSystemError( Tcl_Interp *interp, /* Current interpreter. */ DWORD error) /* Result code from error. */ { size_t length; TCHAR *tMsgPtr, **tMsgPtrPtr = &tMsgPtr; const char *msg; char id[TCL_INTEGER_SPACE], msgBuf[24 + TCL_INTEGER_SPACE]; Tcl_DString ds; Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); if (Tcl_IsShared(resultPtr)) { resultPtr = Tcl_DuplicateObj(resultPtr); } length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (TCHAR *) tMsgPtrPtr, 0, NULL); if (length == 0) { sprintf(msgBuf, "unknown error: %ld", error); msg = msgBuf; } else { char *msgPtr; Tcl_WinTCharToUtf(tMsgPtr, TCL_STRLEN, &ds); LocalFree(tMsgPtr); msgPtr = Tcl_DStringValue(&ds); length = Tcl_DStringLength(&ds); /* * Trim the trailing CR/LF from the system message. |
︙ | ︙ |
Changes to win/tclWinSerial.c.
︙ | ︙ | |||
107 108 109 110 111 112 113 | DWORD writeError; /* An error caused by the last background * write. Set to 0 if no error has been * detected. This word is shared with the * writer thread so access must be * synchronized with the evWritable object. */ char *writeBuf; /* Current background output buffer. Access is * synchronized with the evWritable object. */ | | | | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | DWORD writeError; /* An error caused by the last background * write. Set to 0 if no error has been * detected. This word is shared with the * writer thread so access must be * synchronized with the evWritable object. */ char *writeBuf; /* Current background output buffer. Access is * synchronized with the evWritable object. */ size_t writeBufLen; /* Size of write buffer. Access is * synchronized with the evWritable object. */ size_t toWrite; /* Current amount to be written. Access is * synchronized with the evWritable object. */ size_t writeQueue; /* Number of bytes pending in output queue. * Offset to DCB.cbInQue. Used to query * [fconfigure -queue] */ } SerialInfo; typedef struct { /* * The following pointer refers to the head of the list of serials that |
︙ | ︙ | |||
157 158 159 160 161 162 163 | 0, /* WriteTotalTimeoutConstant */ }; /* * Declarations for functions used only in this file. */ | | < | < < < | < | | < | < | > | | > | | | | | | > < < | 157 158 159 160 161 162 163 164 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 | 0, /* WriteTotalTimeoutConstant */ }; /* * Declarations for functions used only in this file. */ static Tcl_DriverBlockModeProc SerialBlockProc; static Tcl_DriverCloseProc SerialCloseProc; static Tcl_DriverGetHandleProc SerialGetHandleProc; static Tcl_DriverGetOptionProc SerialGetOptionProc; static Tcl_DriverInputProc SerialInputProc; static Tcl_DriverOutputProc SerialOutputProc; static Tcl_DriverSetOptionProc SerialSetOptionProc; static Tcl_DriverThreadActionProc SerialThreadActionProc; static Tcl_DriverWatchProc SerialWatchProc; static Tcl_EventCheckProc SerialCheckProc; static Tcl_EventProc SerialEventProc; static Tcl_EventSetupProc SerialSetupProc; static Tcl_ExitProc SerialExitHandler; static Tcl_ExitProc ProcExitHandler; static ThreadSpecificData *SerialInit(void); static DWORD WINAPI SerialWriterThread(LPVOID arg); static int SerialBlockingRead(SerialInfo *infoPtr, LPVOID buf, DWORD bufSize, LPDWORD lpRead, LPOVERLAPPED osPtr); static int SerialBlockingWrite(SerialInfo *infoPtr, LPVOID buf, DWORD bufSize, LPDWORD lpWritten, LPOVERLAPPED osPtr); /* |
︙ | ︙ | |||
882 883 884 885 886 887 888 | * * Side effects: * Reads input from the actual channel. * *---------------------------------------------------------------------- */ | | | | 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 | * * Side effects: * Reads input from the actual channel. * *---------------------------------------------------------------------- */ static ssize_t SerialInputProc( ClientData instanceData, /* Serial state. */ char *buf, /* Where to store data read. */ size_t bufSize, /* How much space is available in the * buffer? */ int *errorCode) /* Where to store error code. */ { SerialInfo *infoPtr = (SerialInfo *) instanceData; DWORD bytesRead = 0; COMSTAT cStat; |
︙ | ︙ | |||
989 990 991 992 993 994 995 | * * Side effects: * Writes output on the actual channel. * *---------------------------------------------------------------------- */ | | | | 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 | * * Side effects: * Writes output on the actual channel. * *---------------------------------------------------------------------- */ static ssize_t SerialOutputProc( ClientData instanceData, /* Serial state. */ const char *buf, /* The data buffer. */ size_t toWrite, /* How many bytes to write? */ int *errorCode) /* Where to store error code. */ { SerialInfo *infoPtr = (SerialInfo *) instanceData; DWORD bytesWritten, timeout; *errorCode = 0; |
︙ | ︙ | |||
1642 1643 1644 1645 1646 1647 1648 | static int SerialSetOptionProc( ClientData instanceData, /* File state. */ Tcl_Interp *interp, /* For error reporting - can be NULL. */ const char *optionName, /* Which option to set? */ const char *value) /* New value for option. */ { | | | < < | | 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 | static int SerialSetOptionProc( ClientData instanceData, /* File state. */ Tcl_Interp *interp, /* For error reporting - can be NULL. */ const char *optionName, /* Which option to set? */ const char *value) /* New value for option. */ { SerialInfo *infoPtr = (SerialInfo *) instanceData; DCB dcb; BOOL result, flag; size_t len, vlen; Tcl_DString ds; const TCHAR *native; size_t argc; const char **argv; /* * Parse options. This would be far easier if we had Tcl_Objs to work with * as that would let us use Tcl_GetIndexFromObj()... */ len = strlen(optionName); vlen = strlen(value); /* * Option -mode baud,parity,databits,stopbits */ if ((len > 2) && (strncmp(optionName, "-mode", len) == 0)) { if (!GetCommState(infoPtr->handle, &dcb)) { goto getStateFailed; } native = Tcl_WinUtfToTChar(value, TCL_STRLEN, &ds); result = BuildCommDCB(native, &dcb); Tcl_DStringFree(&ds); if (result == FALSE) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad value \"%s\" for -mode: should be baud,parity,data,stop", |
︙ | ︙ | |||
1770 1771 1772 1773 1774 1775 1776 | return TCL_ERROR; } if (argc != 2) { badXchar: if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -xchar: should be a list of" | | > | 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 | return TCL_ERROR; } if (argc != 2) { badXchar: if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -xchar: should be a list of" " two elements with each a single character", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "XCHAR", NULL); } ckfree(argv); return TCL_ERROR; } /* |
︙ | ︙ | |||
1843 1844 1845 1846 1847 1848 1849 | break; } if (strncasecmp(argv[i], "DTR", strlen(argv[i])) == 0) { if (!EscapeCommFunction(infoPtr->handle, (DWORD) (flag ? SETDTR : CLRDTR))) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | | | 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 | break; } if (strncasecmp(argv[i], "DTR", strlen(argv[i])) == 0) { if (!EscapeCommFunction(infoPtr->handle, (DWORD) (flag ? SETDTR : CLRDTR))) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't set DTR signal", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE", "TTY_SIGNAL", NULL); } result = TCL_ERROR; break; } } else if (strncasecmp(argv[i], "RTS", strlen(argv[i])) == 0) { if (!EscapeCommFunction(infoPtr->handle, (DWORD) (flag ? SETRTS : CLRRTS))) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't set RTS signal", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE", "TTY_SIGNAL", NULL); } result = TCL_ERROR; break; } } else if (strncasecmp(argv[i], "BREAK", strlen(argv[i])) == 0) { if (!EscapeCommFunction(infoPtr->handle, (DWORD) (flag ? SETBREAK : CLRBREAK))) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't set BREAK signal", TCL_STRLEN)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE", "TTY_SIGNAL", NULL); } result = TCL_ERROR; break; } } else { |
︙ | ︙ |
Changes to win/tclWinSock.c.
︙ | ︙ | |||
16 17 18 19 20 21 22 | * socket messages from the OS. * * - To ensure that message reception is always running this window is * actually owned and handled by an internal thread. This we call the * co-thread of Tcl's thread. * * - The whole structure is set up by InitSockets() which is called for each | | | | | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | * socket messages from the OS. * * - To ensure that message reception is always running this window is * actually owned and handled by an internal thread. This we call the * co-thread of Tcl's thread. * * - The whole structure is set up by InitSockets() which is called for each * Tcl thread. The implementation of the co-thread is in SocketThread(), and * the messages are handled by SocketProc(). The connection between both is * not directly visible, it is done through a Win32 window class. This * class is initialized by InitSockets() as well, and used in the creation * of the message receiver windows. * * - An important thing to note is that *both* thread and co-thread have * access to the list of sockets maintained in the private TSD data of the * thread. The co-thread was given access to it upon creation through the * new thread's client-data. * * Because of this dual access the TSD data contains an OS mutex, the |
︙ | ︙ | |||
225 226 227 228 229 230 231 232 233 234 235 236 237 238 | static DWORD WINAPI SocketThread(LPVOID arg); static void TcpThreadActionProc(ClientData instanceData, int action); static Tcl_EventCheckProc SocketCheckProc; static Tcl_EventProc SocketEventProc; static Tcl_EventSetupProc SocketSetupProc; static Tcl_DriverBlockModeProc TcpBlockProc; static Tcl_DriverCloseProc TcpCloseProc; static Tcl_DriverClose2Proc TcpClose2Proc; static Tcl_DriverSetOptionProc TcpSetOptionProc; static Tcl_DriverGetOptionProc TcpGetOptionProc; static Tcl_DriverInputProc TcpInputProc; static Tcl_DriverOutputProc TcpOutputProc; | > | 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | static DWORD WINAPI SocketThread(LPVOID arg); static void TcpThreadActionProc(ClientData instanceData, int action); static Tcl_EventCheckProc SocketCheckProc; static Tcl_EventProc SocketEventProc; static Tcl_EventSetupProc SocketSetupProc; static Tcl_DriverBlockModeProc TcpBlockProc; static Tcl_DriverCloseProc TcpCloseProc; static Tcl_DriverClose2Proc TcpClose2Proc; static Tcl_DriverSetOptionProc TcpSetOptionProc; static Tcl_DriverGetOptionProc TcpGetOptionProc; static Tcl_DriverInputProc TcpInputProc; static Tcl_DriverOutputProc TcpOutputProc; |
︙ | ︙ | |||
554 555 556 557 558 559 560 | Tcl_MutexUnlock(&socketMutex); if (SocketsEnabled()) { return TCL_OK; } if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 | Tcl_MutexUnlock(&socketMutex); if (SocketsEnabled()) { return TCL_OK; } if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "sockets are not available on this system", TCL_STRLEN)); } return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
732 733 734 735 736 737 738 | /* * Accept the incoming connection request. */ len = sizeof(address); newSocket = accept(fds->fd, &(addr.sa), &len); | > | | | | | | | | | | > > | | | | | > > | | | > | 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 | /* * Accept the incoming connection request. */ len = sizeof(address); newSocket = accept(fds->fd, &(addr.sa), &len); /* * On Tcl server sockets with multiple OS fds we loop over the fds * trying an accept() on each, so we expect INVALID_SOCKET. There * are also other network stack conditions that can result in * FD_ACCEPT but a subsequent failure on accept() by the time we * get around to it. Access to sockets (acceptEventCount, * readyEvents) in socketList is still protected by the lock * (prevents reintroduction of SF Tcl Bug 3056775. */ if (newSocket == INVALID_SOCKET) { /* int err = WSAGetLastError(); */ continue; } /* * It is possible that more than one FD_ACCEPT has been sent, so * an extra count must be kept. Decrement the count, and reset the * readyEvent bit if the count is no longer > 0. */ infoPtr->acceptEventCount--; if (infoPtr->acceptEventCount <= 0) { infoPtr->readyEvents &= ~(FD_ACCEPT); } SetEvent(tsdPtr->socketListLock); /* * Caution: TcpAccept() has the side-effect of evaluating the * server accept script (via AcceptCallbackProc() in tclIOCmd.c), * which can close the server socket and invalidate infoPtr and * fds. If TcpAccept() accepts a socket we must return immediately * and let SocketCheckProc queue additional FD_ACCEPT events. */ TcpAccept(fds, newSocket, addr); return 1; } /* * Loop terminated with no sockets accepted; clear the ready mask so * we can detect the next connection request. Note that connection * requests are level triggered, so if there is a request already * pending, a new event will be generated. */ infoPtr->acceptEventCount = 0; infoPtr->readyEvents &= ~(FD_ACCEPT); SetEvent(tsdPtr->socketListLock); return 1; } |
︙ | ︙ | |||
987 988 989 990 991 992 993 | break; case TCL_CLOSE_WRITE: sd = SD_SEND; break; default: if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | > | | > > | 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 | break; case TCL_CLOSE_WRITE: sd = SD_SEND; break; default: if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "Socket close2proc called bidirectionally", TCL_STRLEN)); } return TCL_ERROR; } /* * Single fd operation: Tcl_OpenTcpServer() does not set TCL_READABLE or * TCL_WRITABLE so this should never be called for a server socket. */ if (shutdown(infoPtr->sockets->fd, sd) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); errorCode = Tcl_GetErrno(); } return errorCode; } |
︙ | ︙ | |||
1045 1046 1047 1048 1049 1050 1051 | } /* Populate new FD */ fds->fd = socket; fds->infoPtr = infoPtr; fds->next = NULL; } | | < | 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 | } /* Populate new FD */ fds->fd = socket; fds->infoPtr = infoPtr; fds->next = NULL; } /* *---------------------------------------------------------------------- * * NewSocketInfo -- * * This function allocates and initializes a new SocketInfo structure. * |
︙ | ︙ | |||
1161 1162 1163 1164 1165 1166 1167 | } if (!TclCreateSocketAddress(interp, &myaddrlist, myaddr, myport, 1, &errorMsg)) { goto error; } if (server) { | < | 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 | } if (!TclCreateSocketAddress(interp, &myaddrlist, myaddr, myport, 1, &errorMsg)) { goto error; } if (server) { for (addrPtr = addrlist; addrPtr != NULL; addrPtr = addrPtr->ai_next) { sock = socket(addrPtr->ai_family, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { TclWinConvertError((DWORD) WSAGetLastError()); continue; } |
︙ | ︙ | |||
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 | */ if (bind(sock, myaddrPtr->ai_addr, myaddrPtr->ai_addrlen) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); goto looperror; } /* * Set the socket into nonblocking mode if the connect should * be done in the background. */ if (async && ioctlsocket(sock, (long) FIONBIO, &flag) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); goto looperror; } /* | > > | 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 | */ if (bind(sock, myaddrPtr->ai_addr, myaddrPtr->ai_addrlen) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); goto looperror; } /* * Set the socket into nonblocking mode if the connect should * be done in the background. */ if (async && ioctlsocket(sock, (long) FIONBIO, &flag) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); goto looperror; } /* |
︙ | ︙ | |||
1720 1721 1722 1723 1724 1725 1726 | * * Side effects: * Consumes input from the socket. * *---------------------------------------------------------------------- */ | | | | | 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 | * * Side effects: * Consumes input from the socket. * *---------------------------------------------------------------------- */ static ssize_t TcpInputProc( ClientData instanceData, /* The socket state. */ char *buf, /* Where to store data. */ size_t toRead, /* Maximum number of bytes to read. */ int *errorCodePtr) /* Where to store error codes. */ { SocketInfo *infoPtr = instanceData; ssize_t bytesRead; DWORD error; ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); *errorCodePtr = 0; /* * Check that WinSock is initialized; do not call it if not, to prevent |
︙ | ︙ | |||
1774 1775 1776 1777 1778 1779 1780 | * read. We have to simulate blocking behavior here since we are always * using non-blocking sockets. */ while (1) { SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, (LPARAM) infoPtr); | > > | > > > | 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 | * read. We have to simulate blocking behavior here since we are always * using non-blocking sockets. */ while (1) { SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, (LPARAM) infoPtr); /* * Single fd operation: this proc is only called for a connected * socket. */ bytesRead = recv(infoPtr->sockets->fd, buf, toRead, 0); infoPtr->readyEvents &= ~(FD_READ); /* * Check for end-of-file condition or successful read. */ |
︙ | ︙ | |||
1857 1858 1859 1860 1861 1862 1863 | * * Side effects: * Produces output on the socket. * *---------------------------------------------------------------------- */ | | | | | 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 | * * Side effects: * Produces output on the socket. * *---------------------------------------------------------------------- */ static ssize_t TcpOutputProc( ClientData instanceData, /* The socket state. */ const char *buf, /* Where to get data. */ size_t toWrite, /* Maximum number of bytes to write. */ int *errorCodePtr) /* Where to store error codes. */ { SocketInfo *infoPtr = instanceData; ssize_t bytesWritten; DWORD error; ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); *errorCodePtr = 0; /* * Check that WinSock is initialized; do not call it if not, to prevent |
︙ | ︙ | |||
1895 1896 1897 1898 1899 1900 1901 | return -1; } while (1) { SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, (LPARAM) infoPtr); | > | > > > | 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 | return -1; } while (1) { SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, (LPARAM) infoPtr); /* * Single fd operation: this proc is only called for a connected * socket. */ bytesWritten = send(infoPtr->sockets->fd, buf, toWrite, 0); if (bytesWritten != SOCKET_ERROR) { /* * Since Windows won't generate a new write event until we hit an * overflow condition, we need to force the event loop to poll * until the condition changes. */ |
︙ | ︙ | |||
1986 1987 1988 1989 1990 1991 1992 | * system crashes. This can happen at exit time if the exit handler for * WinSock ran before other exit handlers that want to use sockets. */ if (!SocketsEnabled()) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 | * system crashes. This can happen at exit time if the exit handler for * WinSock ran before other exit handlers that want to use sockets. */ if (!SocketsEnabled()) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "winsock is not initialized", TCL_STRLEN)); } return TCL_ERROR; } #ifdef TCL_FEATURE_KEEPALIVE_NAGLE #error "TCL_FEATURE_KEEPALIVE_NAGLE not reviewed for whether to treat infoPtr->sockets as single fd or list" sock = infoPtr->sockets->fd; |
︙ | ︙ | |||
2093 2094 2095 2096 2097 2098 2099 | * system crashes. This can happen at exit time if the exit handler for * WinSock ran before other exit handlers that want to use sockets. */ if (!SocketsEnabled()) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( | | | 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 | * system crashes. This can happen at exit time if the exit handler for * WinSock ran before other exit handlers that want to use sockets. */ if (!SocketsEnabled()) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "winsock is not initialized", TCL_STRLEN)); } return TCL_ERROR; } sock = infoPtr->sockets->fd; if (optionName != NULL) { len = strlen(optionName); |
︙ | ︙ | |||
2117 2118 2119 2120 2121 2122 2123 | ret = TclWinGetSockOpt(sock, SOL_SOCKET, SO_ERROR, (char *)&err, &optlen); if (ret == SOCKET_ERROR) { err = WSAGetLastError(); } if (err) { TclWinConvertError(err); | | | 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 | ret = TclWinGetSockOpt(sock, SOL_SOCKET, SO_ERROR, (char *)&err, &optlen); if (ret == SOCKET_ERROR) { err = WSAGetLastError(); } if (err) { TclWinConvertError(err); Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()),TCL_STRLEN); } return TCL_OK; } if (interp != NULL && Tcl_GetVar(interp, SUPPRESS_RDNS_VAR, 0) != NULL) { reverseDNS = NI_NUMERICHOST; } |
︙ | ︙ | |||
2510 2511 2512 2513 2514 2515 2516 | for (infoPtr = tsdPtr->socketList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { for (fds = infoPtr->sockets; fds != NULL; fds = fds->next) { if (fds->fd == socket) { /* * Update the socket state. * | | | | > | | | 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 2554 2555 2556 2557 2558 2559 | for (infoPtr = tsdPtr->socketList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { for (fds = infoPtr->sockets; fds != NULL; fds = fds->next) { if (fds->fd == socket) { /* * Update the socket state. * * A count of FD_ACCEPTS is stored, so if an FD_CLOSE * event happens, then clear the FD_ACCEPT count. * Otherwise, increment the count if the current event is * an FD_ACCEPT. */ if (event & FD_CLOSE) { infoPtr->acceptEventCount = 0; infoPtr->readyEvents &= ~(FD_WRITE|FD_ACCEPT); } else if (event & FD_ACCEPT) { infoPtr->acceptEventCount++; } if (event & FD_CONNECT) { /* * The socket is now connected, clear the async * connect flag. */ infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT); /* * Remember any error that occurred so we can report * connection failures. |
︙ | ︙ | |||
2641 2642 2643 2644 2645 2646 2647 | Tcl_DString ds; if (GetComputerName(tbuf, &length) != 0) { /* * Convert string from native to UTF then change to lowercase. */ | | < | | | 2661 2662 2663 2664 2665 2666 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 | Tcl_DString ds; if (GetComputerName(tbuf, &length) != 0) { /* * Convert string from native to UTF then change to lowercase. */ Tcl_UtfToLower(Tcl_WinTCharToUtf(tbuf, TCL_STRLEN, &ds)); } else { Tcl_DStringInit(&ds); if (TclpHasSockets(NULL) == TCL_OK) { /* * The buffer size of 256 is recommended by the MSDN page that * documents gethostname() as being always adequate. */ Tcl_DString inDs; Tcl_DStringInit(&inDs); Tcl_DStringSetLength(&inDs, 256); if (gethostname(Tcl_DStringValue(&inDs), Tcl_DStringLength(&inDs)) == 0) { Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&inDs), TCL_STRLEN, &ds); } Tcl_DStringFree(&inDs); } } *encodingPtr = Tcl_GetEncoding(NULL, "utf-8"); *lengthPtr = Tcl_DStringLength(&ds); |
︙ | ︙ |
Changes to win/tclWinThrd.c.
︙ | ︙ | |||
207 208 209 210 211 212 213 | */ int TclpThreadCreate( Tcl_ThreadId *idPtr, /* Return, the ID of the thread. */ Tcl_ThreadCreateProc *proc, /* Main() function of the thread. */ ClientData clientData, /* The one argument to Main(). */ | | | | 207 208 209 210 211 212 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 | */ int TclpThreadCreate( Tcl_ThreadId *idPtr, /* Return, the ID of the thread. */ Tcl_ThreadCreateProc *proc, /* Main() function of the thread. */ ClientData clientData, /* The one argument to Main(). */ size_t stackSize, /* Size of stack for the new thread. */ int flags) /* Flags controlling behaviour of the new * thread. */ { WinThread *winThreadPtr; /* Per-thread startup info */ HANDLE tHandle; winThreadPtr = (WinThread *)ckalloc(sizeof(WinThread)); winThreadPtr->lpStartAddress = (LPTHREAD_START_ROUTINE) proc; winThreadPtr->lpParameter = clientData; winThreadPtr->fpControl = _controlfp(0, 0); EnterCriticalSection(&joinLock); *idPtr = 0; /* must initialize as Tcl_Thread is a pointer and * on WIN64 sizeof void* != sizeof unsigned */ #if defined(_MSC_VER) || defined(__MSVCRT__) || defined(__BORLANDC__) tHandle = (HANDLE) _beginthreadex(NULL, stackSize, (Tcl_ThreadCreateProc*) TclWinThreadStart, winThreadPtr, 0, (unsigned *)idPtr); #else tHandle = CreateThread(NULL, (DWORD) stackSize, TclWinThreadStart, winThreadPtr, 0, (LPDWORD)idPtr); #endif |
︙ | ︙ |