Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | merge trunk |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | core-8-6-b3-rc |
Files: | files | file ages | folders |
SHA1: |
ddf95e5e5d2f817de2c63658a3b32141 |
User & Date: | dgp 2012-08-08 20:30:37 |
2012-08-20
| ||
14:14 | merge trunk check-in: e6892c2563 user: dgp tags: core-8-6-b3-rc | |
2012-08-08
| ||
20:30 | merge trunk check-in: ddf95e5e5d user: dgp tags: core-8-6-b3-rc | |
10:00 | [Bug #1536227]: Cygwin network pathname supoort check-in: dfd98db64f user: jan.nijtmans tags: trunk | |
2012-07-12
| ||
10:54 | Update TclOO package to 0.7, correct copyright dates. check-in: b656b5a3a7 user: dkf tags: core-8-6-b3-rc | |
Changes to ChangeLog.
1 2 | 2012-07-10 Jan Nijtmans <[email protected]> | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 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 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 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 | 2012-08-08 Jan Nijtmans <[email protected]> * generic/tclfileName.c: [Bug #1536227]: Cygwin network pathname * tests/fileName.test: support 2012-08-07 Don Porter <[email protected]> * generic/tclIOUtil.c: [Bug 3554250] Overlooked one field of cleanup in the thread exit handler for the filesystem subsystem. 2012-07-31 Donal K. Fellows <[email protected]> * generic/tclInterp.c (Tcl_GetInterpPath): * unix/tclUnixPipe.c (TclGetAndDetachPids, Tcl_PidObjCmd): * win/tclWinPipe.c (TclGetAndDetachPids, Tcl_PidObjCmd): Purge use of Tcl_AppendElement, and corrected conversion of PIDs to integer objects. 2012-07-31 Jan Nijtmans <[email protected]> * win/nmakehlp.c: Add -Q option from sampleextension. * win/Makefile.in: [FRQ 3544967]: Missing objectfiles in static lib * win/makefile.vc: (Thanks to Jos Decoster). 2012-07-29 Jan Nijtmans <[email protected]> * win/Makefile.in: No longer build tcltest.exe to run the tests, but use tclsh86.exe in combination with tcltest86.dll to do that. * tests/*.test: load tcltest86.dll if necessary. 2012-07-28 Jan Nijtmans <[email protected]> * tests/clock.test: [Bug 3549770]: Multiple test failures running * tests/registry.test: tcltest outside build tree * tests/winDde.test: 2012-07-27 Jan Nijtmans <[email protected]> * generic/tclUniData.c: Support Unicode 6.2 (Add Turkish lira sign) * generic/regc_locale.c: 2012-07-25 Alexandre Ferrieux <[email protected]> * win/tclWinPipe.c: [Bug 3547994]: Abandon the synchronous Windows pipe driver to its fate when needed to honour TIP#398. 2012-07-23 Alexandre Ferrieux <[email protected]> * generic/tclIO.c: [Bug 3545365]: Never try a bg-flush on a dead channel, just like before 2011-08-17. 2012-07-19 Joe Mistachkin <[email protected]> * generic/tclTest.c: Fix several more missing mutex-locks in TestasyncCmd. 2012-07-19 Alexandre Ferrieux <[email protected]> * generic/tclTest.c: [Bug 3544685]: Missing mutex-lock in TestasyncCmd since 2011-08-19. Unbounded gratitude to Stuart Cassoff for spotting it. 2012-07-17 Jan Nijtmans <[email protected]> * win/makefile.vc: [Bug 3544932]: Visual studio compiler check fails 2012-07-16 Donal K. Fellows <[email protected]> * generic/tclUtil.c (UpdateStringOfEndOffset): [Bug 3544658]: Stop 1-byte overrun in memcpy, that object placement rules made harmless but which still caused compiler complaints. 2012-07-16 Jan Nijtmans <[email protected]> * library/reg/pkgIndex.tcl: Make registry 1.3 package dynamically loadable when ::tcl::pkgconfig is available. 2012-07-11 Jan Nijtmans <[email protected]> * win/tclWinReg.c: [Bug 3362446]: registry keys command fails with 8.5/8.6. Follow Microsofts example better in order to prevent problems when using HKEY_PERFORMANCE_DATA. 2012-07-10 Jan Nijtmans <[email protected]> * unix/tclUnixNotfy.c: [Bug 3541646]: Don't panic on triggerPipe overrun. 2012-07-10 Donal K. Fellows <[email protected]> * win/tclWinSock.c (InitializeHostName): Corrected logic that extracted the name of the computer from the gethostname call so that it would use the name on success, not failure. Also ensured that the buffer size is exactly that recommended by Microsoft. 2012-07-08 Reinhard Max <[email protected]> * library/http/http.tcl: [Bug 3531209]: Add fix and test for URLs that * tests/http.test: contain literal IPv6 addresses. 2012-07-05 Don Porter <[email protected]> * unix/tclUnixPipe.c: [Bug 1189293]: Make "<<" binary safe. * win/tclWinPipe.c: 2012-07-03 Donal K. Fellows <[email protected]> * generic/tclUtil.c (TclDStringAppendObj, TclDStringAppendDString): * generic/tclInt.h (TclDStringAppendLiteral, TclDStringClear): * generic/tclCompile.h (TclDStringAppendToken): Added wrappers to make common cases of appending to Tcl_DStrings simpler to write. Prompted by looking at [FRQ 1357401] (these are an _internal_ implementation of that FRQ). 2012-06-29 Jan Nijtmans <[email protected]> * library/msgcat/msgcat.tcl: Add tn, ro_MO and ru_MO to msgcat. 2012-06-29 Harald Oehlmann <[email protected]> * library/msgcat/msgcat.tcl: [Bug 3536888]: Locale guessing of * library/msgcat/pkgIndex.tcl: msgcat fails on (some) Windows 7. Bump * unix/Makefile.in: to 1.4.5 * win/Makefile.in: 2012-06-29 Donal K. Fellows <[email protected]> * doc/GetIndex.3: Reinforced the description of the requirement for the tables of names to index over to be static, following posting to tcl-core by Brian Griffin about a bug caused by Tktreectrl not obeying this rule correctly. This does not represent a functionality change, |
︙ | ︙ | |||
57 58 59 60 61 62 63 | 2012-06-26 Reinhard Max <[email protected]> * generic/tclIOSock.c: Use EAI_SYSTEM only if it exists. * unix/tclUnixSock.c: 2012-06-25 Don Porter <[email protected]> | | | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | 2012-06-26 Reinhard Max <[email protected]> * generic/tclIOSock.c: Use EAI_SYSTEM only if it exists. * unix/tclUnixSock.c: 2012-06-25 Don Porter <[email protected]> * generic/tclFileSystem.h: [Bug 3024359]: Make sure that the * generic/tclIOUtil.c: per-thread cache of the list of file systems * generic/tclPathObj.c: currently registered is only updated at times when no active loops are traversing it. Also reduce the amount of epoch storing and checking to where it can make a difference. 2012-06-25 Donal K. Fellows <[email protected]> |
︙ | ︙ | |||
271 272 273 274 275 276 277 | * {win,unix}/configure{,.in}: [Bug 2812981]: Clean up bundled packages' build directory from within Tcl's ./configure, to avoid stale configuration. 2012-05-09 Andreas Kupries <[email protected]> | | | | | | | | | | | 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 | * {win,unix}/configure{,.in}: [Bug 2812981]: Clean up bundled packages' build directory from within Tcl's ./configure, to avoid stale configuration. 2012-05-09 Andreas Kupries <[email protected]> * generic/tclIORChan.c: [Bug 3522560]: Fixed the crash, enabled the test case. Modified [chan postevent] to properly inject the event(s) into the owner thread's event queue for execution in the correct context. Renamed the ForwardOpTo...Thread() function to match with our terminology. * tests/ioCmd.test: [Bug 3522560]: Added a test which crashes the core if it were not disabled as knownBug. For a reflected channel transfered to a different thread the [chan postevent] run in the handler thread tries to execute the owner threads's fileevent scripts by itself, wrongly reaching across thread boundaries. 2012-04-28 Alexandre Ferrieux <[email protected]> * generic/tclIO.c: Properly close nonblocking channels even when not flushing them. 2012-05-03 Jan Nijtmans <[email protected]> |
︙ | ︙ | |||
337 338 339 340 341 342 343 | 2012-04-27 Donal K. Fellows <[email protected]> * library/init.tcl (auto_execok): Allow shell builtins to be detected even if they are upper-cased. 2012-04-26 Jan Nijtmans <[email protected]> | | | | | | | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | 2012-04-27 Donal K. Fellows <[email protected]> * library/init.tcl (auto_execok): Allow shell builtins to be detected even if they are upper-cased. 2012-04-26 Jan Nijtmans <[email protected]> * generic/tclStubInit.c: Get rid of _ANSI_ARGS_ and CONST * generic/tclIO.c: * generic/tclIOCmd.c: * generic/tclTest.c: * unix/tclUnixChan.c: 2012-04-25 Donal K. Fellows <[email protected]> * generic/tclUtil.c (TclDStringToObj): Added internal function to make the fairly-common operation of converting a DString into an Obj a more efficient one; for long strings, it can just transfer the ownership of the buffer directly. Replaces this: |
︙ | ︙ | |||
406 407 408 409 410 411 412 | * win/tclWinInit.c: [Bug 3448512]: clock scan "1958-01-01" fails * win/tcl.m4: only in debug compilation. * win/configure: * unix/tcl.m4: Use NDEBUG consistantly meaning: no debugging. * unix/configure: * generic/tclBasic.c: | | | | 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | * win/tclWinInit.c: [Bug 3448512]: clock scan "1958-01-01" fails * win/tcl.m4: only in debug compilation. * win/configure: * unix/tcl.m4: Use NDEBUG consistantly meaning: no debugging. * unix/configure: * generic/tclBasic.c: * library/dde/pkgIndex.tcl: Use [::tcl::pkgconfig get debug] instead * library/reg/pkgIndex.tcl: of [info exists ::tcl_platform(debug)] 2012-04-10 Donal K. Fellows <[email protected]> * generic/tcl.h (TCL_DEPRECATED_API): [Bug 2458976]: Added macro that can be used to mark parts of Tcl's API as deprecated. Currently only used for fields of Tcl_Interp, which TIPs 330 and 336 have deprecated with a migration strategy; we want to encourage people to move away |
︙ | ︙ | |||
497 498 499 500 501 502 503 | 2012-03-27 Jan Nijtmans <[email protected]> * generic/tcl.h: [Bug 3508771]: Wrong Tcl_StatBuf used on MinGW. * generic/tclFCmd.c: [Bug 2015723]: Duplicate inodes from file stat * generic/tclCmdAH.c: on windows (but now for cygwin as well). * generic/tclOODefineCmds.c: minor gcc warning * win/tclWinPort.h: Use lower numbers, preventing integer overflow. | | | 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | 2012-03-27 Jan Nijtmans <[email protected]> * generic/tcl.h: [Bug 3508771]: Wrong Tcl_StatBuf used on MinGW. * generic/tclFCmd.c: [Bug 2015723]: Duplicate inodes from file stat * generic/tclCmdAH.c: on windows (but now for cygwin as well). * generic/tclOODefineCmds.c: minor gcc warning * win/tclWinPort.h: Use lower numbers, preventing integer overflow. Remove the workaround for mingw-w64 [Bug 3407992]. It's long fixed. 2012-03-27 Donal K. Fellows <[email protected]> IMPLEMENTATION OF TIP#397. * generic/tclOO.c (Tcl_CopyObjectInstance): [Bug 3474460]: Make the target object name optional when copying classes. [RFE 3485060]: Add |
︙ | ︙ | |||
572 573 574 575 576 577 578 | * generic/tclPlatDecls.h: a dummy TclWinCPUID) for Cygwin, so win32 * generic/tclStubInit.c: extensions using those can be loaded in * unix/tclUnixCompat.c: the cygwin version of tclsh. 2012-03-19 Venkat Iyer <[email protected]> * library/tzdata/America/Atikokan: Update to tzdata2012b. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 | * generic/tclPlatDecls.h: a dummy TclWinCPUID) for Cygwin, so win32 * generic/tclStubInit.c: extensions using those can be loaded in * unix/tclUnixCompat.c: the cygwin version of tclsh. 2012-03-19 Venkat Iyer <[email protected]> * library/tzdata/America/Atikokan: Update to tzdata2012b. * library/tzdata/America/Blanc-Sablon: * library/tzdata/America/Dawson_Creek: * library/tzdata/America/Edmonton: * library/tzdata/America/Glace_Bay: * library/tzdata/America/Goose_Bay: * library/tzdata/America/Halifax: * library/tzdata/America/Havana: * library/tzdata/America/Moncton: * library/tzdata/America/Montreal: * library/tzdata/America/Nipigon: * library/tzdata/America/Rainy_River: * library/tzdata/America/Regina: * library/tzdata/America/Santiago: * library/tzdata/America/St_Johns: * library/tzdata/America/Swift_Current: * library/tzdata/America/Toronto: * library/tzdata/America/Vancouver: * library/tzdata/America/Winnipeg: * library/tzdata/Antarctica/Casey: * library/tzdata/Antarctica/Davis: * library/tzdata/Antarctica/Palmer: * library/tzdata/Asia/Yerevan: * library/tzdata/Atlantic/Stanley: * library/tzdata/Pacific/Easter: * library/tzdata/Pacific/Fakaofo: * library/tzdata/America/Creston: (new) 2012-03-19 Reinhard Max <[email protected]> * unix/tclUnixSock.c (Tcl_OpenTcpServer): Use the values returned by getaddrinfo() for all three arguments to socket() instead of only using ai_family. Try to keep the most meaningful error while iterating over the result list, because using the last error can be misleading. 2012-03-15 Jan Nijtmans <[email protected]> * generic/tcl.h: [Bug 3288345]: Wrong Tcl_StatBuf used on Cygwin * unix/tclUnixFile.c: * unix/tclUnixPort.h: * win/cat.c: Remove cygwin stuff no longer needed * win/tclWinFile.c: * win/tclWinPort.h: 2012-03-12 Jan Nijtmans <[email protected]> * win/tclWinFile.c: [Bug 3388350]: mingw64 compiler warnings 2012-03-11 Donal K. Fellows <[email protected]> |
︙ | ︙ | |||
658 659 660 661 662 663 664 | caller might still overwrite, but we should at least avoid known-useless work.) 2012-02-29 Jan Nijtmans <[email protected]> * generic/tclIOUtil.c: [Bug 3466099]: BOM in Unicode * generic/tclEncoding.c: | | | 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 | caller might still overwrite, but we should at least avoid known-useless work.) 2012-02-29 Jan Nijtmans <[email protected]> * generic/tclIOUtil.c: [Bug 3466099]: BOM in Unicode * generic/tclEncoding.c: * tests/source.test: 2012-02-23 Donal K. Fellows <[email protected]> * tests/reg.test (14.21-23): Add tests relating to Bug 1115587. Actual bug is characterised by test marked with 'knownBug'. 2012-02-17 Jan Nijtmans <[email protected]> |
︙ | ︙ | |||
812 813 814 815 816 817 818 | fail if one timezone abbreviation was a proper tail of another, and zic used the same bytes of the file to represent both of them. Added a test case for the bug, using the same data that caused the observed failure "in the wild." 2011-12-30 Venkat Iyer <[email protected]> | | | | | | | | | 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 | fail if one timezone abbreviation was a proper tail of another, and zic used the same bytes of the file to represent both of them. Added a test case for the bug, using the same data that caused the observed failure "in the wild." 2011-12-30 Venkat Iyer <[email protected]> * library/tzdata/America/Bahia: Update to Olson's tzdata2011n * library/tzdata/America/Havana: * library/tzdata/Europe/Kiev: * library/tzdata/Europe/Simferopol: * library/tzdata/Europe/Uzhgorod: * library/tzdata/Europe/Zaporozhye: * library/tzdata/Pacific/Fiji: 2011-12-23 Jan Nijtmans <[email protected]> * generic/tclUtf.c: [Bug 3464428]: [string is graph \u0120] is wrong. * generic/tclUniData.c: * generic/regc_locale.c: * tests/utf.test: |
︙ | ︙ | |||
870 871 872 873 874 875 876 | 2011-11-22 Donal K. Fellows <[email protected]> * generic/tclExecute.c (TclCompileObj): Simplify and de-indent the logic so that it is easier to comprehend. 2011-11-22 Jan Nijtmans <[email protected]> | | | 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 | 2011-11-22 Donal K. Fellows <[email protected]> * generic/tclExecute.c (TclCompileObj): Simplify and de-indent the logic so that it is easier to comprehend. 2011-11-22 Jan Nijtmans <[email protected]> * win/tclWinPort.h: [Bug 3354324]: Windows: [file mtime] sets wrong * win/tclWinFile.c: time (VS2005+ only). * generic/tclTest.c: 2011-11-20 Joe Mistachkin <[email protected]> * tests/thread.test: Remove unnecessary [after] calls from the thread tests. Make error message matching more robust for tests that may |
︙ | ︙ | |||
957 958 959 960 961 962 963 | * library/clock.tcl (::tcl::clock::GetSystemTimeZone): Cache the time zone only if it was detected by one of the expensive methods. Otherwise after unsetting TCL_TZ or TZ the previous value will still be used. 2011-10-15 Venkat Iyer <[email protected]> | | | | | 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 | * library/clock.tcl (::tcl::clock::GetSystemTimeZone): Cache the time zone only if it was detected by one of the expensive methods. Otherwise after unsetting TCL_TZ or TZ the previous value will still be used. 2011-10-15 Venkat Iyer <[email protected]> * library/tzdata/America/Sitka: Update to Olson's tzdata2011l * library/tzdata/Pacific/Fiji: * library/tzdata/Asia/Hebron: (New) 2011-10-11 Jan Nijtmans <[email protected]> * win/tclWinFile.c: [Bug 2935503]: Incorrect mode field returned by [file stat] command. 2011-10-09 Donal K. Fellows <[email protected]> |
︙ | ︙ | |||
993 994 995 996 997 998 999 | * win/tclWinInt.h: Remove tclWinProcs, as it is no longer * win/tclWin32Dll.c: being used. 2011-10-03 Venkat Iyer <[email protected]> * library/tzdata/Africa/Dar_es_Salaam: Update to Olson's tzdata2011k | | | | | | | | | | | | 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 | * win/tclWinInt.h: Remove tclWinProcs, as it is no longer * win/tclWin32Dll.c: being used. 2011-10-03 Venkat Iyer <[email protected]> * library/tzdata/Africa/Dar_es_Salaam: Update to Olson's tzdata2011k * library/tzdata/Africa/Kampala: * library/tzdata/Africa/Nairobi: * library/tzdata/Asia/Gaza: * library/tzdata/Europe/Kaliningrad: * library/tzdata/Europe/Kiev: * library/tzdata/Europe/Minsk: * library/tzdata/Europe/Simferopol: * library/tzdata/Europe/Uzhgorod: * library/tzdata/Europe/Zaporozhye: * library/tzdata/Pacific/Apia: 2011-09-29 Donal K. Fellows <[email protected]> * tools/tcltk-man2html.tcl, tools/tcltk-man2html-utils.tcl: More refactoring so that more of the utility code is decently out of the way. Adjusted the header-material generator so that version numbers are only included in locations where there is room. |
︙ | ︙ | |||
1101 1102 1103 1104 1105 1106 1107 | * tests/ioCmd.test: by `make valgrind'. * unix/Makefile.in: 2011-09-16 Jan Nijtmans <[email protected]> IMPLEMENTATION OF TIP #388 | | | | | | | | | | | 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 | * tests/ioCmd.test: by `make valgrind'. * unix/Makefile.in: 2011-09-16 Jan Nijtmans <[email protected]> IMPLEMENTATION OF TIP #388 * doc/Tcl.n: * doc/re_syntax.n: * generic/regc_lex.c: * generic/regcomp.c: * generic/regcustom.h: * generic/tcl.h: * generic/tclParse.c: * tests/reg.test: * tests/utf.test: 2011-09-16 Donal K. Fellows <[email protected]> * generic/tclProc.c (ProcWrongNumArgs): [Bugs 3400658,3408830]: Corrected the handling of procedure error messages (found by TclOO). 2011-09-16 Jan Nijtmans <[email protected]> |
︙ | ︙ | |||
1188 1189 1190 1191 1192 1193 1194 | * library/tzdata/Pacific/Apia: * library/tzdata/Pacific/Honolulu: * library/tzdata/Africa/Juba: (new) 2011-09-06 Jan Nijtmans <[email protected]> * generic/tcl.h: [RFE 1711975]: Tcl_MainEx() (like Tk_MainEx()) | | | | 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 | * library/tzdata/Pacific/Apia: * library/tzdata/Pacific/Honolulu: * library/tzdata/Africa/Juba: (new) 2011-09-06 Jan Nijtmans <[email protected]> * generic/tcl.h: [RFE 1711975]: Tcl_MainEx() (like Tk_MainEx()) * generic/tclDecls.h: * generic/tclMain.c: 2011-09-02 Don Porter <[email protected]> * tests/http.test: Convert [testthread] use to Thread package use. Eliminates memory leak seen in `make valgrind`. 2011-09-01 Alexandre Ferrieux <[email protected]> |
︙ | ︙ | |||
1260 1261 1262 1263 1264 1265 1266 | 2011-08-18 Alexandre Ferrieux <[email protected]> * generic/tclIO.c: [Bug 3096275]: Sync fcopy buffers input. 2011-08-18 Jan Nijtmans <[email protected]> * generic/tclUniData.c: [Bug 3393714]: Overflow in toupper delta | | | | 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 | 2011-08-18 Alexandre Ferrieux <[email protected]> * generic/tclIO.c: [Bug 3096275]: Sync fcopy buffers input. 2011-08-18 Jan Nijtmans <[email protected]> * generic/tclUniData.c: [Bug 3393714]: Overflow in toupper delta * tools/uniParse.tcl: * tests/utf.test: 2011-08-17 Alexandre Ferrieux <[email protected]> * generic/tclIO.c: [Bug 2946474]: Consistently resume backgrounded * tests/ioCmd.test: flushes+closes when exiting. 2011-08-17 Alexandre Ferrieux <[email protected]> |
︙ | ︙ | |||
1298 1299 1300 1301 1302 1303 1304 | * generic/tclBasic.c: [Bug 3390272]: Leak of [info script] value. 2011-08-15 Jan Nijtmans <[email protected]> * generic/tclPosixStr.c: [Bug 3388350]: mingw64 compiler warnings * win/tclWinPort.h: | | | | 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 | * generic/tclBasic.c: [Bug 3390272]: Leak of [info script] value. 2011-08-15 Jan Nijtmans <[email protected]> * generic/tclPosixStr.c: [Bug 3388350]: mingw64 compiler warnings * win/tclWinPort.h: * win/configure.in: * win/configure: 2011-08-14 Jan Nijtmans <[email protected]> * doc/FindExec.3: [Patch 3124554]: Move WishPanic from Tk to Tcl * doc/Panic.3 Added Documentation 2011-08-12 Don Porter <[email protected]> |
︙ | ︙ | |||
1337 1338 1339 1340 1341 1342 1343 | * generic/tclCompCmds.c: [Bug 3386417]: Avoid a reference loop between * generic/tclInt.h: the bytecode and its companion errostack * generic/tclResult.c: when compiling a syntax error. 2011-08-09 Jan Nijtmans <[email protected]> * win/tclWinConsole.c: [Bug 3388350]: mingw64 compiler warnings | | | | | 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 | * generic/tclCompCmds.c: [Bug 3386417]: Avoid a reference loop between * generic/tclInt.h: the bytecode and its companion errostack * generic/tclResult.c: when compiling a syntax error. 2011-08-09 Jan Nijtmans <[email protected]> * win/tclWinConsole.c: [Bug 3388350]: mingw64 compiler warnings * win/tclWinDde.c: * win/tclWinPipe.c: * win/tclWinSerial.c: 2011-08-09 Jan Nijtmans <[email protected]> * generic/tclInt.h: Change the signature of TclParseHex(), such that * generic/tclParse.c: it can now parse up to 8 hex characters. 2011-08-08 Donal K. Fellows <[email protected]> |
︙ | ︙ | |||
1665 1666 1667 1668 1669 1670 1671 | * generic/tclUtil.c: rooting all growth routines by default on a common tunable parameter TCL_MIN_GROWTH. 2011-05-25 Don Porter <[email protected]> * library/msgcat/msgcat.tcl: Bump to msgcat 1.4.4. * library/msgcat/pkgIndex.tcl: | | | | 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 | * generic/tclUtil.c: rooting all growth routines by default on a common tunable parameter TCL_MIN_GROWTH. 2011-05-25 Don Porter <[email protected]> * library/msgcat/msgcat.tcl: Bump to msgcat 1.4.4. * library/msgcat/pkgIndex.tcl: * unix/Makefile.in: * win/Makefile.in: 2011-05-25 Donal K. Fellows <[email protected]> * generic/tclOO.h (TCLOO_VERSION): Bump version. IMPLEMENTATION OF TIP#381. |
︙ | ︙ | |||
2072 2073 2074 2075 2076 2077 2078 | 2011-03-22 Miguel Sofer <[email protected]> * generic/tclThreadAlloc.c: Simpler initialization of Cache under HAVE_FAST_TSD, from mig-alloc-reform. 2011-03-21 Jan Nijtmans <[email protected]> | | | 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 | 2011-03-22 Miguel Sofer <[email protected]> * generic/tclThreadAlloc.c: Simpler initialization of Cache under HAVE_FAST_TSD, from mig-alloc-reform. 2011-03-21 Jan Nijtmans <[email protected]> * unix/tclLoadDl.c: [Bug 3216070]: Loading extension libraries * unix/tclLoadDyld.c: from embedded Tcl applications. ***POTENTIAL INCOMPATIBILITY*** For extensions which rely on symbols from other extensions being present in the global symbol table. For an example and some discussion of workarounds, see http://stackoverflow.com/q/8330614/301832 2011-03-21 Miguel Sofer <[email protected]> |
︙ | ︙ | |||
2349 2350 2351 2352 2353 2354 2355 | 2011-01-25 Jan Nijtmans <[email protected]> * generic/tclPreserve.c: Don't miss 64-bit address bits in panic message. * win/tclWinChan.c: Fix various gcc-4.5.2 64-bit warning * win/tclWinConsole.c: messages, e.g. by using full 64-bits for * win/tclWinDde.c: socket fd's | | | | | | | | | | | | | | | 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 2474 2475 2476 | 2011-01-25 Jan Nijtmans <[email protected]> * generic/tclPreserve.c: Don't miss 64-bit address bits in panic message. * win/tclWinChan.c: Fix various gcc-4.5.2 64-bit warning * win/tclWinConsole.c: messages, e.g. by using full 64-bits for * win/tclWinDde.c: socket fd's * win/tclWinPipe.c: * win/tclWinReg.c: * win/tclWinSerial.c: * win/tclWinSock.c: * win/tclWinThrd.c: 2011-01-19 Jan Nijtmans <[email protected]> * tools/genStubs.tcl: [FRQ 3159920]: Tcl_ObjPrintf() crashes with * generic/tcl.decls bad format specifier. * generic/tcl.h: * generic/tclDecls.h: 2011-01-18 Donal K. Fellows <[email protected]> * generic/tclOOMethod.c (PushMethodCallFrame): [Bug 3001438]: Make sure that the cmdPtr field of the procPtr is correct and relevant at all times so that [info frame] can report sensible information about a frame after a return to it from a recursive call, instead of probably crashing (depending on what else has overwritten the Tcl stack!) 2011-01-18 Jan Nijtmans <[email protected]> * generic/tclBasic.c: Various mismatches between Tcl_Panic * generic/tclCompCmds.c: format string and its arguments, * generic/tclCompCmdsSZ.c: discovered thanks to [Bug 3159920] * generic/tclCompExpr.c: * generic/tclEnsemble.c: * generic/tclPreserve.c: * generic/tclTest.c: 2011-01-17 Jan Nijtmans <[email protected]> * generic/tclIOCmd.c: [Bug 3148192]: Commands "read/puts" incorrectly * tests/chanio.test: interpret parameters. Improved error-message * tests/io.test regarding legacy form. * tests/ioCmd.test |
︙ | ︙ | |||
2621 2622 2623 2624 2625 2626 2627 | quarantined at the front of the file and function headers follow the modern Tcl style. 2010-12-06 Jan Nijtmans <[email protected]> * generic/tclBinary.c: [Bug 3129448]: Possible over-allocation on * generic/tclCkalloc.c: 64-bit platforms. | | | 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 | quarantined at the front of the file and function headers follow the modern Tcl style. 2010-12-06 Jan Nijtmans <[email protected]> * generic/tclBinary.c: [Bug 3129448]: Possible over-allocation on * generic/tclCkalloc.c: 64-bit platforms. * generic/tclTrace.c: 2010-12-05 Jan Nijtmans <[email protected]> * unix/tcl.m4: [Patch 3116490]: Cross-compile support for unix * unix/configure: (autoconf-2.59) 2010-12-03 Jeff Hobbs <[email protected]> |
︙ | ︙ | |||
2757 2758 2759 2760 2761 2762 2763 | 2010-11-16 Jan Nijtmans <[email protected]> * win/tclAppInit.c:Bring compilation under mingw-w64 a bit closer * win/cat.c: to reality. See for what's missing: * win/tcl.m4: <https://sourceforge.net/apps/trac/mingw-w64/wiki/Unicode%20apps> * win/configure: (re-generated) | | | 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 | 2010-11-16 Jan Nijtmans <[email protected]> * win/tclAppInit.c:Bring compilation under mingw-w64 a bit closer * win/cat.c: to reality. See for what's missing: * win/tcl.m4: <https://sourceforge.net/apps/trac/mingw-w64/wiki/Unicode%20apps> * win/configure: (re-generated) * win/tclWinPort.h: [Bug 3110161]: Extensions using TCHAR don't compile on VS2005 SP1 2010-11-15 Andreas Kupries <[email protected]> * doc/interp.n: [Bug 3081184]: TIP #378. * doc/tclvars.n: Performance fix for TIP #280. * generic/tclBasic.c: |
︙ | ︙ | |||
6911 6912 6913 6914 6915 6916 6917 | * tests/httpd11.test: modes (normal, -channel and -handler) * makefiles: package version set to 2.8.0 2009-04-10 Daniel Steffen <[email protected]> * unix/tclUnixChan.c: TclUnixWaitForFile(): use FD_* macros * macosx/tclMacOSXNotify.c: to manipulate select masks (Cassoff). | | | | 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 | * tests/httpd11.test: modes (normal, -channel and -handler) * makefiles: package version set to 2.8.0 2009-04-10 Daniel Steffen <[email protected]> * unix/tclUnixChan.c: TclUnixWaitForFile(): use FD_* macros * macosx/tclMacOSXNotify.c: to manipulate select masks (Cassoff). [FRQ 1960647] [Bug 3486554] * unix/tclLoadDyld.c: Use RTLD_GLOBAL instead of RTLD_LOCAL. [Bug 1961211] * macosx/tclMacOSXNotify.c: revise CoreFoundation notifier to allow embedding into applications that already have a CFRunLoop running and want to run the tcl event loop via Tcl_ServiceModeHook(TCL_SERVICE_ALL). |
︙ | ︙ | |||
7109 7110 7111 7112 7113 7114 7115 | 2009-03-16 Donal K. Fellows <[email protected]> * generic/tclCmdMZ.c (TryPostBody): [Bug 2688063]: Extract information from list before getting rid of last reference to it. 2009-03-15 Joe Mistachkin <[email protected]> | | | < | 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 | 2009-03-16 Donal K. Fellows <[email protected]> * generic/tclCmdMZ.c (TryPostBody): [Bug 2688063]: Extract information from list before getting rid of last reference to it. 2009-03-15 Joe Mistachkin <[email protected]> * generic/tclThread.c: [Bug 2687952]: Modify fix for TSD leak to match * generic/tclThreadStorage.c: Tcl 8.5 (and prior) allocation semantics 2009-03-15 Donal K. Fellows <[email protected]> * generic/tclThreadStorage.c (TSDTableDelete): [Bug 2687952]: Ensure * generic/tclThread.c (Tcl_GetThreadData): that structures in Tcl's TSD system are all freed. Use the correct matching allocator. |
︙ | ︙ | |||
7199 7200 7201 7202 7203 7204 7205 | is significantly improved by this change (according to the MAP collection of benchmarks in tclbench). Just in case there was some wisdom in the old ways that I missed, I left in the ability to restore the old patterns with a #define COMPAT 1 at the top of the file. 2009-02-20 Don Porter <[email protected]> | | | | | | 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 | is significantly improved by this change (according to the MAP collection of benchmarks in tclbench). Just in case there was some wisdom in the old ways that I missed, I left in the ability to restore the old patterns with a #define COMPAT 1 at the top of the file. 2009-02-20 Don Porter <[email protected]> * generic/tclPathObj.c: [Bug 2571597]: Fixed mistaken logic in * tests/fileName.test: TclFSGetPathType() that assumed (not "absolute") => "relative". This is a false assumption on Windows, where "volumerelative" is another possibility. 2009-02-18 Don Porter <[email protected]> * generic/tclStringObj.c: Simplify the logic of the Tcl_*SetObjLength() routines. * generic/tclStringObj.c: Rewrite GrowStringBuffer() so that it |
︙ | ︙ | |||
7256 7257 7258 7259 7260 7261 7262 | in ExtendStringRepWithUnicode. Use cheap checks to determine that no reallocation is necessary without cost of computing the precise number of bytes needed. Also make use of the string growth algortihm in the case of repeated appends. 2009-02-16 Jan Nijtmans <[email protected]> | | | | | | | | | | 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 | in ExtendStringRepWithUnicode. Use cheap checks to determine that no reallocation is necessary without cost of computing the precise number of bytes needed. Also make use of the string growth algortihm in the case of repeated appends. 2009-02-16 Jan Nijtmans <[email protected]> * generic/tclZlib.c: Hack needed for official zlib1.dll build. * win/configure.in: fix [Feature Request 2605263] use official * win/Makefile.in: zlib build. * win/configure: (regenerated) * compat/zlib/zdll.lib: new files * compat/zlib/zlib1.dll: * win/Makefile.in: [Bug 2605232]: tdbc doesn't build when Tcl is compiled with --disable-shared. 2009-02-15 Don Porter <[email protected]> * generic/tclStringObj.c: [Bug 2603158]: Added protections from * generic/tclTestObj.c: invalid memory accesses when we append * tests/stringObj.test: (some part of) a Tcl_Obj to itself. Added the appendself and appendself2 subcommands to the [teststringobj] testing command and added tests to the test suite. * generic/tclStringObj.c: Factor out duplicate code from Tcl_AppendObjToObj. * generic/tclStringObj.c: Replace the 'size_t uallocated' field of the String struct, storing the number of bytes allocated to store the Tcl_UniChar array, with an 'int maxChars' field, storing the |
︙ | ︙ | |||
7408 7409 7410 7411 7412 7413 7414 | Simplify SetStringFromAny() by removing unreachable and duplicate code. Simplify Tcl_SetObjLength by removing unreachable code. Removed handling of (objPtr->bytes != NULL) from UpdateStringOfString, which is only called when objPtr->bytes is NULL. 2009-02-09 Jan Nijtmans <[email protected]> | | | | | 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 | Simplify SetStringFromAny() by removing unreachable and duplicate code. Simplify Tcl_SetObjLength by removing unreachable code. Removed handling of (objPtr->bytes != NULL) from UpdateStringOfString, which is only called when objPtr->bytes is NULL. 2009-02-09 Jan Nijtmans <[email protected]> * generic/tclCompile.c: [Bug 2555129]: const compiler warning (as error) in tclCompile.c 2009-02-07 Donal K. Fellows <[email protected]> * generic/tclZlib.c (TclZlibCmd): [Bug 2573172]: Ensure that when invalid subcommand name is given, the list of valid subcommands is produced. This gives a better experience when using the command interactively. 2009-02-05 Joe Mistachkin <[email protected]> * generic/tclInterp.c: [Bug 2544618]: Fix argument checking for [interp cancel]. * unix/Makefile.in: Fix build issue with zlib on FreeBSD (and possibly other platforms). 2009-02-05 Donal K. Fellows <[email protected]> * generic/tclCmdMZ.c (StringIndexCmd, StringRangeCmd, StringLenCmd): Simplify the implementation of some commands now that the underlying |
︙ | ︙ | |||
7443 7444 7445 7446 7447 7448 7449 | Part of scheme to address [Bug 1665628] by making the basic string operations more efficient on byte arrays. (Tcl_GetCharLength, Tcl_GetUniChar, Tcl_GetRange): More special casing work for bytearrays. 2009-02-04 Don Porter <[email protected]> | | | | | | | 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 | Part of scheme to address [Bug 1665628] by making the basic string operations more efficient on byte arrays. (Tcl_GetCharLength, Tcl_GetUniChar, Tcl_GetRange): More special casing work for bytearrays. 2009-02-04 Don Porter <[email protected]> * generic/tclStringObj.c: [Bug 2561794]: Added overflow protections to the AppendUtfToUtfRep routine to either avoid invalid arguments and crashes, or to replace them with controlled panics. * generic/tclCmdMZ.c: [Bug 2561746]: Prevent crashes due to int overflow of the length of the result of [string repeat]. 2009-02-03 Jan Nijtmans <[email protected]> * macosx/tclMacOSXFCmd.c: Eliminate some unnessary type casts * unix/tclLoadDyld.c: some internal const decorations * unix/tclUnixCompat.c: spacing * unix/tclUnixFCmd.c |
︙ | ︙ | |||
7480 7481 7482 7483 7484 7485 7486 | * generic/tclObj.c (tclCmdNameType): [Bug 2558422]: Corrected the type of this structure so that extensions that write it (yuk!) will still be able to function correctly. 2009-02-03 Don Porter <[email protected]> | | | | | 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 | * generic/tclObj.c (tclCmdNameType): [Bug 2558422]: Corrected the type of this structure so that extensions that write it (yuk!) will still be able to function correctly. 2009-02-03 Don Porter <[email protected]> * generic/tclStringObj.c (SetUnicodeObj): [Bug 2561488]: Corrected failure of Tcl_SetUnicodeObj() to panic on a shared object. Also factored out common code to reduce duplication. * generic/tclObj.c (Tcl_GetStringFromObj): Reduce code duplication. 2009-02-02 Don Porter <[email protected]> * generic/tclInterp.c: Reverted the conversion of [interp] into an * tests/interp.test: ensemble. Such conversion is not necessary |
︙ | ︙ | |||
7557 7558 7559 7560 7561 7562 7563 | * generic/tclOODefineCmds.c (Tcl_ClassSetConstructor): [Bug 2531577]: Ensure that caches of constructor chains are cleared when the constructor is changed. 2009-01-26 Alexandre Ferrieux <[email protected]> | | | | | | | | | 7640 7641 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 | * generic/tclOODefineCmds.c (Tcl_ClassSetConstructor): [Bug 2531577]: Ensure that caches of constructor chains are cleared when the constructor is changed. 2009-01-26 Alexandre Ferrieux <[email protected]> * generic/tclInt.h: [Bug 1028264]: WSACleanup() too early. * generic/tclEvent.c: The fix introduces "late exit handlers" for * win/tclWinSock.c: similar late process-wide cleanups. 2009-01-26 Alexandre Ferrieux <[email protected]> * win/tclWinSock.c: [Bug 2446662]: Resync Win behavior on RST with that of unix (EOF). 2009-01-26 Donal K. Fellows <[email protected]> * generic/tclZlib.c (ChanClose): [Bug 2536400]: Only generate error messages in the interpreter when the thread is not being closed down. 2009-01-23 Donal K. Fellows <[email protected]> * doc/zlib.n: Added a note that 'zlib push' is reversed by 'chan pop'. 2009-01-22 Jan Nijtmans <[email protected]> |
︙ | ︙ | |||
7596 7597 7598 7599 7600 7601 7602 | * unix/tcl.m4: Corrected a typo ($(SHLIB_VERSION) should be ${SHLIB_VERSION}). * unix/configure: Autoconf 2.59 2009-01-21 Andreas Kupries <[email protected]> | | | | | | | | | 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 | * unix/tcl.m4: Corrected a typo ($(SHLIB_VERSION) should be ${SHLIB_VERSION}). * unix/configure: Autoconf 2.59 2009-01-21 Andreas Kupries <[email protected]> * generic/tclIORChan.c (ReflectClose): [Bug 2458202]: * generic/tclIORTrans.c (ReflectClose): Closing a channel may supply NULL for the 'interp'. Test for finalization needs to be different, and one place has to pull the interp out of the channel instead. 2009-01-21 Don Porter <[email protected]> * generic/tclStringObj.c: New fix for [Bug 2494093] replaces the flawed attempt committed 2009-01-09. 2009-01-19 Kevin B. Kenny <[email protected]> * unix/Makefile.in: [Patch 907924]:Added a CONFIG_INSTALL_DIR * unix/tcl.m4: parameter so that distributors can control where tclConfig.sh goes. Made the installation of 'ldAix' conditional upon actually being on an AIX system. Allowed for downstream packagers to customize SHLIB_VERSION on BSD-derived systems. Thanks to Stuart Cassoff for his help. * unix/configure: Autoconf 2.59 2009-01-19 David Gravereaux <[email protected]> * win/build.vc.bat: Improved tools detection and error message * win/makefile.vc: Reorganized the $(TCLOBJ) file list into seperate parts for easier maintenance. Matched all sources built using -GL to |
︙ | ︙ | |||
7650 7651 7652 7653 7654 7655 7656 | a Command when deleting it is important so that tests for certain classes of commands don't return false positives when applied to deleted command tokens. Overall change is now just replacement of a false comment with a true one. 2009-01-13 Jan Nijtmans <[email protected]> | | | | 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 | a Command when deleting it is important so that tests for certain classes of commands don't return false positives when applied to deleted command tokens. Overall change is now just replacement of a false comment with a true one. 2009-01-13 Jan Nijtmans <[email protected]> * unix/tcl.m4: [Bug 2502365]: Building of head on HPUX is broken when using the native CC. * unix/configure (autoconf-2.59) 2009-01-13 Donal K. Fellows <[email protected]> * generic/tclCmdMZ.c (Tcl_ThrowObjCmd): Move implementation of [throw] * library/init.tcl (throw): to C from Tcl. |
︙ | ︙ | |||
7674 7675 7676 7677 7678 7679 7680 | setting to NULL, since any extension following the advice of the old comment is going to be broken by NRE anyway, and needs to shift to flag-based testing (or stop intruding into such internal matters). Part of [Bug 2486550]. 2009-01-09 Don Porter <[email protected]> | | | | | | | | | | | | | | | | | | | | | | | | 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 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 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 | setting to NULL, since any extension following the advice of the old comment is going to be broken by NRE anyway, and needs to shift to flag-based testing (or stop intruding into such internal matters). Part of [Bug 2486550]. 2009-01-09 Don Porter <[email protected]> * generic/tclStringObj.c (STRING_SIZE): [Bug 2494093]: Corrected failure to limit memory allocation requests to the sizes that can be supported by Tcl's memory allocation routines. 2009-01-09 Donal K. Fellows <[email protected]> * generic/tclNamesp.c (NamespaceEnsembleCmd): [Bug 1558654]: Error out when someone gives wrong # of args to [namespace ensemble create]. 2009-01-08 Don Porter <[email protected]> * generic/tclStringObj.c (STRING_UALLOC): [Bug 2494093]: Added missing parens required to get correct results out of things like STRING_UALLOC(num + append). 2009-01-08 Donal K. Fellows <[email protected]> * generic/tclDictObj.c, generic/tclIndexObj.c, generic/tclListObj.c, * generic/tclObj.c, generic/tclStrToD.c, generic/tclUtil.c, * generic/tclVar.c: Generate errorcodes for the error cases which approximate to "I can't interpret that string as one of those" and "You gave me the wrong number of arguments". 2009-01-07 Donal K. Fellows <[email protected]> * doc/dict.n: [Tk Bug 2491235]: Added more examples. * tests/oo.test (oo-22.1): Adjusted test to be less dependent on the specifics of how [info frame] reports general frame information, and instead to focus on what methods add to it; that's really what the test is about anyway. 2009-01-06 Don Porter <[email protected]> * tests/stringObj.test: Revise tests that demand a NULL Tcl_ObjType in certain values to construct those values with [testdstring] so there's no lack of robustness depending on the shimmer history of shared literals. 2009-01-06 Donal K. Fellows <[email protected]> * generic/tclDictObj.c (DictIncrCmd): Corrected twiddling in internals of dictionaries so that literals can't get destroyed. * tests/expr.test: [Bug 2006879]: Eliminate non-ASCII char. * generic/tclOOInfo.c (InfoObjectMethodsCmd,InfoClassMethodsCmd): [Bug 2489836]: Only delete pointers that were actually allocated! * generic/tclOO.c (TclNRNewObjectInstance, Tcl_NewObjectInstance): [Bug 2481109]: Perform search for existing commands in right context. 2009-01-05 Donal K. Fellows <[email protected]> * generic/tclCmdMZ.c (TclNRSourceObjCmd): [Bug 2412068]: Make * generic/tclIOUtil.c (TclNREvalFile): implementation of the [source] command be NRE enabled so that [yield] inside a script sourced in a coroutine can work. 2009-01-04 Donal K. Fellows <[email protected]> * generic/tclCmdAH.c: Tidy up spacing and code style. 2009-01-03 Kevin B. Kenny <[email protected]> * library/clock.tcl (tcl::clock::add): Fixed error message formatting in the case where [clock add] is presented with a bad switch. * tests/clock.test (clock-65.1) Added a test case for the above problem [Bug 2481670]. 2009-01-02 Donal K. Fellows <[email protected]> * unix/tcl.m4 (SC_CONFIG_CFLAGS): [Bug 878333]: Force the use of the compatibility version of mkstemp() on IRIX. * unix/configure.in, unix/Makefile.in (mkstemp.o): * compat/mkstemp.c (new file): [Bug 741967]: Added a compatibility implementation of the mkstemp() function, which is apparently needed on some platforms. ****************************************************************** *** CHANGELOG ENTRIES FOR 2008 IN "ChangeLog.2008" *** *** CHANGELOG ENTRIES FOR 2006-2007 IN "ChangeLog.2007" *** *** CHANGELOG ENTRIES FOR 2005 IN "ChangeLog.2005" *** *** CHANGELOG ENTRIES FOR 2004 IN "ChangeLog.2004" *** *** CHANGELOG ENTRIES FOR 2003 IN "ChangeLog.2003" *** *** CHANGELOG ENTRIES FOR 2002 IN "ChangeLog.2002" *** *** CHANGELOG ENTRIES FOR 2001 IN "ChangeLog.2001" *** *** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000" *** *** CHANGELOG ENTRIES FOR 1999 AND EARLIER IN "ChangeLog.1999" *** ****************************************************************** |
Changes to changes.
︙ | ︙ | |||
7991 7992 7993 7994 7995 7996 7997 | 2011-10-11 (bug fix)[2935503] [file stat] returns bad mode (nadkarni,nijtmans) 2011-10-20 (bug fix)[3418547] cmd lits and custom resolvers (soberning,fellows) 2011-10-31 (bug fix)[3414754] EIAS violation in fs paths (porter) | | | 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 | 2011-10-11 (bug fix)[2935503] [file stat] returns bad mode (nadkarni,nijtmans) 2011-10-20 (bug fix)[3418547] cmd lits and custom resolvers (soberning,fellows) 2011-10-31 (bug fix)[3414754] EIAS violation in fs paths (porter) 2011-11-22 (bug fix)[3354324] Win: [file mtime] sets wrong time (nijtmans) 2011-11-30 (bug fix)[967195] Simply args passed to child processes (nijtmans) => tcltest 2.3.4 2011-12-07 (bug fix)[3444754] fix [string tolower \u01C5] (nijtmans) 2011-12-11 (update)[3457031] Update [[:print:]] to Unicode 6.0 (nijtmans) |
︙ | ︙ | |||
8065 8066 8067 8068 8069 8070 8071 | 2012-05-02 (enhancement) Better use of Intel cpuid instruction (nijtmans) 2012-05-03 (bug fix)[3428753] Unbreak synchronous [socket -async] (porter) 2012-05-10 (bug fix)[2812981] force consistent config of Tcl+pkgs (ferrieux) 2012-05-10 (bug fix)[473946] correct send of special characters (nijtmans) | < > | > > > > | 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 | 2012-05-02 (enhancement) Better use of Intel cpuid instruction (nijtmans) 2012-05-03 (bug fix)[3428753] Unbreak synchronous [socket -async] (porter) 2012-05-10 (bug fix)[2812981] force consistent config of Tcl+pkgs (ferrieux) 2012-05-10 (bug fix)[473946] correct send of special characters (nijtmans) 2012-05-17 (bug fix)[3445787] fix [file] ensemble in Safe Base (fellows) 2012-05-17 (bug fix)[2964715] fix [glob] in Safe Base (fellows) 2012-05-17 (bug fix)[3106532] proper [switch -indexvar] values (fellows) *** POTENTIAL INCOMPATIBILITY *** 2012-05-21 (TIP 106) New -binary option to [dde execute|poke] (oehlmann) => dde 1.4.0 2012-05-23 (bug fix)[3525907] [zlib push decompress] & [chan event] (fellows,ferrieux,kupries) 2012-05-28 (bug fix)[3529949] Protect ~ paths in Safe Base (fellows) 2012-06-21 (bug fix)[3362446] [registry keys] failure (nijtmans) => registry 1.3.0 2012-06-25 (bug fix)[3537605] [encoding dirs a b] error message (fellows) 2012-06-25 (bug fix)[3024359] crash when multi-thread concurrent [file system] and Tcl_FSMountsChanged(). (porter) 2012-06-29 (bug fix)[3536888] fix locale guessing (oehlmann,nijtmans) => msgcat 1.4.5 2012-07-05 (bug fix)[1189293] make "<<" redirect binary safe (porter) 2012-07-08 (bug fix)[3531209] accept IPv6 URLs (max) => http 2.8.4 2012-07-24 (bug fix) stop mem corruption in stacked channel events (max,porter) 2012-07-25 (bug fix)[3546275] [auto_execok] search match [exec] (danckaert) Many revisions to better support a Cygwin environment (nijtmans) --- Released 8.6b3, July 30, 2012 --- See ChangeLog for details --- |
Changes to generic/regc_locale.c.
︙ | ︙ | |||
613 614 615 616 617 618 619 | {0x1a60, 0x1a7c}, {0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49}, {0x1c4d, 0x1c7f}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6}, {0x1d00, 0x1de6}, {0x1dfc, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e}, | | | 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 | {0x1a60, 0x1a7c}, {0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49}, {0x1c4d, 0x1c7f}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6}, {0x1d00, 0x1de6}, {0x1dfc, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e}, {0x2074, 0x208e}, {0x2090, 0x209c}, {0x20a0, 0x20ba}, {0x20d0, 0x20f0}, {0x2100, 0x2189}, {0x2190, 0x23f3}, {0x2400, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x26ff}, {0x2701, 0x2b4c}, {0x2b50, 0x2b59}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3}, {0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e3b}, {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb}, {0x3001, 0x303f}, {0x3041, 0x3096}, |
︙ | ︙ |
Changes to generic/tclBasic.c.
︙ | ︙ | |||
1704 1705 1706 1707 1708 1709 1710 | * * But as we currently limit ourselves to the global namespace only for * the source, in order to avoid potential confusion, lets prevent "::" in * the token too. - dl */ if (strstr(hiddenCmdToken, "::") != NULL) { | | | | 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 | * * But as we currently limit ourselves to the global namespace only for * 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)", -1)); 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 |
︙ | ︙ | |||
1729 1730 1731 1732 1733 1734 1735 | cmdPtr = (Command *) cmd; /* * Check that the command is really in global namespace */ if (cmdPtr->nsPtr != iPtr->globalNsPtr) { | | | > | 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 | cmdPtr = (Command *) cmd; /* * 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)", -1)); Tcl_SetErrorCode(interp, "TCL", "HIDE", "NON_GLOBAL", NULL); return TCL_ERROR; } /* * Initialize the hidden command table if necessary. */ |
︙ | ︙ | |||
1754 1755 1756 1757 1758 1759 1760 | * It is an error to move an exposed command to a hidden command with * hiddenCmdToken if a hidden command with the name hiddenCmdToken already * exists. */ hPtr = Tcl_CreateHashEntry(hiddenCmdTablePtr, hiddenCmdToken, &isNew); if (!isNew) { | | | > | 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 | * It is an error to move an exposed command to a hidden command with * hiddenCmdToken if a hidden command with the name hiddenCmdToken already * exists. */ hPtr = Tcl_CreateHashEntry(hiddenCmdTablePtr, hiddenCmdToken, &isNew); if (!isNew) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "hidden command named \"%s\" already exists", hiddenCmdToken)); Tcl_SetErrorCode(interp, "TCL", "HIDE", "ALREADY_HIDDEN", NULL); return TCL_ERROR; } /* * NB: This code is currently 'like' a rename to a specialy set apart name * table. Changes here and in TclRenameCommand must be kept in synch until |
︙ | ︙ | |||
1857 1858 1859 1860 1861 1862 1863 | /* * 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) { | | | > | | | | | | | 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 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 | /* * 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)", -1)); Tcl_SetErrorCode(interp, "TCL", "EXPOSE", "NON_GLOBAL", NULL); return TCL_ERROR; } /* * Get the command from the hidden command table: */ hPtr = NULL; hiddenCmdTablePtr = iPtr->hiddenCmdTablePtr; if (hiddenCmdTablePtr != NULL) { hPtr = Tcl_FindHashEntry(hiddenCmdTablePtr, hiddenCmdToken); } if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown hidden command \"%s\"", hiddenCmdToken)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "HIDDENTOKEN", hiddenCmdToken, NULL); return TCL_ERROR; } cmdPtr = Tcl_GetHashValue(hPtr); /* * Check that we have a true global namespace command (enforced by * Tcl_HideCommand but let's double check. (If it was not, we would not * really know how to handle it). */ if (cmdPtr->nsPtr != iPtr->globalNsPtr) { /* * 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", -1)); return TCL_ERROR; } /* * This is the global table. */ nsPtr = cmdPtr->nsPtr; /* * It is an error to overwrite an existing exposed command as a result of * exposing a previously hidden command. */ hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &isNew); if (!isNew) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "exposed command \"%s\" already exists", cmdName)); Tcl_SetErrorCode(interp, "TCL", "EXPOSE", "COMMAND_EXISTS", NULL); return TCL_ERROR; } /* * Command resolvers (per-interp, per-namespace) might have resolved to a * command for the given namespace scope with this command not being |
︙ | ︙ | |||
2493 2494 2495 2496 2497 2498 2499 | * Find the existing command. An error is returned if cmdName can't be * found. */ cmd = Tcl_FindCommand(interp, oldName, NULL, /*flags*/ 0); cmdPtr = (Command *) cmd; if (cmdPtr == NULL) { | | > | | 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 | * Find the existing command. An error is returned if cmdName can't be * found. */ cmd = Tcl_FindCommand(interp, oldName, NULL, /*flags*/ 0); cmdPtr = (Command *) cmd; if (cmdPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't %s \"%s\": command doesn't exist", ((newName == NULL)||(*newName == '\0'))? "delete":"rename", oldName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", oldName, NULL); return TCL_ERROR; } cmdNsPtr = cmdPtr->nsPtr; oldFullName = Tcl_NewObj(); Tcl_IncrRefCount(oldFullName); Tcl_GetCommandFullName(interp, cmd, oldFullName); |
︙ | ︙ | |||
2525 2526 2527 2528 2529 2530 2531 | * create the containing namespaces just like Tcl_CreateCommand would. */ TclGetNamespaceForQualName(interp, newName, NULL, TCL_CREATE_NS_IF_UNKNOWN, &newNsPtr, &dummy1, &dummy2, &newTail); if ((newNsPtr == NULL) || (newTail == NULL)) { | | | | | | 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 | * create the containing namespaces just like Tcl_CreateCommand would. */ TclGetNamespaceForQualName(interp, newName, NULL, TCL_CREATE_NS_IF_UNKNOWN, &newNsPtr, &dummy1, &dummy2, &newTail); if ((newNsPtr == NULL) || (newTail == NULL)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't rename to \"%s\": bad command name", newName)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL); result = TCL_ERROR; goto done; } if (Tcl_FindHashEntry(&newNsPtr->cmdTable, newTail) != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't rename to \"%s\": command already exists", newName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "RENAME", "TARGET_EXISTS", NULL); result = TCL_ERROR; goto done; } /* |
︙ | ︙ | |||
3534 3535 3536 3537 3538 3539 3540 | } #endif if (result != TCL_OK) { /* * We have a non-numeric argument. */ | | | | 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 | } #endif if (result != TCL_OK) { /* * We have a non-numeric argument. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "argument to math function didn't have numeric value", -1)); TclCheckBadOctal(interp, Tcl_GetString(valuePtr)); ckfree(args); return TCL_ERROR; } /* * Copy the object's numeric value to the argument record, converting |
︙ | ︙ | |||
3823 3824 3825 3826 3827 3828 3829 | Tcl_ResetResult(interp); /* * If the interpreter has been deleted, return an error. */ if (iPtr->flags & DELETED) { | < | | | 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 | Tcl_ResetResult(interp); /* * 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", -1)); Tcl_SetErrorCode(interp, "TCL", "IDELETE", "attempt to call eval in deleted interpreter", NULL); return TCL_ERROR; } if (iPtr->execEnvPtr->rewind) { return TCL_ERROR; |
︙ | ︙ | |||
3853 3854 3855 3856 3857 3858 3859 | * probably because of an infinite loop somewhere. */ if (((iPtr->numLevels) <= iPtr->maxNestingDepth)) { return TCL_OK; } | | | | 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 | * probably because of an infinite loop somewhere. */ if (((iPtr->numLevels) <= iPtr->maxNestingDepth)) { return TCL_OK; } Tcl_SetObjResult(interp, Tcl_NewStringObj( "too many nested evaluations (infinite loop?)", -1)); Tcl_SetErrorCode(interp, "TCL", "LIMIT", "STACK", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3988 3989 3990 3991 3992 3993 3994 | } else { id = "ICANCEL"; if (length == 0) { message = "eval canceled"; } } | | < | 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 | } else { id = "ICANCEL"; if (length == 0) { message = "eval canceled"; } } Tcl_SetObjResult(interp, Tcl_NewStringObj(message, -1)); 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. |
︙ | ︙ | |||
4612 4613 4614 4615 4616 4617 4618 | * * In this case we worry a bit less about recursion for now, and call the * "blocking" interface. */ cmdPtr = TEOV_LookupCmdFromObj(interp, newObjv[0], lookupNsPtr); if (cmdPtr == NULL) { | | | | 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 | * * In this case we worry a bit less about recursion for now, and call the * "blocking" interface. */ cmdPtr = TEOV_LookupCmdFromObj(interp, newObjv[0], lookupNsPtr); if (cmdPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid command name \"%s\"", TclGetString(objv[0]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", TclGetString(objv[0]), NULL); /* * Release any resources we locked and allocated during the handler * call. */ |
︙ | ︙ | |||
6281 6282 6283 6284 6285 6286 6287 | * result code was returned. */ int returnCode) /* The unexpected result code. */ { char buf[TCL_INTEGER_SPACE]; Tcl_ResetResult(interp); if (returnCode == TCL_BREAK) { | | | | | | 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 | * result code was returned. */ 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", -1)); } else if (returnCode == TCL_CONTINUE) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "invoked \"continue\" outside of a loop", -1)); } 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); } |
︙ | ︙ | |||
6620 6621 6622 6623 6624 6625 6626 | int result; if (interp == NULL) { return TCL_ERROR; } if ((objc < 1) || (objv == NULL)) { | > | > | < | 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 | int result; if (interp == NULL) { return TCL_ERROR; } if ((objc < 1) || (objv == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal argument vector", -1)); return TCL_ERROR; } if ((flags & TCL_INVOKE_HIDDEN) == 0) { Tcl_Panic("TclObjInvoke: called without TCL_INVOKE_HIDDEN"); } if (TclInterpReady(interp) == TCL_ERROR) { return TCL_ERROR; } cmdName = TclGetString(objv[0]); hTblPtr = iPtr->hiddenCmdTablePtr; if (hTblPtr != NULL) { hPtr = Tcl_FindHashEntry(hTblPtr, cmdName); } if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid hidden command name \"%s\"", cmdName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "HIDDENTOKEN", cmdName, NULL); return TCL_ERROR; } cmdPtr = Tcl_GetHashValue(hPtr); /* |
︙ | ︙ | |||
7265 7266 7267 7268 7269 7270 7271 | mp_sqrt(&big, &root); mp_clear(&big); Tcl_SetObjResult(interp, Tcl_NewBignumObj(&root)); } return TCL_OK; negarg: | > | | 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 | mp_sqrt(&big, &root); mp_clear(&big); Tcl_SetObjResult(interp, Tcl_NewBignumObj(&root)); } return TCL_OK; negarg: Tcl_SetObjResult(interp, Tcl_NewStringObj( "square root of negative argument", -1)); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "domain error: argument not in valid range", NULL); return TCL_ERROR; } static int ExprSqrtFunc( |
︙ | ︙ | |||
8315 8316 8317 8318 8319 8320 8321 | if (objc < 1) { Tcl_WrongNumArgs(interp, 1, objv, "?command? ?arg ...?"); return TCL_ERROR; } if (!iPtr->varFramePtr->isProcCallFrame) { /* or is upleveled */ | | | < | 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 | if (objc < 1) { Tcl_WrongNumArgs(interp, 1, objv, "?command? ?arg ...?"); return TCL_ERROR; } if (!iPtr->varFramePtr->isProcCallFrame) { /* or is upleveled */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "tailcall can only be called from a proc or lambda", -1)); 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. |
︙ | ︙ | |||
8476 8477 8478 8479 8480 8481 8482 | if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?returnValue?"); return TCL_ERROR; } if (!corPtr) { | > | < | 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 | 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", -1)); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL); return TCL_ERROR; } if (objc == 2) { Tcl_SetObjResult(interp, objv[1]); } |
︙ | ︙ | |||
8510 8511 8512 8513 8514 8515 8516 | if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "command ?arg ...?"); return TCL_ERROR; } if (!corPtr) { | > | < | 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 | 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", -1)); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL); return TCL_ERROR; } /* * Add the tailcall in the caller env, then just yield. * |
︙ | ︙ | |||
8759 8760 8761 8762 8763 8764 8765 | iPtr->numLevels += numLevels; } else { /* * Coroutine is active: yield */ if (corPtr->stackLevel != stackLevel) { | > | < | 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 | iPtr->numLevels += numLevels; } else { /* * Coroutine is active: yield */ if (corPtr->stackLevel != stackLevel) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot yield: C stack busy", -1)); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "CANT_YIELD", NULL); return TCL_ERROR; } if (type == CORO_ACTIVATE_YIELD) { corPtr->nargs = COROUTINE_ARGUMENTS_SINGLE_OPTIONAL; |
︙ | ︙ | |||
8819 8820 8821 8822 8823 8824 8825 | 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)) { | > | < | | | 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 | 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", -1)); 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", -1)); 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. |
︙ | ︙ | |||
8856 8857 8858 8859 8860 8861 8862 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { CoroutineData *corPtr = clientData; if (!COR_IS_SUSPENDED(corPtr)) { | | < | > | 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875 | Tcl_Interp *interp, /* Current interpreter. */ int 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", Tcl_GetString(objv[0]))); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "BUSY", NULL); return TCL_ERROR; } /* * Parse all the arguments to work out what to feed as the result of the * [yield]. TRICKY POINT: objc==0 happens here! It occurs when a coroutine |
︙ | ︙ | |||
8939 8940 8941 8942 8943 8944 8945 | */ fullName = TclGetString(objv[1]); TclGetNamespaceForQualName(interp, fullName, NULL, 0, &nsPtr, &altNsPtr, &cxtNsPtr, &procName); if (nsPtr == NULL) { | | | > | | > > | | < | 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 | */ fullName = TclGetString(objv[1]); TclGetNamespaceForQualName(interp, fullName, NULL, 0, &nsPtr, &altNsPtr, &cxtNsPtr, &procName); if (nsPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create procedure \"%s\": unknown namespace", fullName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", NULL); return TCL_ERROR; } if (procName == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create procedure \"%s\": bad procedure name", fullName)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", fullName, NULL); return TCL_ERROR; } if ((nsPtr != iPtr->globalNsPtr) && (procName != NULL) && (procName[0] == ':')) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create procedure \"%s\" in non-global namespace with" " name starting with \":\"", procName)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", procName, NULL); return TCL_ERROR; } /* * We ARE creating the coroutine command: allocate the corresponding * struct and create the corresponding command. |
︙ | ︙ |
Changes to generic/tclBinary.c.
︙ | ︙ | |||
869 870 871 872 873 874 875 | return TCL_ERROR; } arg++; if (count == BINARY_ALL) { count = listc; } else if (count > listc) { | | | | | < | 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 | 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", -1)); 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\"", -1)); return TCL_ERROR; } else if (count == BINARY_NOCOUNT) { count = 1; } offset += count; break; case 'X': |
︙ | ︙ | |||
1194 1195 1196 1197 1198 1199 1200 | } } Tcl_SetObjResult(interp, resultPtr); return TCL_OK; badValue: Tcl_ResetResult(interp); | | | > > | | | 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 | } } Tcl_SetObjResult(interp, resultPtr); return TCL_OK; badValue: Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected %s string but got \"%s\" instead", errorString, errorValue)); return TCL_ERROR; badCount: errorString = "missing count for \"@\" field specifier"; goto error; badIndex: errorString = "not enough arguments for all format specifiers"; goto error; badField: { Tcl_UniChar ch; char buf[TCL_UTF_MAX + 1]; Tcl_UtfToUniChar(errorString, &ch); 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, -1)); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * BinaryScanCmd -- |
︙ | ︙ | |||
1582 1583 1584 1585 1586 1587 1588 | badField: { Tcl_UniChar ch; char buf[TCL_UTF_MAX + 1]; Tcl_UtfToUniChar(errorString, &ch); buf[Tcl_UniCharToUtf(ch, buf)] = '\0'; | > | | | 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 | badField: { Tcl_UniChar ch; char buf[TCL_UTF_MAX + 1]; Tcl_UtfToUniChar(errorString, &ch); 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, -1)); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * GetFormatSpec -- |
︙ | ︙ |
Changes to generic/tclCkalloc.c.
︙ | ︙ | |||
166 167 168 169 170 171 172 | * * Display the global memory management statistics. * *---------------------------------------------------------------------- */ int | | > > | > > | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | * * Display the global memory management statistics. * *---------------------------------------------------------------------- */ int TclDumpMemoryInfo( ClientData clientData, int flags) { char buf[1024]; if (clientData == NULL) { return 0; } sprintf(buf, "total mallocs %10d\n" "total frees %10d\n" "current packets allocated %10d\n" "current bytes allocated %10lu\n" "maximum packets allocated %10d\n" "maximum bytes allocated %10lu\n", |
︙ | ︙ | |||
811 812 813 814 815 816 817 | const char *fileName; FILE *fileP; Tcl_DString buffer; int result; size_t len; if (argc < 2) { | | | | > | | | > | 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 845 846 847 848 849 | const char *fileName; FILE *fileP; Tcl_DString buffer; int result; size_t len; if (argc < 2) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "wrong # args: should be \"%s option [args..]\"", argv[0])); return TCL_ERROR; } if (strcmp(argv[1], "active") == 0 || strcmp(argv[1], "display") == 0) { if (argc != 3) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "wrong # args: should be \"%s %s file\"", argv[0], argv[1])); return TCL_ERROR; } fileName = Tcl_TranslateFileName(interp, argv[2], &buffer); if (fileName == NULL) { return TCL_ERROR; } result = Tcl_DumpActiveMemory(fileName); Tcl_DStringFree(&buffer); if (result != TCL_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("error accessing %s: %s", argv[2], Tcl_PosixError(interp))); return TCL_ERROR; } return TCL_OK; } if (strcmp(argv[1],"break_on_malloc") == 0) { if (argc != 3) { goto argError; |
︙ | ︙ | |||
853 854 855 856 857 858 859 | "total mallocs", total_mallocs, "total frees", total_frees, "current packets allocated", current_malloc_packets, "current bytes allocated", (unsigned long)current_bytes_malloced, "maximum packets allocated", maximum_malloc_packets, "maximum bytes allocated", (unsigned long)maximum_bytes_malloced)); return TCL_OK; } | | | | | > | > | | | | | 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 | "total mallocs", total_mallocs, "total frees", total_frees, "current packets allocated", current_malloc_packets, "current bytes allocated", (unsigned long)current_bytes_malloced, "maximum packets allocated", maximum_malloc_packets, "maximum bytes allocated", (unsigned long)maximum_bytes_malloced)); return TCL_OK; } if (strcmp(argv[1], "init") == 0) { if (argc != 3) { goto bad_suboption; } init_malloced_bodies = (strcmp(argv[2],"on") == 0); return TCL_OK; } if (strcmp(argv[1], "objs") == 0) { if (argc != 3) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "wrong # args: should be \"%s objs file\"", argv[0])); return TCL_ERROR; } fileName = Tcl_TranslateFileName(interp, argv[2], &buffer); if (fileName == NULL) { return TCL_ERROR; } fileP = fopen(fileName, "w"); if (fileP == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cannot open output file: %s", Tcl_PosixError(interp))); return TCL_ERROR; } TclDbDumpActiveObjects(fileP); fclose(fileP); Tcl_DStringFree(&buffer); return TCL_OK; } if (strcmp(argv[1],"onexit") == 0) { if (argc != 3) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "wrong # args: should be \"%s onexit file\"", argv[0])); return TCL_ERROR; } fileName = Tcl_TranslateFileName(interp, argv[2], &buffer); if (fileName == NULL) { return TCL_ERROR; } onExitMemDumpFileName = dumpFile; strcpy(onExitMemDumpFileName,fileName); Tcl_DStringFree(&buffer); return TCL_OK; } if (strcmp(argv[1],"tag") == 0) { if (argc != 3) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "wrong # args: should be \"%s tag string\"", argv[0])); return TCL_ERROR; } if ((curTagPtr != NULL) && (curTagPtr->refCount == 0)) { TclpFree((char *) curTagPtr); } len = strlen(argv[2]); curTagPtr = (MemTag *) TclpAlloc(TAG_SIZE(len)); |
︙ | ︙ | |||
935 936 937 938 939 940 941 | if (argc != 3) { goto bad_suboption; } validate_memory = (strcmp(argv[2],"on") == 0); return TCL_OK; } | | | | > | | | | | 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 | if (argc != 3) { goto bad_suboption; } validate_memory = (strcmp(argv[2],"on") == 0); return TCL_OK; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad option \"%s\": should be active, break_on_malloc, info, " "init, objs, onexit, tag, trace, trace_on_at_malloc, or validate", argv[1])); return TCL_ERROR; argError: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "wrong # args: should be \"%s %s count\"", argv[0], argv[1])); return TCL_ERROR; bad_suboption: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "wrong # args: should be \"%s %s on|off\"", argv[0], argv[1])); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * CheckmemCmd -- |
︙ | ︙ | |||
977 978 979 980 981 982 983 | CheckmemCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter for evaluation. */ int argc, /* Number of arguments. */ const char *argv[]) /* String values of arguments. */ { if (argc != 2) { | | | | 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 | CheckmemCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Interpreter for evaluation. */ int 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; } tclMemDumpFileName = dumpFile; strcpy(tclMemDumpFileName, argv[1]); return TCL_OK; } |
︙ | ︙ | |||
1246 1247 1248 1249 1250 1251 1252 | Tcl_ValidateAllMemory( const char *file, int line) { } int | | > > | 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 | Tcl_ValidateAllMemory( const char *file, int line) { } int TclDumpMemoryInfo( ClientData clientData, int flags) { return 1; } #endif /* TCL_MEM_DEBUG */ /* |
︙ | ︙ |
Changes to generic/tclClock.c.
︙ | ︙ | |||
874 875 876 877 878 879 880 | /* * If conversion fails, report an error. */ if (localErrno != 0 || (fields->seconds == -1 && timeVal.tm_yday == -1)) { | > | < | 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 | /* * 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", -1)); return TCL_ERROR; } return TCL_OK; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1014 1015 1016 1017 1018 1019 1020 | /* * Use 'localtime' to determine local year, month, day, time of day. */ tock = (time_t) fields->seconds; if ((Tcl_WideInt) tock != fields->seconds) { | | | | | | 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 | /* * 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", -1)); 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)", -1)); Tcl_SetErrorCode(interp, "CLOCK", "localtimeFailed", NULL); return TCL_ERROR; } /* * Fill in the date in 'fields' and use it to derive Julian Day. */ |
︙ | ︙ |
Changes to generic/tclCmdAH.c.
︙ | ︙ | |||
190 191 192 193 194 195 196 | int patObjc, j; const char **patObjv; const char *pat; unsigned char *p; if (i == caseObjc-1) { Tcl_ResetResult(interp); | > | | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | int patObjc, j; const char **patObjv; const char *pat; unsigned char *p; if (i == caseObjc-1) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_NewStringObj( "extra case pattern with no body", -1)); return TCL_ERROR; } /* * Check for special case of single pattern (no list) with no * backslash sequences. */ |
︙ | ︙ | |||
405 406 407 408 409 410 411 | Tcl_IncrRefCount(dir); } if (Tcl_FSConvertToPathType(interp, dir) != TCL_OK) { result = TCL_ERROR; } else { result = Tcl_FSChdir(dir); if (result != TCL_OK) { | > | | | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | Tcl_IncrRefCount(dir); } if (Tcl_FSConvertToPathType(interp, dir) != TCL_OK) { result = TCL_ERROR; } else { result = Tcl_FSChdir(dir); if (result != TCL_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't change working directory to \"%s\": %s", TclGetString(dir), Tcl_PosixError(interp))); result = TCL_ERROR; } } if (objc != 2) { Tcl_DecrRefCount(dir); } return result; |
︙ | ︙ | |||
638 639 640 641 642 643 644 | if (objc == 2) { Tcl_SetObjResult(interp, Tcl_GetEncodingSearchPath()); return TCL_OK; } dirListObj = objv[2]; if (Tcl_SetEncodingSearchPath(dirListObj) == TCL_ERROR) { | > | | | 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 | if (objc == 2) { Tcl_SetObjResult(interp, Tcl_GetEncodingSearchPath()); return TCL_OK; } dirListObj = objv[2]; if (Tcl_SetEncodingSearchPath(dirListObj) == TCL_ERROR) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected directory list but got \"%s\"", TclGetString(dirListObj))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "ENCODING", "BADPATH", NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, dirListObj); return TCL_OK; } |
︙ | ︙ | |||
1161 1162 1163 1164 1165 1166 1167 | return TCL_ERROR; } tval.actime = newTime; tval.modtime = buf.st_mtime; if (Tcl_FSUtime(objv[1], &tval) != 0) { | > | | < | 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 | return TCL_ERROR; } tval.actime = newTime; tval.modtime = buf.st_mtime; if (Tcl_FSUtime(objv[1], &tval) != 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not set access time for file \"%s\": %s", TclGetString(objv[1]), Tcl_PosixError(interp))); return TCL_ERROR; } /* * Do another stat to ensure that the we return the new recognized * atime - hopefully the same as the one we sent in. However, fs's * like FAT don't even know what atime is. |
︙ | ︙ | |||
1233 1234 1235 1236 1237 1238 1239 | return TCL_ERROR; } tval.actime = buf.st_atime; tval.modtime = newTime; if (Tcl_FSUtime(objv[1], &tval) != 0) { | > | < | | 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 | return TCL_ERROR; } tval.actime = buf.st_atime; tval.modtime = newTime; if (Tcl_FSUtime(objv[1], &tval) != 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not set modification time for file \"%s\": %s", TclGetString(objv[1]), Tcl_PosixError(interp))); return TCL_ERROR; } /* * Do another stat to ensure that the we return the new recognized * mtime - hopefully the same as the one we sent in. */ |
︙ | ︙ | |||
1838 1839 1840 1841 1842 1843 1844 | if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } fsInfo = Tcl_FSFileSystemInfo(objv[1]); if (fsInfo == NULL) { | | | 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 | 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", -1)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "FILESYSTEM", Tcl_GetString(objv[1]), NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, fsInfo); return TCL_OK; } |
︙ | ︙ | |||
1986 1987 1988 1989 1990 1991 1992 | if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } res = Tcl_FSSplitPath(objv[1], NULL); if (res == NULL) { | | | > | 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 | if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } res = Tcl_FSSplitPath(objv[1], NULL); if (res == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": no such file or directory", TclGetString(objv[1]))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PATHSPLIT", "NONESUCH", NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, res); return TCL_OK; } |
︙ | ︙ | |||
2088 2089 2090 2091 2092 2093 2094 | break; } Tcl_SetObjResult(interp, Tcl_NewStringObj(separator, 1)); } else { Tcl_Obj *separatorObj = Tcl_FSPathSeparator(objv[1]); if (separatorObj == NULL) { | > | | 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 | break; } 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", -1)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "FILESYSTEM", Tcl_GetString(objv[1]), NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, separatorObj); } return TCL_OK; |
︙ | ︙ | |||
2207 2208 2209 2210 2211 2212 2213 | return TCL_ERROR; } status = statProc(pathPtr, statPtr); if (status < 0) { if (interp != NULL) { | > | | < | 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 | return TCL_ERROR; } status = statProc(pathPtr, statPtr); if (status < 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": %s", TclGetString(pathPtr), Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; } /* |
︙ | ︙ | |||
2644 2645 2646 2647 2648 2649 2650 | if (statePtr->vCopyList[i] == NULL) { result = TCL_ERROR; goto done; } TclListObjGetElements(NULL, statePtr->vCopyList[i], &statePtr->varcList[i], &statePtr->varvList[i]); if (statePtr->varcList[i] < 1) { | > | | 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 | if (statePtr->vCopyList[i] == NULL) { result = TCL_ERROR; goto done; } TclListObjGetElements(NULL, statePtr->vCopyList[i], &statePtr->varcList[i], &statePtr->varvList[i]); if (statePtr->varcList[i] < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "foreach varlist is empty", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FOREACH", "NEEDVARS", NULL); result = TCL_ERROR; goto done; } statePtr->aCopyList[i] = TclListObjCopy(interp, objv[2+i*2]); |
︙ | ︙ |
Changes to generic/tclCmdIL.c.
︙ | ︙ | |||
23 24 25 26 27 28 29 | /* * During execution of the "lsort" command, structures of the following type * are used to arrange the objects being sorted into a collection of linked * lists. */ typedef struct SortElement { | | | | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /* * During execution of the "lsort" command, structures of the following type * are used to arrange the objects being sorted into a collection of linked * lists. */ typedef struct SortElement { union { /* The value that we sorting by. */ const char *strValuePtr; long intValue; double doubleValue; Tcl_Obj *objValuePtr; } collationKey; union { /* Object being sorted, or its index. */ Tcl_Obj *objPtr; int index; } payload; struct SortElement *nextPtr;/* Next element in the list, or NULL for end * of list. */ } SortElement; /* * These function pointer types are used with the "lsearch" and "lsort" |
︙ | ︙ | |||
225 226 227 228 229 230 231 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *boolObj; if (objc <= 1) { | > | | | 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | Tcl_Interp *interp, /* Current interpreter. */ int 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", TclGetString(objv[0]))); Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); return TCL_ERROR; } /* * At this point, objv[1] refers to the main expression to test. The * arguments after the expression must be "then" (optional) and a script |
︙ | ︙ | |||
315 316 317 318 319 320 321 | * At this point in the loop, objv and objc refer to an expression to * test, either for the main expression or an expression following an * "elseif". The arguments after the expression must be "then" * (optional) and a script to execute if the expression is true. */ if (i >= objc) { | | | > | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | * At this point in the loop, objv and objc refer to an expression to * test, either for the main expression or an expression following an * "elseif". The arguments after the expression must be "then" * (optional) and a script to execute if the expression is true. */ if (i >= objc) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "wrong # args: no expression after \"%s\" argument", clause)); Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); return TCL_ERROR; } if (!thenScriptIndex) { TclNewObj(boolObj); Tcl_NRAddCallback(interp, IfConditionCallback, data[0], data[1], INT2PTR(i), boolObj); |
︙ | ︙ | |||
341 342 343 344 345 346 347 | if (strcmp(clause, "else") == 0) { i++; if (i >= objc) { goto missingScript; } } if (i < objc - 1) { | | | > > > | < < | 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 | if (strcmp(clause, "else") == 0) { i++; if (i >= objc) { goto missingScript; } } if (i < objc - 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "wrong # args: extra words after \"else\" clause in \"if\" command", -1)); Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); return TCL_ERROR; } if (thenScriptIndex) { /* * TIP #280. Make invoking context available to branch/else. */ return TclNREvalObjEx(interp, objv[thenScriptIndex], 0, iPtr->cmdFramePtr, thenScriptIndex); } return TclNREvalObjEx(interp, objv[i], 0, iPtr->cmdFramePtr, i); missingScript: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "wrong # args: no script following \"%s\" argument", TclGetString(objv[i-1]))); Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
487 488 489 490 491 492 493 | Tcl_WrongNumArgs(interp, 1, objv, "procname"); return TCL_ERROR; } name = TclGetString(objv[1]); procPtr = TclFindProc(iPtr, name); if (procPtr == NULL) { | > | | 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | Tcl_WrongNumArgs(interp, 1, objv, "procname"); return TCL_ERROR; } name = TclGetString(objv[1]); procPtr = TclFindProc(iPtr, name); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" isn't a procedure", name)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", name, NULL); return TCL_ERROR; } /* * Build a return list containing the arguments. */ |
︙ | ︙ | |||
548 549 550 551 552 553 554 | Tcl_WrongNumArgs(interp, 1, objv, "procname"); return TCL_ERROR; } name = TclGetString(objv[1]); procPtr = TclFindProc(iPtr, name); if (procPtr == NULL) { | > | | 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | Tcl_WrongNumArgs(interp, 1, objv, "procname"); return TCL_ERROR; } name = TclGetString(objv[1]); procPtr = TclFindProc(iPtr, name); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" isn't a procedure", name)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", name, NULL); return TCL_ERROR; } /* * Here we used to return procPtr->bodyPtr, except when the body was * bytecompiled - in that case, the return was a copy of the body's string |
︙ | ︙ | |||
977 978 979 980 981 982 983 | } procName = TclGetString(objv[1]); argName = TclGetString(objv[2]); procPtr = TclFindProc(iPtr, procName); if (procPtr == NULL) { | > | | 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 | } procName = TclGetString(objv[1]); argName = TclGetString(objv[2]); procPtr = TclFindProc(iPtr, procName); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" isn't a procedure", procName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", procName, NULL); return TCL_ERROR; } for (localPtr = procPtr->firstLocalPtr; localPtr != NULL; localPtr = localPtr->nextPtr) { |
︙ | ︙ | |||
1008 1009 1010 1011 1012 1013 1014 | } Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); } return TCL_OK; } } | | | > | 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 | } Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); } return TCL_OK; } } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "procedure \"%s\" doesn't have an argument \"%s\"", procName, argName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARGUMENT", argName, NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1051 1052 1053 1054 1055 1056 1057 | if ((objc != 1) && (objc != 2)) { Tcl_WrongNumArgs(interp, 1, objv, "?interp?"); return TCL_ERROR; } target = interp; if (objc == 2) { | | | | | | 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 | if ((objc != 1) && (objc != 2)) { Tcl_WrongNumArgs(interp, 1, objv, "?interp?"); return TCL_ERROR; } target = interp; if (objc == 2) { target = Tcl_GetSlave(interp, Tcl_GetString(objv[1])); if (target == NULL) { return TCL_ERROR; } } iPtr = (Interp *) target; Tcl_SetObjResult(interp, iPtr->errorStack); return TCL_OK; } |
︙ | ︙ | |||
1154 1155 1156 1157 1158 1159 1160 1161 1162 | : iPtr->cmdFramePtr->level); if (corPtr) { /* * A coroutine: must fix the level computations AND the cmdFrame chain, * which is interrupted at the base. */ CmdFrame *lastPtr = NULL; | > | | | 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 | : iPtr->cmdFramePtr->level); if (corPtr) { /* * A coroutine: must fix the level computations AND the cmdFrame chain, * which is interrupted at the base. */ CmdFrame *lastPtr = NULL; runPtr = iPtr->cmdFramePtr; /* TODO - deal with overflow */ topLevel += corPtr->caller.cmdFramePtr->level; while (runPtr) { runPtr->level += corPtr->caller.cmdFramePtr->level; lastPtr = runPtr; runPtr = runPtr->nextPtr; } if (lastPtr) { lastPtr->nextPtr = corPtr->caller.cmdFramePtr; |
︙ | ︙ | |||
1192 1193 1194 1195 1196 1197 1198 | if (TclGetIntFromObj(interp, objv[1], &level) != TCL_OK) { code = TCL_ERROR; goto done; } if ((level > topLevel) || (level <= - topLevel)) { levelError: | > | < | 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 | if (TclGetIntFromObj(interp, objv[1], &level) != TCL_OK) { code = TCL_ERROR; goto done; } if ((level > topLevel) || (level <= - topLevel)) { levelError: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad level \"%s\"", TclGetString(objv[1]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_FRAME", TclGetString(objv[1]), NULL); code = TCL_ERROR; goto done; } /* |
︙ | ︙ | |||
1397 1398 1399 1400 1401 1402 1403 | * Procedure CallFrame. */ if (procPtr != NULL) { Tcl_HashEntry *namePtr = procPtr->cmdPtr->hPtr; if (namePtr) { | | | | | | 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 | * Procedure CallFrame. */ if (procPtr != NULL) { Tcl_HashEntry *namePtr = procPtr->cmdPtr->hPtr; if (namePtr) { Tcl_Obj *procNameObj; /* * This is a regular command. */ TclNewObj(procNameObj); Tcl_GetCommandFullName(interp, (Tcl_Command) procPtr->cmdPtr, procNameObj); ADD_PAIR("proc", procNameObj); } else if (procPtr->cmdPtr->clientData) { ExtraFrameInfo *efiPtr = procPtr->cmdPtr->clientData; int i; /* * This is a non-standard command. Luckily, it's told us how to |
︙ | ︙ | |||
1534 1535 1536 1537 1538 1539 1540 | } name = Tcl_GetHostName(); if (name) { Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1)); return TCL_OK; } | > > | | 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 | } name = Tcl_GetHostName(); if (name) { Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1)); return TCL_OK; } Tcl_SetObjResult(interp, Tcl_NewStringObj( "unable to determine name of host", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "HOSTNAME", "UNKNOWN", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1605 1606 1607 1608 1609 1610 1611 | return TCL_OK; } Tcl_WrongNumArgs(interp, 1, objv, "?number?"); return TCL_ERROR; levelError: | > | < | 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 | return TCL_OK; } Tcl_WrongNumArgs(interp, 1, objv, "?number?"); return TCL_ERROR; levelError: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad level \"%s\"", TclGetString(objv[1]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_LEVEL", TclGetString(objv[1]), NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1652 1653 1654 1655 1656 1657 1658 | } libDirName = Tcl_GetVar(interp, "tcl_library", TCL_GLOBAL_ONLY); if (libDirName != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(libDirName, -1)); return TCL_OK; } | > > | | 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 | } libDirName = Tcl_GetVar(interp, "tcl_library", TCL_GLOBAL_ONLY); if (libDirName != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(libDirName, -1)); return TCL_OK; } Tcl_SetObjResult(interp, Tcl_NewStringObj( "no library has been specified for Tcl", -1)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", "tcl_library",NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
2586 2587 2588 2589 2590 2591 2592 | Tcl_WrongNumArgs(interp, 1, objv, "count ?value ...?"); return TCL_ERROR; } if (TCL_OK != TclGetIntFromObj(interp, objv[1], &elementCount)) { return TCL_ERROR; } if (elementCount < 0) { | | | | > | | 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 | Tcl_WrongNumArgs(interp, 1, objv, "count ?value ...?"); return TCL_ERROR; } if (TCL_OK != TclGetIntFromObj(interp, objv[1], &elementCount)) { return TCL_ERROR; } if (elementCount < 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad count \"%d\": must be integer >= 0", elementCount)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPEAT", "NEGARG", NULL); return TCL_ERROR; } /* * Skip forward to the interesting arguments now we've finished parsing. */ objc -= 2; objv += 2; /* Final sanity check. Do not exceed limits on max list length. */ if (elementCount && objc > 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; /* * Get an empty list object that is allocated large enough to hold each * init value elementCount times. |
︙ | ︙ | |||
2719 2720 2721 2722 2723 2724 2725 | * Complain if the user asked for a start element that is greater than the * list length. This won't ever trigger for the "end-*" case as that will * be properly constrained by TclGetIntForIndex because we use listLen-1 * (to allow for replacing the last elem). */ if ((first >= listLen) && (listLen > 0)) { | | | | > | 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 | * Complain if the user asked for a start element that is greater than the * list length. This won't ever trigger for the "end-*" case as that will * be properly constrained by TclGetIntForIndex because we use listLen-1 * (to allow for replacing the last elem). */ 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 = listLen - 1; } if (first <= last) { numToDelete = last - first + 1; |
︙ | ︙ | |||
2992 2993 2994 2995 2996 2997 2998 | * because it will either be replaced or there will be an error. */ if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } if (i > objc-4) { | > | | | 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 | * because it will either be replaced or there will be an error. */ if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } if (i > objc-4) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing starting index", -1)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); result = TCL_ERROR; goto done; } i++; if (objv[i] == objv[objc - 2]) { /* * Take copy to prevent shimmering problems. Note that it does |
︙ | ︙ | |||
3023 3024 3025 3026 3027 3028 3029 | if (sortInfo.indexc > 1) { TclStackFree(interp, sortInfo.indexv); } if (i > objc-4) { if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } | | | | | 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 | if (sortInfo.indexc > 1) { TclStackFree(interp, sortInfo.indexv); } if (i > objc-4) { if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-index\" option must be followed by list index", -1)); 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 * that has shimmering problems. |
︙ | ︙ | |||
3084 3085 3086 3087 3088 3089 3090 | * Subindices only make sense if asked for with -index option set. */ if (returnSubindices && sortInfo.indexc==0) { if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } | | | | | | | | | | 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 | * Subindices only make sense if asked for with -index option set. */ if (returnSubindices && sortInfo.indexc==0) { if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } Tcl_SetObjResult(interp, Tcl_NewStringObj( "-subindices cannot be used without -index option", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH", "BAD_OPTION_MIX", NULL); return TCL_ERROR; } if (mode == REGEXP) { /* * We can shimmer regexp/list if listv[i] == pattern, so get the * regexp rep before the list rep. First time round, omit the interp |
︙ | ︙ | |||
3527 3528 3529 3530 3531 3532 3533 | /* * Check parameter count. */ if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, | | | 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 | /* * Check parameter count. */ if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "listVar ?index? ?index ...? value"); return TCL_ERROR; } /* * Look up the list variable's value. */ |
︙ | ︙ | |||
3660 3661 3662 3663 3664 3665 3666 | } switch ((enum Lsort_Switches) index) { case LSORT_ASCII: sortInfo.sortMode = SORTMODE_ASCII; break; case LSORT_COMMAND: if (i == objc-2) { | | | | | | | > | | | | | | | | | | | | | > | | | > | < | | | | | | | | | | | | | | | | | | | | 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 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 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 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 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 | } switch ((enum Lsort_Switches) index) { 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", -1)); 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: { int indexc, dummy; Tcl_Obj **indexv; if (i == objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-index\" option must be followed by list index", -1)); 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; goto done2; } /* * Check each of the indices for syntactic correctness. Note that * we do not store the converted values here because we do not * know if this is the only -index option yet and so we can't * allocate any space; that happens after the scan through all the * 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 %d)", j)); sortInfo.resultCode = TCL_ERROR; goto done2; } } indexPtr = objv[i+1]; i++; break; } case LSORT_INTEGER: sortInfo.sortMode = SORTMODE_INTEGER; break; case LSORT_NOCASE: nocase = 1; break; case LSORT_REAL: sortInfo.sortMode = SORTMODE_REAL; break; case LSORT_UNIQUE: sortInfo.unique = 1; break; 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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADSTRIDE", NULL); sortInfo.resultCode = TCL_ERROR; goto done2; } group = 1; i++; break; } } if (nocase && (sortInfo.sortMode == SORTMODE_ASCII)) { sortInfo.sortMode = SORTMODE_ASCII_NC; } /* * Now extract the -index list for real, if present. No failures are * expected here; the values are all of the right type or convertible to * it. */ if (indexPtr) { Tcl_Obj **indexv; TclListObjGetElements(interp, indexPtr, &sortInfo.indexc, &indexv); switch (sortInfo.indexc) { case 0: sortInfo.indexv = NULL; break; case 1: sortInfo.indexv = &sortInfo.singleIndex; break; default: sortInfo.indexv = TclStackAlloc(interp, sizeof(int) * 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]); } } listObj = objv[objc-1]; if (sortInfo.sortMode == SORTMODE_COMMAND) { Tcl_Obj *newCommandPtr, *newObjPtr; |
︙ | ︙ | |||
3843 3844 3845 3846 3847 3848 3849 | /* * Check for sanity when grouping elements of the overall list together * because of the -stride option. [TIP #326] */ if (group) { if (length % groupSize) { | | | | | > | | < | | | 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 3891 3892 3893 3894 3895 3896 3897 3898 | /* * Check for sanity when grouping elements of the overall list together * 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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADINDEX", NULL); sortInfo.resultCode = TCL_ERROR; goto done; } if (sortInfo.indexc == 1) { sortInfo.indexc = 0; sortInfo.indexv = NULL; } else { |
︙ | ︙ | |||
4251 4252 4253 4254 4255 4256 4257 | /* * Parse the result of the command. */ if (TclGetIntFromObj(infoPtr->interp, Tcl_GetObjResult(infoPtr->interp), &order) != TCL_OK) { | < | | | | | 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 | /* * 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", -1)); Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT", "COMPARISONFAILED", NULL); infoPtr->resultCode = TCL_ERROR; return 0; } } if (!infoPtr->isIncreasing) { order = -order; } |
︙ | ︙ | |||
4466 4467 4468 4469 4470 4471 4472 | if (Tcl_ListObjIndex(infoPtr->interp, objPtr, index, ¤tObj) != TCL_OK) { infoPtr->resultCode = TCL_ERROR; return NULL; } if (currentObj == NULL) { | | | | | | < | 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 | if (Tcl_ListObjIndex(infoPtr->interp, objPtr, index, ¤tObj) != TCL_OK) { infoPtr->resultCode = TCL_ERROR; return NULL; } if (currentObj == NULL) { Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf( "element %d missing from sublist \"%s\"", index, TclGetString(objPtr))); Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT", "INDEXFAILED", NULL); infoPtr->resultCode = TCL_ERROR; return NULL; } objPtr = currentObj; } return objPtr; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * tab-width: 8 * End: */ |
Changes to generic/tclCmdMZ.c.
︙ | ︙ | |||
200 201 202 203 204 205 206 | /* * Check if the user requested -inline, but specified match variables; a * no-no. */ if (doinline && ((objc - 2) != 0)) { | | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | /* * 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", -1)); goto optionError; } /* * Handle the odd about case separately. */ |
︙ | ︙ | |||
1835 1836 1837 1838 1839 1840 1841 | if (objc == 4) { const char *string = TclGetStringFromObj(objv[1], &length2); if ((length2 > 1) && strncmp(string, "-nocase", (size_t) length2) == 0) { nocase = 1; } else { | | | | 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 | if (objc == 4) { const char *string = TclGetStringFromObj(objv[1], &length2); if ((length2 > 1) && strncmp(string, "-nocase", (size_t) length2) == 0) { nocase = 1; } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad option \"%s\": must be -nocase", string)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option", string, NULL); return TCL_ERROR; } } /* |
︙ | ︙ | |||
2102 2103 2104 2105 2106 2107 2108 | int length; const char *string = TclGetStringFromObj(objv[1], &length); if ((length > 1) && strncmp(string, "-nocase", (size_t) length) == 0) { nocase = TCL_MATCH_NOCASE; } else { | | | | 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 | int 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( "bad option \"%s\": must be -nocase", string)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option", string, NULL); return TCL_ERROR; } } Tcl_SetObjResult(interp, Tcl_NewBooleanObj( TclStringMatchObj(objv[objc-1], objv[objc-2], nocase))); |
︙ | ︙ | |||
2563 2564 2565 2566 2567 2568 2569 | goto str_cmp_args; } i++; if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) { return TCL_ERROR; } } else { | | | > | 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 | goto str_cmp_args; } i++; if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) { return TCL_ERROR; } } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad option \"%s\": must be -nocase or -length", string2)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option", string2, NULL); return TCL_ERROR; } } /* |
︙ | ︙ | |||
2712 2713 2714 2715 2716 2717 2718 | goto str_cmp_args; } i++; if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) { return TCL_ERROR; } } else { | | | > | 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 | goto str_cmp_args; } i++; if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) { return TCL_ERROR; } } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad option \"%s\": must be -nocase or -length", string2)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option", string2, NULL); return TCL_ERROR; } } /* |
︙ | ︙ | |||
3511 3512 3513 3514 3515 3516 3517 | default: if (foundmode) { /* * Mode already set via -exact, -glob, or -regexp. */ | | > | < > | | > | | | | | | | 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 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 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 | default: if (foundmode) { /* * Mode already set via -exact, -glob, or -regexp. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad option \"%s\": %s option already found", TclGetString(objv[i]), options[mode])); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "DOUBLEOPT", NULL); return TCL_ERROR; } foundmode = 1; mode = index; break; /* * Check for TIP#75 options specifying the variables to write * regexp information into. */ case OPT_INDEXV: i++; if (i >= objc-2) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "missing variable name argument to %s option", "-indexvar")); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "NOVAR", NULL); return TCL_ERROR; } indexVarObj = objv[i]; numMatchesSaved = -1; break; case OPT_MATCHV: i++; if (i >= objc-2) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "missing variable name argument to %s option", "-matchvar")); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "NOVAR", NULL); return TCL_ERROR; } matchVarObj = objv[i]; numMatchesSaved = -1; break; } } finishedOptions: if (objc - i < 2) { Tcl_WrongNumArgs(interp, 1, objv, "?-switch ...? string ?pattern body ...? ?default body?"); return TCL_ERROR; } if (indexVarObj != NULL && mode != OPT_REGEXP) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s option requires -regexp option", "-indexvar")); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "MODERESTRICTION", NULL); return TCL_ERROR; } if (matchVarObj != NULL && mode != OPT_REGEXP) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s option requires -regexp option", "-matchvar")); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "MODERESTRICTION", NULL); return TCL_ERROR; } stringObj = objv[i]; objc -= i + 1; |
︙ | ︙ | |||
3618 3619 3620 3621 3622 3623 3624 | /* * Complain if there is an odd number of words in the list of patterns and * bodies. */ if (objc % 2) { Tcl_ResetResult(interp); | > | | | | | | | | | 3622 3623 3624 3625 3626 3627 3628 3629 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 | /* * 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", -1)); 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", -1); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "BADARM", "COMMENT?", NULL); break; } } } return TCL_ERROR; } /* * Complain if the last body is a continuation. Note that this check * assumes that the list is non-empty! */ if (strcmp(TclGetString(objv[objc-1]), "-") == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "no body specified for pattern \"%s\"", TclGetString(objv[objc-2]))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "BADARM", "FALLTHROUGH", NULL); return TCL_ERROR; } for (i = 0; i < objc; i += 2) { /* |
︙ | ︙ | |||
3981 3982 3983 3984 3985 3986 3987 | /* * 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) { | > | | 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 | /* * 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", -1)); 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 |
︙ | ︙ | |||
4165 4166 4167 4168 4169 4170 4171 | 0, &type) != TCL_OK) { Tcl_DecrRefCount(handlersObj); return TCL_ERROR; } switch ((enum Handlers) type) { case TryFinally: /* finally script */ if (i < objc-2) { | > | > | < | | | | | > > | | | 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 | 0, &type) != TCL_OK) { Tcl_DecrRefCount(handlersObj); return TCL_ERROR; } switch ((enum Handlers) type) { case TryFinally: /* finally script */ if (i < objc-2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "finally clause must be last", -1)); Tcl_DecrRefCount(handlersObj); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "FINALLY", "NONTERMINAL", NULL); return TCL_ERROR; } else if (i == objc-1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "wrong # args to finally clause: must be" " \"... finally script\"", -1)); 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 > objc-4) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "wrong # args to on clause: must be \"... on code" " variableList script\"", -1)); 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 > objc-4) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "wrong # args to trap clause: " "must be \"... trap pattern variableList script\"", -1)); 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) { |
︙ | ︙ | |||
4244 4245 4246 4247 4248 4249 4250 | Tcl_NewListObj(5, info)); haveHandlers = 1; i += 3; break; } } if (bodyShared) { | | | < | 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 | Tcl_NewListObj(5, info)); haveHandlers = 1; i += 3; break; } } if (bodyShared) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "last non-finally clause must not have a body of \"-\"", -1)); Tcl_DecrRefCount(handlersObj); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "BADFALLTHROUGH", NULL); return TCL_ERROR; } if (!haveHandlers) { Tcl_DecrRefCount(handlersObj); |
︙ | ︙ |
Changes to generic/tclConfig.c.
︙ | ︙ | |||
232 233 234 235 236 237 238 | 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. */ | | | > | < | 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 | 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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CONFIG", Tcl_GetString(objv[2]), NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, val); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); return TCL_ERROR; } if (n) { Tcl_DictSearch s; Tcl_Obj *key; |
︙ | ︙ |
Changes to generic/tclDictObj.c.
︙ | ︙ | |||
696 697 698 699 700 701 702 | dict->refcount = 1; objPtr->internalRep.otherValuePtr = dict; objPtr->typePtr = &tclDictType; return TCL_OK; missingValue: if (interp != NULL) { | > | | 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 | dict->refcount = 1; objPtr->internalRep.otherValuePtr = dict; objPtr->typePtr = &tclDictType; return TCL_OK; missingValue: if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing value to go with key", -1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL); } result = TCL_ERROR; errorExit: if (interp != NULL) { Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL); |
︙ | ︙ | |||
775 776 777 778 779 780 781 | int isNew; /* Dummy */ if (flags & DICT_PATH_EXISTS) { return DICT_PATH_NON_EXISTENT; } if ((flags & DICT_PATH_CREATE) != DICT_PATH_CREATE) { if (interp != NULL) { | | < | > | 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | int isNew; /* Dummy */ if (flags & DICT_PATH_EXISTS) { return DICT_PATH_NON_EXISTENT; } if ((flags & DICT_PATH_CREATE) != DICT_PATH_CREATE) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "key \"%s\" not known in dictionary", TclGetString(keyv[i]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT", TclGetString(keyv[i]), NULL); } return NULL; } /* |
︙ | ︙ | |||
1567 1568 1569 1570 1571 1572 1573 | return TCL_ERROR; } result = Tcl_DictObjGet(interp, dictPtr, objv[objc-1], &valuePtr); if (result != TCL_OK) { return result; } if (valuePtr == NULL) { | | < | > | 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 | return TCL_ERROR; } result = Tcl_DictObjGet(interp, dictPtr, objv[objc-1], &valuePtr); if (result != TCL_OK) { return result; } if (valuePtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "key \"%s\" not known in dictionary", TclGetString(objv[objc-1]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT", TclGetString(objv[objc-1]), NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, valuePtr); return TCL_OK; } |
︙ | ︙ | |||
2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 | ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *dictPtr; Dict *dict; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "dictionary"); return TCL_ERROR; } dictPtr = objv[1]; if (dictPtr->typePtr != &tclDictType) { int result = SetDictFromAny(interp, dictPtr); if (result != TCL_OK) { return result; } } dict = dictPtr->internalRep.otherValuePtr; | > | > > | 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 | ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tcl_Obj *dictPtr; Dict *dict; char *statsStr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "dictionary"); return TCL_ERROR; } dictPtr = objv[1]; if (dictPtr->typePtr != &tclDictType) { int result = SetDictFromAny(interp, dictPtr); if (result != TCL_OK) { return result; } } dict = dictPtr->internalRep.otherValuePtr; statsStr = Tcl_HashStats(&dict->table); Tcl_SetObjResult(interp, Tcl_NewStringObj(statsStr, -1)); ckfree(statsStr); return TCL_OK; } /* *---------------------------------------------------------------------- * * DictIncrCmd -- |
︙ | ︙ | |||
2367 2368 2369 2370 2371 2372 2373 | * Parse arguments. */ if (TclListObjGetElements(interp, objv[1], &varc, &varv) != TCL_OK) { return TCL_ERROR; } if (varc != 2) { | > | < | 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 | * 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", -1)); 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; |
︙ | ︙ | |||
2783 2784 2785 2786 2787 2788 2789 | * copying from the "dict for" implementation has occurred! */ if (TclListObjGetElements(interp, objv[3], &varc, &varv) != TCL_OK) { return TCL_ERROR; } if (varc != 2) { | > | < | 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 | * copying from the "dict for" implementation has occurred! */ 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", -1)); return TCL_ERROR; } keyVarObj = varv[0]; valueVarObj = varv[1]; scriptObj = objv[4]; /* |
︙ | ︙ | |||
2824 2825 2826 2827 2828 2829 2830 | */ Tcl_IncrRefCount(keyObj); Tcl_IncrRefCount(valueObj); if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj, TCL_LEAVE_ERR_MSG) == NULL) { Tcl_ResetResult(interp); | > | | > | | > | 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 | */ Tcl_IncrRefCount(keyObj); Tcl_IncrRefCount(valueObj); if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj, TCL_LEAVE_ERR_MSG) == NULL) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't set key variable: \"%s\"", TclGetString(keyVarObj))); result = TCL_ERROR; goto abnormalResult; } if (Tcl_ObjSetVar2(interp, valueVarObj, NULL, valueObj, TCL_LEAVE_ERR_MSG) == NULL) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't set value variable: \"%s\"", TclGetString(valueVarObj))); result = TCL_ERROR; goto abnormalResult; } /* * TIP #280. Make invoking context available to loop body. */ |
︙ | ︙ |
Changes to generic/tclEncoding.c.
︙ | ︙ | |||
1538 1539 1540 1541 1542 1543 1544 | map = Tcl_DuplicateObj(TclGetProcessGlobalValue(&encodingFileMap)); Tcl_DictObjPut(NULL, map, nameObj, dir[i]); TclSetProcessGlobalValue(&encodingFileMap, map, NULL); } } if ((NULL == chan) && (interp != NULL)) { | > | | 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 | map = Tcl_DuplicateObj(TclGetProcessGlobalValue(&encodingFileMap)); Tcl_DictObjPut(NULL, map, nameObj, dir[i]); TclSetProcessGlobalValue(&encodingFileMap, map, NULL); } } if ((NULL == chan) && (interp != NULL)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown encoding \"%s\"", name)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, NULL); } Tcl_DecrRefCount(fileNameObj); Tcl_DecrRefCount(nameObj); Tcl_DecrRefCount(searchPath); return chan; |
︙ | ︙ | |||
1612 1613 1614 1615 1616 1617 1618 | encoding = LoadTableEncoding(name, ENCODING_MULTIBYTE, chan); break; case 'E': encoding = LoadEscapeEncoding(name, chan); break; } if ((encoding == NULL) && (interp != NULL)) { | > | | 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 | encoding = LoadTableEncoding(name, ENCODING_MULTIBYTE, chan); break; case 'E': encoding = LoadEscapeEncoding(name, chan); break; } if ((encoding == NULL) && (interp != NULL)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid encoding file \"%s\"", name)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, NULL); } Tcl_Close(NULL, chan); return encoding; } |
︙ | ︙ |
Changes to generic/tclEnsemble.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include "tclInt.h" #include "tclCompile.h" /* * Declarations for functions local to this file: */ static inline int EnsembleUnknownCallback(Tcl_Interp *interp, EnsembleConfig *ensemblePtr, int objc, Tcl_Obj *const objv[], Tcl_Obj **prefixObjPtr); static int NsEnsembleImplementationCmd(ClientData clientData, Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]); static int NsEnsembleImplementationCmdNR(ClientData clientData, Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]); | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include "tclInt.h" #include "tclCompile.h" /* * Declarations for functions local to this file: */ static inline Tcl_Obj * NewNsObj(Tcl_Namespace *namespacePtr); static inline int EnsembleUnknownCallback(Tcl_Interp *interp, EnsembleConfig *ensemblePtr, int objc, Tcl_Obj *const objv[], Tcl_Obj **prefixObjPtr); static int NsEnsembleImplementationCmd(ClientData clientData, Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]); static int NsEnsembleImplementationCmdNR(ClientData clientData, Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]); |
︙ | ︙ | |||
73 74 75 76 77 78 79 80 81 82 83 84 85 86 | const Tcl_ObjType tclEnsembleCmdType = { "ensembleCommand", /* the type's name */ FreeEnsembleCmdRep, /* freeIntRepProc */ DupEnsembleCmdRep, /* dupIntRepProc */ StringOfEnsembleCmdRep, /* updateStringProc */ NULL /* setFromAnyProc */ }; /* *---------------------------------------------------------------------- * * TclNamespaceEnsembleCmd -- * * Invoked to implement the "namespace ensemble" command that creates and | > > > > > > > > > > > > > | 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 | const Tcl_ObjType tclEnsembleCmdType = { "ensembleCommand", /* the type's name */ FreeEnsembleCmdRep, /* freeIntRepProc */ DupEnsembleCmdRep, /* dupIntRepProc */ StringOfEnsembleCmdRep, /* updateStringProc */ NULL /* setFromAnyProc */ }; static inline Tcl_Obj * NewNsObj( Tcl_Namespace *namespacePtr) { register Namespace *nsPtr = (Namespace *) namespacePtr; if (namespacePtr == TclGetGlobalNamespace(nsPtr->interp)) { return Tcl_NewStringObj("::", 2); } else { return Tcl_NewStringObj(nsPtr->fullName, -1); } } /* *---------------------------------------------------------------------- * * TclNamespaceEnsembleCmd -- * * Invoked to implement the "namespace ensemble" command that creates and |
︙ | ︙ | |||
112 113 114 115 116 117 118 | Tcl_Command token; Tcl_DictSearch search; Tcl_Obj *listObj; int index, done; if (nsPtr == NULL || nsPtr->flags & NS_DYING) { if (!Tcl_InterpDeleted(interp)) { | | | > | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | 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", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "DEAD", NULL); } return TCL_ERROR; } if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?arg ...?"); return TCL_ERROR; |
︙ | ︙ | |||
231 232 233 234 235 236 237 | } if (allocatedMapFlag) { Tcl_DecrRefCount(mapObj); } return TCL_ERROR; } if (len < 1) { | | | > > | | 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 | } if (allocatedMapFlag) { Tcl_DecrRefCount(mapObj); } return TCL_ERROR; } if (len < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "ensemble subcommand implementations " "must be non-empty lists", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "EMPTY_TARGET", NULL); Tcl_DictObjDone(&search); if (patchedDict) { Tcl_DecrRefCount(patchedDict); } if (allocatedMapFlag) { Tcl_DecrRefCount(mapObj); } return TCL_ERROR; } cmd = TclGetString(listv[0]); if (!(cmd[0] == ':' && cmd[1] == ':')) { Tcl_Obj *newList = Tcl_NewListObj(len, listv); Tcl_Obj *newCmd = NewNsObj((Tcl_Namespace *) nsPtr); if (nsPtr->parentPtr) { Tcl_AppendStringsToObj(newCmd, "::", NULL); } Tcl_AppendObjToObj(newCmd, listv[0]); Tcl_ListObjReplace(NULL, newList, 0, 1, 1, &newCmd); if (patchedDict == NULL) { |
︙ | ︙ | |||
366 367 368 369 370 371 372 | if (resultObj != NULL) { Tcl_SetObjResult(interp, resultObj); } break; case CONF_NAMESPACE: namespacePtr = NULL; /* silence gcc 4 warning */ Tcl_GetEnsembleNamespace(NULL, token, &namespacePtr); | | < | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | if (resultObj != NULL) { Tcl_SetObjResult(interp, resultObj); } break; case CONF_NAMESPACE: namespacePtr = NULL; /* silence gcc 4 warning */ Tcl_GetEnsembleNamespace(NULL, token, &namespacePtr); Tcl_SetObjResult(interp, NewNsObj(namespacePtr)); break; case CONF_PREFIX: { int flags = 0; /* silence gcc 4 warning */ Tcl_GetEnsembleFlags(NULL, token, &flags); Tcl_SetObjResult(interp, Tcl_NewBooleanObj(flags & TCL_ENSEMBLE_PREFIX)); |
︙ | ︙ | |||
407 408 409 410 411 412 413 | /* -namespace option */ Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(ensembleConfigOptions[CONF_NAMESPACE], -1)); namespacePtr = NULL; /* silence gcc 4 warning */ Tcl_GetEnsembleNamespace(NULL, token, &namespacePtr); | | < < | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | /* -namespace option */ Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(ensembleConfigOptions[CONF_NAMESPACE], -1)); 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], -1)); Tcl_GetEnsembleParameterList(NULL, token, &tmpObj); Tcl_ListObjAppendElement(NULL, resultObj, (tmpObj != NULL) ? tmpObj : Tcl_NewObj()); |
︙ | ︙ | |||
511 512 513 514 515 516 517 | Tcl_DictObjDone(&search); if (patchedDict) { Tcl_DecrRefCount(patchedDict); } goto freeMapAndError; } if (len < 1) { | | | > > | < | 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 | Tcl_DictObjDone(&search); if (patchedDict) { Tcl_DecrRefCount(patchedDict); } goto freeMapAndError; } if (len < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "ensemble subcommand implementations " "must be non-empty lists", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "EMPTY_TARGET", NULL); Tcl_DictObjDone(&search); if (patchedDict) { Tcl_DecrRefCount(patchedDict); } goto freeMapAndError; } cmd = TclGetString(listv[0]); if (!(cmd[0] == ':' && cmd[1] == ':')) { Tcl_Obj *newList = Tcl_DuplicateObj(listObj); Tcl_Obj *newCmd = NewNsObj((Tcl_Namespace*)nsPtr); if (nsPtr->parentPtr) { Tcl_AppendStringsToObj(newCmd, "::", NULL); } Tcl_AppendObjToObj(newCmd, listv[0]); Tcl_ListObjReplace(NULL, newList, 0,1, 1,&newCmd); if (patchedDict == NULL) { |
︙ | ︙ | |||
550 551 552 553 554 555 556 | mapObj = (patchedDict ? patchedDict : objv[1]); if (patchedDict) { allocatedMapFlag = 1; } continue; } case CONF_NAMESPACE: | > | > | 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 | mapObj = (patchedDict ? patchedDict : objv[1]); if (patchedDict) { allocatedMapFlag = 1; } continue; } case CONF_NAMESPACE: Tcl_SetObjResult(interp, Tcl_NewStringObj( "option -namespace is read-only", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "READ_ONLY", NULL); goto freeMapAndError; case CONF_PREFIX: if (Tcl_GetBooleanFromObj(interp, objv[1], &permitPrefix) != TCL_OK) { goto freeMapAndError; } |
︙ | ︙ | |||
625 626 627 628 629 630 631 | /* * Make the name of the ensemble into a fully qualified name. This might * allocate a temporary object. */ if (!(name[0] == ':' && name[1] == ':')) { | | | 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 | /* * Make the name of the ensemble into a fully qualified name. This might * allocate a temporary object. */ if (!(name[0] == ':' && name[1] == ':')) { nameObj = NewNsObj((Tcl_Namespace *) nsPtr); if (nsPtr->parentPtr == NULL) { Tcl_AppendStringsToObj(nameObj, name, NULL); } else { Tcl_AppendStringsToObj(nameObj, "::", name, NULL); } Tcl_IncrRefCount(nameObj); name = TclGetString(nameObj); |
︙ | ︙ | |||
698 699 700 701 702 703 704 | Tcl_Obj *subcmdList) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { | > | > | 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | Tcl_Obj *subcmdList) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); return TCL_ERROR; } if (subcmdList != NULL) { int length; if (TclListObjLength(interp, subcmdList, &length) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
772 773 774 775 776 777 778 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; int length; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { | > | > | 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 | { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; int length; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); return TCL_ERROR; } if (paramList == NULL) { length = 0; } else { if (TclListObjLength(interp, paramList, &length) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
846 847 848 849 850 851 852 | Tcl_Obj *mapDict) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldDict; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { | > | > | 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 | Tcl_Obj *mapDict) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldDict; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); return TCL_ERROR; } if (mapDict != NULL) { int size, done; Tcl_DictSearch search; Tcl_Obj *valuePtr; |
︙ | ︙ | |||
869 870 871 872 873 874 875 | if (Tcl_ListObjIndex(interp, valuePtr, 0, &cmdObjPtr) != TCL_OK) { Tcl_DictObjDone(&search); return TCL_ERROR; } bytes = TclGetString(cmdObjPtr); if (bytes[0] != ':' || bytes[1] != ':') { | | > > | | 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 | 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", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "UNQUALIFIED_TARGET", NULL); Tcl_DictObjDone(&search); return TCL_ERROR; } } if (size < 1) { mapDict = NULL; |
︙ | ︙ | |||
941 942 943 944 945 946 947 | Tcl_Obj *unknownList) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { | > | > | 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 | Tcl_Obj *unknownList) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); return TCL_ERROR; } if (unknownList != NULL) { int length; if (TclListObjLength(interp, unknownList, &length) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
1005 1006 1007 1008 1009 1010 1011 | int flags) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; int wasCompiled; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { | > | > | 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 | int flags) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; int wasCompiled; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; wasCompiled = ensemblePtr->flags & ENSEMBLE_COMPILE; /* |
︙ | ︙ | |||
1080 1081 1082 1083 1084 1085 1086 | Tcl_Obj **subcmdListPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { | > | > | 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 | Tcl_Obj **subcmdListPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *subcmdListPtr = ensemblePtr->subcmdList; return TCL_OK; |
︙ | ︙ | |||
1120 1121 1122 1123 1124 1125 1126 | Tcl_Obj **paramListPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { | > | > | 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 | Tcl_Obj **paramListPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *paramListPtr = ensemblePtr->parameterList; return TCL_OK; |
︙ | ︙ | |||
1160 1161 1162 1163 1164 1165 1166 | Tcl_Obj **mapDictPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { | > | > | 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 | Tcl_Obj **mapDictPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *mapDictPtr = ensemblePtr->subcommandDict; return TCL_OK; |
︙ | ︙ | |||
1199 1200 1201 1202 1203 1204 1205 | Tcl_Obj **unknownListPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { | > | > | 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 | Tcl_Obj **unknownListPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *unknownListPtr = ensemblePtr->unknownHandler; return TCL_OK; |
︙ | ︙ | |||
1238 1239 1240 1241 1242 1243 1244 | int *flagsPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { | > | > | 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 | int *flagsPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *flagsPtr = ensemblePtr->flags; return TCL_OK; |
︙ | ︙ | |||
1277 1278 1279 1280 1281 1282 1283 | Tcl_Namespace **namespacePtrPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { | > | > | 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 | Tcl_Namespace **namespacePtrPtr) { Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; if (cmdPtr->objProc != NsEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); } return TCL_ERROR; } ensemblePtr = cmdPtr->objClientData; *namespacePtrPtr = (Tcl_Namespace *) ensemblePtr->nsPtr; return TCL_OK; |
︙ | ︙ | |||
1333 1334 1335 1336 1337 1338 1339 | * rather than duplicating it. */ cmdPtr = (Command *) TclGetOriginalCommand((Tcl_Command) cmdPtr); if (cmdPtr == NULL || cmdPtr->objProc != NsEnsembleImplementationCmd){ if (flags & TCL_LEAVE_ERR_MSG) { | | | > | 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 | * rather than duplicating it. */ cmdPtr = (Command *) TclGetOriginalCommand((Tcl_Command) cmdPtr); if (cmdPtr == NULL || cmdPtr->objProc != NsEnsembleImplementationCmd){ if (flags & TCL_LEAVE_ERR_MSG) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" is not an ensemble command", TclGetString(cmdNameObj))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENSEMBLE", TclGetString(cmdNameObj), NULL); } return NULL; } } |
︙ | ︙ | |||
1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 | Tcl_Obj *prefixObj; /* An object containing the prefix words of * the command that implements the * subcommand. */ Tcl_HashEntry *hPtr; /* Used for efficient lookup of fully * specified but not yet cached command * names. */ int reparseCount = 0; /* Number of reparses. */ /* * Must recheck objc, since numParameters might have changed. Cf. test * namespace-53.9. */ restartEnsembleParse: | > | 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 | Tcl_Obj *prefixObj; /* An object containing the prefix words of * the command that implements the * subcommand. */ Tcl_HashEntry *hPtr; /* Used for efficient lookup of fully * specified but not yet cached command * names. */ int reparseCount = 0; /* Number of reparses. */ Tcl_Obj *errorObj; /* Used for building error messages. */ /* * Must recheck objc, since numParameters might have changed. Cf. test * namespace-53.9. */ restartEnsembleParse: |
︙ | ︙ | |||
1627 1628 1629 1630 1631 1632 1633 | if (ensemblePtr->nsPtr->flags & NS_DYING) { /* * Don't know how we got here, but make things give up quickly. */ if (!Tcl_InterpDeleted(interp)) { | | | > | 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 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( "ensemble activated for deleted namespace", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "DEAD", NULL); } return TCL_ERROR; } /* * Determine if the table of subcommands is right. If so, we can just look * up in there and go straight to dispatch. |
︙ | ︙ | |||
1876 1877 1878 1879 1880 1881 1882 | * We cannot determine what subcommand to hand off to, so generate a * (standard) failure message. Note the one odd case compared with * standard ensemble-like command, which is where a namespace has no * exported commands at all... */ Tcl_ResetResult(interp); | | > | > | < | | | < | < | > | | | < | 1920 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 | * We cannot determine what subcommand to hand off to, so generate a * (standard) failure message. Note the one odd case compared with * standard ensemble-like command, which is where a namespace has no * exported commands at all... */ Tcl_ResetResult(interp); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "SUBCOMMAND", TclGetString(objv[1+ensemblePtr->numParameters]), NULL); if (ensemblePtr->subcommandTable.numEntries == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown subcommand \"%s\": namespace %s does not" " export any commands", TclGetString(objv[1+ensemblePtr->numParameters]), ensemblePtr->nsPtr->fullName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "SUBCOMMAND", 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], -1); } else { int i; for (i=0 ; i<ensemblePtr->subcommandTable.numEntries-1 ; i++) { Tcl_AppendToObj(errorObj, ensemblePtr->subcommandArrayPtr[i], -1); Tcl_AppendToObj(errorObj, ", ", 2); } Tcl_AppendPrintfToObj(errorObj, "or %s", ensemblePtr->subcommandArrayPtr[i]); } Tcl_SetObjResult(interp, errorObj); return TCL_ERROR; } int TclClearRootEnsemble( ClientData data[], Tcl_Interp *interp, |
︙ | ︙ | |||
2030 2031 2032 2033 2034 2035 2036 | EnsembleConfig *ensemblePtr, int objc, Tcl_Obj *const objv[], Tcl_Obj **prefixObjPtr) { int paramc, i, result, prefixObjc; Tcl_Obj **paramv, *unknownCmd, *ensObj; | < | 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 | EnsembleConfig *ensemblePtr, int objc, Tcl_Obj *const objv[], Tcl_Obj **prefixObjPtr) { int paramc, i, result, prefixObjc; Tcl_Obj **paramv, *unknownCmd, *ensObj; /* * Create the unknown command callback to determine what to do. */ unknownCmd = Tcl_DuplicateObj(ensemblePtr->unknownHandler); TclNewObj(ensObj); |
︙ | ︙ | |||
2057 2058 2059 2060 2061 2062 2063 | * do that! */ Tcl_Preserve(ensemblePtr); ((Interp *) interp)->evalFlags |= TCL_EVAL_REDIRECT; result = Tcl_EvalObjv(interp, paramc, paramv, 0); if ((result == TCL_OK) && (ensemblePtr->flags & ENSEMBLE_DEAD)) { | > | | > | > | 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 | * do that! */ Tcl_Preserve(ensemblePtr); ((Interp *) interp)->evalFlags |= TCL_EVAL_REDIRECT; 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", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "UNKNOWN_DELETED", NULL); } result = TCL_ERROR; } Tcl_Release(ensemblePtr); /* * If we succeeded, we should either have a list of words that form the * command to be executed, or an empty list. In the empty-list case, the |
︙ | ︙ | |||
2108 2109 2110 2111 2112 2113 2114 | /* * Oh no! An exceptional result. Convert to an error. */ if (!Tcl_InterpDeleted(interp)) { if (result != TCL_ERROR) { Tcl_ResetResult(interp); | | | < | | | | < > > | 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 2179 2180 2181 2182 2183 2184 2185 2186 | /* * 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: ", -1)); switch (result) { case TCL_RETURN: Tcl_AppendToObj(Tcl_GetObjResult(interp), "return", -1); break; case TCL_BREAK: Tcl_AppendToObj(Tcl_GetObjResult(interp), "break", -1); break; case TCL_CONTINUE: Tcl_AppendToObj(Tcl_GetObjResult(interp), "continue", -1); break; default: Tcl_AppendPrintfToObj(Tcl_GetObjResult(interp), "%d", result); } Tcl_AddErrorInfo(interp, "\n result of " "ensemble unknown subcommand handler: "); Tcl_AddErrorInfo(interp, TclGetString(unknownCmd)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "UNKNOWN_RESULT", NULL); } else { Tcl_AddErrorInfo(interp, "\n (ensemble unknown subcommand handler)"); } } TclDecrRefCount(unknownCmd); return TCL_ERROR; |
︙ | ︙ | |||
2388 2389 2390 2391 2392 2393 2394 | /* * Not there, so map onto the namespace. Note in this case that we * do not guarantee that the command is actually there; that is * the programmer's responsibility (or [::unknown] of course). */ | | | 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 | /* * Not there, so map onto the namespace. Note in this case that we * do not guarantee that the command is actually there; that is * the programmer's responsibility (or [::unknown] of course). */ cmdObj = NewNsObj((Tcl_Namespace *) ensemblePtr->nsPtr); if (ensemblePtr->nsPtr->parentPtr != NULL) { Tcl_AppendStringsToObj(cmdObj, "::", name, NULL); } else { Tcl_AppendStringsToObj(cmdObj, name, NULL); } cmdPrefixObj = Tcl_NewListObj(1, &cmdObj); Tcl_SetHashValue(hPtr, cmdPrefixObj); |
︙ | ︙ |
Changes to generic/tclEvent.c.
︙ | ︙ | |||
1412 1413 1414 1415 1416 1417 1418 | 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); | | | | > | 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 | 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", -1)); break; } } Tcl_UntraceVar(interp, nameString, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, VwaitVarProc, &done); if (!foundEvent) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't wait for variable \"%s\": would wait forever", nameString)); Tcl_SetErrorCode(interp, "TCL", "EVENT", "NO_SOURCES", NULL); return TCL_ERROR; } if (!done) { /* * The interpreter's result was already set to the right error message * prior to exiting the loop above. |
︙ | ︙ | |||
1515 1516 1517 1518 1519 1520 1521 | 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); | | | 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 | 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", -1)); return TCL_ERROR; } } /* * Must clear the interpreter's result because event handlers could have * executed commands. |
︙ | ︙ |
Changes to generic/tclExecute.c.
︙ | ︙ | |||
4892 4893 4894 4895 4896 4897 4898 | } lResult = l1 - l2*lResult; goto longResultOfArithmetic; } case INST_RSHIFT: if (l2 < 0) { | > | < | 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 | } lResult = l1 - l2*lResult; goto longResultOfArithmetic; } case INST_RSHIFT: if (l2 < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "negative shift argument", -1)); #if 0 DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "domain error: argument not in valid range", NULL); CACHE_STACK_INFO(); #endif |
︙ | ︙ | |||
4940 4941 4942 4943 4944 4945 4946 | lResult = l1 >> ((int) l2); goto longResultOfArithmetic; } case INST_LSHIFT: if (l2 < 0) { | > | < | 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 | lResult = l1 >> ((int) l2); goto longResultOfArithmetic; } case INST_LSHIFT: if (l2 < 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "negative shift argument", -1)); #if 0 DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "domain error: argument not in valid range", NULL); CACHE_STACK_INFO(); #endif |
︙ | ︙ | |||
4963 4964 4965 4966 4967 4968 4969 | /* * 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. */ | | | < | 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 | /* * 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", -1)); #if 0 DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", "integer value too large to represent", NULL); CACHE_STACK_INFO(); #endif goto gotError; |
︙ | ︙ | |||
5667 5668 5669 5670 5671 5672 5673 | if (Tcl_DictObjGet(interp, dictPtr, OBJ_AT_TOS, &objResultPtr) == TCL_OK) { if (objResultPtr) { TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); NEXT_INST_V(5, opnd+1, 1); } DECACHE_STACK_INFO(); | | < | > | 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 | if (Tcl_DictObjGet(interp, dictPtr, OBJ_AT_TOS, &objResultPtr) == TCL_OK) { if (objResultPtr) { TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); NEXT_INST_V(5, opnd+1, 1); } DECACHE_STACK_INFO(); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "key \"%s\" not known in dictionary", TclGetString(OBJ_AT_TOS))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT", TclGetString(OBJ_AT_TOS), NULL); CACHE_STACK_INFO(); TRACE_WITH_OBJ(("%u => ERROR ", opnd), Tcl_GetObjResult(interp)); } else { TRACE_WITH_OBJ(( "%u => ERROR reading leaf dictionary key \"%s\": ", |
︙ | ︙ | |||
6300 6301 6302 6303 6304 6305 6306 | /* * Division by zero in an expression. Control only reaches this point * by "goto divideByZero". */ divideByZero: DECACHE_STACK_INFO(); | | > | < | 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 | /* * 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", -1)); 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", -1)); 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). |
︙ | ︙ | |||
6689 6690 6691 6692 6693 6694 6695 | mp_clear(&big2); break; default: /* Unused, here to silence compiler warning */ invalid = 0; } if (invalid) { | > | | 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 | mp_clear(&big2); break; default: /* Unused, here to silence compiler warning */ invalid = 0; } if (invalid) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "negative shift argument", -1)); return GENERAL_ARITHMETIC_ERROR; } /* * Zero shifted any number of bits is still zero. */ |
︙ | ︙ | |||
6719 6720 6721 6722 6723 6724 6725 | /* * 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. */ | > | < | 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 | /* * 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", -1)); return GENERAL_ARITHMETIC_ERROR; } shift = (int)(*((const long *)ptr2)); /* * Handle shifts within the native wide range. */ |
︙ | ︙ | |||
7121 7122 7123 7124 7125 7126 7127 | * 268435455, which fits into a signed 32 bit int which is within the * 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) { | > | | 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 | * 268435455, which fits into a signed 32 bit int which is within the * 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", -1)); return GENERAL_ARITHMETIC_ERROR; } if (type1 == TCL_NUMBER_LONG) { if (l1 == 2) { /* * Reduce small powers of 2 to shifts. |
︙ | ︙ | |||
7359 7360 7361 7362 7363 7364 7365 | } #endif overflowExpon: Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); if (big2.used > 1) { mp_clear(&big2); | > | | 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 | } #endif overflowExpon: Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); if (big2.used > 1) { mp_clear(&big2); Tcl_SetObjResult(interp, Tcl_NewStringObj( "exponent too large", -1)); 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); |
︙ | ︙ |
Changes to generic/tclFCmd.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclFCmd.c * * This file implements the generic portion of file manipulation * subcommands of the "file" command. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ | < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* * tclFCmd.c * * This file implements the generic portion of file manipulation * subcommands of the "file" command. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" #include "tclFileSystem.h" /* * Declarations for local functions defined in this file: */ |
︙ | ︙ | |||
148 149 150 151 152 153 154 | * overwriting the symlink. */ if ((Tcl_FSStat(target, &statBuf) != 0) || !S_ISDIR(statBuf.st_mode)) { if ((objc - i) > 2) { errno = ENOTDIR; Tcl_PosixError(interp); | | | | | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | * overwriting the symlink. */ if ((Tcl_FSStat(target, &statBuf) != 0) || !S_ISDIR(statBuf.st_mode)) { if ((objc - i) > 2) { errno = ENOTDIR; Tcl_PosixError(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error %s: target \"%s\" is not a directory", (copyFlag?"copying":"renaming"), TclGetString(target))); result = TCL_ERROR; } else { /* * Even though already have target == translated(objv[i+1]), pass * the original argument down, so if there's an error, the error * message will reflect the original arguments. */ |
︙ | ︙ | |||
300 301 302 303 304 305 306 | } Tcl_DecrRefCount(split); split = NULL; } done: if (errfile != NULL) { | > | | | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | } Tcl_DecrRefCount(split); split = NULL; } done: if (errfile != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create directory \"%s\": %s", TclGetString(errfile), Tcl_PosixError(interp))); result = TCL_ERROR; } if (split != NULL) { Tcl_DecrRefCount(split); } if (target != NULL) { Tcl_DecrRefCount(target); |
︙ | ︙ | |||
380 381 382 383 384 385 386 | * We own a reference count on errorBuffer, if it was set as a * result of this call. */ result = Tcl_FSRemoveDirectory(objv[i], force, &errorBuffer); if (result != TCL_OK) { if ((force == 0) && (errno == EEXIST)) { | > | | < | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 | * We own a reference count on errorBuffer, if it was set as a * result of this call. */ result = Tcl_FSRemoveDirectory(objv[i], force, &errorBuffer); if (result != TCL_OK) { if ((force == 0) && (errno == EEXIST)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error deleting \"%s\": directory not empty", TclGetString(objv[i]))); Tcl_PosixError(interp); goto done; } /* * If possible, use the untranslated name for the file. */ |
︙ | ︙ | |||
422 423 424 425 426 427 428 | } if (result != TCL_OK) { if (errfile == NULL) { /* * We try to accomodate poor error results from our Tcl_FS calls. */ | > | | > | | < | 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | } if (result != TCL_OK) { if (errfile == NULL) { /* * We try to accomodate poor error results from our Tcl_FS calls. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error deleting unknown file: %s", Tcl_PosixError(interp))); } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error deleting \"%s\": %s", TclGetString(errfile), Tcl_PosixError(interp))); } } done: if (errorBuffer != NULL) { Tcl_DecrRefCount(errorBuffer); } |
︙ | ︙ | |||
536 537 538 539 540 541 542 | * implementations of copy and rename on all platforms also prevent * this. */ if (S_ISDIR(sourceStatBuf.st_mode) && !S_ISDIR(targetStatBuf.st_mode)) { errno = EISDIR; | | | | > | | < | 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 | * implementations of copy and rename on all platforms also prevent * this. */ if (S_ISDIR(sourceStatBuf.st_mode) && !S_ISDIR(targetStatBuf.st_mode)) { errno = EISDIR; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't overwrite file \"%s\" with directory \"%s\"", TclGetString(target), TclGetString(source))); goto done; } if (!S_ISDIR(sourceStatBuf.st_mode) && S_ISDIR(targetStatBuf.st_mode)) { errno = EISDIR; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't overwrite directory \"%s\" with file \"%s\"", TclGetString(target), TclGetString(source))); goto done; } /* * The destination exists, but appears to be ok to over-write, and * -force is given. We now try to adjust permissions to ensure the * operation succeeds. If we can't adjust permissions, we'll let the |
︙ | ︙ | |||
577 578 579 580 581 582 583 | if (copyFlag == 0) { result = Tcl_FSRenameFile(source, target); if (result == TCL_OK) { goto done; } if (errno == EINVAL) { | | < | | > | 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 | if (copyFlag == 0) { result = Tcl_FSRenameFile(source, target); if (result == TCL_OK) { goto done; } if (errno == EINVAL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error renaming \"%s\" to \"%s\": trying to rename a" " volume or move a directory into itself", TclGetString(source), TclGetString(target))); goto done; } else if (errno != EXDEV) { errfile = target; goto done; } /* |
︙ | ︙ | |||
624 625 626 627 628 629 630 | */ if (Tcl_FSStat(source, &sourceStatBuf) != 0) { /* * Actual file doesn't exist. */ | | | > | 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 | */ if (Tcl_FSStat(source, &sourceStatBuf) != 0) { /* * Actual file doesn't exist. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error copying \"%s\": the target of this link doesn't" " exist", TclGetString(source))); goto done; } else { int counter = 0; while (1) { Tcl_Obj *path = Tcl_FSLink(actualSource, NULL, 0); if (path == NULL) { |
︙ | ︙ | |||
760 761 762 763 764 765 766 | } else { result = Tcl_FSDeleteFile(source); if (result != TCL_OK) { errfile = source; } } if (result != TCL_OK) { | | | > | | > | > | > | | 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 | } else { result = Tcl_FSDeleteFile(source); if (result != TCL_OK) { errfile = source; } } if (result != TCL_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("can't unlink \"%s\": %s", TclGetString(errfile), Tcl_PosixError(interp))); errfile = NULL; } } done: if (errfile != NULL) { Tcl_Obj *errorMsg = Tcl_ObjPrintf("error %s \"%s\"", (copyFlag ? "copying" : "renaming"), TclGetString(source)); if (errfile != source) { Tcl_AppendPrintfToObj(errorMsg, " to \"%s\"", TclGetString(target)); if (errfile != target) { Tcl_AppendPrintfToObj(errorMsg, ": \"%s\"", TclGetString(errfile)); } } Tcl_AppendPrintfToObj(errorMsg, ": %s", Tcl_PosixError(interp)); Tcl_SetObjResult(interp, errorMsg); } if (errorBuffer != NULL) { Tcl_DecrRefCount(errorBuffer); } if (actualSource != NULL) { Tcl_DecrRefCount(actualSource); } |
︙ | ︙ | |||
979 980 981 982 983 984 985 | if (objStrings == NULL) { if (Tcl_GetErrno() != 0) { /* * There was an error, probably that the filePtr is not * accepted by any filesystem */ | > > | | < | 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 | if (objStrings == NULL) { if (Tcl_GetErrno() != 0) { /* * There was an error, probably that the filePtr is not * accepted by any filesystem */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": %s", TclGetString(filePtr), Tcl_PosixError(interp))); } return TCL_ERROR; } /* * We own the object now. */ |
︙ | ︙ | |||
1067 1068 1069 1070 1071 1072 1073 | * Get one attribute. */ int index; Tcl_Obj *objPtr = NULL; if (numObjStrings == 0) { | | | | | 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 | * Get one attribute. */ int index; Tcl_Obj *objPtr = NULL; if (numObjStrings == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad option \"%s\", there are no file attributes in this" " filesystem", TclGetString(objv[0]))); Tcl_SetErrorCode(interp, "TCL","OPERATION","FATTR","NONE", NULL); goto end; } if (Tcl_GetIndexFromObj(interp, objv[0], attributeStrings, "option", 0, &index) != TCL_OK) { goto end; |
︙ | ︙ | |||
1094 1095 1096 1097 1098 1099 1100 | /* * Set option/value pairs. */ int i, index; if (numObjStrings == 0) { | | | | | | | 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 | /* * Set option/value pairs. */ int i, index; if (numObjStrings == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad option \"%s\", there are no file attributes in this" " filesystem", TclGetString(objv[0]))); Tcl_SetErrorCode(interp, "TCL","OPERATION","FATTR","NONE", NULL); goto end; } for (i = 0; i < objc ; i += 2) { if (Tcl_GetIndexFromObj(interp, objv[i], attributeStrings, "option", 0, &index) != TCL_OK) { goto end; } if (attributeStringsAllocated != NULL) { TclFreeIntRep(objv[i]); } if (i + 1 == objc) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "value for \"%s\" missing", TclGetString(objv[i]))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FATTR", "NOVALUE", NULL); goto end; } if (Tcl_FSFileAttrsSet(interp, index, filePtr, objv[i + 1]) != TCL_OK) { goto end; |
︙ | ︙ | |||
1220 1221 1222 1223 1224 1225 1226 | if (contents == NULL) { /* * We handle three common error cases specially, and for all other * errors, we use the standard posix error message. */ if (errno == EEXIST) { | > | | < > | | < > | | | < > | | | < > | | < | 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 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 | if (contents == NULL) { /* * We handle three common error cases specially, and for all other * errors, we use the standard posix error message. */ if (errno == EEXIST) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not create new link \"%s\": that path already" " exists", TclGetString(objv[index]))); Tcl_PosixError(interp); } else if (errno == ENOENT) { /* * There are two cases here: either the target doesn't exist, * or the directory of the src doesn't exist. */ int access; Tcl_Obj *dirPtr = TclPathPart(interp, objv[index], TCL_PATH_DIRNAME); if (dirPtr == NULL) { return TCL_ERROR; } access = Tcl_FSAccess(dirPtr, F_OK); Tcl_DecrRefCount(dirPtr); if (access != 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not create new link \"%s\": no such file" " or directory", TclGetString(objv[index]))); Tcl_PosixError(interp); } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not create new link \"%s\": target \"%s\" " "doesn't exist", TclGetString(objv[index]), TclGetString(objv[index+1]))); errno = ENOENT; Tcl_PosixError(interp); } } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not create new link \"%s\" pointing to \"%s\": %s", TclGetString(objv[index]), TclGetString(objv[index+1]), Tcl_PosixError(interp))); } return TCL_ERROR; } } else { if (Tcl_FSConvertToPathType(interp, objv[index]) != TCL_OK) { return TCL_ERROR; } /* * Read link */ contents = Tcl_FSLink(objv[index], NULL, 0); if (contents == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read link \"%s\": %s", TclGetString(objv[index]), Tcl_PosixError(interp))); return TCL_ERROR; } } Tcl_SetObjResult(interp, contents); if (objc == 2) { /* * If we are reading a link, we need to free this result refCount. If |
︙ | ︙ | |||
1328 1329 1330 1331 1332 1333 1334 | if (Tcl_FSConvertToPathType(interp, objv[1]) != TCL_OK) { return TCL_ERROR; } contents = Tcl_FSLink(objv[1], NULL, 0); if (contents == NULL) { | > | | | 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 | if (Tcl_FSConvertToPathType(interp, objv[1]) != TCL_OK) { return TCL_ERROR; } contents = Tcl_FSLink(objv[1], NULL, 0); if (contents == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read link \"%s\": %s", TclGetString(objv[1]), Tcl_PosixError(interp))); return TCL_ERROR; } Tcl_SetObjResult(interp, contents); Tcl_DecrRefCount(contents); return TCL_OK; } |
︙ | ︙ | |||
1483 1484 1485 1486 1487 1488 1489 | * Deal with results. */ if (chan == NULL) { if (nameVarObj) { TclDecrRefCount(nameObj); } | | | | | 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 | * Deal with results. */ if (chan == NULL) { if (nameVarObj) { TclDecrRefCount(nameObj); } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create temporary file: %s", Tcl_PosixError(interp))); return TCL_ERROR; } Tcl_RegisterChannel(interp, chan); 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), -1)); return TCL_OK; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclFileName.c.
︙ | ︙ | |||
407 408 409 410 411 412 413 | case TCL_PLATFORM_UNIX: { const char *origPath = path; /* * Paths that begin with / are absolute. */ | > > | | | | < | | | | | > > > > > > | > > > < < < < < < < | | 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | case TCL_PLATFORM_UNIX: { const char *origPath = path; /* * Paths that begin with / are absolute. */ if (path[0] == '/') { ++path; #if defined(__CYGWIN__) || defined(__QNX__) /* * Check for "//" network path prefix */ if ((*path == '/') && path[1] && (path[1] != '/')) { path += 2; while (*path && *path != '/') { ++path; } #if defined(__CYGWIN__) /* UNC paths need to be followed by a share name */ if (*path++ && (*path && *path != '/')) { ++path; while (*path && *path != '/') { ++path; } } else { path = origPath + 1; } #endif } #endif if (driveNameLengthPtr != NULL) { /* * We need this addition in case the QNX or Cygwin code was used. */ *driveNameLengthPtr = (path - origPath); } } else { type = TCL_PATH_RELATIVE; } break; } case TCL_PLATFORM_WINDOWS: { |
︙ | ︙ | |||
636 637 638 639 640 641 642 | */ static Tcl_Obj * SplitUnixPath( const char *path) /* Pointer to string containing a path. */ { int length; | | > > > | | | | > > > > | > > | < | | | | > > | | < | | < < < < < > | < | < < | | | | | | | 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 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 713 | */ static Tcl_Obj * SplitUnixPath( const char *path) /* Pointer to string containing a path. */ { int length; const char *origPath = path, *elementStart; Tcl_Obj *result = Tcl_NewObj(); /* * Deal with the root directory as a special case. */ if (*path == '/') { Tcl_Obj *rootElt; ++path; #if defined(__CYGWIN__) || defined(__QNX__) /* * Check for "//" network path prefix */ if ((*path == '/') && path[1] && (path[1] != '/')) { path += 2; while (*path && *path != '/') { ++path; } #if defined(__CYGWIN__) /* UNC paths need to be followed by a share name */ if (*path++ && (*path && *path != '/')) { ++path; while (*path && *path != '/') { ++path; } } else { path = origPath + 1; } #endif } #endif rootElt = Tcl_NewStringObj(origPath, path - origPath); Tcl_ListObjAppendElement(NULL, result, rootElt); while (*path == '/') { ++path; } } /* * Split on slashes. Embedded elements that start with tilde will be * prefixed with "./" so they are not affected by tilde substitution. */ for (;;) { elementStart = path; while ((*path != '\0') && (*path != '/')) { path++; } length = path - elementStart; if (length > 0) { Tcl_Obj *nextElt; if ((elementStart[0] == '~') && (elementStart != origPath)) { TclNewLiteralStringObj(nextElt, "./"); Tcl_AppendToObj(nextElt, elementStart, length); } else { nextElt = Tcl_NewStringObj(elementStart, length); } Tcl_ListObjAppendElement(NULL, result, nextElt); } if (*path++ == '\0') { break; } } return result; } /* |
︙ | ︙ | |||
1170 1171 1172 1173 1174 1175 1176 | if (*user == '\0') { Tcl_DString dirString; dir = TclGetEnv("HOME", &dirString); if (dir == NULL) { if (interp) { | | | | > > | | | 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 | if (*user == '\0') { 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", -1)); Tcl_SetErrorCode(interp, "TCL", "FILENAME", "NO_HOME", NULL); } return NULL; } Tcl_JoinPath(1, &dir, resultPtr); Tcl_DStringFree(&dirString); } else if (TclpGetUserHome(user, resultPtr) == NULL) { if (interp) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "user \"%s\" doesn't exist", user)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "USER", user, NULL); } return NULL; } return Tcl_DStringValue(resultPtr); } /* |
︙ | ︙ | |||
1325 1326 1327 1328 1329 1330 1331 | i++; goto endOfForLoop; } } endOfForLoop: if ((globFlags & TCL_GLOBMODE_TAILS) && (pathOrDir == NULL)) { | | | | 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 | 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\"", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BADOPTIONCOMBINATION", NULL); return TCL_ERROR; } separators = NULL; /* lint. */ switch (tclPlatform) { |
︙ | ︙ | |||
1621 1622 1623 1624 1625 1626 1627 | */ result = TCL_ERROR; goto endOfGlob; } if (length == 0) { | > | | > | > | < > | | 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 | */ result = TCL_ERROR; goto endOfGlob; } if (length == 0) { Tcl_Obj *errorMsg = Tcl_ObjPrintf("no files matched glob pattern%s \"", (join || (objc == 1)) ? "" : "s"); if (join) { Tcl_AppendToObj(errorMsg, Tcl_DStringValue(&prefix), -1); } else { const char *sep = ""; for (i = 0; i < objc; i++) { Tcl_AppendPrintfToObj(errorMsg, "%s%s", sep, Tcl_GetString(objv[i])); sep = " "; } } Tcl_AppendToObj(errorMsg, "\"", -1); Tcl_SetObjResult(interp, errorMsg); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "NOMATCH", NULL); result = TCL_ERROR; } } endOfGlob: |
︙ | ︙ | |||
1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 | } pathPrefix = TclDStringToObj(&buffer); Tcl_IncrRefCount(pathPrefix); globFlags |= TCL_GLOBMODE_DIR; if (c != '\0') { tail++; } } else { tail = pattern; } } else { Tcl_IncrRefCount(pathPrefix); tail = pattern; } | > | 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 | } pathPrefix = TclDStringToObj(&buffer); Tcl_IncrRefCount(pathPrefix); globFlags |= TCL_GLOBMODE_DIR; if (c != '\0') { tail++; } Tcl_DStringFree(&buffer); } else { tail = pattern; } } else { Tcl_IncrRefCount(pathPrefix); tail = pattern; } |
︙ | ︙ | |||
2202 2203 2204 2205 2206 2207 2208 | /* * Balanced braces. */ closeBrace = p; break; } | > | < > | < | 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 | /* * Balanced braces. */ closeBrace = p; break; } Tcl_SetObjResult(interp, Tcl_NewStringObj( "unmatched open-brace in file name", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BALANCE", NULL); return TCL_ERROR; } } /* |
︙ | ︙ |
Changes to generic/tclIO.c.
︙ | ︙ | |||
423 424 425 426 427 428 429 | */ active = 0; for (statePtr = tsdPtr->firstCSPtr; statePtr != NULL; statePtr = statePtr->nextCSPtr) { chanPtr = statePtr->topChanPtr; | > > > | | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 | */ active = 0; 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; } } |
︙ | ︙ | |||
1020 1021 1022 1023 1024 1025 1026 | { ChannelState *statePtr; /* State of the real channel. */ statePtr = ((Channel *) chan)->state->bottomChanPtr->state; if (GotFlag(statePtr, CHANNEL_INCLOSE)) { if (interp != NULL) { | > | | | 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 | { ChannelState *statePtr; /* State of the real channel. */ 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", -1)); } return TCL_ERROR; } if (DetachChannel(interp, chan) != TCL_OK) { return TCL_OK; } |
︙ | ︙ | |||
1256 1257 1258 1259 1260 1261 1262 | name = chanPtr->state->channelName; } } hTblPtr = GetChannelTable(interp); hPtr = Tcl_FindHashEntry(hTblPtr, name); if (hPtr == NULL) { | > | < | 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 | name = chanPtr->state->channelName; } } hTblPtr = GetChannelTable(interp); hPtr = Tcl_FindHashEntry(hTblPtr, name); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can not find channel named \"%s\"", chanName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CHANNEL", chanName, NULL); return NULL; } /* * Always return bottom-most channel in the stack. This one lives the * longest - other channels may go away unnoticed. The other APIs |
︙ | ︙ | |||
1577 1578 1579 1580 1581 1582 1583 | while ((statePtr != NULL) && (statePtr->topChanPtr != prevChanPtr)) { statePtr = statePtr->nextCSPtr; } if (statePtr == NULL) { if (interp) { | > | | | | | | 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 | while ((statePtr != NULL) && (statePtr->topChanPtr != prevChanPtr)) { statePtr = statePtr->nextCSPtr; } if (statePtr == NULL) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't find state for channel \"%s\"", Tcl_GetChannelName(prevChan))); } return NULL; } /* * Here we check if the given "mask" matches the "flags" of the already * existing channel. * * | - | R | W | RW | * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) * - | | | | | * R | | + | | + | The superceding channel is allowed to restrict * W | | | + | + | the capabilities of the superceded one! * RW| | + | + | + | * --+---+---+---+----+ */ if ((mask & (statePtr->flags & (TCL_READABLE | TCL_WRITABLE))) == 0) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "reading and writing both disallowed for channel \"%s\"", Tcl_GetChannelName(prevChan))); } return NULL; } /* * Flush the buffers. This ensures that any data still in them at this * time is not handled by the new transformation. Restrict this to |
︙ | ︙ | |||
1623 1624 1625 1626 1627 1628 1629 | statePtr->csPtrR = NULL; statePtr->csPtrW = NULL; if (Tcl_Flush((Tcl_Channel) prevChanPtr) != TCL_OK) { statePtr->csPtrR = csPtrR; statePtr->csPtrW = csPtrW; if (interp) { | > | | | 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 | statePtr->csPtrR = NULL; statePtr->csPtrW = NULL; if (Tcl_Flush((Tcl_Channel) prevChanPtr) != TCL_OK) { statePtr->csPtrR = csPtrR; statePtr->csPtrW = csPtrW; if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not flush channel \"%s\"", Tcl_GetChannelName(prevChan))); } return NULL; } statePtr->csPtrR = csPtrR; statePtr->csPtrW = csPtrW; } |
︙ | ︙ | |||
1777 1778 1779 1780 1781 1782 1783 | * Move error messages put by the driver into the chan/ip * bypass area into the regular interpreter result. Fall back * to the regular message if nothing was found in the * bypasses. */ if (!TclChanCaughtErrorBypass(interp, chan) && interp) { | > | | < | 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 | * Move error messages put by the driver into the chan/ip * bypass area into the regular interpreter result. Fall back * to the regular message if nothing was found in the * bypasses. */ if (!TclChanCaughtErrorBypass(interp, chan) && interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not flush channel \"%s\"", Tcl_GetChannelName((Tcl_Channel) chanPtr))); } return TCL_ERROR; } statePtr->csPtrR = csPtrR; statePtr->csPtrW = csPtrW; } |
︙ | ︙ | |||
2311 2312 2313 2314 2315 2316 2317 | { if (!GotFlag(statePtr, CHANNEL_DEAD)) { return 0; } Tcl_SetErrno(EINVAL); if (interp) { | > | < | 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 | { if (!GotFlag(statePtr, CHANNEL_DEAD)) { return 0; } Tcl_SetErrno(EINVAL); if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unable to access channel: invalid channel", -1)); } return 1; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3044 3045 3046 3047 3048 3049 3050 | if (statePtr->refCount > 0) { Tcl_Panic("called Tcl_Close on channel with refCount > 0"); } if (GotFlag(statePtr, CHANNEL_INCLOSE)) { if (interp) { | > | | | 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 | if (statePtr->refCount > 0) { 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", -1)); } return TCL_ERROR; } SetFlag(statePtr, CHANNEL_INCLOSE); /* * When the channel has an escape sequence driven encoding such as |
︙ | ︙ | |||
3203 3204 3205 3206 3207 3208 3209 | statePtr = chanPtr->state; /* * Does the channel support half-close anyway? Error if not. */ if (!chanPtr->typePtr->close2Proc) { | > | | | | < | | | > | | | 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 | statePtr = chanPtr->state; /* * Does the channel support half-close anyway? Error if not. */ if (!chanPtr->typePtr->close2Proc) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "half-close of channels not supported by %ss", chanPtr->typePtr->typeName)); return TCL_ERROR; } /* * 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", -1)); 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). */ if (!(statePtr->flags & (TCL_READABLE | TCL_WRITABLE) & flags)) { const char *msg; if (flags & TCL_CLOSE_READ) { msg = "read"; } else { msg = "write"; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "Half-close of %s-side not possible, side not opened or" " already closed", msg)); return TCL_ERROR; } /* * A user may try to call half-close from within a channel close * 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", -1)); } return TCL_ERROR; } if (flags & TCL_CLOSE_READ) { /* * Call the finalization code directly. There are no events to handle, |
︙ | ︙ | |||
7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 | { if (interp != NULL) { const char *genericopt = "blocking buffering buffersize encoding eofchar translation"; const char **argv; int argc, i; Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, genericopt, -1); if (optionList && (*optionList)) { TclDStringAppendLiteral(&ds, " "); Tcl_DStringAppend(&ds, optionList, -1); } if (Tcl_SplitList(interp, Tcl_DStringValue(&ds), &argc, &argv) != TCL_OK) { Tcl_Panic("malformed option list in channel driver"); } Tcl_ResetResult(interp); | > < | > | > | | 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 | { if (interp != NULL) { const char *genericopt = "blocking buffering buffersize encoding eofchar translation"; const char **argv; int argc, i; Tcl_DString ds; Tcl_Obj *errObj; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, genericopt, -1); if (optionList && (*optionList)) { TclDStringAppendLiteral(&ds, " "); Tcl_DStringAppend(&ds, optionList, -1); } 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 ", optionName); argc--; for (i = 0; i < argc; i++) { Tcl_AppendPrintfToObj(errObj, "-%s, ", argv[i]); } Tcl_AppendPrintfToObj(errObj, "or -%s", argv[i]); Tcl_SetObjResult(interp, errObj); Tcl_DStringFree(&ds); ckfree(argv); } Tcl_SetErrno(EINVAL); return TCL_ERROR; } |
︙ | ︙ | |||
7836 7837 7838 7839 7840 7841 7842 | /* * If the channel is in the middle of a background copy, fail. */ if (statePtr->csPtrR || statePtr->csPtrW) { if (interp) { | > | | | 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 | /* * 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", -1)); } 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 |
︙ | ︙ | |||
7886 7887 7888 7889 7890 7891 7892 | ResetFlag(statePtr, CHANNEL_UNBUFFERED); SetFlag(statePtr, CHANNEL_LINEBUFFERED); } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { ResetFlag(statePtr, CHANNEL_LINEBUFFERED); SetFlag(statePtr, CHANNEL_UNBUFFERED); } else if (interp) { | > | | | 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 | ResetFlag(statePtr, CHANNEL_UNBUFFERED); SetFlag(statePtr, CHANNEL_LINEBUFFERED); } 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", -1)); return TCL_ERROR; } return TCL_OK; } else if (HaveOpt(7, "-buffersize")) { int newBufferSize; if (Tcl_GetInt(interp, newValue, &newBufferSize) == TCL_ERROR) { |
︙ | ︙ | |||
7942 7943 7944 7945 7946 7947 7948 | } else if (argc == 1 || argc == 2) { int outIndex = (argc - 1); int inValue = (int) argv[0][0]; int outValue = (int) argv[outIndex][0]; if (inValue & 0x80 || outValue & 0x80) { if (interp) { | > | | | | | 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 | } else if (argc == 1 || argc == 2) { int outIndex = (argc - 1); 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", -1)); } 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", -1)); } ckfree(argv); return TCL_ERROR; } if (argv != NULL) { ckfree(argv); } |
︙ | ︙ | |||
7990 7991 7992 7993 7994 7995 7996 | readMode = GotFlag(statePtr, TCL_READABLE) ? argv[0] : NULL; writeMode = GotFlag(statePtr, TCL_WRITABLE) ? argv[0] : NULL; } else if (argc == 2) { readMode = GotFlag(statePtr, TCL_READABLE) ? argv[0] : NULL; writeMode = GotFlag(statePtr, TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { | | | | 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 | readMode = GotFlag(statePtr, TCL_READABLE) ? argv[0] : NULL; writeMode = GotFlag(statePtr, TCL_WRITABLE) ? argv[0] : NULL; } 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", -1)); } ckfree(argv); return TCL_ERROR; } if (readMode) { TclEolTranslation translation; |
︙ | ︙ | |||
8020 8021 8022 8023 8024 8025 8026 | translation = TCL_TRANSLATE_CR; } else if (strcmp(readMode, "crlf") == 0) { translation = TCL_TRANSLATE_CRLF; } else if (strcmp(readMode, "platform") == 0) { translation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { | | | | < | 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 | translation = TCL_TRANSLATE_CR; } else if (strcmp(readMode, "crlf") == 0) { 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", -1)); } ckfree(argv); return TCL_ERROR; } /* * Reset the EOL flags since we need to look at any buffered data |
︙ | ︙ | |||
8071 8072 8073 8074 8075 8076 8077 | statePtr->outputTranslation = TCL_TRANSLATE_CR; } else if (strcmp(writeMode, "crlf") == 0) { statePtr->outputTranslation = TCL_TRANSLATE_CRLF; } else if (strcmp(writeMode, "platform") == 0) { statePtr->outputTranslation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { | | | | < | 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 | statePtr->outputTranslation = TCL_TRANSLATE_CR; } else if (strcmp(writeMode, "crlf") == 0) { 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", -1)); } ckfree(argv); return TCL_ERROR; } } ckfree(argv); return TCL_OK; |
︙ | ︙ | |||
8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 | /* * We must preserve the interpreter so we can report errors on it later. * Note that we do not need to preserve the channel because that is done * by Tcl_NotifyChannel before calling channel handlers. */ Tcl_Preserve(interp); result = Tcl_EvalObjEx(interp, esPtr->scriptPtr, TCL_EVAL_GLOBAL); /* * On error, cause a background error and remove the channel handler and * the script record. * * NOTE: Must delete channel handler before causing the background error * because the background error may want to reinstall the handler. */ if (result != TCL_OK) { if (chanPtr->typePtr != NULL) { DeleteScriptRecord(interp, chanPtr, mask); } Tcl_BackgroundException(interp, result); } Tcl_Release(interp); } /* *---------------------------------------------------------------------- * * Tcl_FileEventObjCmd -- | > > | 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 | /* * We must preserve the interpreter so we can report errors on it later. * Note that we do not need to preserve the channel because that is done * by Tcl_NotifyChannel before calling channel handlers. */ Tcl_Preserve(interp); Tcl_Preserve(chanPtr); result = Tcl_EvalObjEx(interp, esPtr->scriptPtr, TCL_EVAL_GLOBAL); /* * On error, cause a background error and remove the channel handler and * the script record. * * NOTE: Must delete channel handler before causing the background error * because the background error may want to reinstall the handler. */ if (result != TCL_OK) { if (chanPtr->typePtr != NULL) { DeleteScriptRecord(interp, chanPtr, mask); } Tcl_BackgroundException(interp, result); } Tcl_Release(chanPtr); Tcl_Release(interp); } /* *---------------------------------------------------------------------- * * Tcl_FileEventObjCmd -- |
︙ | ︙ | |||
8892 8893 8894 8895 8896 8897 8898 | chan = Tcl_GetChannel(interp, chanName, NULL); if (chan == NULL) { return TCL_ERROR; } chanPtr = (Channel *) chan; statePtr = chanPtr->state; if ((statePtr->flags & mask) == 0) { | | | | 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 | chan = Tcl_GetChannel(interp, chanName, NULL); if (chan == NULL) { return TCL_ERROR; } chanPtr = (Channel *) chan; statePtr = chanPtr->state; if ((statePtr->flags & mask) == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("channel is not %s", (mask == TCL_READABLE) ? "readable" : "writable")); return TCL_ERROR; } /* * If we are supposed to return the script, do so. */ |
︙ | ︙ | |||
9014 9015 9016 9017 9018 9019 9020 | int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0; inStatePtr = inPtr->state; outStatePtr = outPtr->state; if (BUSY_STATE(inStatePtr, TCL_READABLE)) { if (interp) { | | | | | | 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 | int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0; inStatePtr = inPtr->state; outStatePtr = outPtr->state; if (BUSY_STATE(inStatePtr, TCL_READABLE)) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" is busy", Tcl_GetChannelName(inChan))); } return TCL_ERROR; } if (BUSY_STATE(outStatePtr, TCL_WRITABLE)) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" is busy", Tcl_GetChannelName(outChan))); } return TCL_ERROR; } readFlags = inStatePtr->flags; writeFlags = outStatePtr->flags; |
︙ | ︙ | |||
10148 10149 10150 10151 10152 10153 10154 | * * Note that we cannot have a message in the interpreter bypass * area, StackSetBlockMode is restricted to the channel bypass. * We still need the interp as the destination of the move. */ if (!TclChanCaughtErrorBypass(interp, (Tcl_Channel) chanPtr)) { | > | | | 10161 10162 10163 10164 10165 10166 10167 10168 10169 10170 10171 10172 10173 10174 10175 10176 10177 | * * Note that we cannot have a message in the interpreter bypass * area, StackSetBlockMode is restricted to the channel bypass. * We still need the interp as the destination of the move. */ if (!TclChanCaughtErrorBypass(interp, (Tcl_Channel) chanPtr)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error setting blocking mode: %s", Tcl_PosixError(interp))); } } else { /* * TIP #219. * If we have no interpreter to put a bypass message into we have * to clear it, to prevent its propagation and use in other places * unrelated to the actual occurence of the problem. |
︙ | ︙ |
Changes to generic/tclIOCmd.c.
︙ | ︙ | |||
170 171 172 173 174 175 176 | Tcl_CreateThreadExitHandler(FinalizeIOCmdTSD, NULL); } chanObjPtr = tsdPtr->stdoutObjPtr; } if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } | | | | > | 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | Tcl_CreateThreadExitHandler(FinalizeIOCmdTSD, NULL); } chanObjPtr = tsdPtr->stdoutObjPtr; } if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } if (!(mode & TCL_WRITABLE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" wasn't opened for writing", TclGetString(chanObjPtr))); return TCL_ERROR; } result = Tcl_WriteObj(chan, string); if (result < 0) { goto error; } |
︙ | ︙ | |||
197 198 199 200 201 202 203 | * 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. */ error: if (!TclChanCaughtErrorBypass(interp, chan)) { | | | | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | * 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. */ error: if (!TclChanCaughtErrorBypass(interp, chan)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("error writing \"%s\": %s", TclGetString(chanObjPtr), Tcl_PosixError(interp))); } return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
240 241 242 243 244 245 246 | Tcl_WrongNumArgs(interp, 1, objv, "channelId"); return TCL_ERROR; } chanObjPtr = objv[1]; if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } | | | | > > | | < | 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 | Tcl_WrongNumArgs(interp, 1, objv, "channelId"); return TCL_ERROR; } chanObjPtr = objv[1]; if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } if (!(mode & TCL_WRITABLE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" wasn't opened for writing", TclGetString(chanObjPtr))); return TCL_ERROR; } if (Tcl_Flush(chan) != TCL_OK) { /* * 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. */ if (!TclChanCaughtErrorBypass(interp, chan)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error flushing \"%s\": %s", TclGetString(chanObjPtr), Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; } /* |
︙ | ︙ | |||
302 303 304 305 306 307 308 | Tcl_WrongNumArgs(interp, 1, objv, "channelId ?varName?"); return TCL_ERROR; } chanObjPtr = objv[1]; if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } | | | | > | | | < | 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 | Tcl_WrongNumArgs(interp, 1, objv, "channelId ?varName?"); return TCL_ERROR; } chanObjPtr = objv[1]; if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } if (!(mode & TCL_READABLE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" wasn't opened for reading", TclGetString(chanObjPtr))); return TCL_ERROR; } linePtr = Tcl_NewObj(); lineLen = Tcl_GetsObj(chan, linePtr); if (lineLen < 0) { if (!Tcl_Eof(chan) && !Tcl_InputBlocked(chan)) { Tcl_DecrRefCount(linePtr); /* * 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. */ if (!TclChanCaughtErrorBypass(interp, chan)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error reading \"%s\": %s", TclGetString(chanObjPtr), Tcl_PosixError(interp))); } return TCL_ERROR; } lineLen = -1; } if (objc == 3) { if (Tcl_ObjSetVar2(interp, objv[2], NULL, linePtr, |
︙ | ︙ | |||
407 408 409 410 411 412 413 | goto argerror; } chanObjPtr = objv[i]; if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } | | | | > | 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 | goto argerror; } chanObjPtr = objv[i]; if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } if (!(mode & TCL_READABLE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" wasn't opened for reading", TclGetString(chanObjPtr))); return TCL_ERROR; } i++; /* Consumed channel name. */ /* * Compute how many bytes to read. */ |
︙ | ︙ | |||
432 433 434 435 436 437 438 | * form of the command that is no longer recommended or * documented. See also [Bug #3151675]. Will be removed in Tcl 9, * maybe even earlier. */ if (strcmp(TclGetString(objv[i]), "nonewline") != 0) { #endif | | | | | | | | | < | 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 | * form of the command that is no longer recommended or * documented. See also [Bug #3151675]. Will be removed in Tcl 9, * maybe even earlier. */ if (strcmp(TclGetString(objv[i]), "nonewline") != 0) { #endif 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; #if TCL_MAJOR_VERSION < 9 } newline = 1; #endif } } resultPtr = Tcl_NewObj(); Tcl_IncrRefCount(resultPtr); charactersRead = Tcl_ReadChars(chan, resultPtr, toRead, 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. */ if (!TclChanCaughtErrorBypass(interp, chan)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error reading \"%s\": %s", TclGetString(chanObjPtr), Tcl_PosixError(interp))); } Tcl_DecrRefCount(resultPtr); return TCL_ERROR; } /* * If requested, remove the last newline in the channel if at EOF. |
︙ | ︙ | |||
548 549 550 551 552 553 554 | * 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. */ if (!TclChanCaughtErrorBypass(interp, chan)) { | > | | < | 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 | * 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. */ if (!TclChanCaughtErrorBypass(interp, chan)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error during seek on \"%s\": %s", TclGetString(objv[1]), Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; } /* |
︙ | ︙ | |||
675 676 677 678 679 680 681 | /* * 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). */ if (!(dir & Tcl_GetChannelMode(chan))) { | | | | | 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 | /* * 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). */ if (!(dir & Tcl_GetChannelMode(chan))) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "Half-close of %s-side not possible, side not opened" " or already closed", dirOptions[index])); return TCL_ERROR; } /* * Special handling is needed if and only if the channel mode supports * more than the direction to close. Because if the close the last * direction suppported we can and will go through the regular |
︙ | ︙ | |||
973 974 975 976 977 978 979 | * 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. */ if (!TclChanCaughtErrorBypass(interp, chan)) { | | | | | 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 | * 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. */ if (!TclChanCaughtErrorBypass(interp, chan)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error reading output from command: %s", Tcl_PosixError(interp))); Tcl_DecrRefCount(resultPtr); } return TCL_ERROR; } } /* |
︙ | ︙ | |||
1044 1045 1046 1047 1048 1049 1050 | Tcl_WrongNumArgs(interp, 1, objv, "channelId"); return TCL_ERROR; } if (TclGetChannelFromObj(interp, objv[1], &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } | | | | > | 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | Tcl_WrongNumArgs(interp, 1, objv, "channelId"); return TCL_ERROR; } if (TclGetChannelFromObj(interp, objv[1], &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } if (!(mode & TCL_READABLE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" wasn't opened for reading", TclGetString(objv[1]))); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewBooleanObj(Tcl_InputBlocked(chan))); return TCL_OK; } |
︙ | ︙ | |||
1170 1171 1172 1173 1174 1175 1176 | } ckfree(cmdArgv); } if (chan == NULL) { return TCL_ERROR; } Tcl_RegisterChannel(interp, chan); | | | 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 | } ckfree(cmdArgv); } if (chan == NULL) { return TCL_ERROR; } Tcl_RegisterChannel(interp, chan); Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1)); return TCL_OK; } /* *---------------------------------------------------------------------- * * TcpAcceptCallbacksDeleteProc -- |
︙ | ︙ | |||
1475 1476 1477 1478 1479 1480 1481 | if (Tcl_GetIndexFromObj(interp, objv[a], socketOptions, "option", TCL_EXACT, &optionIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum socketOptions) optionIndex) { case SKT_ASYNC: if (server == 1) { | | | | | | | | | | | > | < | 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 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 | if (Tcl_GetIndexFromObj(interp, objv[a], socketOptions, "option", 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", -1)); return TCL_ERROR; } async = 1; break; case SKT_MYADDR: a++; if (a >= objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no argument given for -myaddr option", -1)); 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", -1)); 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", -1)); return TCL_ERROR; } server = 1; a++; if (a >= objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no argument given for -server option", -1)); 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", -1)); return TCL_ERROR; } } else if (a < objc) { host = TclGetString(objv[a]); a++; } else { Interp *iPtr; |
︙ | ︙ | |||
1595 1596 1597 1598 1599 1600 1601 1602 | Tcl_CreateCloseHandler(chan, TcpServerCloseProc, acceptCallbackPtr); } else { chan = Tcl_OpenTcpClient(interp, port, host, myaddr, myport, async); if (chan == NULL) { return TCL_ERROR; } } Tcl_RegisterChannel(interp, chan); | > | < | 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 | Tcl_CreateCloseHandler(chan, TcpServerCloseProc, acceptCallbackPtr); } else { 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), -1)); return TCL_OK; } /* *---------------------------------------------------------------------- * * Tcl_FcopyObjCmd -- |
︙ | ︙ | |||
1647 1648 1649 1650 1651 1652 1653 | * Parse the channel arguments and verify that they are readable or * writable, as appropriate. */ if (TclGetChannelFromObj(interp, objv[1], &inChan, &mode, 0) != TCL_OK) { return TCL_ERROR; } | | | | > | | | > | 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 1676 | * Parse the channel arguments and verify that they are readable or * writable, as appropriate. */ if (TclGetChannelFromObj(interp, objv[1], &inChan, &mode, 0) != TCL_OK) { return TCL_ERROR; } if (!(mode & TCL_READABLE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" wasn't opened for reading", TclGetString(objv[1]))); return TCL_ERROR; } if (TclGetChannelFromObj(interp, objv[2], &outChan, &mode, 0) != TCL_OK) { return TCL_ERROR; } if (!(mode & TCL_WRITABLE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" wasn't opened for writing", TclGetString(objv[2]))); return TCL_ERROR; } toRead = -1; cmdPtr = NULL; for (i = 3; i < objc; i += 2) { if (Tcl_GetIndexFromObj(interp, objv[i], switches, "switch", 0, |
︙ | ︙ | |||
1741 1742 1743 1744 1745 1746 1747 | if (TclGetChannelFromObj(interp, objv[2], &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } switch ((enum options) index) { case PENDING_INPUT: | | | | 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 | if (TclGetChannelFromObj(interp, objv[2], &chan, &mode, 0) != TCL_OK) { return TCL_ERROR; } switch ((enum options) index) { case PENDING_INPUT: if (!(mode & TCL_READABLE)) { Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); } else { Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_InputBuffered(chan))); } break; case PENDING_OUTPUT: if (!(mode & TCL_WRITABLE)) { Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); } else { Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_OutputBuffered(chan))); } break; } return TCL_OK; |
︙ | ︙ | |||
1802 1803 1804 1805 1806 1807 1808 | * User is supplying an explicit length. */ if (Tcl_GetWideIntFromObj(interp, objv[2], &length) != TCL_OK) { return TCL_ERROR; } if (length < 0) { | | | | | | < > | | < | 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 | * User is supplying an explicit length. */ 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", -1)); return TCL_ERROR; } } else { /* * User wants to truncate to the current file position. */ length = Tcl_Tell(chan); if (length == Tcl_WideAsLong(-1)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not determine current location in \"%s\": %s", TclGetString(objv[1]), Tcl_PosixError(interp))); return TCL_ERROR; } } if (Tcl_TruncateChannel(chan, length) != TCL_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error during truncate on \"%s\": %s", TclGetString(objv[1]), Tcl_PosixError(interp))); return TCL_ERROR; } return TCL_OK; } /* |
︙ | ︙ |
Changes to generic/tclIOGT.c.
︙ | ︙ | |||
280 281 282 283 284 285 286 | Tcl_IncrRefCount(dataPtr->command); ResultInit(&dataPtr->result); dataPtr->self = Tcl_StackChannel(interp, &transformChannelType, dataPtr, mode, chan); if (dataPtr->self == NULL) { | | | | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | Tcl_IncrRefCount(dataPtr->command); ResultInit(&dataPtr->result); dataPtr->self = Tcl_StackChannel(interp, &transformChannelType, dataPtr, mode, chan); if (dataPtr->self == NULL) { Tcl_AppendPrintfToObj(Tcl_GetObjResult(interp), "\nfailed to stack channel \"%s\"", Tcl_GetChannelName(chan)); Tcl_DecrRefCount(dataPtr->command); ResultClear(&dataPtr->result); ckfree(dataPtr); return TCL_ERROR; } /* |
︙ | ︙ |
Changes to generic/tclIORChan.c.
︙ | ︙ | |||
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) \ | | | | | | | | | | | | 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 | 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) \ if ((i) != NULL) { \ Tcl_SetChannelErrorInterp((i), \ Tcl_NewStringObj((p)->base.msgStr, -1)); \ } \ FreeReceivedError(p) #define PassReceivedError(c,p) \ Tcl_SetChannelError((c), Tcl_NewStringObj((p)->base.msgStr, -1)); \ FreeReceivedError(p) #define ForwardSetStaticError(p,emsg) \ (p)->base.code = TCL_ERROR; \ (p)->base.mustFree = 0; \ (p)->base.msgStr = (char *) (emsg) #define ForwardSetDynamicError(p,emsg) \ (p)->base.code = TCL_ERROR; \ (p)->base.mustFree = 1; \ (p)->base.msgStr = (char *) (emsg) static void ForwardSetObjError(ForwardParam *p, Tcl_Obj *objPtr); static ReflectedChannelMap * GetThreadReflectedChannelMap(void); static void DeleteThreadReflectedChannelMap(ClientData clientData); |
︙ | ︙ | |||
735 736 737 738 739 740 741 | Tcl_SetHashValue(hPtr, chan); #endif /* * Return handle as result of command. */ | > | | 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 | Tcl_SetHashValue(hPtr, chan); #endif /* * Return handle as result of command. */ Tcl_SetObjResult(interp, Tcl_NewStringObj(chanPtr->state->channelName, -1)); return TCL_OK; error: /* * Signal to ReflectClose to not call 'finalize'. */ |
︙ | ︙ | |||
770 771 772 773 774 775 776 | * Posts events to a reflected channel, invokes event handlers. The * latter implies that arbitrary side effects are possible. * *---------------------------------------------------------------------- */ typedef struct ReflectEvent { | | | | | > > | | | > > | | < < | 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 | * Posts events to a reflected channel, invokes event handlers. The * latter implies that arbitrary side effects are possible. * *---------------------------------------------------------------------- */ typedef struct ReflectEvent { Tcl_Event header; ReflectedChannel *rcPtr; int events; } ReflectEvent; static int ReflectEventRun( Tcl_Event *ev, int flags) { /* OWNER thread * * Note: When the channel is closed any pending events of this type are * deleted. See ReflectClose() for the Tcl_DeleteEvents() calls * accomplishing that. */ ReflectEvent *e = (ReflectEvent *) ev; Tcl_NotifyChannel(e->rcPtr->chan, e->events); return 1; } static int ReflectEventDelete( Tcl_Event *ev, ClientData cd) { /* OWNER thread * * Invoked by DeleteThreadReflectedChannelMap() and ReflectClose(). The * latter ensures that no pending events of this type are run on an * invalid channel. */ ReflectEvent *e = (ReflectEvent *) ev; if ((ev->proc != ReflectEventRun) || ((cd != NULL) && (cd != e->rcPtr))) { return 0; } return 1; } int TclChanPostEventObjCmd( |
︙ | ︙ | |||
863 864 865 866 867 868 869 | chanId = TclGetString(objv[CHAN]); rcmPtr = GetReflectedChannelMap(interp); hPtr = Tcl_FindHashEntry(&rcmPtr->map, chanId); if (hPtr == NULL) { | > | < | 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 | chanId = TclGetString(objv[CHAN]); rcmPtr = GetReflectedChannelMap(interp); hPtr = Tcl_FindHashEntry(&rcmPtr->map, chanId); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can not find reflected channel named \"%s\"", chanId)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CHANNEL", chanId, NULL); return TCL_ERROR; } /* * Note that the search above subsumes several of the older checks, namely: * |
︙ | ︙ | |||
921 922 923 924 925 926 927 | } /* * Check that the channel is actually interested in the provided events. */ if (events & ~rcPtr->interest) { | | | > | > | > | > | | | 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 | } /* * Check that the channel is actually interested in the provided events. */ if (events & ~rcPtr->interest) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "tried to post events channel \"%s\" is not interested in", chanId)); return TCL_ERROR; } /* * We have the channel and the events to post. */ #ifdef TCL_THREADS if (rcPtr->owner == rcPtr->thread) { #endif Tcl_NotifyChannel(chan, events); #ifdef TCL_THREADS } else { ReflectEvent *ev = ckalloc(sizeof(ReflectEvent)); ev->header.proc = ReflectEventRun; ev->events = events; ev->rcPtr = rcPtr; /* * We are not preserving the structure here. When the channel is * closed any pending events are deleted, see ReflectClose(), and * ReflectEventDelete(). Trying to preserve and later release when the * event is run may generate a situation where the channel structure * is deleted but not our structure, crashing in * FreeReflectedChannel(). * * Force creation of the RCM, for proper cleanup on thread teardown. * The teardown of unprocessed events is currently coupled to the * thread reflected channel map */ (void) GetThreadReflectedChannelMap(); /* XXX Race condition !! * XXX The destination thread may not exist anymore already. * XXX (Delayed postevent executed after channel got removed). * XXX Can we detect this ? (check the validity of the owner threadid ?) * XXX Actually, in that case the channel should be dead also ! */ Tcl_ThreadQueueEvent(rcPtr->owner, (Tcl_Event *) ev, TCL_QUEUE_TAIL); Tcl_ThreadAlert(rcPtr->owner); } #endif /* * Squash interp results left by the event script. */ |
︙ | ︙ | |||
1152 1153 1154 1155 1156 1157 1158 | #ifdef TCL_THREADS if (rcPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p); result = p.base.code; | > | > > | | | > | > > | | | 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 | #ifdef TCL_THREADS if (rcPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p); result = p.base.code; /* * Now squash the pending reflection events for this channel. */ Tcl_DeleteEvents(ReflectEventDelete, rcPtr); if (result != TCL_OK) { FreeReceivedError(&p); } } #endif Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); return EOK; } /* * -- No -- ASSERT rcPtr->methods & FLAG(METH_FINAL) * * A cleaned method mask here implies that the channel creation was * aborted, and "finalize" must not be called. */ if (rcPtr->methods == 0) { Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); return EOK; } /* * Are we in the correct thread? */ #ifdef TCL_THREADS if (rcPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p); result = p.base.code; /* * Now squash the pending reflection events for this channel. */ Tcl_DeleteEvents(ReflectEventDelete, rcPtr); Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); if (result != TCL_OK) { PassReceivedErrorInterp(interp, &p); } } else { #endif result = InvokeTclMethod(rcPtr, "finalize", NULL, NULL, &resObj); |
︙ | ︙ | |||
1236 1237 1238 1239 1240 1241 1242 | hPtr = Tcl_FindHashEntry(&rcmPtr->map, Tcl_GetChannelName(rcPtr->chan)); if (hPtr) { Tcl_DeleteHashEntry(hPtr); } #endif | | | 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 | hPtr = Tcl_FindHashEntry(&rcmPtr->map, Tcl_GetChannelName(rcPtr->chan)); if (hPtr) { Tcl_DeleteHashEntry(hPtr); } #endif Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); #ifdef TCL_THREADS } #endif return (result == TCL_OK) ? EOK : EINVAL; } /* |
︙ | ︙ | |||
1344 1345 1346 1347 1348 1349 1350 | SetChannelErrorStr(rcPtr->chan, msg_read_toomuch); goto invalid; } *errorCodePtr = EOK; if (bytec > 0) { | | | 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 | SetChannelErrorStr(rcPtr->chan, msg_read_toomuch); goto invalid; } *errorCodePtr = EOK; if (bytec > 0) { memcpy(buf, bytev, (size_t) bytec); } stop: Tcl_DecrRefCount(toReadObj); Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ Tcl_Release(rcPtr); return bytec; |
︙ | ︙ | |||
1545 1546 1547 1548 1549 1550 1551 | #endif /* ASSERT: rcPtr->method & FLAG(METH_SEEK) */ Tcl_Preserve(rcPtr); offObj = Tcl_NewWideIntObj(offset); | | > | | | 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 | #endif /* 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", -1); Tcl_IncrRefCount(offObj); Tcl_IncrRefCount(baseObj); if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj) != TCL_OK) { Tcl_SetChannelError(rcPtr->chan, resObj); goto invalid; } if (Tcl_GetWideIntFromObj(rcPtr->interp, resObj, &newLoc) != TCL_OK) { Tcl_SetChannelError(rcPtr->chan, MarshallError(rcPtr->interp)); goto invalid; |
︙ | ︙ | |||
1756 1757 1758 1759 1760 1761 1762 | * Side effects: * Allocates memory. Arbitrary, as it calls upon a script. * *---------------------------------------------------------------------- */ static void | | > > | | 1770 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 1798 | * Side effects: * Allocates memory. Arbitrary, as it calls upon a script. * *---------------------------------------------------------------------- */ static void ReflectThread( ClientData clientData, int action) { ReflectedChannel *rcPtr = clientData; switch (action) { case TCL_CHANNEL_THREAD_INSERT: rcPtr->owner = Tcl_GetCurrentThread(); break; case TCL_CHANNEL_THREAD_REMOVE: rcPtr->owner = NULL; break; default: Tcl_Panic("Unknown thread action code."); break; } } #endif /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
2042 2043 2044 2045 2046 2047 2048 | * list. */ if (Tcl_ListObjGetElements(interp, obj, &listc, &listv) != TCL_OK) { return TCL_ERROR; } if (listc < 1) { | > | | 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 | * list. */ if (Tcl_ListObjGetElements(interp, obj, &listc, &listv) != TCL_OK) { return TCL_ERROR; } if (listc < 1) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad %s list: is empty", objName)); return TCL_ERROR; } events = 0; while (listc > 0) { if (Tcl_GetIndexFromObj(interp, listv[listc-1], eventOptions, objName, 0, &evIndex) != TCL_OK) { |
︙ | ︙ | |||
2803 2804 2805 2806 2807 2808 2809 | /* * Run over the event queue of this thread and remove all ReflectEvent's * still pending. These are inbound events for reflected channels this * thread owns but doesn't handle. The inverse of the channel map * actually. */ | | | 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 | /* * Run over the event queue of this thread and remove all ReflectEvent's * still pending. These are inbound events for reflected channels this * thread owns but doesn't handle. The inverse of the channel map * actually. */ Tcl_DeleteEvents(ReflectEventDelete, NULL); /* * Get the map of all channels handled by the current thread. This is a * ReflectedChannelMap, but on a per-thread basis, not per-interp. Go * through the channels, remove all, mark them as dead. */ |
︙ | ︙ | |||
2974 2975 2976 2977 2978 2979 2980 | ForwardingEvent *evPtr = (ForwardingEvent *) evGPtr; ForwardingResult *resultPtr = evPtr->resultPtr; ReflectedChannel *rcPtr = evPtr->rcPtr; Tcl_Interp *interp = rcPtr->interp; ForwardParam *paramPtr = evPtr->param; Tcl_Obj *resObj = NULL; /* Interp result of InvokeTclMethod */ | | < | | 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 | ForwardingEvent *evPtr = (ForwardingEvent *) evGPtr; ForwardingResult *resultPtr = evPtr->resultPtr; ReflectedChannel *rcPtr = evPtr->rcPtr; Tcl_Interp *interp = rcPtr->interp; ForwardParam *paramPtr = evPtr->param; Tcl_Obj *resObj = NULL; /* Interp result of InvokeTclMethod */ ReflectedChannelMap *rcmPtr;/* 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) { |
︙ | ︙ | |||
3019 3020 3021 3022 3023 3024 3025 | * We remove the channel from both interpreter and thread maps before * releasing the memory, to prevent future accesses (like by * 'postevent') from finding and dereferencing a dangling pointer. */ rcmPtr = GetReflectedChannelMap(interp); hPtr = Tcl_FindHashEntry(&rcmPtr->map, | | | | 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 | * We remove the channel from both interpreter and thread maps before * releasing the memory, to prevent future accesses (like by * 'postevent') from finding and dereferencing a dangling pointer. */ rcmPtr = GetReflectedChannelMap(interp); hPtr = Tcl_FindHashEntry(&rcmPtr->map, Tcl_GetChannelName(rcPtr->chan)); Tcl_DeleteHashEntry(hPtr); rcmPtr = GetThreadReflectedChannelMap(); hPtr = Tcl_FindHashEntry(&rcmPtr->map, Tcl_GetChannelName(rcPtr->chan)); Tcl_DeleteHashEntry(hPtr); FreeReflectedChannelArgs(rcPtr); break; case ForwardedInput: { Tcl_Obj *toReadObj = Tcl_NewIntObj(paramPtr->input.toRead); |
︙ | ︙ | |||
3059 3060 3061 3062 3063 3064 3065 | bytev = Tcl_GetByteArrayFromObj(resObj, &bytec); if (paramPtr->input.toRead < bytec) { ForwardSetStaticError(paramPtr, msg_read_toomuch); paramPtr->input.toRead = -1; } else { if (bytec > 0) { | | | | 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 | bytev = Tcl_GetByteArrayFromObj(resObj, &bytec); if (paramPtr->input.toRead < bytec) { ForwardSetStaticError(paramPtr, msg_read_toomuch); paramPtr->input.toRead = -1; } else { if (bytec > 0) { memcpy(paramPtr->input.buf, bytev, (size_t) bytec); } paramPtr->input.toRead = bytec; } } Tcl_Release(rcPtr); Tcl_DecrRefCount(toReadObj); break; } case ForwardedOutput: { Tcl_Obj *bufObj = Tcl_NewByteArrayObj((unsigned char *) paramPtr->output.buf, paramPtr->output.toWrite); Tcl_IncrRefCount(bufObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, "write", bufObj, NULL, &resObj) != TCL_OK) { int code = ErrnoReturn(rcPtr, resObj); if (code < 0) { |
︙ | ︙ | |||
3111 3112 3113 3114 3115 3116 3117 | Tcl_DecrRefCount(bufObj); break; } case ForwardedSeek: { Tcl_Obj *offObj = Tcl_NewWideIntObj(paramPtr->seek.offset); Tcl_Obj *baseObj = Tcl_NewStringObj( | | | | 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 | Tcl_DecrRefCount(bufObj); 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", -1); Tcl_IncrRefCount(offObj); Tcl_IncrRefCount(baseObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj)!=TCL_OK){ ForwardSetObjError(paramPtr, resObj); |
︙ | ︙ | |||
3162 3163 3164 3165 3166 3167 3168 | Tcl_DecrRefCount(maskObj); Tcl_Release(rcPtr); break; } case ForwardedBlock: { Tcl_Obj *blockObj = Tcl_NewBooleanObj(!paramPtr->block.nonblocking); | < > | | < > | 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 | Tcl_DecrRefCount(maskObj); Tcl_Release(rcPtr); break; } case ForwardedBlock: { Tcl_Obj *blockObj = Tcl_NewBooleanObj(!paramPtr->block.nonblocking); Tcl_IncrRefCount(blockObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, "blocking", blockObj, NULL, &resObj) != TCL_OK) { ForwardSetObjError(paramPtr, resObj); } Tcl_Release(rcPtr); Tcl_DecrRefCount(blockObj); break; } case ForwardedSetOpt: { Tcl_Obj *optionObj = Tcl_NewStringObj(paramPtr->setOpt.name, -1); Tcl_Obj *valueObj = Tcl_NewStringObj(paramPtr->setOpt.value, -1); 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, -1); Tcl_IncrRefCount(optionObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, "cget", optionObj, NULL, &resObj)!=TCL_OK){ ForwardSetObjError(paramPtr, resObj); } else { TclDStringAppendObj(paramPtr->getOpt.value, resObj); } Tcl_Release(rcPtr); |
︙ | ︙ |
Changes to generic/tclIORTrans.c.
︙ | ︙ | |||
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) \ | > | | | > > | | | | | > > | > | > > | | | > > | | | > < | | | 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 403 404 405 406 407 408 409 | 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, -1)); \ } \ FreeReceivedError(p); \ } while (0) #define PassReceivedError(c,p) \ do { \ Tcl_SetChannelError((c), \ Tcl_NewStringObj((p)->base.msgStr, -1)); \ 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), -1)) static Tcl_Obj * MarshallError(Tcl_Interp *interp); static void UnmarshallErrorResult(Tcl_Interp *interp, |
︙ | ︙ | |||
509 510 511 512 513 514 515 | Tcl_Obj *modeObj; /* mode in obj form for method call */ int 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. */ | < | 519 520 521 522 523 524 525 526 527 528 529 530 531 532 | Tcl_Obj *modeObj; /* mode in obj form for method call */ int 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 * in this interp. */ Tcl_HashEntry *hPtr; /* Entry in the above map */ int isNew; /* Placeholder. */ /* |
︙ | ︙ | |||
604 605 606 607 608 609 610 | goto error; } methods = 0; while (listc > 0) { if (Tcl_GetIndexFromObj(interp, listv[listc-1], methodNames, "method", TCL_EXACT, &methIndex) != TCL_OK) { | < | | | | | 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 | goto error; } methods = 0; while (listc > 0) { if (Tcl_GetIndexFromObj(interp, listv[listc-1], methodNames, "method", TCL_EXACT, &methIndex) != TCL_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "chan handler \"%s initialize\" returned %s", Tcl_GetString(cmdObj), Tcl_GetString(Tcl_GetObjResult(interp)))); Tcl_DecrRefCount(resObj); goto error; } methods |= FLAG(methIndex); listc--; } |
︙ | ︙ | |||
691 692 693 694 695 696 697 | Tcl_Panic("TclChanPushObjCmd: duplicate transformation handle"); } Tcl_SetHashValue(hPtr, rtPtr); #ifdef TCL_THREADS rtmPtr = GetThreadReflectedTransformMap(); hPtr = Tcl_CreateHashEntry(&rtmPtr->map, Tcl_GetString(rtId), &isNew); Tcl_SetHashValue(hPtr, rtPtr); | | > | | | 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 | Tcl_Panic("TclChanPushObjCmd: duplicate transformation handle"); } Tcl_SetHashValue(hPtr, rtPtr); #ifdef TCL_THREADS rtmPtr = GetThreadReflectedTransformMap(); hPtr = Tcl_CreateHashEntry(&rtmPtr->map, Tcl_GetString(rtId), &isNew); Tcl_SetHashValue(hPtr, rtPtr); #endif /* TCL_THREADS */ /* * Return the channel as the result of the command. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( Tcl_GetChannelName(rtPtr->chan), -1)); return TCL_OK; error: /* * We are not going through ReflectClose as we never had a channel * structure. */ Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform); return TCL_ERROR; #undef CHAN #undef CMD } /* |
︙ | ︙ | |||
909 910 911 912 913 914 915 | ForwardOpToOwnerThread(rtPtr, ForwardedClose, &p); result = p.base.code; if (result != TCL_OK) { FreeReceivedError(&p); } } | | | | | | | | | | 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 984 985 986 987 988 989 990 991 992 993 | ForwardOpToOwnerThread(rtPtr, ForwardedClose, &p); result = p.base.code; if (result != TCL_OK) { FreeReceivedError(&p); } } #endif /* TCL_THREADS */ Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform); return EOK; } /* * In the reflected channel implementation a cleaned method mask here * implies that the channel creation was aborted, and "finalize" must not * be called. for transformations however we are not going through here on * such an abort, but directly through FreeReflectedTransform. So for us * that check is not necessary. We always go through 'finalize'. */ if (HAS(rtPtr->methods, METH_DRAIN) && !rtPtr->readIsDrained) { if (!TransformDrain(rtPtr, &errorCode)) { #ifdef TCL_THREADS if (rtPtr->thread != Tcl_GetCurrentThread()) { Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform); return errorCode; } #endif /* TCL_THREADS */ errorCodeSet = 1; goto cleanup; } } if (HAS(rtPtr->methods, METH_FLUSH)) { if (!TransformFlush(rtPtr, &errorCode, FLUSH_WRITE)) { #ifdef TCL_THREADS if (rtPtr->thread != Tcl_GetCurrentThread()) { Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform); return errorCode; } #endif /* TCL_THREADS */ errorCodeSet = 1; goto cleanup; } } /* * Are we in the correct thread? */ #ifdef TCL_THREADS if (rtPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToOwnerThread(rtPtr, ForwardedClose, &p); result = p.base.code; Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform); if (result != TCL_OK) { PassReceivedErrorInterp(interp, &p); return EINVAL; } return EOK; } #endif /* TCL_THREADS */ /* * Do the actual invokation of "finalize" now; we're in the right thread. */ result = InvokeTclMethod(rtPtr, "finalize", NULL, NULL, &resObj); if ((result != TCL_OK) && (interp != NULL)) { |
︙ | ︙ | |||
1018 1019 1020 1021 1022 1023 1024 | #ifdef TCL_THREADS rtmPtr = GetThreadReflectedTransformMap(); hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle)); if (hPtr) { Tcl_DeleteHashEntry(hPtr); } | | | 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 | #ifdef TCL_THREADS rtmPtr = GetThreadReflectedTransformMap(); hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle)); if (hPtr) { Tcl_DeleteHashEntry(hPtr); } #endif /* TCL_THREADS */ } Tcl_EventuallyFree (rtPtr, (Tcl_FreeProc *) FreeReflectedTransform); return errorCodeSet ? errorCode : ((result == TCL_OK) ? EOK : EINVAL); } /* |
︙ | ︙ | |||
1344 1345 1346 1347 1348 1349 1350 | || HAS(rtPtr->methods, METH_FLUSH))) { /* * Neither a tell request, nor clear/flush both not supported. We have * to go through the Tcl level to clear and/or flush the * transformation. */ | | | 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 | || HAS(rtPtr->methods, METH_FLUSH))) { /* * Neither a tell request, nor clear/flush both not supported. We have * to go through the Tcl level to clear and/or flush the * transformation. */ if (rtPtr->methods & FLAG(METH_CLEAR)) { TransformClear(rtPtr); } /* * When flushing the transform for seeking the generated results are * irrelevant. We cannot put them into the channel, this would move * the location, throwing it off with regard to where we are and are |
︙ | ︙ | |||
2136 2137 2138 2139 2140 2141 2142 | Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ ReflectedTransform *rtPtr; #ifdef TCL_THREADS ForwardingResult *resultPtr; ForwardingEvent *evPtr; ForwardParam *paramPtr; | | | 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 | Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ ReflectedTransform *rtPtr; #ifdef TCL_THREADS ForwardingResult *resultPtr; ForwardingEvent *evPtr; ForwardParam *paramPtr; #endif /* TCL_THREADS */ /* * Delete all entries. The channels may have been closed already, or will * be closed later, by the standard IO finalization of an interpreter * under destruction. Except for the channels which were moved to a * different interpreter and/or thread. They do not exist from the IO * systems point of view and will not get closed. Therefore mark all as |
︙ | ︙ | |||
2228 2229 2230 2231 2232 2233 2234 | resultPtr->result = TCL_ERROR; ForwardSetStaticError(paramPtr, msg_send_dstlost); Tcl_ConditionNotify(&resultPtr->done); } Tcl_MutexUnlock(&rtForwardMutex); | < | | 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 | resultPtr->result = TCL_ERROR; ForwardSetStaticError(paramPtr, msg_send_dstlost); Tcl_ConditionNotify(&resultPtr->done); } Tcl_MutexUnlock(&rtForwardMutex); #endif /* TCL_THREADS */ } #ifdef TCL_THREADS /* *---------------------------------------------------------------------- * * GetThreadReflectedTransformMap -- |
︙ | ︙ | |||
2627 2628 2629 2630 2631 2632 2633 | } } Tcl_DecrRefCount(bufObj); break; } | | | 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 | } } 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. |
︙ | ︙ | |||
2652 2653 2654 2655 2656 2657 2658 | paramPtr->transform.buf = ckalloc(bytec); memcpy(paramPtr->transform.buf, bytev, (size_t)bytec); } else { paramPtr->transform.buf = NULL; } } break; | | < | | 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 | 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. |
︙ | ︙ | |||
2680 2681 2682 2683 2684 2685 2686 | paramPtr->transform.buf = ckalloc(bytec); memcpy(paramPtr->transform.buf, bytev, (size_t)bytec); } else { paramPtr->transform.buf = NULL; } } break; | | < | < | 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 | 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 if (Tcl_GetIntFromObj(interp, resObj, ¶mPtr->limit.max) != TCL_OK) { |
︙ | ︙ | |||
2791 2792 2793 2794 2795 2796 2797 | int len; const char *msgStr = Tcl_GetStringFromObj(obj, &len); len++; ForwardSetDynamicError(paramPtr, ckalloc(len)); memcpy(paramPtr->base.msgStr, msgStr, (unsigned) len); } | | | 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 | int len; const char *msgStr = Tcl_GetStringFromObj(obj, &len); len++; ForwardSetDynamicError(paramPtr, ckalloc(len)); memcpy(paramPtr->base.msgStr, msgStr, (unsigned) len); } #endif /* TCL_THREADS */ /* *---------------------------------------------------------------------- * * TimerKill -- * * Timer management. Removes the internal timer if it exists. |
︙ | ︙ | |||
3088 3089 3090 3091 3092 3093 3094 | } *errorCodePtr = EOK; ResultAdd(&rtPtr->result, UCHARP(p.transform.buf), p.transform.size); ckfree(p.transform.buf); return 1; } | | | 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 | } *errorCodePtr = EOK; ResultAdd(&rtPtr->result, UCHARP(p.transform.buf), p.transform.size); ckfree(p.transform.buf); return 1; } #endif /* TCL_THREADS */ /* ASSERT: rtPtr->method & FLAG(METH_READ) */ /* ASSERT: rtPtr->mode & TCL_READABLE */ bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toRead); Tcl_IncrRefCount(bufObj); |
︙ | ︙ | |||
3149 3150 3151 3152 3153 3154 3155 | } *errorCodePtr = EOK; res = Tcl_WriteRaw(rtPtr->parent, (char *) p.transform.buf, p.transform.size); ckfree(p.transform.buf); } else | | | 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 | } *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) { |
︙ | ︙ | |||
3211 3212 3213 3214 3215 3216 3217 | return 0; } *errorCodePtr = EOK; ResultAdd(&rtPtr->result, UCHARP(p.transform.buf), p.transform.size); ckfree(p.transform.buf); } else | | | 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 | return 0; } *errorCodePtr = EOK; ResultAdd(&rtPtr->result, UCHARP(p.transform.buf), p.transform.size); ckfree(p.transform.buf); } else #endif /* TCL_THREADS */ { 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; } |
︙ | ︙ | |||
3266 3267 3268 3269 3270 3271 3272 | res = Tcl_WriteRaw(rtPtr->parent, (char *) p.transform.buf, p.transform.size); } else { res = 0; } ckfree(p.transform.buf); } else | | | 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 | res = Tcl_WriteRaw(rtPtr->parent, (char *) p.transform.buf, p.transform.size); } else { res = 0; } ckfree(p.transform.buf); } else #endif /* TCL_THREADS */ { 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; } |
︙ | ︙ | |||
3307 3308 3309 3310 3311 3312 3313 | #ifdef TCL_THREADS if (rtPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToOwnerThread(rtPtr, ForwardedClear, &p); return; } | | | 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 | #ifdef TCL_THREADS if (rtPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToOwnerThread(rtPtr, ForwardedClear, &p); return; } #endif /* TCL_THREADS */ /* ASSERT: rtPtr->method & FLAG(METH_READ) */ /* ASSERT: rtPtr->mode & TCL_READABLE */ (void) InvokeTclMethod(rtPtr, "clear", NULL, NULL, NULL); rtPtr->readIsDrained = 0; |
︙ | ︙ |
Changes to generic/tclIOSock.c.
︙ | ︙ | |||
60 61 62 63 64 65 66 | return TCL_OK; } } if (Tcl_GetInt(interp, string, portPtr) != TCL_OK) { return TCL_ERROR; } if (*portPtr > 0xFFFF) { | > | < | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 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", -1)); return TCL_ERROR; } return TCL_OK; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
96 97 98 99 100 101 102 | void *sock, /* Socket file descriptor */ int size) /* Minimum buffer size */ { int current; socklen_t len; len = sizeof(int); | | > | > | > | > | 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 | void *sock, /* Socket file descriptor */ int size) /* Minimum buffer size */ { int current; socklen_t len; len = sizeof(int); getsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_SNDBUF, (char *) ¤t, &len); if (current < size) { len = sizeof(int); setsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_SNDBUF, (char *) &size, len); } len = sizeof(int); getsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF, (char *) ¤t, &len); if (current < size) { len = sizeof(int); setsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF, (char *) &size, len); } return TCL_OK; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
148 149 150 151 152 153 154 | struct addrinfo *v4head = NULL, *v4ptr = NULL; struct addrinfo *v6head = NULL, *v6ptr = NULL; char *native = NULL, portstring[TCL_INTEGER_SPACE]; const char *family = NULL; Tcl_DString ds; int result, i; | < < | < > > | | 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 | struct addrinfo *v4head = NULL, *v4ptr = NULL; struct addrinfo *v6head = NULL, *v6ptr = NULL; char *native = NULL, portstring[TCL_INTEGER_SPACE]; const char *family = NULL; Tcl_DString ds; int result, i; if (host != NULL) { native = Tcl_UtfToExternalDString(NULL, host, -1, &ds); } TclFormatInt(portstring, port); (void) memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* * Magic variable to enforce a certain address family - to be superseded * by a TIP that adds explicit switches to [socket] */ if (interp != NULL) { family = Tcl_GetVar(interp, "::tcl::unsupported::socketAF", 0); if (family != NULL) { if (strcmp(family, "inet") == 0) { hints.ai_family = AF_INET; } else if (strcmp(family, "inet6") == 0) { hints.ai_family = AF_INET6; } } } hints.ai_socktype = SOCK_STREAM; #if 0 /* * We found some problems when using AI_ADDRCONFIG, e.g. on systems that * have no networking besides the loopback interface and want to resolve * localhost. See [Bugs 3385024, 3382419, 3382431]. As the advantage of * using AI_ADDRCONFIG in situations where it works, is probably low, * we'll leave it out for now. After all, it is just an optimisation. * * Missing on: OpenBSD, NetBSD. * Causes failure when used on AIX 5.1 and HP-UX */ |
︙ | ︙ | |||
202 203 204 205 206 207 208 | result = getaddrinfo(native, portstring, &hints, addrlist); if (host != NULL) { Tcl_DStringFree(&ds); } if (result != 0) { | > | | < < | | | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | result = getaddrinfo(native, portstring, &hints, addrlist); if (host != NULL) { Tcl_DStringFree(&ds); } if (result != 0) { *errorMsgPtr = #ifdef EAI_SYSTEM /* Doesn't exist on Windows */ (result == EAI_SYSTEM) ? Tcl_PosixError(interp) : #endif /* EAI_SYSTEM */ gai_strerror(result); return 0; } /* * Put IPv4 addresses before IPv6 addresses to maximize backwards * compatibility of [fconfigure -sockname] output. * |
︙ | ︙ |
Changes to generic/tclIOUtil.c.
︙ | ︙ | |||
456 457 458 459 460 461 462 463 464 465 466 467 468 469 | fsRecPtr = tsdPtr->filesystemList; while (fsRecPtr != NULL) { tmpFsRecPtr = fsRecPtr->nextPtr; fsRecPtr->fsPtr = NULL; ckfree(fsRecPtr); fsRecPtr = tmpFsRecPtr; } tsdPtr->initialized = 0; } int TclFSCwdIsNative(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); | > | 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | fsRecPtr = tsdPtr->filesystemList; while (fsRecPtr != NULL) { tmpFsRecPtr = fsRecPtr->nextPtr; fsRecPtr->fsPtr = NULL; ckfree(fsRecPtr); fsRecPtr = tmpFsRecPtr; } tsdPtr->filesystemList = NULL; tsdPtr->initialized = 0; } int TclFSCwdIsNative(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); |
︙ | ︙ | |||
643 644 645 646 647 648 649 | TclFSEpochOk( int filesystemEpoch) { return (filesystemEpoch == 0 || filesystemEpoch == theFilesystemEpoch); } static void | | > | > | > | 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 | TclFSEpochOk( int filesystemEpoch) { return (filesystemEpoch == 0 || filesystemEpoch == theFilesystemEpoch); } static void Claim(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); tsdPtr->claims++; } static void Disclaim(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); tsdPtr->claims--; } int TclFSEpoch(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); return tsdPtr->filesystemEpoch; } /* * If non-NULL, clientData is owned by us and must be freed later. */ |
︙ | ︙ | |||
1090 1091 1092 1093 1094 1095 1096 | * single filesystem's implementation of Tcl_FSMatchInDirectory will have * to deal with it for us. */ cwd = Tcl_FSGetCwd(NULL); if (cwd == NULL) { if (interp != NULL) { | | | > | 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 | * single filesystem's implementation of Tcl_FSMatchInDirectory will have * to deal with it for us. */ cwd = Tcl_FSGetCwd(NULL); if (cwd == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "glob couldn't determine the current working directory", -1)); } return TCL_ERROR; } fsPtr = Tcl_FSGetFileSystemForPath(cwd); if (fsPtr != NULL && fsPtr->matchInDirectoryProc != NULL) { TclNewObj(tmpResultPtr); |
︙ | ︙ | |||
1568 1569 1570 1571 1572 1573 1574 | } return mode; error: *seekFlagPtr = 0; *binaryPtr = 0; if (interp != NULL) { | | | | 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 | } return mode; error: *seekFlagPtr = 0; *binaryPtr = 0; if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "illegal access mode \"%s\"", modeString)); } return -1; } /* * The access modes are specified using a list of POSIX modes such as * O_CREAT. |
︙ | ︙ | |||
1618 1619 1620 1621 1622 1623 1624 | mode |= O_EXCL; } else if ((c == 'N') && (strcmp(flag, "NOCTTY") == 0)) { #ifdef O_NOCTTY mode |= O_NOCTTY; #else if (interp != NULL) { | | | > | | > | | | > | | > | 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 | mode |= O_EXCL; } else if ((c == 'N') && (strcmp(flag, "NOCTTY") == 0)) { #ifdef O_NOCTTY mode |= O_NOCTTY; #else if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "access mode \"%s\" not supported by this system", flag)); } ckfree(modeArgv); return -1; #endif } else if ((c == 'N') && (strcmp(flag, "NONBLOCK") == 0)) { #ifdef O_NONBLOCK mode |= O_NONBLOCK; #else if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "access mode \"%s\" not supported by this system", flag)); } ckfree(modeArgv); return -1; #endif } else if ((c == 'T') && (strcmp(flag, "TRUNC") == 0)) { mode |= O_TRUNC; } else if ((c == 'B') && (strcmp(flag, "BINARY") == 0)) { *binaryPtr = 1; } else { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid access mode \"%s\": must be RDONLY, WRONLY, " "RDWR, APPEND, BINARY, CREAT, EXCL, NOCTTY, NONBLOCK," " or TRUNC", flag)); } ckfree(modeArgv); return -1; } } ckfree(modeArgv); if (!gotRW) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "access mode must include either RDONLY, WRONLY, or RDWR", -1)); } return -1; } return mode; } /* |
︙ | ︙ | |||
1717 1718 1719 1720 1721 1722 1723 | if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) { return result; } if (Tcl_FSStat(pathPtr, &statBuf) == -1) { Tcl_SetErrno(errno); | > | | | | | | 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 | if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) { return result; } if (Tcl_FSStat(pathPtr, &statBuf) == -1) { Tcl_SetErrno(errno); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", Tcl_GetString(pathPtr), Tcl_PosixError(interp))); return result; } chan = Tcl_FSOpenFileChannel(interp, pathPtr, "r", 0644); if (chan == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", Tcl_GetString(pathPtr), Tcl_PosixError(interp))); return result; } /* * The eofchar is \32 (^Z). This is the usual on Windows, but we effect * this cross-platform to allow for scripted documents. [Bug: 2040] */ |
︙ | ︙ | |||
1759 1760 1761 1762 1763 1764 1765 | /* * Try to read first character of stream, so we can check for utf-8 BOM to * be handled especially. */ if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) { Tcl_Close(interp, chan); | > | | > | | | 1769 1770 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 1798 1799 1800 | /* * Try to read first character of stream, so we can check for utf-8 BOM to * be handled especially. */ if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", Tcl_GetString(pathPtr), Tcl_PosixError(interp))); goto end; } 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, -1, 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; } if (Tcl_Close(interp, chan) != TCL_OK) { goto end; } |
︙ | ︙ | |||
1848 1849 1850 1851 1852 1853 1854 | if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) { return TCL_ERROR; } if (Tcl_FSStat(pathPtr, &statBuf) == -1) { Tcl_SetErrno(errno); | > | | | | | | 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 | if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) { return TCL_ERROR; } if (Tcl_FSStat(pathPtr, &statBuf) == -1) { Tcl_SetErrno(errno); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", Tcl_GetString(pathPtr), Tcl_PosixError(interp))); return TCL_ERROR; } chan = Tcl_FSOpenFileChannel(interp, pathPtr, "r", 0644); if (chan == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", Tcl_GetString(pathPtr), Tcl_PosixError(interp))); return TCL_ERROR; } /* * The eofchar is \32 (^Z). This is the usual on Windows, but we effect * this cross-platform to allow for scripted documents. [Bug: 2040] */ |
︙ | ︙ | |||
1890 1891 1892 1893 1894 1895 1896 | /* * Try to read first character of stream, so we can check for utf-8 BOM to * be handled especially. */ if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) { Tcl_Close(interp, chan); | > | | > | | | 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 | /* * Try to read first character of stream, so we can check for utf-8 BOM to * be handled especially. */ if (Tcl_ReadChars(chan, objPtr, 1, 0) < 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; } 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, -1, 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; } if (Tcl_Close(interp, chan) != TCL_OK) { Tcl_DecrRefCount(objPtr); return TCL_ERROR; |
︙ | ︙ | |||
2242 2243 2244 2245 2246 2247 2248 | /* * Apply appropriate flags parsed out above. */ if (seekFlag && Tcl_Seek(retVal, (Tcl_WideInt) 0, SEEK_END) < (Tcl_WideInt) 0) { if (interp != NULL) { | | | | > | | | 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 2288 2289 2290 2291 2292 | /* * Apply appropriate flags parsed out above. */ if (seekFlag && Tcl_Seek(retVal, (Tcl_WideInt) 0, SEEK_END) < (Tcl_WideInt) 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not seek to end of file while opening \"%s\": %s", Tcl_GetString(pathPtr), Tcl_PosixError(interp))); } Tcl_Close(NULL, retVal); return NULL; } if (binary) { Tcl_SetChannelOption(interp, retVal, "-translation", "binary"); } return retVal; } /* * File doesn't belong to any filesystem that can open it. */ Tcl_SetErrno(ENOENT); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open \"%s\": %s", Tcl_GetString(pathPtr), Tcl_PosixError(interp))); } return NULL; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
2680 2681 2682 2683 2684 2685 2686 | fsRecPtr->fsPtr->freeInternalRepProc(retCd); } Tcl_DecrRefCount(retVal); retVal = NULL; Disclaim(); goto cdDidNotChange; } else if (interp != NULL) { | | | | | 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 | fsRecPtr->fsPtr->freeInternalRepProc(retCd); } Tcl_DecrRefCount(retVal); retVal = NULL; Disclaim(); goto cdDidNotChange; } else if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error getting working directory name: %s", Tcl_PosixError(interp))); } } Disclaim(); /* * Now the 'cwd' may NOT be normalized, at least on some platforms. * For the sake of efficiency, we want a completely normalized cwd at |
︙ | ︙ | |||
2756 2757 2758 2759 2760 2761 2762 | * New API. */ TclFSGetCwdProc2 *proc2 = (TclFSGetCwdProc2 *) fsPtr->getCwdProc; retCd = proc2(tsdPtr->cwdClientData); if (retCd == NULL && interp != NULL) { | | | | | 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 | * New API. */ TclFSGetCwdProc2 *proc2 = (TclFSGetCwdProc2 *) fsPtr->getCwdProc; retCd = proc2(tsdPtr->cwdClientData); if (retCd == NULL && interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error getting working directory name: %s", Tcl_PosixError(interp))); } if (retCd == tsdPtr->cwdClientData) { goto cdDidNotChange; } /* |
︙ | ︙ | |||
3148 3149 3150 3151 3152 3153 3154 | * The filesystem doesn't support 'load', so we fall back on the following * technique: * * First check if it is readable -- and exists! */ if (Tcl_FSAccess(pathPtr, R_OK) != 0) { | > | | | 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 | * The filesystem doesn't support 'load', so we fall back on the following * technique: * * First check if it is readable -- and exists! */ if (Tcl_FSAccess(pathPtr, R_OK) != 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't load library \"%s\": %s", Tcl_GetString(pathPtr), Tcl_PosixError(interp))); return TCL_ERROR; } #ifdef TCL_LOAD_FROM_MEMORY /* * The platform supports loading code from memory, so ask for a buffer of * the appropriate size, read the file into it and load the code from the |
︙ | ︙ | |||
3199 3200 3201 3202 3203 3204 3205 | if (ret == TCL_OK && *handlePtr != NULL) { goto resolveSymbols; } } mustCopyToTempAnyway: Tcl_ResetResult(interp); | | > | < | 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 | if (ret == TCL_OK && *handlePtr != NULL) { goto resolveSymbols; } } mustCopyToTempAnyway: Tcl_ResetResult(interp); #endif /* TCL_LOAD_FROM_MEMORY */ /* * Get a temporary filename to use, first to copy the file into, and then * to load. */ copyToPtr = TclpTempFileNameForLibrary(interp, pathPtr); Tcl_IncrRefCount(copyToPtr); copyFsPtr = Tcl_FSGetFileSystemForPath(copyToPtr); if ((copyFsPtr == NULL) || (copyFsPtr == fsPtr)) { /* * We already know we can't use Tcl_FSLoadFile from this filesystem, * 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", -1)); return TCL_ERROR; } if (TclCrossFilesystemCopy(interp, pathPtr, copyToPtr) != TCL_OK) { /* * Cross-platform copy failed. */ |
︙ | ︙ |
Changes to generic/tclIndexObj.c.
︙ | ︙ | |||
596 597 598 599 600 601 602 | return TCL_ERROR; } switch ((enum matchOptions) index) { case PRFMATCH_EXACT: flags |= TCL_EXACT; break; case PRFMATCH_MESSAGE: | | | > | > | | > | 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 | return TCL_ERROR; } 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", -1)); 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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL); return TCL_ERROR; } errorPtr = objv[i]; break; } } |
︙ | ︙ | |||
1170 1171 1172 1173 1174 1175 1176 | continue; } if (infoPtr->keyStr[length] == 0) { matchPtr = infoPtr; goto gotMatch; } if (matchPtr != NULL) { | > | < > | < | 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 | continue; } if (infoPtr->keyStr[length] == 0) { matchPtr = infoPtr; goto gotMatch; } if (matchPtr != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "ambiguous option \"%s\"", str)); goto error; } matchPtr = infoPtr; } if (matchPtr == NULL) { /* * Unrecognized argument. Just copy it down, unless the caller * prefers an error to be registered. */ if (remObjv == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unrecognized argument \"%s\"", str)); goto error; } dstIndex++; /* This argument is now handled */ leftovers[nrem++] = curArg; continue; } |
︙ | ︙ | |||
1209 1210 1211 1212 1213 1214 1215 | break; case TCL_ARGV_INT: if (objc == 0) { goto missingArg; } if (Tcl_GetIntFromObj(interp, objv[srcIndex], (int *) infoPtr->dstPtr) == TCL_ERROR) { | | | | | 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 | break; case TCL_ARGV_INT: if (objc == 0) { goto missingArg; } if (Tcl_GetIntFromObj(interp, objv[srcIndex], (int *) infoPtr->dstPtr) == TCL_ERROR) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected integer argument for \"%s\" but got \"%s\"", infoPtr->keyStr, Tcl_GetString(objv[srcIndex]))); goto error; } srcIndex++; objc--; break; case TCL_ARGV_STRING: if (objc == 0) { |
︙ | ︙ | |||
1242 1243 1244 1245 1246 1247 1248 | goto argsDone; case TCL_ARGV_FLOAT: if (objc == 0) { goto missingArg; } if (Tcl_GetDoubleFromObj(interp, objv[srcIndex], (double *) infoPtr->dstPtr) == TCL_ERROR) { | > | < | | 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 | goto argsDone; case TCL_ARGV_FLOAT: if (objc == 0) { goto missingArg; } if (Tcl_GetDoubleFromObj(interp, objv[srcIndex], (double *) infoPtr->dstPtr) == TCL_ERROR) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected floating-point argument for \"%s\" but got \"%s\"", infoPtr->keyStr, Tcl_GetString(objv[srcIndex]))); goto error; } srcIndex++; objc--; break; case TCL_ARGV_FUNC: { Tcl_ArgvFuncProc *handlerProc = (Tcl_ArgvFuncProc *) |
︙ | ︙ | |||
1318 1319 1320 1321 1322 1323 1324 | /* * Make sure to handle freeing any temporary space we've allocated on the * way to an error. */ missingArg: | | | | 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 | /* * Make sure to handle freeing any temporary space we've allocated on the * way to an error. */ missingArg: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" option requires an additional argument", str)); error: if (leftovers != NULL) { ckfree(leftovers); } return TCL_ERROR; } |
︙ | ︙ | |||
1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 | * descriptions. */ { register const Tcl_ArgvInfo *infoPtr; int width, numSpaces; #define NUM_SPACES 20 static const char spaces[] = " "; char tmp[TCL_DOUBLE_SPACE]; /* * First, compute the width of the widest option key, so that we can make * everything line up. */ width = 4; | > | 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 | * descriptions. */ { register const Tcl_ArgvInfo *infoPtr; int width, numSpaces; #define NUM_SPACES 20 static const char spaces[] = " "; char tmp[TCL_DOUBLE_SPACE]; Tcl_Obj *msg; /* * First, compute the width of the widest option key, so that we can make * everything line up. */ width = 4; |
︙ | ︙ | |||
1380 1381 1382 1383 1384 1385 1386 | } } /* * Now add the option information, with pretty-printing. */ | | | | | | | > | < > > < | < | | > | | | | | | > | | > | < < | 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 1441 1442 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 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 | } } /* * Now add the option information, with pretty-printing. */ msg = Tcl_NewStringObj("Command-specific options:", -1); 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, -1); 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", *((double *) infoPtr->dstPtr)); sprintf(tmp, "%g", *((double *) infoPtr->dstPtr)); break; case TCL_ARGV_STRING: { char *string = *((char **) infoPtr->dstPtr); if (string != NULL) { Tcl_AppendPrintfToObj(msg, "\n\t\tDefault value: \"%s\"", string); } break; } default: break; } } Tcl_SetObjResult(interp, msg); } /* *---------------------------------------------------------------------- * * TclGetCompletionCodeFromObj -- * * Parses Completion code Code * * Results: * Returns TCL_ERROR if the value is an invalid completion code. * Otherwise, returns TCL_OK, and writes the completion code to the * pointer provided. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TclGetCompletionCodeFromObj( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *value, int *codePtr) /* Argument objects. */ { static const char *const returnCodes[] = { "ok", "error", "return", "break", "continue", NULL }; if ((value->typePtr != &indexType) && TclGetIntFromObj(NULL, value, codePtr) == TCL_OK) { return TCL_OK; } if (Tcl_GetIndexFromObj(NULL, value, returnCodes, NULL, TCL_EXACT, codePtr) == TCL_OK) { return TCL_OK; } /* * Value is not a legal completion code. */ if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad completion code \"%s\": must be" " ok, error, return, break, continue, or an integer", TclGetString(value))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_CODE", NULL); } return TCL_ERROR; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclInterp.c.
︙ | ︙ | |||
1039 1040 1041 1042 1043 1044 1045 | } aliasName = TclGetString(objv[3]); iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo; hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName); if (hPtr == NULL) { | | > | | | < | | 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 | } aliasName = TclGetString(objv[3]); iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo; hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "alias \"%s\" in path \"%s\" not found", aliasName, Tcl_GetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS", aliasName, NULL); return TCL_ERROR; } aliasPtr = Tcl_GetHashValue(hPtr); if (Tcl_GetInterpPath(interp, aliasPtr->targetInterp) != TCL_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "target interpreter for alias \"%s\" in path \"%s\" is " "not my descendant", aliasName, Tcl_GetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "TARGETSHROUDED", NULL); return TCL_ERROR; } return TCL_OK; } } |
︙ | ︙ | |||
1230 1231 1232 1233 1234 1235 1236 | Tcl_HashEntry *hPtr; Alias *aliasPtr; int i, objc; Tcl_Obj **objv; hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName); if (hPtr == NULL) { | | > | 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 | Tcl_HashEntry *hPtr; Alias *aliasPtr; int 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); return TCL_ERROR; } aliasPtr = Tcl_GetHashValue(hPtr); objc = aliasPtr->objc; objv = &aliasPtr->objPtr; |
︙ | ︙ | |||
1291 1292 1293 1294 1295 1296 1297 | Tcl_HashEntry *hPtr; Alias *aliasPtr; int objc; Tcl_Obj **objv; hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName); if (hPtr == NULL) { | | > | 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 | Tcl_HashEntry *hPtr; Alias *aliasPtr; int 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); return TCL_ERROR; } aliasPtr = Tcl_GetHashValue(hPtr); objc = aliasPtr->objc; objv = &aliasPtr->objPtr; |
︙ | ︙ | |||
1379 1380 1381 1382 1383 1384 1385 | if (Tcl_InterpDeleted(nextAliasPtr->targetInterp)) { /* * The slave interpreter can be deleted while creating the alias. * [Bug #641195] */ | > | | < > | | < | 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 | if (Tcl_InterpDeleted(nextAliasPtr->targetInterp)) { /* * The slave interpreter can be deleted while creating the alias. * [Bug #641195] */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cannot define or rename alias \"%s\": interpreter deleted", Tcl_GetCommandName(cmdInterp, cmd))); return TCL_ERROR; } cmdNamePtr = nextAliasPtr->objPtr; aliasCmd = Tcl_FindCommand(nextAliasPtr->targetInterp, TclGetString(cmdNamePtr), Tcl_GetGlobalNamespace(nextAliasPtr->targetInterp), /*flags*/ 0); if (aliasCmd == NULL) { return TCL_OK; } aliasCmdPtr = (Command *) aliasCmd; if (aliasCmdPtr == cmdPtr) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cannot define or rename alias \"%s\": would create a loop", Tcl_GetCommandName(cmdInterp, cmd))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "ALIASLOOP", NULL); return TCL_ERROR; } /* * Otherwise, follow the chain one step further. See if the target |
︙ | ︙ | |||
1617 1618 1619 1620 1621 1622 1623 | * the original name (with which it was created) to find the alias to * delete it. */ slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave; hPtr = Tcl_FindHashEntry(&slavePtr->aliasTable, TclGetString(namePtr)); if (hPtr == NULL) { | | | | 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 | * the original name (with which it was created) to find the alias to * delete it. */ slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave; hPtr = Tcl_FindHashEntry(&slavePtr->aliasTable, TclGetString(namePtr)); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "alias \"%s\" not found", TclGetString(namePtr))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS", TclGetString(namePtr), NULL); return TCL_ERROR; } aliasPtr = Tcl_GetHashValue(hPtr); Tcl_DeleteCommandFromToken(slaveInterp, aliasPtr->slaveCmd); return TCL_OK; |
︙ | ︙ | |||
2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 | Tcl_GetInterpPath( Tcl_Interp *askingInterp, /* Interpreter to start search from. */ Tcl_Interp *targetInterp) /* Interpreter to find. */ { InterpInfo *iiPtr; if (targetInterp == askingInterp) { return TCL_OK; } if (targetInterp == NULL) { return TCL_ERROR; } iiPtr = (InterpInfo *) ((Interp *) targetInterp)->interpInfo; | > | > | | | 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 | Tcl_GetInterpPath( Tcl_Interp *askingInterp, /* Interpreter to start search from. */ Tcl_Interp *targetInterp) /* Interpreter to find. */ { InterpInfo *iiPtr; if (targetInterp == askingInterp) { Tcl_SetObjResult(askingInterp, Tcl_NewObj()); return TCL_OK; } if (targetInterp == NULL) { return TCL_ERROR; } 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), -1)); return TCL_OK; } /* *---------------------------------------------------------------------- * * GetInterp -- |
︙ | ︙ | |||
2214 2215 2216 2217 2218 2219 2220 | slavePtr = Tcl_GetHashValue(hPtr); searchInterp = slavePtr->slaveInterp; if (searchInterp == NULL) { break; } } if (searchInterp == NULL) { | | | | 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 | slavePtr = Tcl_GetHashValue(hPtr); searchInterp = slavePtr->slaveInterp; if (searchInterp == NULL) { break; } } if (searchInterp == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not find interpreter \"%s\"", TclGetString(pathPtr))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INTERP", TclGetString(pathPtr), NULL); } return searchInterp; } /* |
︙ | ︙ | |||
2252 2253 2254 2255 2256 2257 2258 | Tcl_Obj *const objv[]) /* Argument strings. */ { if (objc) { int length; if (TCL_ERROR == TclListObjLength(NULL, objv[0], &length) || (length < 1)) { | > | < | 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 | Tcl_Obj *const objv[]) /* Argument strings. */ { if (objc) { int length; if (TCL_ERROR == TclListObjLength(NULL, objv[0], &length) || (length < 1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "cmdPrefix must be list of length >= 1", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BGERRORFORMAT", NULL); return TCL_ERROR; } TclSetBgErrorHandler(slaveInterp, objv[0]); } Tcl_SetObjResult(interp, TclGetBgErrorHandler(slaveInterp)); |
︙ | ︙ | |||
2322 2323 2324 2325 2326 2327 2328 | safe = Tcl_IsSafe(masterInterp); } masterInfoPtr = (InterpInfo *) ((Interp *) masterInterp)->interpInfo; hPtr = Tcl_CreateHashEntry(&masterInfoPtr->master.slaveTable, path, &isNew); if (isNew == 0) { | | | > | 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 | safe = Tcl_IsSafe(masterInterp); } masterInfoPtr = (InterpInfo *) ((Interp *) masterInterp)->interpInfo; hPtr = Tcl_CreateHashEntry(&masterInfoPtr->master.slaveTable, path, &isNew); if (isNew == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "interpreter named \"%s\" already exists, cannot create", path)); return NULL; } slaveInterp = Tcl_CreateInterp(); slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave; slavePtr->masterInterp = masterInterp; slavePtr->slaveEntryPtr = hPtr; |
︙ | ︙ | |||
2856 2857 2858 2859 2860 2861 2862 | Tcl_Obj *const objv[]) /* Argument strings. */ { Interp *iPtr; int limit; if (objc) { if (Tcl_IsSafe(interp)) { | | | | 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 | 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE", NULL); return TCL_ERROR; } if (TclGetIntFromObj(interp, objv[0], &limit) == TCL_ERROR) { return TCL_ERROR; } |
︙ | ︙ | |||
3316 3317 3318 3319 3320 3321 3322 | (iPtr->limit.cmdCount < iPtr->cmdCount)) { 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) { | | | | 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 | (iPtr->limit.cmdCount < iPtr->cmdCount)) { 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", -1)); Tcl_SetErrorCode(interp, "TCL", "LIMIT", "COMMANDS", NULL); Tcl_Release(interp); return TCL_ERROR; } Tcl_Release(interp); } |
︙ | ︙ | |||
3342 3343 3344 3345 3346 3347 3348 | Tcl_Preserve(interp); 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) { | | | | 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 | Tcl_Preserve(interp); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "LIMIT", "TIME", NULL); Tcl_Release(interp); return TCL_ERROR; } Tcl_Release(interp); } } |
︙ | ︙ | |||
4349 4350 4351 4352 4353 4354 4355 | * First, ensure that we are not reading or writing the calling * 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) { | | | > | 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 | * First, ensure that we are not reading or writing the calling * 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "SELF", NULL); return TCL_ERROR; } if (objc == consumedObjc) { Tcl_Obj *dictPtr; TclNewObj(dictPtr); |
︙ | ︙ | |||
4446 4447 4448 4449 4450 4451 4452 | break; case OPT_GRAN: granObj = objv[i+1]; if (TclGetIntFromObj(interp, objv[i+1], &gran) != TCL_OK) { return TCL_ERROR; } if (gran < 1) { | | | > | < | 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 | 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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADVALUE", NULL); return TCL_ERROR; } break; } } |
︙ | ︙ | |||
4536 4537 4538 4539 4540 4541 4542 | * First, ensure that we are not reading or writing the calling * 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) { | | | > | 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 | * First, ensure that we are not reading or writing the calling * 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "SELF", NULL); return TCL_ERROR; } if (objc == consumedObjc) { Tcl_Obj *dictPtr; TclNewObj(dictPtr); |
︙ | ︙ | |||
4654 4655 4656 4657 4658 4659 4660 | break; case OPT_GRAN: granObj = objv[i+1]; if (TclGetIntFromObj(interp, objv[i+1], &gran) != TCL_OK) { return TCL_ERROR; } if (gran < 1) { | | | > | < | > | < > | | > | | | 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 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 | 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", -1)); 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", -1)); 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", -1)); 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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADUSAGE", NULL); return TCL_ERROR; } } if (milliLen > 0 || secLen > 0) { |
︙ | ︙ |
Changes to generic/tclLoad.c.
︙ | ︙ | |||
153 154 155 156 157 158 159 | if (objc >= 3) { packageName = Tcl_GetString(objv[2]); if (packageName[0] == '\0') { packageName = NULL; } } if ((fullFileName[0] == 0) && (packageName == NULL)) { | | | < | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | if (objc >= 3) { 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "NOLIBRARY", NULL); code = TCL_ERROR; goto done; } /* |
︙ | ︙ | |||
221 222 223 224 225 226 227 | defaultPtr = pkgPtr; } if (filesMatch && !namesMatch && (fullFileName[0] != 0)) { /* * Can't have two different packages loaded from the same file. */ | | | | | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | defaultPtr = pkgPtr; } if (filesMatch && !namesMatch && (fullFileName[0] != 0)) { /* * Can't have two different packages loaded from the same file. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" is already loaded for package \"%s\"", fullFileName, pkgPtr->packageName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "SPLITPERSONALITY", NULL); code = TCL_ERROR; Tcl_MutexUnlock(&packageMutex); goto done; } } |
︙ | ︙ | |||
259 260 261 262 263 264 265 | if (pkgPtr == NULL) { /* * The desired file isn't currently loaded, so load it. It's an error * if the desired package is a static one. */ if (fullFileName[0] == 0) { | | | | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | if (pkgPtr == NULL) { /* * The desired file isn't currently loaded, so load it. It's an error * if the desired package is a static one. */ if (fullFileName[0] == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "package \"%s\" isn't loaded statically", packageName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "NOTSTATIC", NULL); code = TCL_ERROR; goto done; } /* |
︙ | ︙ | |||
317 318 319 320 321 322 323 | || !(isalpha(UCHAR(ch)) /* INTL: ISO only */ || (UCHAR(ch) == '_'))) { break; } } if (p == pkgGuess) { Tcl_DecrRefCount(splitPtr); | | | | | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | || !(isalpha(UCHAR(ch)) /* INTL: ISO only */ || (UCHAR(ch) == '_'))) { break; } } if (p == pkgGuess) { Tcl_DecrRefCount(splitPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't figure out package name for %s", fullFileName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "WHATPACKAGE", NULL); code = TCL_ERROR; goto done; } Tcl_DStringAppend(&pkgName, pkgGuess, p - pkgGuess); Tcl_DecrRefCount(splitPtr); |
︙ | ︙ | |||
414 415 416 417 418 419 420 | /* * Invoke the package's initialization function (either the normal one or * the safe one, depending on whether or not the interpreter is safe). */ if (Tcl_IsSafe(target)) { if (pkgPtr->safeInitProc == NULL) { | | | | | | | | 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 | /* * Invoke the package's initialization function (either the normal one or * the safe one, depending on whether or not the interpreter is safe). */ if (Tcl_IsSafe(target)) { if (pkgPtr->safeInitProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't use package in a safe interpreter: no" " %s_SafeInit procedure", pkgPtr->packageName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "UNSAFE", NULL); code = TCL_ERROR; goto done; } code = pkgPtr->safeInitProc(target); } else { if (pkgPtr->initProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't attach package to interpreter: no %s_Init procedure", pkgPtr->packageName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "ENTRYPOINT", NULL); code = TCL_ERROR; goto done; } code = pkgPtr->initProc(target); } |
︙ | ︙ | |||
577 578 579 580 581 582 583 | if (objc - i >= 2) { packageName = Tcl_GetString(objv[i+1]); if (packageName[0] == '\0') { packageName = NULL; } } if ((fullFileName[0] == 0) && (packageName == NULL)) { | | | < | 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 | if (objc - i >= 2) { 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NOLIBRARY", NULL); code = TCL_ERROR; goto done; } /* |
︙ | ︙ | |||
651 652 653 654 655 656 657 | } Tcl_MutexUnlock(&packageMutex); if (fullFileName[0] == 0) { /* * It's an error to try unload a static package. */ | | | > | | | 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 | } Tcl_MutexUnlock(&packageMutex); if (fullFileName[0] == 0) { /* * It's an error to try unload a static package. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "package \"%s\" is loaded statically and cannot be unloaded", packageName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "STATIC", NULL); code = TCL_ERROR; goto done; } if (pkgPtr == NULL) { /* * The DLL pointed by the provided filename has never been loaded. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" has never been loaded", fullFileName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NEVERLOADED", NULL); code = TCL_ERROR; goto done; } /* |
︙ | ︙ | |||
692 693 694 695 696 697 698 | } } if (code != TCL_OK) { /* * The package has not been loaded in this interpreter. */ | | | > | | > | | > | 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 734 735 | } } if (code != TCL_OK) { /* * The package has not been loaded in this interpreter. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" has never been loaded in this interpreter", fullFileName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NEVERLOADED", NULL); code = TCL_ERROR; goto done; } /* * Ensure that the DLL can be unloaded. If it is a trusted interpreter, * pkgPtr->unloadProc must not be NULL for the DLL to be unloadable. If * the interpreter is a safe one, pkgPtr->safeUnloadProc must be non-NULL. */ if (Tcl_IsSafe(target)) { if (pkgPtr->safeUnloadProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" cannot be unloaded under a safe interpreter", fullFileName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "CANNOT", NULL); code = TCL_ERROR; goto done; } unloadProc = pkgPtr->safeUnloadProc; } else { if (pkgPtr->unloadProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" cannot be unloaded under a trusted interpreter", fullFileName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "CANNOT", NULL); code = TCL_ERROR; goto done; } unloadProc = pkgPtr->unloadProc; } |
︙ | ︙ | |||
858 859 860 861 862 863 864 | ckfree(ipPtr); Tcl_MutexUnlock(&packageMutex); } else { code = TCL_ERROR; } } #else | | | > | 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 | ckfree(ipPtr); Tcl_MutexUnlock(&packageMutex); } else { code = TCL_ERROR; } } #else Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" cannot be unloaded: unloading disabled", fullFileName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "DISABLED", NULL); code = TCL_ERROR; #endif } done: |
︙ | ︙ |
Changes to generic/tclLoadNone.c.
︙ | ︙ | |||
40 41 42 43 44 45 46 | * 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. */ { | | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | * 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. */ { Tcl_SetObjResult(interp, Tcl_NewStringObj( "dynamic loading is not currently available on this system", -1)); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclGuessPackageName -- |
︙ | ︙ |
Changes to generic/tclMain.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 2000 Ajuba Solutions. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ | | | | | > | | | | < > | 12 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 52 53 54 55 56 | * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 2000 Ajuba Solutions. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ /* * On Windows, this file needs to be compiled twice, once with TCL_ASCII_MAIN * defined. This way both Tcl_Main and Tcl_MainExW can be implemented, sharing * the same source code. */ #if defined(TCL_ASCII_MAIN) # ifdef UNICODE # undef UNICODE # undef _UNICODE # else # define UNICODE # define _UNICODE # endif #endif #include "tclInt.h" /* * The default prompt used when the user has not overridden it. */ #define DEFAULT_PRIMARY_PROMPT "% " /* * This file can be compiled on Windows in UNICODE mode, as well as on all * other platforms using the native encoding. This is done by using the normal * Windows functions like _tcscmp, but on platforms which don't have <tchar.h> * we have to translate that to strcmp here. */ #ifndef __WIN32__ # define TCHAR char # define TEXT(arg) arg # define _tcscmp strcmp #endif /* |
︙ | ︙ | |||
124 125 126 127 128 129 130 | /* * Forward declarations for functions defined later in this file. */ MODULE_SCOPE Tcl_MainLoopProc *TclGetMainLoop(void); static void Prompt(Tcl_Interp *interp, InteractiveState *isPtr); static void StdinProc(ClientData clientData, int mask); | | > | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | /* * Forward declarations for functions defined later in this file. */ MODULE_SCOPE Tcl_MainLoopProc *TclGetMainLoop(void); static void Prompt(Tcl_Interp *interp, InteractiveState *isPtr); static void StdinProc(ClientData clientData, int mask); static void FreeMainInterp(ClientData clientData); #ifndef TCL_ASCII_MAIN static Tcl_ThreadDataKey dataKey; /* *---------------------------------------------------------------------- * * Tcl_SetStartupScript -- * * Sets the path and encoding of the startup script to be evaluated by * Tcl_Main, used to override the command line processing. |
︙ | ︙ | |||
329 330 331 332 333 334 335 | * -encoding ENCODING FILENAME * or like * FILENAME */ if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1])) && (TEXT('-') != argv[3][0])) { | | | > | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | * -encoding ENCODING FILENAME * or like * FILENAME */ if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1])) && (TEXT('-') != argv[3][0])) { Tcl_Obj *value = NewNativeObj(argv[2], -1); Tcl_SetStartupScript(NewNativeObj(argv[3], -1), Tcl_GetString(value)); Tcl_DecrRefCount(value); argc -= 3; argv += 3; } else if ((argc > 1) && (TEXT('-') != argv[1][0])) { Tcl_SetStartupScript(NewNativeObj(argv[1], -1), NULL); argc--; argv++; |
︙ | ︙ | |||
391 392 393 394 395 396 397 | if (Tcl_LimitExceeded(interp)) { goto done; } if (TclFullFinalizationRequested()) { /* * Arrange for final deletion of the main interp */ | > | | | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | if (Tcl_LimitExceeded(interp)) { goto done; } if (TclFullFinalizationRequested()) { /* * Arrange for final deletion of the main interp */ /* ARGH Munchhausen effect */ Tcl_CreateExitHandler(FreeMainInterp, interp); } /* * Invoke the script specified on the command line, if any. Must fetch it * again, as the appInitProc might have reset it. */ |
︙ | ︙ | |||
454 455 456 457 458 459 460 461 462 463 464 465 466 467 | 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) { int length; if (is.tty) { Prompt(interp, &is); if (Tcl_InterpDeleted(interp)) { break; } if (Tcl_LimitExceeded(interp)) { break; | > | 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | 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) { int length; if (is.tty) { Prompt(interp, &is); if (Tcl_InterpDeleted(interp)) { break; } if (Tcl_LimitExceeded(interp)) { break; |
︙ | ︙ | |||
519 520 521 522 523 524 525 | /* * The final newline is syntactically redundant, and causes some * error messages troubles deeper in, so lop it back off. */ Tcl_GetStringFromObj(is.commandPtr, &length); Tcl_SetObjLength(is.commandPtr, --length); | | > | 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 | /* * The final newline is syntactically redundant, and causes some * error messages troubles deeper in, so lop it back off. */ Tcl_GetStringFromObj(is.commandPtr, &length); Tcl_SetObjLength(is.commandPtr, --length); 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) { |
︙ | ︙ | |||
553 554 555 556 557 558 559 | */ if (is.input) { if (is.tty) { Prompt(interp, &is); } | | > < > | | < | < | | | | | | | | | | | | > | | 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 640 641 642 643 644 645 646 647 648 649 650 651 652 653 | */ if (is.input) { if (is.tty) { Prompt(interp, &is); } Tcl_CreateChannelHandler(is.input, TCL_READABLE, StdinProc, &is); } mainLoopProc(); Tcl_SetMainLoop(NULL); if (is.input) { Tcl_DeleteChannelHandler(is.input, StdinProc, &is); } is.input = Tcl_GetStdChannel(TCL_STDIN); } /* * This code here only for the (unsupported and deprecated) [checkmem] * command. */ #ifdef TCL_MEM_DEBUG if (tclMemDumpFileName != NULL) { Tcl_SetMainLoop(NULL); Tcl_DeleteInterp(interp); } #endif /* TCL_MEM_DEBUG */ } done: mainLoopProc = TclGetMainLoop(); if ((exitCode == 0) && mainLoopProc && !Tcl_LimitExceeded(interp)) { /* * If everything has gone OK so far, call the main loop proc, if it * exists. Packages (like Tk) can set it to start processing events at * this point. */ mainLoopProc(); Tcl_SetMainLoop(NULL); } if (is.commandPtr != NULL) { Tcl_DecrRefCount(is.commandPtr); } /* * Rather than calling exit, invoke the "exit" command so that users can * replace "exit" with some other command to do additional cleanup on * exit. The Tcl_EvalObjEx call should never return. */ if (!Tcl_InterpDeleted(interp) && !Tcl_LimitExceeded(interp)) { Tcl_Obj *cmd = Tcl_ObjPrintf("exit %d", exitCode); Tcl_IncrRefCount(cmd); Tcl_EvalObjEx(interp, cmd, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(cmd); } /* * If Tcl_EvalObjEx returns, trying to eval [exit], something unusual is * happening. Maybe interp has been deleted; maybe [exit] was redefined, * maybe we've blown up because of an exceeded limit. We still want to * cleanup and exit. */ Tcl_Exit(exitCode); } #if (TCL_MAJOR_VERSION == 8) && !defined(UNICODE) #undef Tcl_Main extern DLLEXPORT void Tcl_Main( int argc, /* Number of arguments. */ char **argv, /* Array of argument strings. */ Tcl_AppInitProc *appInitProc) /* Application-specific initialization * function to call after most initialization * but before starting to execute commands. */ { Tcl_FindExecutable(argv[0]); Tcl_MainEx(argc, argv, appInitProc, Tcl_CreateInterp()); } #endif /* TCL_MAJOR_VERSION == 8 && !UNICODE */ #ifndef TCL_ASCII_MAIN /* *--------------------------------------------------------------- * * Tcl_SetMainLoop -- |
︙ | ︙ | |||
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 | * hunting etc). * * Results: * A boolean. * *---------------------------------------------------------------------- */ MODULE_SCOPE int TclFullFinalizationRequested(void) { #ifdef PURIFY return 1; #else const char *fin; Tcl_DString ds; int finalize = 0; fin = TclGetEnv("TCL_FINALIZE_ON_EXIT", &ds); finalize = ((fin != NULL) && strcmp(fin, "0")); if (fin != NULL) { Tcl_DStringFree(&ds); } return finalize; | > | | 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 | * hunting etc). * * Results: * A boolean. * *---------------------------------------------------------------------- */ MODULE_SCOPE int TclFullFinalizationRequested(void) { #ifdef PURIFY return 1; #else const char *fin; Tcl_DString ds; int finalize = 0; fin = TclGetEnv("TCL_FINALIZE_ON_EXIT", &ds); finalize = ((fin != NULL) && strcmp(fin, "0")); if (fin != NULL) { Tcl_DStringFree(&ds); } return finalize; #endif /* PURIFY */ } #endif /* !TCL_ASCII_MAIN */ /* *---------------------------------------------------------------------- * * StdinProc -- |
︙ | ︙ | |||
862 863 864 865 866 867 868 | * *---------------------------------------------------------------------- */ static void Prompt( Tcl_Interp *interp, /* Interpreter to use for prompting. */ | | | < | | 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 | * *---------------------------------------------------------------------- */ static void Prompt( Tcl_Interp *interp, /* Interpreter to use for prompting. */ InteractiveState *isPtr) /* InteractiveState. Filled with PROMPT_NONE * after a prompt is printed. */ { Tcl_Obj *promptCmdPtr; int code; Tcl_Channel chan; if (isPtr->prompt == PROMPT_NONE) { return; } promptCmdPtr = Tcl_GetVar2Ex(interp, (isPtr->prompt==PROMPT_CONTINUE ? "tcl_prompt2" : "tcl_prompt1"), NULL, TCL_GLOBAL_ONLY); if (Tcl_InterpDeleted(interp)) { return; } if (promptCmdPtr == NULL) { defaultPrompt: |
︙ | ︙ | |||
916 917 918 919 920 921 922 | } /* *---------------------------------------------------------------------- * * FreeMainInterp -- * | | | | | | | | | 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 | } /* *---------------------------------------------------------------------- * * FreeMainInterp -- * * Exit handler used to cleanup the main interpreter and ancillary * startup script storage at exit. * *---------------------------------------------------------------------- */ static void FreeMainInterp( ClientData clientData) { Tcl_Interp *interp = clientData; /*if (TclInExit()) return;*/ if (!Tcl_InterpDeleted(interp)) { Tcl_DeleteInterp(interp); } Tcl_SetStartupScript(NULL, NULL); Tcl_Release(interp); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclNamesp.c.
︙ | ︙ | |||
683 684 685 686 687 688 689 | * Treat this namespace as the global namespace, and avoid looking for * a parent. */ parentPtr = NULL; simpleName = ""; } else if (*name == '\0') { | < | | | 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | * Treat this namespace as the global namespace, and avoid looking for * a parent. */ parentPtr = NULL; simpleName = ""; } else if (*name == '\0') { Tcl_SetObjResult(interp, Tcl_NewStringObj("can't create namespace" " \"\": only global namespace can have empty name", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE", "CREATEGLOBAL", NULL); return NULL; } else { /* * Find the parent for the new namespace. */ |
︙ | ︙ | |||
721 722 723 724 725 726 727 | #ifndef BREAK_NAMESPACE_COMPAT Tcl_FindHashEntry(&parentPtr->childTable, simpleName) != NULL #else parentPtr->childTablePtr != NULL && Tcl_FindHashEntry(parentPtr->childTablePtr, simpleName) != NULL #endif ) { | | | | 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 | #ifndef BREAK_NAMESPACE_COMPAT Tcl_FindHashEntry(&parentPtr->childTable, simpleName) != NULL #else parentPtr->childTablePtr != NULL && Tcl_FindHashEntry(parentPtr->childTablePtr, simpleName) != NULL #endif ) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create namespace \"%s\": already exists", name)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE", "CREATEEXISTING", NULL); return NULL; } } /* |
︙ | ︙ | |||
1332 1333 1334 1335 1336 1337 1338 | */ TclGetNamespaceForQualName(interp, pattern, nsPtr, /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY), &exportNsPtr, &dummyPtr, &dummyPtr, &simplePattern); if ((exportNsPtr != nsPtr) || (strcmp(pattern, simplePattern) != 0)) { | | | | 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 | */ TclGetNamespaceForQualName(interp, pattern, nsPtr, /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY), &exportNsPtr, &dummyPtr, &dummyPtr, &simplePattern); if ((exportNsPtr != nsPtr) || (strcmp(pattern, simplePattern) != 0)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid export pattern" " \"%s\": pattern can't specify a namespace", pattern)); Tcl_SetErrorCode(interp, "TCL", "EXPORT", "INVALID", NULL); return TCL_ERROR; } /* * Make sure that we don't already have the pattern in the array */ |
︙ | ︙ | |||
1547 1548 1549 1550 1551 1552 1553 | return TCL_ERROR; } TclGetNamespaceForQualName(interp, pattern, nsPtr, /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY), &importNsPtr, &dummyPtr, &dummyPtr, &simplePattern); if (importNsPtr == NULL) { | > | < | | | | | | | 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 | return TCL_ERROR; } TclGetNamespaceForQualName(interp, pattern, nsPtr, /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY), &importNsPtr, &dummyPtr, &dummyPtr, &simplePattern); if (importNsPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown namespace in import pattern \"%s\"", pattern)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", pattern, NULL); return TCL_ERROR; } if (importNsPtr == nsPtr) { if (pattern == simplePattern) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "no namespace specified in import pattern \"%s\"", pattern)); Tcl_SetErrorCode(interp, "TCL", "IMPORT", "ORIGIN", NULL); } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "import pattern \"%s\" tries to import from namespace" " \"%s\" into itself", pattern, importNsPtr->name)); Tcl_SetErrorCode(interp, "TCL", "IMPORT", "SELF", NULL); } return TCL_ERROR; } /* * Scan through the command table in the source namespace and look for |
︙ | ︙ | |||
1680 1681 1682 1683 1684 1685 1686 | Command *overwrite = Tcl_GetHashValue(found); Command *linkCmd = cmdPtr; while (linkCmd->deleteProc == DeleteImportedCmd) { dataPtr = linkCmd->objClientData; linkCmd = dataPtr->realCmdPtr; if (overwrite == linkCmd) { | > | | | | 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 | Command *overwrite = Tcl_GetHashValue(found); Command *linkCmd = cmdPtr; while (linkCmd->deleteProc == DeleteImportedCmd) { dataPtr = linkCmd->objClientData; linkCmd = dataPtr->realCmdPtr; if (overwrite == linkCmd) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "import pattern \"%s\" would create a loop" " containing command \"%s\"", pattern, Tcl_DStringValue(&ds))); Tcl_DStringFree(&ds); Tcl_SetErrorCode(interp, "TCL", "IMPORT", "LOOP", NULL); return TCL_ERROR; } } } |
︙ | ︙ | |||
1722 1723 1724 1725 1726 1727 1728 | /* * Repeated import of same command is acceptable. */ return TCL_OK; } } | | | | 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 | /* * Repeated import of same command is acceptable. */ return TCL_OK; } } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't import command \"%s\": already exists", cmdName)); Tcl_SetErrorCode(interp, "TCL", "IMPORT", "OVERWRITE", NULL); return TCL_ERROR; } return TCL_OK; } /* |
︙ | ︙ | |||
1792 1793 1794 1795 1796 1797 1798 | */ TclGetNamespaceForQualName(interp, pattern, nsPtr, /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY), &sourceNsPtr, &dummyPtr, &dummyPtr, &simplePattern); if (sourceNsPtr == NULL) { | | | | | 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 | */ TclGetNamespaceForQualName(interp, pattern, nsPtr, /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY), &sourceNsPtr, &dummyPtr, &dummyPtr, &simplePattern); if (sourceNsPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown namespace in namespace forget pattern \"%s\"", pattern)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", pattern, NULL); return TCL_ERROR; } if (strcmp(pattern, simplePattern) == 0) { /* * The pattern is simple. Delete any imported commands that match it. |
︙ | ︙ | |||
2398 2399 2400 2401 2402 2403 2404 | flags|TCL_FIND_ONLY_NS, &nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy); if (nsPtr != NULL) { return (Tcl_Namespace *) nsPtr; } if (flags & TCL_LEAVE_ERR_MSG) { | | | | 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 | flags|TCL_FIND_ONLY_NS, &nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy); if (nsPtr != NULL) { return (Tcl_Namespace *) nsPtr; } if (flags & TCL_LEAVE_ERR_MSG) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown namespace \"%s\"", name)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", name, NULL); } return NULL; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
2585 2586 2587 2588 2589 2590 2591 | } if (cmdPtr != NULL) { return (Tcl_Command) cmdPtr; } if (flags & TCL_LEAVE_ERR_MSG) { | | | | 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 | } if (cmdPtr != NULL) { return (Tcl_Command) cmdPtr; } if (flags & TCL_LEAVE_ERR_MSG) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown command \"%s\"", name)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", name, NULL); } return NULL; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
3166 3167 3168 3169 3170 3171 3172 | */ for (i = 1; i < objc; i++) { name = TclGetString(objv[i]); namespacePtr = Tcl_FindNamespace(interp, name, NULL, /*flags*/ 0); if ((namespacePtr == NULL) || (((Namespace *) namespacePtr)->flags & NS_KILLED)) { | > | | < | 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 | */ for (i = 1; i < objc; i++) { name = TclGetString(objv[i]); namespacePtr = Tcl_FindNamespace(interp, name, NULL, /*flags*/ 0); if ((namespacePtr == NULL) || (((Namespace *) namespacePtr)->flags & NS_KILLED)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown namespace \"%s\" in namespace delete command", TclGetString(objv[i]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", TclGetString(objv[i]), NULL); return TCL_ERROR; } } /* |
︙ | ︙ | |||
3830 3831 3832 3833 3834 3835 3836 | if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } command = Tcl_GetCommandFromObj(interp, objv[1]); if (command == NULL) { | | | | 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 | if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } command = Tcl_GetCommandFromObj(interp, objv[1]); if (command == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid command name \"%s\"", TclGetString(objv[1]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", TclGetString(objv[1]), NULL); return TCL_ERROR; } origCommand = TclGetOriginalCommand(command); TclNewObj(resultPtr); if (origCommand == NULL) { |
︙ | ︙ |
Changes to generic/tclOO.c.
︙ | ︙ | |||
77 78 79 80 81 82 83 84 85 86 87 88 89 90 | Tcl_Interp *interp); static void MyDeleted(ClientData clientData); static void ObjectNamespaceDeleted(ClientData clientData); static void ObjectRenamedTrace(ClientData clientData, Tcl_Interp *interp, const char *oldName, const char *newName, int flags); static void ReleaseClassContents(Tcl_Interp *interp,Object *oPtr); static void SquelchedNsFirst(ClientData clientData); static int PublicObjectCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int PublicNRObjectCmd(ClientData clientData, Tcl_Interp *interp, int objc, | > | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | Tcl_Interp *interp); static void MyDeleted(ClientData clientData); static void ObjectNamespaceDeleted(ClientData clientData); static void ObjectRenamedTrace(ClientData clientData, 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, int objc, Tcl_Obj *const *objv); static int PublicNRObjectCmd(ClientData clientData, Tcl_Interp *interp, int objc, |
︙ | ︙ | |||
700 701 702 703 704 705 706 707 708 709 710 711 712 713 | return oPtr; } /* * ---------------------------------------------------------------------- * * MyDeleted -- * * This callback is triggered when the object's [my] command is deleted * by any mechanism. It just marks the object as not having a [my] * command, and so prevents cleanup of that when the object itself is * deleted. * | > > > > > > > > > > > > > > > > > > > > > | 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 | return oPtr; } /* * ---------------------------------------------------------------------- * * SquelchCachedName -- * * Encapsulates how to throw away a cached object name. Called from * object rename traces and at object destruction. * * ---------------------------------------------------------------------- */ static inline void SquelchCachedName( Object *oPtr) { if (oPtr->cachedNameObj) { Tcl_DecrRefCount(oPtr->cachedNameObj); oPtr->cachedNameObj = NULL; } } /* * ---------------------------------------------------------------------- * * MyDeleted -- * * This callback is triggered when the object's [my] command is deleted * by any mechanism. It just marks the object as not having a [my] * command, and so prevents cleanup of that when the object itself is * deleted. * |
︙ | ︙ | |||
774 775 776 777 778 779 780 | /* * If this is a rename and not a delete of the object, we just flush the * cache of the object name. */ if (flags & TCL_TRACE_RENAME) { | | < < < | 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 | /* * If this is a rename and not a delete of the object, we just flush the * cache of the object name. */ if (flags & TCL_TRACE_RENAME) { SquelchCachedName(oPtr); return; } /* * Oh dear, the object really is being deleted. Handle this by running the * destructors and deleting the object's namespace, which in turn causes * the real object structures to be deleted. |
︙ | ︙ | |||
1134 1135 1136 1137 1138 1139 1140 | ckfree(oPtr->variables.list); } if (oPtr->chainCache) { TclOODeleteChainCache(oPtr->chainCache); } | | < < < | 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 | ckfree(oPtr->variables.list); } if (oPtr->chainCache) { TclOODeleteChainCache(oPtr->chainCache); } SquelchCachedName(oPtr); if (oPtr->metadataPtr != NULL) { Tcl_ObjectMetadataType *metadataTypePtr; ClientData value; FOREACH_HASH(metadataTypePtr, value, oPtr->metadataPtr) { metadataTypePtr->deleteProc(value); |
︙ | ︙ | |||
1562 1563 1564 1565 1566 1567 1568 | /* * Check if we're going to create an object over an existing command; * that's not allowed. */ if (nameStr && Tcl_FindCommand(interp, nameStr, NULL, TCL_NAMESPACE_ONLY)) { | | | > | 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 | /* * Check if we're going to create an object over an existing command; * that's not allowed. */ if (nameStr && Tcl_FindCommand(interp, nameStr, NULL, TCL_NAMESPACE_ONLY)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create object \"%s\": command already exists with" " that name", nameStr)); Tcl_SetErrorCode(interp, "TCL", "OO", "OVERWRITE_OBJECT", NULL); return NULL; } /* * Create the object. */ |
︙ | ︙ | |||
1629 1630 1631 1632 1633 1634 1635 | /* * 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)) { | > | < | 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 | /* * 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "STILLBORN", NULL); result = TCL_ERROR; } TclOODeleteContext(contextPtr); if (result != TCL_OK) { Tcl_DiscardInterpState(state); |
︙ | ︙ | |||
1685 1686 1687 1688 1689 1690 1691 | /* * Check if we're going to create an object over an existing command; * that's not allowed. */ if (nameStr && Tcl_FindCommand(interp, nameStr, NULL, TCL_NAMESPACE_ONLY)) { | | | > | 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 | /* * Check if we're going to create an object over an existing command; * that's not allowed. */ if (nameStr && Tcl_FindCommand(interp, nameStr, NULL, TCL_NAMESPACE_ONLY)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create object \"%s\": command already exists with" " that name", nameStr)); Tcl_SetErrorCode(interp, "TCL", "OO", "OVERWRITE_OBJECT", NULL); return TCL_ERROR; } /* * Create the object. */ |
︙ | ︙ | |||
1774 1775 1776 1777 1778 1779 1780 | /* * 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)) { | > | | 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 | /* * 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "STILLBORN", NULL); result = TCL_ERROR; } TclOODeleteContext(contextPtr); if (result != TCL_OK) { Tcl_DiscardInterpState(state); |
︙ | ︙ | |||
1831 1832 1833 1834 1835 1836 1837 | int i, result; /* * Sanity check. */ if (IsRootClass(oPtr)) { | > | | 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 | int i, result; /* * Sanity check. */ if (IsRootClass(oPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not clone the class of classes", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "CLONING_CLASS", NULL); return NULL; } /* * Build the instance. Note that this does not run any constructors. */ |
︙ | ︙ | |||
2494 2495 2496 2497 2498 2499 2500 | */ Tcl_IncrRefCount(mappedMethodName); contextPtr = TclOOGetCallContext(oPtr, mappedMethodName, flags | (oPtr->flags & FILTER_HANDLING), methodNamePtr); TclDecrRefCount(mappedMethodName); if (contextPtr == NULL) { | > | | < > | | < | 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 | */ Tcl_IncrRefCount(mappedMethodName); contextPtr = TclOOGetCallContext(oPtr, mappedMethodName, flags | (oPtr->flags & FILTER_HANDLING), methodNamePtr); TclDecrRefCount(mappedMethodName); if (contextPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "impossible to invoke method \"%s\": no defined method or" " unknown method", TclGetString(methodNamePtr))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD_MAPPED", TclGetString(methodNamePtr), NULL); return TCL_ERROR; } } else { /* * Get the call chain. */ noMapping: contextPtr = TclOOGetCallContext(oPtr, methodNamePtr, flags | (oPtr->flags & FILTER_HANDLING), NULL); if (contextPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "impossible to invoke method \"%s\": no defined method or" " unknown method", TclGetString(methodNamePtr))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(methodNamePtr), NULL); return TCL_ERROR; } } /* |
︙ | ︙ | |||
2538 2539 2540 2541 2542 2543 2544 | continue; } if (miPtr->mPtr->declaringClassPtr == startCls) { break; } } if (contextPtr->index >= contextPtr->callPtr->numChain) { | > | < | 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 | continue; } if (miPtr->mPtr->declaringClassPtr == startCls) { break; } } if (contextPtr->index >= contextPtr->callPtr->numChain) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no valid method implementation", -1)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(methodNamePtr), NULL); TclOODeleteContext(contextPtr); return TCL_ERROR; } } |
︙ | ︙ | |||
2620 2621 2622 2623 2624 2625 2626 | methodType = "constructor"; } else if (contextPtr->callPtr->flags & DESTRUCTOR) { methodType = "destructor"; } else { methodType = "method"; } | | | | 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 | methodType = "constructor"; } else if (contextPtr->callPtr->flags & DESTRUCTOR) { methodType = "destructor"; } else { methodType = "method"; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "no next %s implementation", methodType)); Tcl_SetErrorCode(interp, "TCL", "OO", "NOTHING_NEXT", NULL); return TCL_ERROR; } /* * Advance to the next method implementation in the chain in the method * call context while we process the body. However, need to adjust the |
︙ | ︙ | |||
2689 2690 2691 2692 2693 2694 2695 | methodType = "constructor"; } else if (contextPtr->callPtr->flags & DESTRUCTOR) { methodType = "destructor"; } else { methodType = "method"; } | | | | 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 | methodType = "constructor"; } else if (contextPtr->callPtr->flags & DESTRUCTOR) { methodType = "destructor"; } else { methodType = "method"; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "no next %s implementation", methodType)); Tcl_SetErrorCode(interp, "TCL", "OO", "NOTHING_NEXT", NULL); return TCL_ERROR; } /* * Advance to the next method implementation in the chain in the method * call context while we process the body. However, need to adjust the |
︙ | ︙ | |||
2767 2768 2769 2770 2771 2772 2773 | if (cmdPtr == NULL || cmdPtr->objProc != PublicObjectCmd) { goto notAnObject; } } return cmdPtr->objClientData; notAnObject: | | | | 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 | if (cmdPtr == NULL || cmdPtr->objProc != PublicObjectCmd) { goto notAnObject; } } return cmdPtr->objClientData; notAnObject: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s does not refer to an object", TclGetString(objPtr))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "OBJECT", TclGetString(objPtr), NULL); return NULL; } /* * ---------------------------------------------------------------------- |
︙ | ︙ |
Changes to generic/tclOOBasic.c.
︙ | ︙ | |||
164 165 166 167 168 169 170 | * Sanity check; should not be possible to invoke this method on a * non-class. */ if (oPtr->classPtr == NULL) { Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr); | | | > | | 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 | * Sanity check; should not be possible to invoke this method on a * non-class. */ if (oPtr->classPtr == NULL) { Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "object \"%s\" is not a class", TclGetString(cmdnameObj))); Tcl_SetErrorCode(interp, "TCL", "OO", "INSTANTIATE_NONCLASS", NULL); return TCL_ERROR; } /* * Check we have the right number of (sensible) arguments. */ if (objc - Tcl_ObjectContextSkippedArgs(context) < 1) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", NULL); return TCL_ERROR; } /* * Make the object and return its name. */ |
︙ | ︙ | |||
228 229 230 231 232 233 234 | * Sanity check; should not be possible to invoke this method on a * non-class. */ if (oPtr->classPtr == NULL) { Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr); | | | > | > | | 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 | * Sanity check; should not be possible to invoke this method on a * non-class. */ if (oPtr->classPtr == NULL) { Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "object \"%s\" is not a class", TclGetString(cmdnameObj))); Tcl_SetErrorCode(interp, "TCL", "OO", "INSTANTIATE_NONCLASS", NULL); return TCL_ERROR; } /* * Check we have the right number of (sensible) arguments. */ if (objc - Tcl_ObjectContextSkippedArgs(context) < 2) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", NULL); return TCL_ERROR; } /* * Make the object and return its name. */ |
︙ | ︙ | |||
297 298 299 300 301 302 303 | * Sanity check; should not be possible to invoke this method on a * non-class. */ if (oPtr->classPtr == NULL) { Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr); | | | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | * Sanity check; should not be possible to invoke this method on a * non-class. */ if (oPtr->classPtr == NULL) { Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "object \"%s\" is not a class", TclGetString(cmdnameObj))); Tcl_SetErrorCode(interp, "TCL", "OO", "INSTANTIATE_NONCLASS", NULL); return TCL_ERROR; } /* * Make the object and return its name. */ |
︙ | ︙ | |||
500 501 502 503 504 505 506 507 508 509 510 511 512 513 | int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { CallContext *contextPtr = (CallContext *) context; Object *oPtr = contextPtr->oPtr; const char **methodNames; int numMethodNames, i, skip = Tcl_ObjectContextSkippedArgs(context); /* * 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). */ | > | 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 | int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { CallContext *contextPtr = (CallContext *) context; Object *oPtr = contextPtr->oPtr; const char **methodNames; int 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). */ |
︙ | ︙ | |||
525 526 527 528 529 530 531 532 | /* * Special message when there are no visible methods at all. */ if (numMethodNames == 0) { Tcl_Obj *tmpBuf = TclOOObjectName(interp, oPtr); | > < | | > > > | < | | | | > | 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 | /* * Special message when there are no visible methods at all. */ if (numMethodNames == 0) { Tcl_Obj *tmpBuf = TclOOObjectName(interp, oPtr); const char *piece; if (contextPtr->callPtr->flags & PUBLIC_METHOD) { piece = "visible methods"; } else { piece = "methods"; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "object \"%s\" has no %s", TclGetString(tmpBuf), piece)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[skip]), NULL); 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, ", ", -1); } Tcl_AppendToObj(errorMsg, methodNames[i], -1); } if (i) { Tcl_AppendToObj(errorMsg, " or ", -1); } Tcl_AppendToObj(errorMsg, methodNames[i], -1); ckfree(methodNames); Tcl_SetObjResult(interp, errorMsg); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[skip]), NULL); return TCL_ERROR; } /* * ---------------------------------------------------------------------- |
︙ | ︙ | |||
605 606 607 608 609 610 611 | /* * The variable name must not contain a '::' since that's illegal in * local names. */ if (strstr(varName, "::") != NULL) { | | | > | 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 | /* * The variable name must not contain a '::' since that's illegal in * local names. */ if (strstr(varName, "::") != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "variable name \"%s\" illegal: must not contain namespace" " separator", varName)); Tcl_SetErrorCode(interp, "TCL", "UPVAR", "INVERTED", NULL); return TCL_ERROR; } /* * Switch to the object's namespace for the duration of this call. * Like this, the variable is looked up in the namespace of the |
︙ | ︙ | |||
780 781 782 783 784 785 786 | /* * 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. */ if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) { | | | > | 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 | /* * 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. */ if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s may only be called from inside a method", TclGetString(objv[0]))); Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL); return TCL_ERROR; } context = framePtr->clientData; /* * Invoke the (advanced) method call context in the caller context. Note |
︙ | ︙ | |||
818 819 820 821 822 823 824 | /* * 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. */ if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) { | | | > | | > | 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 | /* * 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. */ if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s may only be called from inside a method", TclGetString(objv[0]))); Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL); return TCL_ERROR; } contextPtr = framePtr->clientData; /* * Sanity check the arguments; we need the first one to refer to a class. */ if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "class ?arg...?"); return TCL_ERROR; } object = Tcl_GetObjectFromObj(interp, objv[1]); if (object == NULL) { return TCL_ERROR; } classPtr = ((Object *)object)->classPtr; if (classPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" is not a class", TclGetString(objv[1]))); Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_REQUIRED", NULL); return TCL_ERROR; } /* * Search for an implementation of a method associated with the current * call on the call chain past the point where we currently are. Do not * allow jumping backwards! |
︙ | ︙ | |||
877 878 879 880 881 882 883 | * is on the chain but unreachable, or not on the chain at all. */ for (i=contextPtr->index ; i>=0 ; i--) { struct MInvoke *miPtr = contextPtr->callPtr->chain + i; if (!miPtr->isFilter && miPtr->mPtr->declaringClassPtr == classPtr) { | > | | < > | | | 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 | * is on the chain but unreachable, or not on the chain at all. */ for (i=contextPtr->index ; i>=0 ; i--) { 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; } } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "method has no non-filter implementation by \"%s\"", TclGetString(objv[1]))); return TCL_ERROR; } static int RestoreFrame( ClientData data[], Tcl_Interp *interp, |
︙ | ︙ | |||
944 945 946 947 948 949 950 | ((contextPtr)->callPtr->chain[(contextPtr)->index]) /* * Start with sanity checks on the calling context and the method context. */ if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) { | | | > | 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 | ((contextPtr)->callPtr->chain[(contextPtr)->index]) /* * Start with sanity checks on the calling context and the method context. */ if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s may only be called from inside a method", TclGetString(objv[0]))); Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL); return TCL_ERROR; } contextPtr = framePtr->clientData; /* |
︙ | ︙ | |||
979 980 981 982 983 984 985 | Tcl_SetObjResult(interp, Tcl_NewStringObj( contextPtr->oPtr->namespacePtr->fullName,-1)); return TCL_OK; case SELF_CLASS: { Class *clsPtr = CurrentlyInvoked(contextPtr).mPtr->declaringClassPtr; if (clsPtr == NULL) { | > | > | | 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 | Tcl_SetObjResult(interp, Tcl_NewStringObj( contextPtr->oPtr->namespacePtr->fullName,-1)); 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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", NULL); return TCL_ERROR; } else { register struct MInvoke *miPtr = &CurrentlyInvoked(contextPtr); Object *oPtr; const char *type; |
︙ | ︙ | |||
1024 1025 1026 1027 1028 1029 1030 | 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)){ | > | > | | 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 | 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", -1)); 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!", -1)); return TCL_ERROR; } result[0] = TclOOObjectName(interp, declarerPtr); result[1] = TclOOObjectName(interp, callerPtr->oPtr); if (callerPtr->callPtr->flags & CONSTRUCTOR) { result[2] = declarerPtr->fPtr->constructorName; |
︙ | ︙ | |||
1072 1073 1074 1075 1076 1077 1078 | } else if (mPtr->declaringObjectPtr != NULL) { declarerPtr = mPtr->declaringObjectPtr; } else { /* * This should be unreachable code. */ | > | > | | 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 | } else if (mPtr->declaringObjectPtr != NULL) { declarerPtr = mPtr->declaringObjectPtr; } else { /* * This should be unreachable code. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "method without declarer!", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", NULL); return TCL_ERROR; } else { Method *mPtr; Object *declarerPtr; int i; |
︙ | ︙ | |||
1115 1116 1117 1118 1119 1120 1121 | } else if (mPtr->declaringObjectPtr != NULL) { declarerPtr = mPtr->declaringObjectPtr; } else { /* * This should be unreachable code. */ | > | | 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 | } else if (mPtr->declaringObjectPtr != NULL) { declarerPtr = mPtr->declaringObjectPtr; } else { /* * This should be unreachable code. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "method without declarer!", -1)); return TCL_ERROR; } result[0] = TclOOObjectName(interp, declarerPtr); result[1] = mPtr->namePtr; Tcl_SetObjResult(interp, Tcl_NewListObj(2, result)); return TCL_OK; } |
︙ | ︙ |
Changes to generic/tclOODefineCmds.c.
︙ | ︙ | |||
419 420 421 422 423 424 425 | Tcl_HashEntry *hPtr, *newHPtr = NULL; Method *mPtr; int isNew; if (!useClass) { if (!oPtr->methodsPtr) { noSuchMethod: | | | > | < > | | | 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 | Tcl_HashEntry *hPtr, *newHPtr = NULL; Method *mPtr; int isNew; if (!useClass) { if (!oPtr->methodsPtr) { noSuchMethod: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "method %s does not exist", TclGetString(fromPtr))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(fromPtr), NULL); return TCL_ERROR; } hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) fromPtr); if (hPtr == NULL) { goto noSuchMethod; } if (toPtr) { newHPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, (char *) toPtr, &isNew); if (hPtr == newHPtr) { renameToSelf: Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot rename method to itself", -1)); 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))); Tcl_SetErrorCode(interp, "TCL", "OO", "RENAME_OVER", NULL); return TCL_ERROR; } } } else { hPtr = Tcl_FindHashEntry(&oPtr->classPtr->classMethods, (char *) fromPtr); |
︙ | ︙ | |||
509 510 511 512 513 514 515 | Namespace *nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp); Tcl_HashSearch search; Tcl_HashEntry *hPtr; int soughtLen; const char *soughtStr, *matchedStr = NULL; if (objc < 2) { | > | | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | Namespace *nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp); Tcl_HashSearch search; Tcl_HashEntry *hPtr; int soughtLen; const char *soughtStr, *matchedStr = NULL; if (objc < 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad call of unknown handler", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_UNKNOWN", NULL); return TCL_ERROR; } if (TclOOGetDefineCmdContext(interp) == NULL) { return TCL_ERROR; } |
︙ | ︙ | |||
554 555 556 557 558 559 560 | result = Tcl_EvalObjv(interp, objc-1, newObjv, 0); Tcl_DecrRefCount(newObjv[0]); TclStackFree(interp, newObjv); return result; } noMatch: | > | | 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 | result = Tcl_EvalObjv(interp, objc-1, newObjv, 0); Tcl_DecrRefCount(newObjv[0]); TclStackFree(interp, newObjv); return result; } noMatch: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid command name \"%s\"", soughtStr)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", soughtStr, NULL); return TCL_ERROR; } /* * ---------------------------------------------------------------------- * |
︙ | ︙ | |||
642 643 644 645 646 647 648 | int objc, Tcl_Obj *const objv[]) { CallFrame *framePtr, **framePtrPtr = &framePtr; int result; if (namespacePtr == NULL) { | | | | 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 | int 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", -1)); 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, |
︙ | ︙ | |||
682 683 684 685 686 687 688 | Tcl_Interp *interp) { Interp *iPtr = (Interp *) interp; Tcl_Object object; if ((iPtr->varFramePtr == NULL) || (iPtr->varFramePtr->isProcCallFrame != FRAME_IS_OO_DEFINE)) { | > | | < > | | | 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 | Tcl_Interp *interp) { 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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return NULL; } return object; } /* |
︙ | ︙ | |||
732 733 734 735 736 737 738 | } oPtr = (Object *) Tcl_GetObjectFromObj(interp, className); iPtr->varFramePtr = savedFramePtr; if (oPtr == NULL) { return NULL; } if (oPtr->classPtr == NULL) { | | | 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 | } oPtr = (Object *) Tcl_GetObjectFromObj(interp, className); iPtr->varFramePtr = savedFramePtr; if (oPtr == NULL) { return NULL; } if (oPtr->classPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS", TclGetString(className), NULL); return NULL; } return oPtr->classPtr; } |
︙ | ︙ | |||
812 813 814 815 816 817 818 | } oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]); if (oPtr == NULL) { return TCL_ERROR; } if (oPtr->classPtr == NULL) { | | | | 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 | } oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]); if (oPtr == NULL) { return TCL_ERROR; } if (oPtr->classPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s does not refer to a class",TclGetString(objv[1]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS", TclGetString(objv[1]), NULL); return TCL_ERROR; } /* * Make the oo::define namespace the current namespace and evaluate the |
︙ | ︙ | |||
1157 1158 1159 1160 1161 1162 1163 | */ oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (oPtr->flags & ROOT_OBJECT) { | | | | | | 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 | */ 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", -1)); 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", -1)); 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. */ |
︙ | ︙ | |||
1190 1191 1192 1193 1194 1195 1196 | /* * Apply semantic checks. In particular, classes and non-classes are not * interchangable (too complicated to do the conversion!) so we must * produce an error if any attempt is made to swap from one to the other. */ if ((oPtr->classPtr==NULL) == TclOOIsReachable(fPtr->classCls, clsPtr)) { | > | | | | 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 | /* * Apply semantic checks. In particular, classes and non-classes are not * interchangable (too complicated to do the conversion!) so we must * produce an error if any attempt is made to swap from one to the other. */ if ((oPtr->classPtr==NULL) == TclOOIsReachable(fPtr->classCls, clsPtr)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "may not change a %sclass object into a %sclass object", (oPtr->classPtr==NULL ? "non-" : ""), (oPtr->classPtr==NULL ? "" : "non-"))); Tcl_SetErrorCode(interp, "TCL", "OO", "TRANSMUTATION", NULL); return TCL_ERROR; } /* * Set the object's class. */ |
︙ | ︙ | |||
1313 1314 1315 1316 1317 1318 1319 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceDeleteMethod && !oPtr->classPtr) { | > | | 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceDeleteMethod && !oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); 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. |
︙ | ︙ | |||
1436 1437 1438 1439 1440 1441 1442 | oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } clsPtr = oPtr->classPtr; if (!isInstanceExport && !clsPtr) { | > | | 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 | 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", -1)); 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 |
︙ | ︙ | |||
1527 1528 1529 1530 1531 1532 1533 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceForward && !oPtr->classPtr) { | > | | 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceForward && !oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*") ? PUBLIC_METHOD : 0; /* |
︙ | ︙ | |||
1584 1585 1586 1587 1588 1589 1590 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceMethod && !oPtr->classPtr) { | > | | 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceMethod && !oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*") ? PUBLIC_METHOD : 0; /* |
︙ | ︙ | |||
1635 1636 1637 1638 1639 1640 1641 | Class **mixins; int i; if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceMixin && !oPtr->classPtr) { | > | > | | 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 | Class **mixins; int i; if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceMixin && !oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL); goto freeAndError; } mixins[i-1] = clsPtr; } if (isInstanceMixin) { |
︙ | ︙ | |||
1700 1701 1702 1703 1704 1705 1706 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceRenameMethod && !oPtr->classPtr) { | > | | 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 | } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceRenameMethod && !oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); 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 |
︙ | ︙ | |||
1760 1761 1762 1763 1764 1765 1766 | oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } clsPtr = oPtr->classPtr; if (!isInstanceUnexport && !clsPtr) { | > | | 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 | 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", -1)); 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 |
︙ | ︙ | |||
1945 1946 1947 1948 1949 1950 1951 | Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { | > | | 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 | Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } resultObj = Tcl_NewObj(); FOREACH(filterObj, oPtr->classPtr->filters) { Tcl_ListObjAppendElement(NULL, resultObj, filterObj); |
︙ | ︙ | |||
1980 1981 1982 1983 1984 1985 1986 | return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { | > | | 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 | return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } else if (Tcl_ListObjGetElements(interp, objv[0], &filterc, &filterv) != TCL_OK) { return TCL_ERROR; } |
︙ | ︙ | |||
2023 2024 2025 2026 2027 2028 2029 | Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { | > | | 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 | Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } resultObj = Tcl_NewObj(); FOREACH(mixinPtr, oPtr->classPtr->mixins) { Tcl_ListObjAppendElement(NULL, resultObj, |
︙ | ︙ | |||
2061 2062 2063 2064 2065 2066 2067 | return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { | > | > | | 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 | return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL); goto freeAndError; } } TclOOClassSetMixins(interp, oPtr->classPtr, mixinc, mixins); TclStackFree(interp, mixins); |
︙ | ︙ | |||
2124 2125 2126 2127 2128 2129 2130 | Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { | > | | 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 | Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } resultObj = Tcl_NewObj(); FOREACH(superPtr, oPtr->classPtr->superclasses) { Tcl_ListObjAppendElement(NULL, resultObj, |
︙ | ︙ | |||
2161 2162 2163 2164 2165 2166 2167 | return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { | > | | | | 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 | return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", 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", -1)); 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; } |
︙ | ︙ | |||
2192 2193 2194 2195 2196 2197 2198 | superclasses[i] = GetClassInOuterContext(interp, superv[i], "only a class can be a superclass"); if (superclasses[i] == NULL) { goto failedAfterAlloc; } for (j=0 ; j<i ; j++) { if (superclasses[j] == superclasses[i]) { | | | | | | 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 | superclasses[i] = GetClassInOuterContext(interp, superv[i], "only a class can be a superclass"); if (superclasses[i] == NULL) { goto failedAfterAlloc; } for (j=0 ; j<i ; j++) { if (superclasses[j] == superclasses[i]) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "class should only be a direct superclass once", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "CIRCULARITY", NULL); failedAfterAlloc: ckfree((char *) superclasses); return TCL_ERROR; } } |
︙ | ︙ | |||
2261 2262 2263 2264 2265 2266 2267 | Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { | > | | 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 | Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, NULL); return TCL_ERROR; } if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } resultObj = Tcl_NewObj(); FOREACH(variableObj, oPtr->classPtr->variables) { Tcl_ListObjAppendElement(NULL, resultObj, variableObj); |
︙ | ︙ | |||
2297 2298 2299 2300 2301 2302 2303 | return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { | > | > | | < > | | | 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 | return TCL_ERROR; } objv += Tcl_ObjectContextSkippedArgs(context); if (oPtr == NULL) { return TCL_ERROR; } else if (!oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } else if (Tcl_ListObjGetElements(interp, objv[0], &varc, &varv) != TCL_OK) { return TCL_ERROR; } for (i=0 ; i<varc ; i++) { const char *varName = Tcl_GetString(varv[i]); if (strstr(varName, "::") != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid declared variable name \"%s\": must not %s", varName, "contain namespace separators")); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL); return TCL_ERROR; } if (Tcl_StringMatch(varName, "*(*)")) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid declared variable name \"%s\": must not %s", varName, "refer to an array element")); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL); return TCL_ERROR; } } for (i=0 ; i<varc ; i++) { Tcl_IncrRefCount(varv[i]); |
︙ | ︙ | |||
2587 2588 2589 2590 2591 2592 2593 | return TCL_ERROR; } for (i=0 ; i<varc ; i++) { const char *varName = Tcl_GetString(varv[i]); if (strstr(varName, "::") != NULL) { | > | | < > | | | 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 | return TCL_ERROR; } for (i=0 ; i<varc ; i++) { const char *varName = Tcl_GetString(varv[i]); if (strstr(varName, "::") != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid declared variable name \"%s\": must not %s", varName, "contain namespace separators")); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL); return TCL_ERROR; } if (Tcl_StringMatch(varName, "*(*)")) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid declared variable name \"%s\": must not %s", varName, "refer to an array element")); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL); return TCL_ERROR; } } for (i=0 ; i<varc ; i++) { Tcl_IncrRefCount(varv[i]); } |
︙ | ︙ |
Changes to generic/tclOOInfo.c.
︙ | ︙ | |||
173 174 175 176 177 178 179 | { Object *oPtr = (Object *) Tcl_GetObjectFromObj(interp, objPtr); if (oPtr == NULL) { return NULL; } if (oPtr->classPtr == NULL) { | | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | { Object *oPtr = (Object *) Tcl_GetObjectFromObj(interp, objPtr); if (oPtr == NULL) { return NULL; } if (oPtr->classPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" is not a class", TclGetString(objPtr))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS", TclGetString(objPtr), NULL); return NULL; } return oPtr->classPtr; } |
︙ | ︙ | |||
275 276 277 278 279 280 281 | if (!oPtr->methodsPtr) { goto unknownMethod; } hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]); if (hPtr == NULL) { unknownMethod: | | | | | | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | if (!oPtr->methodsPtr) { goto unknownMethod; } hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]); if (hPtr == NULL) { unknownMethod: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown method \"%s\"", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), 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", -1)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } resultObjs[0] = Tcl_NewObj(); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; |
︙ | ︙ | |||
386 387 388 389 390 391 392 | if (!oPtr->methodsPtr) { goto unknownMethod; } hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]); if (hPtr == NULL) { unknownMethod: | | | | | | 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 | if (!oPtr->methodsPtr) { goto unknownMethod; } hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]); if (hPtr == NULL) { unknownMethod: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown method \"%s\"", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), 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", -1)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, prefixObj); return TCL_OK; |
︙ | ︙ | |||
487 488 489 490 491 492 493 | return TCL_ERROR; } o2Ptr = (Object *) Tcl_GetObjectFromObj(interp, objv[3]); if (o2Ptr == NULL) { return TCL_ERROR; } if (o2Ptr->classPtr == NULL) { | > | | 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | return TCL_ERROR; } 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "NONCLASS", NULL); return TCL_ERROR; } else { Class *mixinPtr; FOREACH(mixinPtr, oPtr->mixins) { if (mixinPtr == o2Ptr->classPtr) { |
︙ | ︙ | |||
512 513 514 515 516 517 518 | return TCL_ERROR; } o2Ptr = (Object *) Tcl_GetObjectFromObj(interp, objv[3]); if (o2Ptr == NULL) { return TCL_ERROR; } if (o2Ptr->classPtr == NULL) { | > | | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | return TCL_ERROR; } 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "NONCLASS", NULL); return TCL_ERROR; } if (TclOOIsReachable(o2Ptr->classPtr, oPtr->selfCls)) { Tcl_SetObjResult(interp, Tcl_NewIntObj(1)); } else { Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); |
︙ | ︙ | |||
647 648 649 650 651 652 653 | if (!oPtr->methodsPtr) { goto unknownMethod; } hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]); if (hPtr == NULL) { unknownMethod: | | | | 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 | if (!oPtr->methodsPtr) { goto unknownMethod; } hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]); if (hPtr == NULL) { unknownMethod: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown method \"%s\"", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } mPtr = Tcl_GetHashValue(hPtr); if (mPtr->typePtr == NULL) { /* |
︙ | ︙ | |||
874 875 876 877 878 879 880 | return TCL_ERROR; } if (clsPtr->constructorPtr == NULL) { return TCL_OK; } procPtr = TclOOGetProcFromMethod(clsPtr->constructorPtr); if (procPtr == NULL) { | | | | 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 | return TCL_ERROR; } 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", NULL); return TCL_ERROR; } resultObjs[0] = Tcl_NewObj(); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { |
︙ | ︙ | |||
933 934 935 936 937 938 939 | } clsPtr = GetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]); if (hPtr == NULL) { | | | | | | 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 | } clsPtr = GetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown method \"%s\"", TclGetString(objv[2]))); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } resultObjs[0] = Tcl_NewObj(); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; |
︙ | ︙ | |||
1002 1003 1004 1005 1006 1007 1008 | } if (clsPtr->destructorPtr == NULL) { return TCL_OK; } procPtr = TclOOGetProcFromMethod(clsPtr->destructorPtr); if (procPtr == NULL) { | | | | 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 | } 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOOGetMethodBody(clsPtr->destructorPtr)); return TCL_OK; } |
︙ | ︙ | |||
1081 1082 1083 1084 1085 1086 1087 | } clsPtr = GetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]); if (hPtr == NULL) { | | | | | | 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 | } clsPtr = GetClassFromObj(interp, objv[1]); if (clsPtr == NULL) { return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown method \"%s\"", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", 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", -1)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, prefixObj); return TCL_OK; |
︙ | ︙ | |||
1265 1266 1267 1268 1269 1270 1271 | if (clsPtr == NULL) { return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]); if (hPtr == NULL) { unknownMethod: | | | | 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 | if (clsPtr == NULL) { return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]); if (hPtr == NULL) { unknownMethod: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown method \"%s\"", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", TclGetString(objv[2]), NULL); return TCL_ERROR; } mPtr = Tcl_GetHashValue(hPtr); if (mPtr->typePtr == NULL) { /* |
︙ | ︙ | |||
1490 1491 1492 1493 1494 1495 1496 | /* * Get the call context and render its call chain. */ contextPtr = TclOOGetCallContext(oPtr, objv[2], PUBLIC_METHOD, NULL); if (contextPtr == NULL) { | > | | 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 | /* * 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", -1)); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOORenderCallChain(interp, contextPtr->callPtr)); TclOODeleteContext(contextPtr); return TCL_OK; } |
︙ | ︙ | |||
1534 1535 1536 1537 1538 1539 1540 | /* * Get an render the stereotypical call chain. */ callPtr = TclOOGetStereotypeCallChain(clsPtr, objv[2], PUBLIC_METHOD); if (callPtr == NULL) { | > | | 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 | /* * 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", -1)); return TCL_ERROR; } Tcl_SetObjResult(interp, TclOORenderCallChain(interp, callPtr)); TclOODeleteChain(callPtr); return TCL_OK; } |
︙ | ︙ |
Changes to generic/tclOOMethod.c.
︙ | ︙ | |||
1325 1326 1327 1328 1329 1330 1331 | register ForwardMethod *fmPtr; Tcl_Obj *cmdObj; if (Tcl_ListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) { return NULL; } if (prefixLen < 1) { | > | < | 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 | 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", NULL); return NULL; } fmPtr = ckalloc(sizeof(ForwardMethod)); fmPtr->prefixObj = prefixObj; Tcl_ListObjIndex(interp, prefixObj, 0, &cmdObj); |
︙ | ︙ | |||
1367 1368 1369 1370 1371 1372 1373 | register ForwardMethod *fmPtr; Tcl_Obj *cmdObj; if (Tcl_ListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) { return NULL; } if (prefixLen < 1) { | > | < | 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 | 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", NULL); return NULL; } fmPtr = ckalloc(sizeof(ForwardMethod)); fmPtr->prefixObj = prefixObj; Tcl_ListObjIndex(interp, prefixObj, 0, &cmdObj); |
︙ | ︙ |
Changes to generic/tclOOStubLib.c.
︙ | ︙ | |||
49 50 51 52 53 54 55 | const char *errMsg = NULL; ClientData clientData = NULL; const char *actualVersion = Tcl_PkgRequireEx(interp, packageName,version, exact, &clientData); if (clientData == NULL) { Tcl_ResetResult(interp); | | | > | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | const char *errMsg = NULL; ClientData clientData = NULL; const char *actualVersion = Tcl_PkgRequireEx(interp, packageName,version, exact, &clientData); if (clientData == NULL) { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error loading %s package; package not present or incomplete", packageName)); return NULL; } else { const TclOOStubs * const stubsPtr = clientData; const TclOOIntStubs * const intStubsPtr = stubsPtr->hooks ? stubsPtr->hooks->tclOOIntStubs : NULL; if (!actualVersion) { |
︙ | ︙ | |||
72 73 74 75 76 77 78 | tclOOStubsPtr = stubsPtr; tclOOIntStubsPtr = intStubsPtr; return actualVersion; error: Tcl_ResetResult(interp); | | | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 | tclOOStubsPtr = stubsPtr; tclOOIntStubsPtr = intStubsPtr; return actualVersion; error: Tcl_ResetResult(interp); Tcl_SetObjResult(interp, Tcl_ObjPrintf("Error loading %s package" " (requested version '%s', loaded version '%s'): %s", packageName, version, actualVersion, errMsg)); return NULL; } } |
Changes to generic/tclObj.c.
︙ | ︙ | |||
4458 4459 4460 4461 4462 4463 4464 | int Tcl_RepresentationCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { | | | < < < < | | > | > | | | | | | > < < | | | > | > > | 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 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 | int Tcl_RepresentationCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { char ptrBuffer[2*TCL_INTEGER_SPACE+6]; Tcl_Obj *descObj; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "value"); return TCL_ERROR; } /* * Value is a bignum with a refcount of 14, object pointer at 0x12345678, * internal representation 0x45671234:0x98765432, string representation * "1872361827361287" */ sprintf(ptrBuffer, "%p", (void *) objv[1]); descObj = Tcl_ObjPrintf("value is a %s with a refcount of %d," " object pointer at %s", objv[1]->typePtr ? objv[1]->typePtr->name : "pure string", objv[1]->refCount, ptrBuffer); if (objv[1]->typePtr) { sprintf(ptrBuffer, "%p:%p", (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 \"", -1); Tcl_AppendLimitedToObj(descObj, objv[1]->bytes, objv[1]->length, 16, "..."); Tcl_AppendToObj(descObj, "\"", -1); } else { Tcl_AppendToObj(descObj, ", no string representation", -1); } Tcl_SetObjResult(interp, descObj); return TCL_OK; } /* * Local Variables: * mode: c * c-basic-offset: 4 |
︙ | ︙ |
Changes to generic/tclParse.c.
︙ | ︙ | |||
254 255 256 257 258 259 260 | * command. */ 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) { | > | | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | * command. */ 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", -1)); } return TCL_ERROR; } if (numBytes < 0) { numBytes = strlen(start); } TclParseInit(interp, start, numBytes, parsePtr); |
︙ | ︙ | |||
564 565 566 567 568 569 570 | if ((type & terminators) != 0) { parsePtr->term = src; src++; break; } if (src[-1] == '"') { if (interp != NULL) { | > | < > | < | 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 | if ((type & terminators) != 0) { parsePtr->term = src; src++; break; } if (src[-1] == '"') { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "extra characters after close-quote", -1)); } parsePtr->errorType = TCL_PARSE_QUOTE_EXTRA; } else { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "extra characters after close-brace", -1)); } parsePtr->errorType = TCL_PARSE_BRACE_EXTRA; } parsePtr->term = src; goto error; } |
︙ | ︙ | |||
1171 1172 1173 1174 1175 1176 1177 | if ((nestedPtr->term < parsePtr->end) && (*(nestedPtr->term) == ']') && !(nestedPtr->incomplete)) { break; } if (numBytes == 0) { if (parsePtr->interp != NULL) { | | | | 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 | if ((nestedPtr->term < parsePtr->end) && (*(nestedPtr->term) == ']') && !(nestedPtr->incomplete)) { break; } if (numBytes == 0) { if (parsePtr->interp != NULL) { Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( "missing close-bracket", -1)); } parsePtr->errorType = TCL_PARSE_MISSING_BRACKET; parsePtr->term = tokenPtr->start; parsePtr->incomplete = 1; TclStackFree(parsePtr->interp, nestedPtr); return TCL_ERROR; } |
︙ | ︙ | |||
1407 1408 1409 1410 1411 1412 1413 | while (numBytes && (*src != '}')) { numBytes--; src++; } if (numBytes == 0) { if (parsePtr->interp != NULL) { | | | | 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 | while (numBytes && (*src != '}')) { numBytes--; src++; } if (numBytes == 0) { if (parsePtr->interp != NULL) { Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( "missing close-brace for variable name", -1)); } parsePtr->errorType = TCL_PARSE_MISSING_VAR_BRACE; parsePtr->term = tokenPtr->start-1; parsePtr->incomplete = 1; goto error; } tokenPtr->size = src - tokenPtr->start; |
︙ | ︙ | |||
1475 1476 1477 1478 1479 1480 1481 | 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) { | | | | 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 | 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 )", -1)); } parsePtr->errorType = TCL_PARSE_MISSING_PAREN; parsePtr->term = src; parsePtr->incomplete = 1; goto error; } src = parsePtr->term + 1; |
︙ | ︙ | |||
1751 1752 1753 1754 1755 1756 1757 | * Skip straight to the exit code since we have no interpreter to put * error message in. */ goto error; } | > | | 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 | * Skip straight to the exit code since we have no interpreter to put * error message in. */ goto error; } Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj( "missing close-brace", -1)); /* * 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. */ |
︙ | ︙ | |||
1773 1774 1775 1776 1777 1778 1779 | openBrace = 1; break; case '\n': openBrace = 0; break; case '#' : if (openBrace && TclIsSpaceProc(src[-1])) { | | | | 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 | openBrace = 1; break; case '\n': openBrace = 0; break; case '#' : if (openBrace && TclIsSpaceProc(src[-1])) { Tcl_AppendToObj(Tcl_GetObjResult(parsePtr->interp), ": possible unbalanced brace in comment", -1); goto error; } break; } } } |
︙ | ︙ | |||
1853 1854 1855 1856 1857 1858 1859 | if (TCL_OK != ParseTokens(start+1, numBytes-1, TYPE_QUOTE, TCL_SUBST_ALL, parsePtr)) { goto error; } if (*parsePtr->term != '"') { if (parsePtr->interp != NULL) { | | > | 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 | 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 \"", -1)); } parsePtr->errorType = TCL_PARSE_MISSING_QUOTE; parsePtr->term = start; parsePtr->incomplete = 1; goto error; } if (termPtr != NULL) { |
︙ | ︙ |
Changes to generic/tclPathObj.c.
︙ | ︙ | |||
1488 1489 1490 1491 1492 1493 1494 | * Free old representation */ if (pathPtr->typePtr != NULL) { if (pathPtr->bytes == NULL) { if (pathPtr->typePtr->updateStringProc == NULL) { if (interp != NULL) { | | < | | 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 | * Free old representation */ 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", -1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "WTF", NULL); } return TCL_ERROR; } pathPtr->typePtr->updateStringProc(pathPtr); } |
︙ | ︙ | |||
2364 2365 2366 2367 2368 2369 2370 | if (split != len) { name[split] = separator; } dir = TclGetEnv("HOME", &dirString); if (dir == NULL) { if (interp) { | | | | | < | | 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 | if (split != len) { name[split] = separator; } dir = TclGetEnv("HOME", &dirString); if (dir == NULL) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "couldn't find HOME environment variable to" " expand path", -1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "HOMELESS", NULL); } return TCL_ERROR; } Tcl_DStringInit(&temp); Tcl_JoinPath(1, &dir, &temp); Tcl_DStringFree(&dirString); } else { /* * We have a user name '~user' */ Tcl_DStringInit(&temp); if (TclpGetUserHome(name+1, &temp) == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "user \"%s\" doesn't exist", name+1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "NOUSER", NULL); } Tcl_DStringFree(&temp); if (split != len) { name[split] = separator; } |
︙ | ︙ |
Changes to generic/tclPipe.c.
︙ | ︙ | |||
102 103 104 105 106 107 108 | if (file == NULL) { Tcl_Obj *msg; Tcl_GetChannelError(chan, &msg); if (msg) { Tcl_SetObjResult(interp, msg); } else { | | > | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | if (file == NULL) { Tcl_Obj *msg; Tcl_GetChannelError(chan, &msg); if (msg) { Tcl_SetObjResult(interp, msg); } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel \"%s\" wasn't opened for %s", Tcl_GetChannelName(chan), ((writing) ? "writing" : "reading"))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "BADCHAN", NULL); } return NULL; } *releasePtr = 1; if (writing) { |
︙ | ︙ | |||
137 138 139 140 141 142 143 | name = Tcl_TranslateFileName(interp, spec, &nameString); if (name == NULL) { return NULL; } file = TclpOpenFile(name, flags); Tcl_DStringFree(&nameString); if (file == NULL) { | | > | | | | | 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 | name = Tcl_TranslateFileName(interp, spec, &nameString); if (name == NULL) { return NULL; } file = TclpOpenFile(name, flags); Tcl_DStringFree(&nameString); if (file == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't %s file \"%s\": %s", (writing ? "write" : "read"), spec, Tcl_PosixError(interp))); return NULL; } *closePtr = 1; } return file; badLastArg: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't specify \"%s\" as last word in command", arg)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "SYNTAX", NULL); return NULL; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
300 301 302 303 304 305 306 | * remind people that ECHILD errors can occur on some * systems if SIGCHLD isn't in its default state. */ msg = "child process lost (is SIGCHLD ignored or trapped?)"; } | > | < | 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | * remind people that ECHILD errors can occur on some * systems if SIGCHLD isn't in its default state. */ msg = "child process lost (is SIGCHLD ignored or trapped?)"; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error waiting for process to exit: %s", msg)); } continue; } /* * Create error messages for unusual process exits. An extra newline * gets appended to each error message, but it gets removed below (in |
︙ | ︙ | |||
331 332 333 334 335 336 337 | } else if (interp != NULL) { const char *p; if (WIFSIGNALED(waitStatus)) { p = Tcl_SignalMsg(WTERMSIG(waitStatus)); Tcl_SetErrorCode(interp, "CHILDKILLED", msg1, Tcl_SignalId(WTERMSIG(waitStatus)), p, NULL); | > | > | < | | | 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 | } else if (interp != NULL) { const char *p; if (WIFSIGNALED(waitStatus)) { p = Tcl_SignalMsg(WTERMSIG(waitStatus)); Tcl_SetErrorCode(interp, "CHILDKILLED", msg1, Tcl_SignalId(WTERMSIG(waitStatus)), p, NULL); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "child killed: %s\n", p)); } else if (WIFSTOPPED(waitStatus)) { 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "ODDWAITRESULT", msg1, NULL); } } } } |
︙ | ︙ | |||
370 371 372 373 374 375 376 | Tcl_Seek(errorChan, (Tcl_WideInt)0, SEEK_SET); objPtr = Tcl_NewObj(); count = Tcl_ReadChars(errorChan, objPtr, -1, 0); if (count < 0) { result = TCL_ERROR; Tcl_DecrRefCount(objPtr); Tcl_ResetResult(interp); | > | | > | | 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 | Tcl_Seek(errorChan, (Tcl_WideInt)0, SEEK_SET); objPtr = Tcl_NewObj(); count = Tcl_ReadChars(errorChan, objPtr, -1, 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))); } else if (count > 0) { anyErrorInfo = 1; Tcl_SetObjResult(interp, objPtr); result = TCL_ERROR; } else { Tcl_DecrRefCount(objPtr); } } Tcl_Close(NULL, errorChan); } /* * 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", -1)); } return result; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
538 539 540 541 542 543 544 | switch (*p++) { case '|': if (*p == '&') { p++; } if (*p == '\0') { if ((i == (lastBar + 1)) || (i == (argc - 1))) { | > | < | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 | switch (*p++) { 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "PIPESYNTAX", NULL); goto error; } } lastBar = i; cmdCount++; |
︙ | ︙ | |||
566 567 568 569 570 571 572 | if (*p == '<') { inputFile = NULL; inputLiteral = p + 1; skip = 1; if (*inputLiteral == '\0') { inputLiteral = ((i + 1) == argc) ? NULL : argv[i + 1]; if (inputLiteral == NULL) { | | | > | 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 | if (*p == '<') { inputFile = NULL; inputLiteral = p + 1; skip = 1; if (*inputLiteral == '\0') { inputLiteral = ((i + 1) == argc) ? NULL : argv[i + 1]; if (inputLiteral == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't specify \"%s\" as last word in command", argv[i])); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "PIPESYNTAX", NULL); goto error; } skip = 2; } } else { |
︙ | ︙ | |||
676 677 678 679 680 681 682 | /* * Special case handling of 2>@1 to redirect stderr to the * exec/open output pipe as well. This is meant for the end of * the command string, otherwise use |& between commands. */ if (i != argc-1) { | | | > | 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | /* * Special case handling of 2>@1 to redirect stderr to the * exec/open output pipe as well. This is meant for the end of * the command string, otherwise use |& between commands. */ if (i != argc-1) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "must specify \"%s\" as last word in command", argv[i])); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "PIPESYNTAX", NULL); goto error; } errorFile = outputFile; errorToOutput = 2; skip = 1; |
︙ | ︙ | |||
718 719 720 721 722 723 724 | } if (needCmd) { /* * We had a bar followed only by redirections. */ | > | < | | | | | | | 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 | } if (needCmd) { /* * We had a bar followed only by redirections. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal use of | or |& in command", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "PIPESYNTAX", NULL); goto error; } if (inputFile == NULL) { if (inputLiteral != NULL) { /* * The input for the first process is immediate data coming from * Tcl. Create a temporary file for it and put the data into the * file. */ inputFile = TclpCreateTempFile(inputLiteral); if (inputFile == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't create input file for command: %s", Tcl_PosixError(interp))); goto error; } inputClose = 1; } else if (inPipePtr != NULL) { /* * The input for the first process in the pipeline is to come from * a pipe that can be written from by the caller. */ if (TclpCreatePipe(&inputFile, inPipePtr) == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't create input pipe for command: %s", Tcl_PosixError(interp))); goto error; } inputClose = 1; } else { /* * The input for the first process comes from stdin. */ |
︙ | ︙ | |||
777 778 779 780 781 782 783 | if (outPipePtr != NULL) { /* * Output from the last process in the pipeline is to go to a pipe * that can be read by the caller. */ if (TclpCreatePipe(outPipePtr, &outputFile) == 0) { | | | | | 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 | if (outPipePtr != NULL) { /* * Output from the last process in the pipeline is to go to a pipe * that can be read by the caller. */ if (TclpCreatePipe(outPipePtr, &outputFile) == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't create output pipe for command: %s", Tcl_PosixError(interp))); goto error; } outputClose = 1; } else { /* * The output for the last process goes to stdout. */ |
︙ | ︙ | |||
817 818 819 820 821 822 823 | * cause the pipeline to deadlock: we'd be waiting for processes * to complete before reading stderr, and processes couldn't * complete because stderr was backed up. */ errorFile = TclpCreateTempFile(NULL); if (errorFile == NULL) { | | | | | 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 | * cause the pipeline to deadlock: we'd be waiting for processes * to complete before reading stderr, and processes couldn't * complete because stderr was backed up. */ errorFile = TclpCreateTempFile(NULL); if (errorFile == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't create error file for command: %s", Tcl_PosixError(interp))); goto error; } *errFilePtr = errorFile; } else { /* * Errors from the pipeline go to stderr. */ |
︙ | ︙ | |||
890 891 892 893 894 895 896 | */ if (lastArg == argc) { curOutFile = outputFile; } else { argv[lastArg] = NULL; if (TclpCreatePipe(&pipeIn, &curOutFile) == 0) { | | | | 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 | */ if (lastArg == argc) { curOutFile = outputFile; } else { argv[lastArg] = NULL; if (TclpCreatePipe(&pipeIn, &curOutFile) == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't create pipe: %s", Tcl_PosixError(interp))); goto error; } } if (joinThisError != 0) { curErrFile = curOutFile; } else { |
︙ | ︙ | |||
1070 1071 1072 1073 1074 1075 1076 | /* * Verify that the pipes that were created satisfy the readable/writable * constraints. */ if (flags & TCL_ENFORCE_MODE) { if ((flags & TCL_STDOUT) && (outPipe == NULL)) { | > | | > | | > | < | 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 | /* * Verify that the pipes that were created satisfy the readable/writable * 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", -1)); 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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "NOPIPE", NULL); goto error; } return channel; error: if (numPids > 0) { |
︙ | ︙ |
Changes to generic/tclPkg.c.
︙ | ︙ | |||
150 151 152 153 154 155 156 | if (res == 0) { if (clientData != NULL) { pkgPtr->clientData = clientData; } return TCL_OK; } | > | | | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | if (res == 0) { if (clientData != NULL) { pkgPtr->clientData = clientData; } return TCL_OK; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "conflicting versions provided for package \"%s\": %s, then %s", name, pkgPtr->version, version)); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
280 281 282 283 284 285 286 | * message. That's the only flaw corrected; other problems with * initialization of the Tcl library are not remedied, so be very * careful about adding any other calls here without checking how they * behave when initialization is incomplete. */ tclEmptyStringRep = &tclEmptyString; | | | | | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | * message. That's the only flaw corrected; other problems with * initialization of the Tcl library are not remedied, so be very * careful about adding any other calls here without checking how they * behave when initialization is incomplete. */ tclEmptyStringRep = &tclEmptyString; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "Cannot load package \"%s\" in standalone executable:" " This package is not compiled with stub support", name)); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNSTUBBED", NULL); return NULL; } /* * Translate between old and new API, and defer to the new function. */ |
︙ | ︙ | |||
370 371 372 373 374 375 376 | /* * Check whether we're already attempting to load some version of this * package (circular dependency detection). */ if (pkgPtr->clientData != NULL) { | > | | | | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | /* * Check whether we're already attempting to load some version of this * package (circular dependency detection). */ if (pkgPtr->clientData != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "circular package dependency:" " attempt to provide %s %s requires %s", name, (char *) pkgPtr->clientData, name)); AddRequirementsToResult(interp, reqc, reqv); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "CIRCULARITY", NULL); return NULL; } /* * The package isn't yet present. Search the list of available |
︙ | ︙ | |||
490 491 492 493 494 495 496 | Tcl_Release(script); pkgPtr = FindPackage(interp, name); if (code == TCL_OK) { Tcl_ResetResult(interp); if (pkgPtr->version == NULL) { code = TCL_ERROR; | > | < | | | | > | | < | | | | | 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 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | Tcl_Release(script); pkgPtr = FindPackage(interp, name); if (code == TCL_OK) { Tcl_ResetResult(interp); if (pkgPtr->version == NULL) { code = TCL_ERROR; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "attempt to provide package %s %s failed:" " no version of package %s provided", name, versionToProvide, name)); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNPROVIDED", NULL); } else { char *pvi, *vi; if (CheckVersionAndConvert(interp, pkgPtr->version, &pvi, NULL) != TCL_OK) { code = TCL_ERROR; } else if (CheckVersionAndConvert(interp, versionToProvide, &vi, NULL) != TCL_OK) { ckfree(pvi); code = TCL_ERROR; } else { int res = CompareVersions(pvi, vi, NULL); ckfree(pvi); ckfree(vi); if (res != 0) { code = TCL_ERROR; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "attempt to provide package %s %s failed:" " package %s %s provided instead", name, versionToProvide, name, pkgPtr->version)); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "WRONGPROVIDE", NULL); } } } } else if (code != TCL_ERROR) { Tcl_Obj *codePtr = Tcl_NewIntObj(code); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "attempt to provide package %s %s failed:" " bad return code: %s", name, versionToProvide, TclGetString(codePtr))); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL); TclDecrRefCount(codePtr); code = TCL_ERROR; } if (code == TCL_ERROR) { Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( |
︙ | ︙ | |||
587 588 589 590 591 592 593 | AddRequirementsToDString(&command, reqc, reqv); code = Tcl_EvalEx(interp, Tcl_DStringValue(&command), Tcl_DStringLength(&command), TCL_EVAL_GLOBAL); Tcl_DStringFree(&command); if ((code != TCL_OK) && (code != TCL_ERROR)) { | < < | | < < > | > | | | 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 | AddRequirementsToDString(&command, reqc, reqv); code = Tcl_EvalEx(interp, Tcl_DStringValue(&command), Tcl_DStringLength(&command), TCL_EVAL_GLOBAL); Tcl_DStringFree(&command); if ((code != TCL_OK) && (code != TCL_ERROR)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad return code: %d", code)); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL); code = TCL_ERROR; } if (code == TCL_ERROR) { Tcl_AddErrorInfo(interp, "\n (\"package unknown\" script)"); return NULL; } Tcl_ResetResult(interp); } } if (pkgPtr->version == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't find package %s", name)); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNFOUND", NULL); AddRequirementsToResult(interp, reqc, reqv); return NULL; } /* * At this point we know that the package is present. Make sure that the * provided version meets the current requirements. */ if (reqc != 0) { CheckVersionAndConvert(interp, pkgPtr->version, &pkgVersionI, NULL); satisfies = SomeRequirementSatisfied(pkgVersionI, reqc, reqv); ckfree(pkgVersionI); if (!satisfies) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "version conflict for package \"%s\": have %s, need", name, pkgPtr->version)); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT", NULL); AddRequirementsToResult(interp, reqc, reqv); return NULL; } } |
︙ | ︙ | |||
717 718 719 720 721 722 723 | NULL); } return foundVersion; } } if (version != NULL) { | | | > | | 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 | NULL); } return foundVersion; } } if (version != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "package %s %s is not present", name, version)); } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "package %s is not present", name)); } Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PACKAGE", name, NULL); return NULL; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
846 847 848 849 850 851 852 | res = CompareVersions(avi, argv3i, NULL); ckfree(avi); if (res == 0){ if (objc == 4) { ckfree(argv3i); | > | | 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 | res = CompareVersions(avi, argv3i, NULL); ckfree(avi); if (res == 0){ if (objc == 4) { ckfree(argv3i); Tcl_SetObjResult(interp, Tcl_NewStringObj(availPtr->script, -1)); return TCL_OK; } Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC); break; } } ckfree(argv3i); |
︙ | ︙ | |||
951 952 953 954 955 956 957 | } argv2 = TclGetString(objv[2]); if (objc == 3) { hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2); if (hPtr != NULL) { pkgPtr = Tcl_GetHashValue(hPtr); if (pkgPtr->version != NULL) { | > | | 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 | } 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, -1)); } } return TCL_OK; } argv3 = TclGetString(objv[3]); if (CheckVersionAndConvert(interp, argv3, NULL, NULL) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
1013 1014 1015 1016 1017 1018 1019 | } break; case PKG_UNKNOWN: { int length; if (objc == 2) { if (iPtr->packageUnknown != NULL) { | > | | 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 | } break; case PKG_UNKNOWN: { int length; if (objc == 2) { if (iPtr->packageUnknown != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(iPtr->packageUnknown, -1)); } } else if (objc == 3) { if (iPtr->packageUnknown != NULL) { ckfree(iPtr->packageUnknown); } argv2 = Tcl_GetStringFromObj(objv[2], &length); if (argv2[0] == 0) { |
︙ | ︙ | |||
1347 1348 1349 1350 1351 1352 1353 | *stable = !hasunstable; } return TCL_OK; } error: ckfree(ibuf); | > | < | 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 | *stable = !hasunstable; } return TCL_OK; } error: ckfree(ibuf); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected version number but got \"%s\"", string)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "VERSION", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1610 1611 1612 1613 1614 1615 1616 | } if (strchr(dash+1, '-') != NULL) { /* * More dashes found after the first. This is wrong. */ | > | < | 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 | } if (strchr(dash+1, '-') != NULL) { /* * More dashes found after the first. This is wrong. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected versionMin-versionMax but got \"%s\"", string)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "VERSIONRANGE", NULL); return TCL_ERROR; } /* * Exactly one dash is present. Copy the string, split at the location of * dash and check that both parts are versions. Note that the max part can |
︙ | ︙ | |||
1663 1664 1665 1666 1667 1668 1669 | AddRequirementsToResult( Tcl_Interp *interp, int reqc, /* Requirements constraining the desired * version. */ Tcl_Obj *const reqv[]) /* 0 means to use the latest version * available. */ { | | | | < | | | | | | < | 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 | AddRequirementsToResult( Tcl_Interp *interp, int reqc, /* Requirements constraining the desired * version. */ Tcl_Obj *const reqv[]) /* 0 means to use the latest version * available. */ { Tcl_Obj *result = Tcl_GetObjResult(interp); int 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)); } else { Tcl_AppendPrintfToObj(result, " %s", v); } } } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1704 1705 1706 1707 1708 1709 1710 | AddRequirementsToDString( Tcl_DString *dsPtr, int reqc, /* Requirements constraining the desired * version. */ Tcl_Obj *const reqv[]) /* 0 means to use the latest version * available. */ { | < | > | 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 | AddRequirementsToDString( Tcl_DString *dsPtr, int reqc, /* Requirements constraining the desired * version. */ Tcl_Obj *const reqv[]) /* 0 means to use the latest version * available. */ { int i; if (reqc > 0) { for (i = 0; i < reqc; i++) { TclDStringAppendLiteral(dsPtr, " "); TclDStringAppendObj(dsPtr, reqv[i]); } } else { TclDStringAppendLiteral(dsPtr, " 0-"); } |
︙ | ︙ |
Changes to generic/tclProc.c.
︙ | ︙ | |||
148 149 150 151 152 153 154 | */ fullName = TclGetString(objv[1]); TclGetNamespaceForQualName(interp, fullName, NULL, 0, &nsPtr, &altNsPtr, &cxtNsPtr, &procName); if (nsPtr == NULL) { | | | > | | > > | | < | 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 | */ fullName = TclGetString(objv[1]); TclGetNamespaceForQualName(interp, fullName, NULL, 0, &nsPtr, &altNsPtr, &cxtNsPtr, &procName); if (nsPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create procedure \"%s\": unknown namespace", fullName)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL); return TCL_ERROR; } if (procName == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create procedure \"%s\": bad procedure name", fullName)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL); return TCL_ERROR; } if ((nsPtr != iPtr->globalNsPtr) && (procName != NULL) && (procName[0] == ':')) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create procedure \"%s\" in non-global namespace with" " name starting with \":\"", procName)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL); return TCL_ERROR; } /* * Create the data structure to represent the procedure. */ |
︙ | ︙ | |||
514 515 516 517 518 519 520 | result = Tcl_SplitList(interp, argArray[i], &fieldCount, &fieldValues); if (result != TCL_OK) { goto procError; } if (fieldCount > 2) { ckfree(fieldValues); | | | | > | | 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 | result = Tcl_SplitList(interp, argArray[i], &fieldCount, &fieldValues); if (result != TCL_OK) { goto procError; } if (fieldCount > 2) { ckfree(fieldValues); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "too many fields in argument specifier \"%s\"", argArray[i])); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC", "FORMALARGUMENTFORMAT", NULL); goto procError; } nameLength = strlen(fieldValues[0]); if (fieldCount == 2) { |
︙ | ︙ | |||
549 550 551 552 553 554 555 | if (*p == '(') { const char *q = p; do { q++; } while (*q != '\0'); q--; if (*q == ')') { /* We have an array element. */ | > | | > | | | 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 | if (*p == '(') { const char *q = p; do { q++; } while (*q != '\0'); q--; if (*q == ')') { /* We have an array element. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "formal parameter \"%s\" is an array element", fieldValues[0])); ckfree(fieldValues); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC", "FORMALARGUMENTFORMAT", NULL); goto procError; } } else if ((*p == ':') && (*(p+1) == ':')) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "formal parameter \"%s\" is not a simple name", fieldValues[0])); ckfree(fieldValues); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC", "FORMALARGUMENTFORMAT", NULL); goto procError; } p++; } |
︙ | ︙ | |||
763 764 765 766 767 768 769 | goto levelError; } *framePtrPtr = framePtr; return result; levelError: | | < | 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 | goto levelError; } *framePtrPtr = framePtr; return result; levelError: Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad level \"%s\"", name)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "STACKLEVEL", NULL); return -1; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
896 897 898 899 900 901 902 | if (framePtr == NULL) { goto levelError; } *framePtrPtr = framePtr; return result; levelError: | | < | 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 | if (framePtr == NULL) { goto levelError; } *framePtrPtr = framePtr; return result; levelError: Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad level \"%s\"", name)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "STACKLEVEL", NULL); return -1; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1875 1876 1877 1878 1879 1880 1881 | case TCL_CONTINUE: case TCL_BREAK: /* * It's an error to get to this point from a 'break' or 'continue', so * transform to an error now. */ | | | | < | 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 | case TCL_CONTINUE: case TCL_BREAK: /* * It's an error to get to this point from a 'break' or 'continue', so * transform to an error now. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invoked \"%s\" outside of a loop", ((result == TCL_BREAK) ? "break" : "continue"))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "UNEXPECTED", NULL); result = TCL_ERROR; /* * Fall through to the TCL_ERROR handling code. */ |
︙ | ︙ | |||
1995 1996 1997 1998 1999 2000 2001 | && (codePtr->nsPtr == nsPtr) && (codePtr->nsEpoch == nsPtr->resolverEpoch)) { return TCL_OK; } if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) { if ((Interp *) *codePtr->interpHandle != iPtr) { | | | | 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 | && (codePtr->nsPtr == nsPtr) && (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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC", "CROSSINTERPBYTECODE", NULL); return TCL_ERROR; } codePtr->compileEpoch = iPtr->compileEpoch; codePtr->nsPtr = nsPtr; } else { |
︙ | ︙ | |||
2928 2929 2930 2931 2932 2933 2934 | if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "procName"); return TCL_ERROR; } procPtr = TclFindProc((Interp *) interp, TclGetString(objv[2])); if (procPtr == NULL) { | | | | 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 | if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "procName"); return TCL_ERROR; } procPtr = TclFindProc((Interp *) interp, TclGetString(objv[2])); if (procPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" isn't a procedure", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROC", TclGetString(objv[2]), NULL); return TCL_ERROR; } /* * Compile (if uncompiled) and disassemble a procedure. |
︙ | ︙ | |||
2978 2979 2980 2981 2982 2983 2984 | */ oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]); if (oPtr == NULL) { return TCL_ERROR; } if (oPtr->classPtr == NULL) { | | | | 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 | */ oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]); if (oPtr == NULL) { return TCL_ERROR; } if (oPtr->classPtr == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" is not a class", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS", TclGetString(objv[2]), NULL); return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&oPtr->classPtr->classMethods, (char *) objv[3]); goto methodBody; |
︙ | ︙ | |||
3013 3014 3015 3016 3017 3018 3019 | /* * Compile (if necessary) and disassemble a method body. */ methodBody: if (hPtr == NULL) { unknownMethod: | | | | | | 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 | /* * Compile (if necessary) and disassemble a method body. */ methodBody: if (hPtr == NULL) { unknownMethod: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown method \"%s\"", TclGetString(objv[3]))); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", "METHODTYPE", NULL); return TCL_ERROR; } if (procPtr->bodyPtr->typePtr != &tclByteCodeType) { Command cmd; |
︙ | ︙ | |||
3057 3058 3059 3060 3061 3062 3063 | /* * Do the actual disassembly. */ if (((ByteCode *) codeObjPtr->internalRep.otherValuePtr)->flags & TCL_BYTECODE_PRECOMPILED) { | > | | 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 | /* * Do the actual disassembly. */ if (((ByteCode *) codeObjPtr->internalRep.otherValuePtr)->flags & TCL_BYTECODE_PRECOMPILED) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not disassemble prebuilt bytecode", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", "BYTECODE", NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, TclDisassembleByteCodeObj(codeObjPtr)); return TCL_OK; } |
︙ | ︙ |
Changes to generic/tclRegexp.c.
︙ | ︙ | |||
710 711 712 713 714 715 716 | void TclRegError( Tcl_Interp *interp, /* Interpreter for error reporting. */ const char *msg, /* Message to prepend to error. */ int status) /* Status code to report. */ { char buf[100]; /* ample in practice */ | | | | 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | void TclRegError( Tcl_Interp *interp, /* Interpreter for error reporting. */ const char *msg, /* Message to prepend to error. */ int status) /* Status code to report. */ { char buf[100]; /* ample in practice */ char cbuf[TCL_INTEGER_SPACE]; size_t n; const char *p; Tcl_ResetResult(interp); n = TclReError(status, NULL, buf, sizeof(buf)); p = (n > sizeof(buf)) ? "..." : ""; Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s%s%s", msg, buf, p)); sprintf(cbuf, "%d", status); (void) TclReError(REG_ITOA, NULL, cbuf, sizeof(cbuf)); Tcl_SetErrorCode(interp, "REGEXP", cbuf, buf, NULL); } /* |
︙ | ︙ |
Changes to generic/tclResult.c.
︙ | ︙ | |||
376 377 378 379 380 381 382 | Tcl_DiscardResult( Tcl_SavedResult *statePtr) /* State returned by Tcl_SaveResult. */ { TclDecrRefCount(statePtr->objResultPtr); if (statePtr->result == statePtr->appendResult) { ckfree(statePtr->appendResult); | | < | | | < | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 | Tcl_DiscardResult( Tcl_SavedResult *statePtr) /* State returned by Tcl_SaveResult. */ { TclDecrRefCount(statePtr->objResultPtr); if (statePtr->result == statePtr->appendResult) { ckfree(statePtr->appendResult); } else if (statePtr->freeProc == TCL_DYNAMIC) { ckfree(statePtr->result); } else if (statePtr->freeProc) { statePtr->freeProc(statePtr->result); } } /* *---------------------------------------------------------------------- * * Tcl_SetResult -- |
︙ | ︙ | |||
581 582 583 584 585 586 587 | int length; /* * If the string result is non-empty, move the string result to the object * result, then reset the string result. */ | | | | 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 | int length; /* * If the string result is non-empty, move the string result to the object * result, then reset the string result. */ if (iPtr->result[0] != 0) { ResetObjResult(iPtr); objResultPtr = iPtr->objResultPtr; length = strlen(iPtr->result); TclInitStringRep(objResultPtr, iPtr->result, length); if (iPtr->freeProc != NULL) { if (iPtr->freeProc == TCL_DYNAMIC) { ckfree(iPtr->result); } else { iPtr->freeProc(iPtr->result); } iPtr->freeProc = 0; } iPtr->result = iPtr->resultSpace; iPtr->result[0] = 0; } return iPtr->objResultPtr; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1102 1103 1104 1105 1106 1107 1108 | } /* *---------------------------------------------------------------------- * * Tcl_GetErrorLine -- * | | < < | < < | 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 | } /* *---------------------------------------------------------------------- * * Tcl_GetErrorLine -- * * Returns the line number associated with the current error. * *---------------------------------------------------------------------- */ int Tcl_GetErrorLine( Tcl_Interp *interp) { return ((Interp *) interp)->errorLine; } /* *---------------------------------------------------------------------- * * Tcl_SetErrorLine -- * * Sets the line number associated with the current error. * *---------------------------------------------------------------------- */ void Tcl_SetErrorLine( Tcl_Interp *interp, |
︙ | ︙ | |||
1270 1271 1272 1273 1274 1275 1276 | } if (code == TCL_ERROR) { if (iPtr->errorInfo) { Tcl_DecrRefCount(iPtr->errorInfo); iPtr->errorInfo = NULL; } | | > | > > > | > > > | > > | > | > | > | 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 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 | } if (code == TCL_ERROR) { if (iPtr->errorInfo) { Tcl_DecrRefCount(iPtr->errorInfo); iPtr->errorInfo = NULL; } Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORINFO], &valuePtr); if (valuePtr != NULL) { int 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) { int len, valueObjc; Tcl_Obj **valueObjv; if (Tcl_IsShared(iPtr->errorStack)) { Tcl_Obj *newObj; newObj = Tcl_DuplicateObj(iPtr->errorStack); Tcl_DecrRefCount(iPtr->errorStack); Tcl_IncrRefCount(newObj); iPtr->errorStack = newObj; } /* * List extraction done after duplication to avoid moving the rug * if someone does [return -errorstack [info errorstack]] */ if (Tcl_ListObjGetElements(interp, valuePtr, &valueObjc, &valueObjv) == TCL_ERROR) { return TCL_ERROR; } iPtr->resetErrorStack = 0; Tcl_ListObjLength(interp, iPtr->errorStack, &len); /* * Reset while keeping the list intrep as much as possible. */ Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, valueObjc, valueObjv); } Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORCODE], &valuePtr); if (valuePtr != NULL) { Tcl_SetObjErrorCode(interp, valuePtr); } else { Tcl_SetErrorCode(interp, "NONE", NULL); } Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORLINE], &valuePtr); if (valuePtr != NULL) { TclGetIntFromObj(NULL, valuePtr, &iPtr->errorLine); } } if (level != 0) { iPtr->returnLevel = level; iPtr->returnCode = code; |
︙ | ︙ | |||
1386 1387 1388 1389 1390 1391 1392 | nestedOptions: if (TCL_ERROR == Tcl_DictObjFirst(NULL, dict, &search, &keyPtr, &valuePtr, &done)) { /* * Value is not a legal dictionary. */ | | < | | | 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 | nestedOptions: if (TCL_ERROR == Tcl_DictObjFirst(NULL, dict, &search, &keyPtr, &valuePtr, &done)) { /* * Value is not a legal dictionary. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad %s value: expected dictionary but got \"%s\"", compare, TclGetString(objv[1]))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_OPTIONS", NULL); goto error; } while (!done) { Tcl_DictObjPut(NULL, returnOpts, keyPtr, valuePtr); |
︙ | ︙ | |||
1418 1419 1420 1421 1422 1423 1424 | /* * Check for bogus -code value. */ Tcl_DictObjGet(NULL, returnOpts, keys[KEY_CODE], &valuePtr); if (valuePtr != NULL) { | | > | < | | | | | | > | | | < | | | | | 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 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 | /* * Check for bogus -code value. */ Tcl_DictObjGet(NULL, returnOpts, keys[KEY_CODE], &valuePtr); if (valuePtr != NULL) { if (TclGetCompletionCodeFromObj(interp, valuePtr, &code) == TCL_ERROR) { goto error; } Tcl_DictObjRemove(NULL, returnOpts, keys[KEY_CODE]); } /* * Check for bogus -level value. */ Tcl_DictObjGet(NULL, returnOpts, keys[KEY_LEVEL], &valuePtr); if (valuePtr != NULL) { if ((TCL_ERROR == TclGetIntFromObj(NULL, valuePtr, &level)) || (level < 0)) { /* * Value is not a legal level. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad -level value: expected non-negative integer but got" " \"%s\"", TclGetString(valuePtr))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_LEVEL", NULL); goto error; } Tcl_DictObjRemove(NULL, returnOpts, keys[KEY_LEVEL]); } /* * Check for bogus -errorcode value. */ Tcl_DictObjGet(NULL, returnOpts, keys[KEY_ERRORCODE], &valuePtr); if (valuePtr != NULL) { int 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) { int 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))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "NONLIST_ERRORSTACK", NULL); goto error; } if (length % 2) { /* * Errorstack must always be an even-sized list */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "forbidden odd-sized list for -errorstack: \"%s\"", TclGetString(valuePtr))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "ODDSIZEDLIST_ERRORSTACK", NULL); goto error; } } /* |
︙ | ︙ | |||
1597 1598 1599 1600 1601 1602 1603 | } /* *------------------------------------------------------------------------- * * TclNoErrorStack -- * | | > | > > < | 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 | } /* *------------------------------------------------------------------------- * * TclNoErrorStack -- * * Removes the -errorstack entry from an options dict to avoid reference * cycles. * * Results: * The (unshared) argument options dict, modified in -place. * *------------------------------------------------------------------------- */ Tcl_Obj * TclNoErrorStack( Tcl_Interp *interp, Tcl_Obj *options) { Tcl_Obj **keys = GetKeys(); Tcl_DictObjRemove(interp, options, keys[KEY_ERRORSTACK]); return options; } /* *------------------------------------------------------------------------- * * Tcl_SetReturnOptions -- |
︙ | ︙ | |||
1646 1647 1648 1649 1650 1651 1652 | { int objc, level, code; Tcl_Obj **objv, *mergedOpts; Tcl_IncrRefCount(options); if (TCL_ERROR == TclListObjGetElements(interp, options, &objc, &objv) || (objc % 2)) { | | < | | 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 | { int objc, level, code; 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))); Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_OPTIONS", NULL); code = TCL_ERROR; } else if (TCL_ERROR == TclMergeReturnOptions(interp, objc, objv, &mergedOpts, &code, &level)) { code = TCL_ERROR; } else { code = TclProcessReturn(interp, code, level, mergedOpts); |
︙ | ︙ |
Changes to generic/tclScan.c.
︙ | ︙ | |||
257 258 259 260 261 262 263 264 265 266 267 268 269 270 | { int gotXpg, gotSequential, value, i, flags; char *end; Tcl_UniChar ch; int objIndex, xpgSize, nspace = numVars; int *nassign = TclStackAlloc(interp, nspace * sizeof(int)); char buf[TCL_UTF_MAX+1]; /* * Initialize an array that records the number of times a variable is * assigned to by the format string. We use this to detect if a variable * is multiply assigned or left unassigned. */ | > > > > | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | { int gotXpg, gotSequential, value, i, flags; char *end; Tcl_UniChar ch; int objIndex, xpgSize, nspace = numVars; int *nassign = TclStackAlloc(interp, nspace * sizeof(int)); char buf[TCL_UTF_MAX+1]; Tcl_Obj *errorMsg; /* Place to build an error messages. Note that * these are messy operations because we do * not want to use the formatting engine; * we're inside there! */ /* * Initialize an array that records the number of times a variable is * assigned to by the format string. We use this to detect if a variable * is multiply assigned or left unassigned. */ |
︙ | ︙ | |||
324 325 326 327 328 329 330 | goto xpgCheckDone; } notXpg: gotSequential = 1; if (gotXpg) { mixedXPG: | | | | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | goto xpgCheckDone; } notXpg: gotSequential = 1; if (gotXpg) { mixedXPG: Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot mix \"%\" and \"%n$\" conversion specifiers", -1)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "MIXEDSPECTYPES", NULL); goto error; } xpgCheckDone: /* * Parse any width specifier. |
︙ | ︙ | |||
371 372 373 374 375 376 377 | /* * Handle the various field types. */ switch (ch) { case 'c': if (flags & SCAN_WIDTH) { | | | | | > | > | | | 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 | /* * Handle the various field types. */ switch (ch) { case 'c': if (flags & SCAN_WIDTH) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "field width may not be specified in %c conversion", -1)); 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 %", -1); Tcl_AppendToObj(errorMsg, buf, -1); Tcl_AppendToObj(errorMsg, " conversion", -1); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL); goto error; } break; /* * Bracket terms need special checking */ |
︙ | ︙ | |||
442 443 444 445 446 447 448 | if (*format == '\0') { goto badSet; } format += Tcl_UtfToUniChar(format, &ch); } break; badSet: | > | < | > | > | > | | 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 | if (*format == '\0') { goto badSet; } format += Tcl_UtfToUniChar(format, &ch); } break; badSet: Tcl_SetObjResult(interp, Tcl_NewStringObj( "unmatched [ in format string", -1)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BRACKET", NULL); goto error; default: buf[Tcl_UniCharToUtf(ch, buf)] = '\0'; errorMsg = Tcl_NewStringObj( "bad scan conversion character \"", -1); Tcl_AppendToObj(errorMsg, buf, -1); Tcl_AppendToObj(errorMsg, "\"", -1); Tcl_SetObjResult(interp, errorMsg); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADTYPE", NULL); goto error; } if (!(flags & SCAN_SUPPRESS)) { if (objIndex >= nspace) { /* * Expand the nassign buffer. If we are using XPG specifiers, * make sure that we grow to a large enough size. xpgSize is |
︙ | ︙ | |||
494 495 496 497 498 499 500 | } } if (totalSubs) { *totalSubs = numVars; } for (i = 0; i < numVars; i++) { if (nassign[i] > 1) { | | | | | > | < | | | 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 | } } 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", -1)); 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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "INDEXRANGE", NULL); } else { Tcl_SetObjResult(interp, Tcl_NewStringObj( "different numbers of variable names and field specifiers", -1)); Tcl_SetErrorCode(interp, "TCL", "FORMAT", "FIELDVARMISMATCH", NULL); } error: TclStackFree(interp, nassign); return TCL_ERROR; } |
︙ | ︙ |
Changes to generic/tclTest.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | * Copyright (c) 1998-2000 Ajuba Solutions. * Copyright (c) 2003 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ | < < < < < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | * Copyright (c) 1998-2000 Ajuba Solutions. * Copyright (c) 2003 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #undef STATIC_BUILD #ifndef USE_TCL_STUBS # define USE_TCL_STUBS #endif #include "tclInt.h" #include "tclOO.h" #include <math.h> |
︙ | ︙ | |||
309 310 311 312 313 314 315 | Tcl_Interp *interp, int argc, const char **argv); static int TestsetmainloopCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestexitmainloopCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestpanicCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); | < < < | | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | Tcl_Interp *interp, int argc, const char **argv); static int TestsetmainloopCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestexitmainloopCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestpanicCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestparseargsCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestparserObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestparsevarObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestparsevarnameObjCmd(ClientData dummy, |
︙ | ︙ | |||
634 635 636 637 638 639 640 | TestgetvarfullnameCmd, NULL, NULL); Tcl_CreateCommand(interp, "testinterpdelete", TestinterpdeleteCmd, NULL, NULL); Tcl_CreateCommand(interp, "testlink", TestlinkCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testlocale", TestlocaleCmd, NULL, NULL); Tcl_CreateCommand(interp, "testpanic", TestpanicCmd, NULL, NULL); | < | 626 627 628 629 630 631 632 633 634 635 636 637 638 639 | TestgetvarfullnameCmd, NULL, NULL); Tcl_CreateCommand(interp, "testinterpdelete", TestinterpdeleteCmd, NULL, NULL); Tcl_CreateCommand(interp, "testlink", TestlinkCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testlocale", TestlocaleCmd, NULL, NULL); Tcl_CreateCommand(interp, "testpanic", TestpanicCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testparseargs", TestparseargsCmd,NULL,NULL); Tcl_CreateObjCommand(interp, "testparser", TestparserObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testparsevar", TestparsevarObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testparsevarname", TestparsevarnameObjCmd, NULL, NULL); |
︙ | ︙ | |||
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 | if (argc != 5) { goto wrongNumArgs; } if ((Tcl_GetInt(interp, argv[2], &id) != TCL_OK) || (Tcl_GetInt(interp, argv[4], &code) != TCL_OK)) { return TCL_ERROR; } for (asyncPtr = firstHandler; asyncPtr != NULL; asyncPtr = asyncPtr->nextPtr) { if (asyncPtr->id == id) { Tcl_AsyncMark(asyncPtr->handler); break; } } Tcl_SetObjResult(interp, Tcl_NewStringObj(argv[3], -1)); return code; #ifdef TCL_THREADS } else if (strcmp(argv[1], "marklater") == 0) { if (argc != 3) { goto wrongNumArgs; } if (Tcl_GetInt(interp, argv[2], &id) != TCL_OK) { return TCL_ERROR; } for (asyncPtr = firstHandler; asyncPtr != NULL; asyncPtr = asyncPtr->nextPtr) { if (asyncPtr->id == id) { Tcl_ThreadId threadID; if (Tcl_CreateThread(&threadID, AsyncThreadProc, INT2PTR(id), TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS) != TCL_OK) { Tcl_SetResult(interp, "can't create thread", TCL_STATIC); return TCL_ERROR; } break; } } } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be create, delete, int, mark, or marklater", NULL); return TCL_ERROR; #else /* !TCL_THREADS */ } else { Tcl_AppendResult(interp, "bad option \"", argv[1], | > > > > > | 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 | if (argc != 5) { goto wrongNumArgs; } if ((Tcl_GetInt(interp, argv[2], &id) != TCL_OK) || (Tcl_GetInt(interp, argv[4], &code) != TCL_OK)) { return TCL_ERROR; } Tcl_MutexLock(&asyncTestMutex); for (asyncPtr = firstHandler; asyncPtr != NULL; asyncPtr = asyncPtr->nextPtr) { if (asyncPtr->id == id) { Tcl_AsyncMark(asyncPtr->handler); break; } } Tcl_SetObjResult(interp, Tcl_NewStringObj(argv[3], -1)); Tcl_MutexUnlock(&asyncTestMutex); return code; #ifdef TCL_THREADS } else if (strcmp(argv[1], "marklater") == 0) { if (argc != 3) { goto wrongNumArgs; } if (Tcl_GetInt(interp, argv[2], &id) != TCL_OK) { return TCL_ERROR; } Tcl_MutexLock(&asyncTestMutex); for (asyncPtr = firstHandler; asyncPtr != NULL; asyncPtr = asyncPtr->nextPtr) { if (asyncPtr->id == id) { Tcl_ThreadId threadID; if (Tcl_CreateThread(&threadID, AsyncThreadProc, INT2PTR(id), TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS) != TCL_OK) { Tcl_SetResult(interp, "can't create thread", TCL_STATIC); Tcl_MutexUnlock(&asyncTestMutex); return TCL_ERROR; } break; } } Tcl_MutexUnlock(&asyncTestMutex); } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be create, delete, int, mark, or marklater", NULL); return TCL_ERROR; #else /* !TCL_THREADS */ } else { Tcl_AppendResult(interp, "bad option \"", argv[1], |
︙ | ︙ | |||
4543 4544 4545 4546 4547 4548 4549 | argString = Tcl_Merge(argc-1, argv+1); Tcl_Panic("%s", argString); ckfree(argString); return TCL_OK; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 | 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. */ int argc, /* Number of arguments. */ Tcl_Obj *const argv[]) /* The argument objects. */ { |
︙ | ︙ |
Changes to generic/tclTimer.c.
︙ | ︙ | |||
825 826 827 828 829 830 831 | || objv[1]->typePtr == &tclBignumType || (Tcl_GetIndexFromObj(NULL, objv[1], afterSubCmds, "", 0, &index) != TCL_OK)) { index = -1; if (Tcl_GetWideIntFromObj(NULL, objv[1], &ms) != TCL_OK) { const char *arg = Tcl_GetString(objv[1]); | > | | | 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 | || objv[1]->typePtr == &tclBignumType || (Tcl_GetIndexFromObj(NULL, objv[1], afterSubCmds, "", 0, &index) != TCL_OK)) { index = -1; if (Tcl_GetWideIntFromObj(NULL, objv[1], &ms) != TCL_OK) { const char *arg = Tcl_GetString(objv[1]); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad argument \"%s\": must be" " cancel, idle, info, or an integer", arg)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "argument", arg, NULL); return TCL_ERROR; } } /* |
︙ | ︙ | |||
964 965 966 967 968 969 970 | Tcl_WrongNumArgs(interp, 2, objv, "?id?"); return TCL_ERROR; } afterPtr = GetAfterEvent(assocPtr, objv[2]); if (afterPtr == NULL) { const char *eventStr = TclGetString(objv[2]); | | | | 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 | Tcl_WrongNumArgs(interp, 2, objv, "?id?"); return TCL_ERROR; } afterPtr = GetAfterEvent(assocPtr, objv[2]); if (afterPtr == NULL) { const char *eventStr = TclGetString(objv[2]); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "event \"%s\" doesn't exist", eventStr)); Tcl_SetErrorCode(interp, "TCL","LOOKUP","EVENT", eventStr, NULL); return TCL_ERROR; } else { Tcl_Obj *resultListPtr = Tcl_NewObj(); Tcl_ListObjAppendElement(interp, resultListPtr, afterPtr->commandPtr); |
︙ | ︙ |
Changes to generic/tclTomMathStubLib.c.
︙ | ︙ | |||
69 70 71 72 73 74 75 | errMsg = "epoch number mismatch"; } else if ((stubsPtr->tclBN_revision)() != revision) { errMsg = "requires a later revision"; } else { tclTomMathStubsPtr = stubsPtr; return actualVersion; } | | | | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | errMsg = "epoch number mismatch"; } else if ((stubsPtr->tclBN_revision)() != revision) { errMsg = "requires a later revision"; } else { tclTomMathStubsPtr = stubsPtr; return actualVersion; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error loading %s (requested version %s, actual version %s): %s", packageName, version, actualVersion, errMsg)); return NULL; } /* * Local Variables: * mode: c * c-basic-offset: 4 |
︙ | ︙ |
Changes to generic/tclTrace.c.
︙ | ︙ | |||
362 363 364 365 366 367 368 | break; } #endif /* TCL_REMOVE_OBSOLETE_TRACES */ } return TCL_OK; badVarOps: | | | > | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | break; } #endif /* TCL_REMOVE_OBSOLETE_TRACES */ } return TCL_OK; badVarOps: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad operations \"%s\": should be one or more of rwua", flagOps)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "BADOPS", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
430 431 432 433 434 435 436 | */ result = Tcl_ListObjGetElements(interp, objv[4], &listLen, &elemPtrs); if (result != TCL_OK) { return result; } if (listLen == 0) { | > | | < | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 | */ 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", -1)); 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) { |
︙ | ︙ | |||
673 674 675 676 677 678 679 | */ result = Tcl_ListObjGetElements(interp, objv[4], &listLen, &elemPtrs); if (result != TCL_OK) { return result; } if (listLen == 0) { | > | | | 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 | */ 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "NOOPS", NULL); return TCL_ERROR; } for (i = 0; i < listLen; i++) { if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings, |
︙ | ︙ | |||
871 872 873 874 875 876 877 | */ result = Tcl_ListObjGetElements(interp, objv[4], &listLen, &elemPtrs); if (result != TCL_OK) { return result; } if (listLen == 0) { | > | | | 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 | */ 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", -1)); 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) { |
︙ | ︙ | |||
2711 2712 2713 2714 2715 2716 2717 | type = "array"; break; } if (disposeFlags & TCL_TRACE_RESULT_OBJECT) { Tcl_SetObjResult((Tcl_Interp *)iPtr, (Tcl_Obj *) result); } else { | | > | 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 | type = "array"; break; } if (disposeFlags & TCL_TRACE_RESULT_OBJECT) { Tcl_SetObjResult((Tcl_Interp *)iPtr, (Tcl_Obj *) result); } else { Tcl_SetObjResult((Tcl_Interp *)iPtr, Tcl_NewStringObj(result, -1)); } 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/tclUniData.c.
︙ | ︙ | |||
878 879 880 881 882 883 884 | 3, 3, 3, 141, 142, 17, 17, 17, 17, 17, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 16, 20, 3, 3, 3, 3, 12, 12, 3, 3, 3, 7, 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 12, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 18, 85, 0, 0, 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 85, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | | | 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 | 3, 3, 3, 141, 142, 17, 17, 17, 17, 17, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 16, 20, 3, 3, 3, 3, 12, 12, 3, 3, 3, 7, 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 12, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 18, 85, 0, 0, 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 85, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 111, 111, 111, 111, 86, 111, 111, 111, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 100, 14, 14, 14, 14, 100, 14, 14, 21, 100, 100, 100, 21, 21, 100, 100, 100, 21, 14, 100, 14, 14, 7, 100, 100, 100, 100, 100, 14, 14, 14, 14, 14, 14, 100, 14, 143, 14, 100, 14, 144, 145, 100, 100, 14, 21, 100, 100, 146, 100, 21, 15, 15, 15, 15, 21, 14, 14, 21, |
︙ | ︙ |
Changes to generic/tclUtil.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | */ static ProcessGlobalValue executableName = { 0, 0, NULL, NULL, NULL, NULL, NULL }; /* | | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | */ static ProcessGlobalValue executableName = { 0, 0, NULL, NULL, NULL, NULL, NULL }; /* * The following values are used in the flags arguments of Tcl*Scan*Element * and Tcl*Convert*Element. The values TCL_DONT_USE_BRACES and * TCL_DONT_QUOTE_HASH are defined in tcl.h, like so: * #define TCL_DONT_USE_BRACES 1 #define TCL_DONT_QUOTE_HASH 8 * * Those are public flag bits which callers of the public routines * Tcl_Convert*Element() can use to indicate: * |
︙ | ︙ | |||
50 51 52 53 54 55 56 | * are for internal use only. Make sure they do not overlap with the public * values above. * * The Tcl*Scan*Element() routines make a determination which of 4 modes of * conversion is most appropriate for Tcl*Convert*Element() to perform, and * sets two bits of the flags value to indicate the mode selected. * | | | | | | | | | | | 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 | * are for internal use only. Make sure they do not overlap with the public * values above. * * The Tcl*Scan*Element() routines make a determination which of 4 modes of * conversion is most appropriate for Tcl*Convert*Element() to perform, and * sets two bits of the flags value to indicate the mode selected. * * CONVERT_NONE The element needs no quoting. Its literal string is * suitable as is. * CONVERT_BRACE The conversion should be enclosing the literal string * in braces. * CONVERT_ESCAPE The conversion should be using backslashes to escape * any characters in the string that require it. * CONVERT_MASK A mask value used to extract the conversion mode from * the flags argument. * Also indicates a strange conversion mode where all * special characters are escaped with backslashes * *except for braces*. This is a strange and unnecessary * case, but it's part of the historical way in which * lists have been formatted in Tcl. To experiment with * removing this case, set the value of COMPAT to 0. * * One last flag value is used only by callers of TclScanElement(). The flag * value produced by a call to Tcl*Scan*Element() will never leave this bit * set. * * CONVERT_ANY The caller of TclScanElement() declares it can make no * promise about what public flags will be passed to the * matching call of TclConvertElement(). As such, * TclScanElement() has to determine the worst case * destination buffer length over all possibilities, and * in other cases this means an overestimate of the * required size. * * For more details, see the comments on the Tcl*Scan*Element and * Tcl*Convert*Element routines. |
︙ | ︙ | |||
125 126 127 128 129 130 131 | UpdateStringOfEndOffset, /* updateStringProc */ SetEndOffsetFromAny }; /* * * STRING REPRESENTATION OF LISTS * * * * | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | > > > | > > > | > > > > | > > | > > | | 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 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 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 | UpdateStringOfEndOffset, /* updateStringProc */ SetEndOffsetFromAny }; /* * * STRING REPRESENTATION OF LISTS * * * * * The next several routines implement the conversions of strings to and from * Tcl lists. To understand their operation, the rules of parsing and * generating the string representation of lists must be known. Here we * describe them in one place. * * A list is made up of zero or more elements. Any string is a list if it is * made up of alternating substrings of element-separating ASCII whitespace * and properly formatted elements. * * The ASCII characters which can make up the whitespace between list elements * are: * * \u0009 \t TAB * \u000A \n NEWLINE * \u000B \v VERTICAL TAB * \u000C \f FORM FEED * \u000D \r CARRIAGE RETURN * \u0020 SPACE * * NOTE: differences between this and other places where Tcl defines a role * for "whitespace". * * * Unlike command parsing, here NEWLINE is just another whitespace * character; its role as a command terminator in a script has no * importance here. * * * Unlike command parsing, the BACKSLASH NEWLINE sequence is not * considered to be a whitespace character. * * * Other Unicode whitespace characters (recognized by [string is space] * or Tcl_UniCharIsSpace()) do not play any role as element separators * in Tcl lists. * * * The NUL byte ought not appear, as it is not in strings properly * encoded for Tcl, but if it is present, it is not treated as * separating whitespace, or a string terminator. It is just another * character in a list element. * * The interpretaton of a formatted substring as a list element follows rules * similar to the parsing of the words of a command in a Tcl script. Backslash * substitution plays a key role, and is defined exactly as it is in command * parsing. The same routine, TclParseBackslash() is used in both command * parsing and list parsing. * * NOTE: This means that if and when backslash substitution rules ever change * for command parsing, the interpretation of strings as lists also changes. * * Backslash substitution replaces an "escape sequence" of one or more * characters starting with * \u005c \ BACKSLASH * with a single character. The one character escape sequent case happens only * when BACKSLASH is the last character in the string. In all other cases, the * escape sequence is at least two characters long. * * The formatted substrings are interpreted as element values according to the * following cases: * * * If the first character of a formatted substring is * \u007b { OPEN BRACE * then the end of the substring is the matching * \u007d } CLOSE BRACE * character, where matching is determined by counting nesting levels, and * not including any brace characters that are contained within a backslash * escape sequence in the nesting count. Having found the matching brace, * all characters between the braces are the string value of the element. * If no matching close brace is found before the end of the string, the * string is not a Tcl list. If the character following the close brace is * not an element separating whitespace character, or the end of the string, * then the string is not a Tcl list. * * NOTE: this differs from a brace-quoted word in the parsing of a Tcl * command only in its treatment of the backslash-newline sequence. In a * list element, the literal characters in the backslash-newline sequence * become part of the element value. In a script word, conversion to a * single SPACE character is done. * * NOTE: Most list element values can be represented by a formatted * substring using brace quoting. The exceptions are any element value that * includes an unbalanced brace not in a backslash escape sequence, and any * value that ends with a backslash not itself in a backslash escape * sequence. * * * If the first character of a formatted substring is * \u0022 " QUOTE * then the end of the substring is the next QUOTE character, not counting * any QUOTE characters that are contained within a backslash escape * sequence. If no next QUOTE is found before the end of the string, the * string is not a Tcl list. If the character following the closing QUOTE is * not an element separating whitespace character, or the end of the string, * then the string is not a Tcl list. Having found the limits of the * substring, the element value is produced by performing backslash * substitution on the character sequence between the open and close QUOTEs. * * NOTE: Any element value can be represented by this style of formatting, * given suitable choice of backslash escape sequences. * * * All other formatted substrings are terminated by the next element * separating whitespace character in the string. Having found the limits * of the substring, the element value is produced by performing backslash * substitution on it. * * NOTE: Any element value can be represented by this style of formatting, * given suitable choice of backslash escape sequences, with one exception. * The empty string cannot be represented as a list element without the use * of either braces or quotes to delimit it. * * This collection of parsing rules is implemented in the routine * TclFindElement(). * * In order to produce lists that can be parsed by these rules, we need the * ability to distinguish between characters that are part of a list element * value from characters providing syntax that define the structure of the * list. This means that our code that generates lists must at a minimum be * able to produce escape sequences for the 10 characters identified above * that have significance to a list parser. * * * * CANONICAL LISTS * * * * * * * In addition to the basic rules for parsing strings into Tcl lists, there * are additional properties to be met by the set of list values that are * generated by Tcl. Such list values are often said to be in "canonical * form": * * * When any canonical list is evaluated as a Tcl script, it is a script of * either zero commands (an empty list) or exactly one command. The command * word is exactly the first element of the list, and each argument word is * exactly one of the following elements of the list. This means that any * characters that have special meaning during script evaluation need * special treatment when canonical lists are produced: * * * Whitespace between elements may not include NEWLINE. * * The command terminating character, * \u003b ; SEMICOLON * must be BRACEd, QUOTEd, or escaped so that it does not terminate the * command prematurely. * * Any of the characters that begin substitutions in scripts, * \u0024 $ DOLLAR * \u005b [ OPEN BRACKET * \u005c \ BACKSLASH * need to be BRACEd or escaped. * * In any list where the first character of the first element is * \u0023 # HASH * that HASH character must be BRACEd, QUOTEd, or escaped so that it * does not convert the command into a comment. * * Any list element that contains the character sequence BACKSLASH * NEWLINE cannot be formatted with BRACEs. The BACKSLASH character * must be represented by an escape sequence, and unless QUOTEs are * used, the NEWLINE must be as well. * * * It is also guaranteed that one can use a canonical list as a building * block of a larger script within command substitution, as in this example: * set script "puts \[[list $cmd $arg]]"; eval $script * To support this usage, any appearance of the character * \u005d ] CLOSE BRACKET * in a list element must be BRACEd, QUOTEd, or escaped. * * * Finally it is guaranteed that enclosing a canonical list in braces * produces a new value that is also a canonical list. This new list has * length 1, and its only element is the original canonical list. This same * guarantee also makes it possible to construct scripts where an argument * word is given a list value by enclosing the canonical form of that list * in braces: * set script "puts {[list $one $two $three]}"; eval $script * This sort of coding was once fairly common, though it's become more * idiomatic to see the following instead: * set script [list puts [list $one $two $three]]; eval $script * In order to support this guarantee, every canonical list must have * balance when counting those braces that are not in escape sequences. * * Within these constraints, the canonical list generation routines * TclScanElement() and TclConvertElement() attempt to generate the string for * any list that is easiest to read. When an element value is itself * acceptable as the formatted substring, it is usually used (CONVERT_NONE). * When some quoting or escaping is required, use of BRACEs (CONVERT_BRACE) is * usually preferred over the use of escape sequences (CONVERT_ESCAPE). There * are some exceptions to both of these preferences for reasons of code * simplicity, efficiency, and continuation of historical habits. Canonical * lists never use the QUOTE formatting to delimit their elements because that * form of quoting does not nest, which makes construction of nested lists far * too much trouble. Canonical lists always use only a single SPACE character * for element-separating whitespace. * * * * FUTURE CONSIDERATIONS * * * * * When a list element requires quoting or escaping due to a CLOSE BRACKET * character or an internal QUOTE character, a strange formatting mode is * recommended. For example, if the value "a{b]c}d" is converted by the usual * modes: * * CONVERT_BRACE: a{b]c}d => {a{b]c}d} * CONVERT_ESCAPE: a{b]c}d => a\{b\]c\}d * * we get perfectly usable formatted list elements. However, this is not what * Tcl releases have been producing. Instead, we have: * * CONVERT_MASK: a{b]c}d => a{b\]c}d * * where the CLOSE BRACKET is escaped, but the BRACEs are not. The same effect * can be seen replacing ] with " in this example. There does not appear to be * any functional or aesthetic purpose for this strange additional mode. The * sole purpose I can see for preserving it is to keep generating the same * formatted lists programmers have become accustomed to, and perhaps written * tests to expect. That is, compatibility only. The additional code * complexity required to support this mode is significant. The lines of code * supporting it are delimited in the routines below with #if COMPAT * directives. This makes it easy to experiment with eliminating this * formatting mode simply with "#define COMPAT 0" above. I believe this is * worth considering. * * Another consideration is the treatment of QUOTE characters in list * elements. TclConvertElement() must have the ability to produce the escape * sequence \" so that when a list element begins with a QUOTE we do not * confuse that first character with a QUOTE used as list syntax to define * list structure. However, that is the only place where QUOTE characters need * quoting. In this way, handling QUOTE could really be much more like the way * we handle HASH which also needs quoting and escaping only in particular * situations. Following up this could increase the set of list elements that * can use the CONVERT_NONE formatting mode. * * More speculative is that the demands of canonical list form require brace * balance for the list as a whole, while the current implementation achieves * this by establishing brace balance for every element. * * Finally, a reminder that the rules for parsing and formatting lists are * closely tied together with the rules for parsing and evaluating scripts, * and will need to evolve in sync. */ /* *---------------------------------------------------------------------- * * 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 -1, 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. * *---------------------------------------------------------------------- */ int TclMaxListLength( const char *bytes, int numBytes, const char **endPtr) { int count = 0; if ((numBytes == 0) || ((numBytes == -1) && (*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 == -1) && (*bytes == '\0')) { break; } if (TclIsSpaceProc(*bytes)) { /* * Space run started; bump count. */ count++; do { bytes++; numBytes -= (numBytes != -1); } while (numBytes && TclIsSpaceProc(*bytes)); if ((numBytes == 0) || ((numBytes == -1) && (*bytes == '\0'))) { break; } /* * (*bytes) is non-space; return to counting state. */ } bytes++; numBytes -= (numBytes != -1); } /* * No list element following trailing white space. */ count -= TclIsSpaceProc(bytes[-1]); done: if (endPtr) { *endPtr = bytes; } return count; } /* |
︙ | ︙ | |||
445 446 447 448 449 450 451 | * * If TCL_OK is returned, then *elementPtr will be set to point to the * first element of list, and *nextPtr will be set to point to the * character just after any white space following the last character * that's part of the element. If this is the last argument in the list, * then *nextPtr will point just after the last character in the list * (i.e., at the character at list+listLength). If sizePtr is non-NULL, | | | | | | | | | | 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 | * * If TCL_OK is returned, then *elementPtr will be set to point to the * first element of list, and *nextPtr will be set to point to the * character just after any white space following the last character * that's part of the element. If this is the last argument in the list, * then *nextPtr will point just after the last character in the list * (i.e., at the character at list+listLength). If sizePtr is non-NULL, * *sizePtr is filled in with the number of bytes in the element. If the * element is in braces, then *elementPtr will point to the character * after the opening brace and *sizePtr will not include either of the * braces. If there isn't an element in the list, *sizePtr will be zero, * and both *elementPtr and *nextPtr will point just after the last * character in the list. If literalPtr is non-NULL, *literalPtr is set * to a boolean value indicating whether the substring returned as the * values of **elementPtr and *sizePtr is the literal value of a list * element. If not, a call to TclCopyAndCollapse() is needed to produce * the actual value of the list element. Note: this function does NOT * collapse backslash sequences, but uses *literalPtr to tell callers * when it is required for them to do so. * * Side effects: * None. * *---------------------------------------------------------------------- */ |
︙ | ︙ | |||
583 584 585 586 587 588 589 | */ case '\\': if (openBraces == 0) { /* * A backslash sequence not within a brace quoted element * means the value of the element is different from the | | | > | 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 | */ case '\\': if (openBraces == 0) { /* * A backslash sequence not within a brace quoted element * means the value of the element is different from the * substring we are parsing. A call to TclCopyAndCollapse() is * needed to produce the element value. Inform the caller. */ literal = 0; } TclParseBackslash(p, limit - p, &numChars, NULL); p += (numChars - 1); break; /* |
︙ | ︙ | |||
651 652 653 654 655 656 657 | /* * End of list: terminate element. */ if (p == limit) { if (openBraces != 0) { if (interp != NULL) { | > | < > | < | 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 | /* * End of list: terminate element. */ if (p == limit) { if (openBraces != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unmatched open brace in list", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "QUOTE", NULL); } return TCL_ERROR; } size = (p - elemStart); } |
︙ | ︙ | |||
693 694 695 696 697 698 699 | * * TclCopyAndCollapse -- * * Copy a string and substitute all backslash escape sequences * * Results: * Count bytes get copied from src to dst. Along the way, backslash | | | | > | 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 | * * TclCopyAndCollapse -- * * Copy a string and substitute all backslash escape sequences * * Results: * Count bytes get copied from src to dst. Along the way, backslash * sequences are substituted in the copy. After scanning count bytes from * src, a null character is placed at the end of dst. Returns the number * of bytes that got written to dst. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TclCopyAndCollapse( int count, /* Number of byte to copy from src. */ const char *src, /* Copy from here... */ char *dst) /* ... to here. */ { int newCount = 0; while (count > 0) { char c = *src; if (c == '\\') { int numRead; int backslashCount = TclParseBackslash(src, count, &numRead, dst); dst += backslashCount; newCount += backslashCount; src += numRead; |
︙ | ︙ | |||
776 777 778 779 780 781 782 | * of pointers to list elements. */ { const char **argv, *end, *element; char *p; int length, size, i, result, elSize; /* | | | | | < | | 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 | * of pointers to list elements. */ { const char **argv, *end, *element; char *p; int length, size, i, result, 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, -1, &end) + 1; length = end - list; argv = ckalloc((size * sizeof(char *)) + length + 1); for (i = 0, p = ((char *) argv) + size*sizeof(char *); |
︙ | ︙ | |||
806 807 808 809 810 811 812 | } if (*element == 0) { break; } if (i >= size) { ckfree(argv); if (interp != NULL) { | > | < | 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 | } if (*element == 0) { break; } if (i >= size) { ckfree(argv); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "internal error in Tcl_SplitList", -1)); Tcl_SetErrorCode(interp, "TCL", "INTERNAL", "Tcl_SplitList", NULL); } return TCL_ERROR; } argv[i] = p; if (literal) { |
︙ | ︙ | |||
840 841 842 843 844 845 846 | * Tcl_ScanElement -- * * This function is a companion function to Tcl_ConvertElement. 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. * * Results: | | | | | 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 | * Tcl_ScanElement -- * * This function is a companion function to Tcl_ConvertElement. 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. * * Results: * The return value is an overestimate of the number of bytes that will * be needed by Tcl_ConvertElement to produce a valid list element from * src. The word at *flagPtr is filled in with a value needed by * Tcl_ConvertElement when doing the actual conversion. * * Side effects: * None. * *---------------------------------------------------------------------- */ |
︙ | ︙ | |||
872 873 874 875 876 877 878 | * 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 -1, then the string is scanned from src up * to the first null byte. * * Results: | | | | | | 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 | * 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 -1, 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. * *---------------------------------------------------------------------- */ |
︙ | ︙ | |||
902 903 904 905 906 907 908 | } /* *---------------------------------------------------------------------- * * TclScanElement -- * | | | | | | | | | | | | | | | | > | > > > | | | > | > > | | > | > > > > | > > | | > | > > > | > > | | > > > | > > | | | | | > > | > > | | | | < > > > | > > > | > > > | > > > | > > > | > > | | 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 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 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 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 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 | } /* *---------------------------------------------------------------------- * * 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 -1, 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. * *---------------------------------------------------------------------- */ int TclScanElement( const char *src, /* String to convert to Tcl list element. */ int length, /* Number of bytes in src, or -1. */ int *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. */ int 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 == -1))) { /* * Empty string element must be brace quoted. */ *flagPtr = CONVERT_BRACE; return 2; } if ((*p == '{') || (*p == '"')) { /* * Must escape or protect so leading character of value is not * misinterpreted as list element delimiting syntax. */ 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 == -1) && (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 > 0); p++; break; } if ((p[1] == '{') || (p[1] == '}') || (p[1] == '\\')) { extra++; /* Escape sequences all one byte longer. */ length -= (length > 0); p++; } forbidNone = 1; #if COMPAT preferBrace = 1; #endif /* COMPAT */ break; case '\0': /* TYPE_SUBS */ if (length == -1) { goto endOfString; } /* TODO: Panic on improper encoding? */ break; } } length -= (length > 0); p++; } endOfString: if (nestingLevel != 0) { /* * Unbalanced braces! Cannot format with brace quoting. */ requireEscape = 1; } /* * We need at least as many bytes as are in the element value... */ bytesNeeded = p - src; if (requireEscape) { /* * We must use escape sequences. Add all the extra bytes needed to * have room to create them. */ bytesNeeded += extra; /* * Make room to escape leading #, if needed. */ if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) { bytesNeeded++; } *flagPtr = CONVERT_ESCAPE; goto overflowCheck; } 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 * don't request too small a buffer in those edge cases where that's * not true. */ if (extra < 2) { extra = 2; } *flagPtr &= ~CONVERT_ANY; *flagPtr |= TCL_DONT_USE_BRACES; } if (forbidNone) { /* * We must request some form of quoting of escaping... */ #if COMPAT if (preferEscape && !preferBrace) { /* * If we are quoting solely due to ] or internal " characters use * the CONVERT_MASK mode where we escape all special characters * except for braces. "extra" counted space needed to escape * braces too, so substract "braceCount" to get our actual needs. */ bytesNeeded += (extra - braceCount); /* Make room to escape leading #, if needed. */ if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) { bytesNeeded++; } /* * If the caller reports it will direct TclConvertElement() to * use full escapes on the element, add back the bytes needed to * escape the braces. */ if (*flagPtr & TCL_DONT_USE_BRACES) { bytesNeeded += braceCount; } *flagPtr = CONVERT_MASK; goto overflowCheck; } #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. */ bytesNeeded += extra; /* * Make room to escape leading #, if needed. */ if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) { bytesNeeded++; } } else { /* * Add 2 bytes for room for the enclosing braces. */ bytesNeeded += 2; } *flagPtr = CONVERT_BRACE; goto overflowCheck; } /* * 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; overflowCheck: if (bytesNeeded < 0) { Tcl_Panic("TclScanElement: string length overflow"); } return bytesNeeded; } /* |
︙ | ︙ | |||
1216 1217 1218 1219 1220 1221 1222 | } /* *---------------------------------------------------------------------- * * TclConvertElement -- * | | | | > | > | > > > | > > | > | > > > | > > > | > > > | > > | | > < < | 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 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 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 | } /* *---------------------------------------------------------------------- * * TclConvertElement -- * * This is a companion function to TclScanElement. Given the information * produced by TclScanElement, this function converts a string to a list * element equal to that string. * * Results: * Information is copied to *dst in the form of a list element identical * to src (i.e. if Tcl_SplitList is applied to dst it will produce a * string identical to src). The return value is a count of the number of * characters copied (not including the terminating NULL character). * * Side effects: * None. * *---------------------------------------------------------------------- */ int TclConvertElement( register const char *src, /* Source information for list element. */ int length, /* Number of bytes in src, or -1. */ char *dst, /* Place to put list-ified element. */ int flags) /* Flags produced by Tcl_ScanElement. */ { int 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 == -1)) { 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 > 0); } else { conversion = CONVERT_BRACE; } } /* * No escape or quoting needed. Copy the literal string value. */ if (conversion == CONVERT_NONE) { if (length == -1) { /* 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 == -1) { /* 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 > 0)) { switch (*src) { case ']': case '[': case '$': case ';': case ' ': case '\\': case '"': *p = '\\'; p++; break; case '{': case '}': #if COMPAT if (conversion == CONVERT_ESCAPE) #endif /* COMPAT */ { *p = '\\'; p++; } break; case '\f': *p = '\\'; p++; *p = 'f'; p++; continue; |
︙ | ︙ | |||
1358 1359 1360 1361 1362 1363 1364 1365 | *p = 'v'; p++; continue; case '\0': if (length == -1) { return p - dst; } /* | > | | | | | > | 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 | *p = 'v'; p++; continue; case '\0': if (length == -1) { 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 * day ever comes when we stop tolerating such things, this is * where to put the Tcl_Panic(). */ break; } *p = *src; p++; } return p - dst; } |
︙ | ︙ | |||
1398 1399 1400 1401 1402 1403 1404 | */ char * Tcl_Merge( int argc, /* How many strings to merge. */ const char *const *argv) /* Array of string values. */ { | | < | | | | > > | | | | | | < | | | > | 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 1523 1524 1525 1526 | */ char * Tcl_Merge( int argc, /* How many strings to merge. */ const char *const *argv) /* Array of string values. */ { #define LOCAL_SIZE 20 int localFlags[LOCAL_SIZE], *flagPtr = NULL; int i, bytesNeeded = 0; char *result, *dst; const int maxFlags = UINT_MAX / sizeof(int); /* * Handle empty list case first, so logic of the general case can be * simpler. */ if (argc == 0) { result = ckalloc(1); result[0] = '\0'; return result; } /* * Pass 1: estimate space, gather flags. */ if (argc <= LOCAL_SIZE) { flagPtr = localFlags; } else if (argc > maxFlags) { /* * We cannot allocate a large enough flag array to format this list in * one pass. We could imagine converting this routine to a multi-pass * implementation, but for sizeof(int) == 4, the limit is a max of * 2^30 list elements and since each element is at least one byte * formatted, and requires one byte space between it and the next one, * that a minimum space requirement of 2^31 bytes, which is already * INT_MAX. If we tried to format a list of > maxFlags elements, we're * just going to overflow the size limits on the formatted string * anyway, so just issue that same panic early. */ Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); } else { flagPtr = ckalloc(argc * sizeof(int)); } for (i = 0; i < argc; i++) { flagPtr[i] = ( i ? TCL_DONT_QUOTE_HASH : 0 ); bytesNeeded += TclScanElement(argv[i], -1, &flagPtr[i]); |
︙ | ︙ | |||
1507 1508 1509 1510 1511 1512 1513 | return (char) ch; } /* *---------------------------------------------------------------------- * * TclTrimRight -- | > | | | | | | | > | > > > | > > > | > > > | > > > | | | | | | | > | > > > | > > > | > > > | > > | 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 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 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 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 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 | return (char) ch; } /* *---------------------------------------------------------------------- * * TclTrimRight -- * * Takes two counted strings in the Tcl encoding which must both be null * terminated. Conceptually trims from the right side of the first string * all characters found in the second string. * * Results: * The number of bytes to be removed from the end of the string. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TclTrimRight( const char *bytes, /* String to be trimmed... */ int numBytes, /* ...and its length in bytes */ const char *trim, /* String of trim characters... */ int 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"); } /* * Empty strings -> nothing to do. */ if ((numBytes == 0) || (numTrim == 0)) { return 0; } /* * Outer loop: iterate over string to be trimmed. */ do { Tcl_UniChar ch1; const char *q = trim; int bytesLeft = numTrim; p = Tcl_UtfPrev(p, bytes); pInc = TclUtfToUniChar(p, &ch1); /* * Inner loop: scan trim string for match to current character. */ do { Tcl_UniChar ch2; int qInc = TclUtfToUniChar(q, &ch2); if (ch1 == ch2) { break; } q += qInc; bytesLeft -= qInc; } while (bytesLeft); if (bytesLeft == 0) { /* * No match; trim task done; *p is last non-trimmed char. */ p += pInc; break; } } while (p > bytes); return numBytes - (p - bytes); } /* *---------------------------------------------------------------------- * * TclTrimLeft -- * * Takes two counted strings in the Tcl encoding which must both be null * terminated. Conceptually trims from the left side of the first string * all characters found in the second string. * * Results: * The number of bytes to be removed from the start of the string. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TclTrimLeft( const char *bytes, /* String to be trimmed... */ int numBytes, /* ...and its length in bytes */ const char *trim, /* String of trim characters... */ int 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"); } /* * Empty strings -> nothing to do. */ if ((numBytes == 0) || (numTrim == 0)) { return 0; } /* * Outer loop: iterate over string to be trimmed. */ do { Tcl_UniChar ch1; int pInc = TclUtfToUniChar(p, &ch1); const char *q = trim; int bytesLeft = numTrim; /* * Inner loop: scan trim string for match to current character. */ do { Tcl_UniChar ch2; int qInc = TclUtfToUniChar(q, &ch2); if (ch1 == ch2) { break; } q += qInc; bytesLeft -= qInc; } while (bytesLeft); if (bytesLeft == 0) { /* * No match; trim task done; *p is first non-trimmed char. */ break; } p += pInc; numBytes -= pInc; } while (numBytes); |
︙ | ︙ | |||
1669 1670 1671 1672 1673 1674 1675 | Tcl_Concat( int argc, /* Number of strings to concatenate. */ const char *const *argv) /* Array of strings to concatenate. */ { int i, needSpace = 0, bytesNeeded = 0; char *result, *p; | > | > > > | > > | | > > > | > > | > | > > | | > | > > > | > > | 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 | Tcl_Concat( int argc, /* Number of strings to concatenate. */ const char *const *argv) /* Array of strings to concatenate. */ { int i, needSpace = 0, bytesNeeded = 0; char *result, *p; /* * Dispose of the empty result corner case first to simplify later code. */ if (argc == 0) { result = (char *) 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]); if (bytesNeeded < 0) { Tcl_Panic("Tcl_Concat: max size of Tcl value exceeded"); } } 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++) { int trim, elemLength; const char *element; element = argv[i]; elemLength = strlen(argv[i]); /* * Trim away the leading whitespace. */ trim = TclTrimLeft(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); element += trim; elemLength -= trim; /* * Trim away the trailing whitespace. Do not permit trimming to expose * a final backslash character. */ trim = TclTrimRight(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); trim -= trim && (element[elemLength - trim - 1] == '\\'); elemLength -= trim; /* * If we're left with empty element after trimming, do nothing. */ if (elemLength == 0) { continue; } /* * Append to the result with space if needed. */ if (needSpace) { *p++ = ' '; } memcpy(p, element, (size_t) elemLength); p += elemLength; needSpace = 1; } |
︙ | ︙ | |||
1798 1799 1800 1801 1802 1803 1804 1805 1806 | } return resPtr; } /* * Something cannot be determined to be safe, so build the concatenation * the slow way, using the string representations. */ | > > < > | | | > > | > > | | > | > > > | > > | 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 1988 1989 1990 1991 1992 1993 | } return resPtr; } /* * Something cannot be determined to be safe, so build the concatenation * the slow way, using the string representations. * * First try to pre-allocate the size required. */ for (i = 0; i < objc; i++) { element = TclGetStringFromObj(objv[i], &elemLength); bytesNeeded += elemLength; if (bytesNeeded < 0) { break; } } /* * 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++) { int trim; element = TclGetStringFromObj(objv[i], &elemLength); /* * Trim away the leading whitespace. */ trim = TclTrimLeft(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); element += trim; elemLength -= trim; /* * Trim away the trailing whitespace. Do not permit trimming to expose * a final backslash character. */ trim = TclTrimRight(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); trim -= trim && (element[elemLength - trim - 1] == '\\'); elemLength -= trim; /* * If we're left with empty element after trimming, do nothing. */ if (elemLength == 0) { continue; } /* * Append to the result with space if needed. */ if (needSpace) { Tcl_AppendToObj(resPtr, " ", 1); } Tcl_AppendToObj(resPtr, element, elemLength); needSpace = 1; } return resPtr; |
︙ | ︙ | |||
2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 | endChar = *pattern; pattern++; if (((startChar <= ch1) && (ch1 <= endChar)) || ((endChar <= ch1) && (ch1 <= startChar))) { /* * Matches ranges of form [a-z] or [z-a]. */ break; } } else if (startChar == ch1) { break; } } while (*pattern != ']') { | > | 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 | endChar = *pattern; pattern++; if (((startChar <= ch1) && (ch1 <= endChar)) || ((endChar <= ch1) && (ch1 <= startChar))) { /* * Matches ranges of form [a-z] or [z-a]. */ break; } } else if (startChar == ch1) { break; } } while (*pattern != ']') { |
︙ | ︙ | |||
2291 2292 2293 2294 2295 2296 2297 | } /* *---------------------------------------------------------------------- * * TclStringMatchObj -- * | | | | | 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 | } /* *---------------------------------------------------------------------- * * TclStringMatchObj -- * * See if a particular string matches a particular pattern. Allows case * insensitivity. This is the generic multi-type handler for the various * matching algorithms. * * Results: * The return value is 1 if string matches pattern, and 0 otherwise. The * matching operation permits the following special characters in the * pattern: *?\[] (see the manual entry for details on what these mean). * * Side effects: |
︙ | ︙ | |||
2653 2654 2655 2656 2657 2658 2659 | void Tcl_DStringResult( Tcl_Interp *interp, /* Interpreter whose result is to be reset. */ Tcl_DString *dsPtr) /* Dynamic string that is to become the * result of interp. */ { | < < | < < < < < < < < < < < < < < | 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 | void Tcl_DStringResult( Tcl_Interp *interp, /* Interpreter whose result is to be reset. */ Tcl_DString *dsPtr) /* Dynamic string that is to become the * result of interp. */ { Tcl_ResetResult(interp); Tcl_SetObjResult(interp, TclDStringToObj(dsPtr)); } /* *---------------------------------------------------------------------- * * Tcl_DStringGetResult -- * |
︙ | ︙ | |||
2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 | * of interp. */ { Interp *iPtr = (Interp *) interp; if (dsPtr->string != dsPtr->staticSpace) { ckfree(dsPtr->string); } /* * If the string result is empty, move the object result to the string * result, then reset the object result. */ (void) Tcl_GetStringResult(interp); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 | * of interp. */ { Interp *iPtr = (Interp *) interp; if (dsPtr->string != dsPtr->staticSpace) { ckfree(dsPtr->string); } /* * Do more efficient transfer when we know the result is a Tcl_Obj. When * there's no st`ring result, we only have to deal with two cases: * * 1. When the string rep is the empty string, when we don't copy but * instead use the staticSpace in the DString to hold an empty string. * 2. When the string rep is not there or there's a real string rep, when * we use Tcl_GetString to fetch (or generate) the string rep - which * we know to have been allocated with ckalloc() - and use it to * populate the DString space. Then, we free the internal rep. and set * the object's string representation back to the canonical empty * string. */ if (!iPtr->result[0] && iPtr->objResultPtr && !Tcl_IsShared(iPtr->objResultPtr)) { if (iPtr->objResultPtr->bytes == tclEmptyStringRep) { dsPtr->string = dsPtr->staticSpace; dsPtr->string[0] = 0; dsPtr->length = 0; dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE; } else { dsPtr->string = Tcl_GetString(iPtr->objResultPtr); dsPtr->length = iPtr->objResultPtr->length; dsPtr->spaceAvl = dsPtr->length + 1; TclFreeIntRep(iPtr->objResultPtr); iPtr->objResultPtr->bytes = tclEmptyStringRep; iPtr->objResultPtr->length = 0; } return; } /* * If the string result is empty, move the object result to the string * result, then reset the object result. */ (void) Tcl_GetStringResult(interp); |
︙ | ︙ | |||
2943 2944 2945 2946 2947 2948 2949 | * the given number, choose the shortest, breaking ties in favour of * the nearest, breaking remaining ties in favour of the one ending in * an even digit." * * Tcl 8.4 implements the first of these, which gives rise to * anomalies in formatting: * | | | | | | | | | | 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 | * the given number, choose the shortest, breaking ties in favour of * the nearest, breaking remaining ties in favour of the one ending in * an even digit." * * Tcl 8.4 implements the first of these, which gives rise to * anomalies in formatting: * * % expr 0.1 * 0.10000000000000001 * % expr 0.01 * 0.01 * % expr 1e-7 * 9.9999999999999995e-08 * * For human readability, it appears better to choose the second rule, * and let [expr 0.1] return 0.1. But for 8.4 compatibility, we prefer * the first (the recommended zero value for tcl_precision avoids the * problem entirely). * * Uncomment TCL_DD_SHORTEN_FLAG in the next call to prefer the method * that allows floating point values to be shortened if it can be done * without loss of precision. */ digits = TclDoubleDigits(value, *precisionPtr, TCL_DD_E_FORMAT /* | TCL_DD_SHORTEN_FLAG */, &exponent, &signum, &end); } if (signum) { *dst++ = '-'; } p = digits; if (exponent < -4 || exponent > 16) { /* |
︙ | ︙ | |||
3218 3219 3220 3221 3222 3223 3224 | * The formatted characters are written into the storage pointer to by * the "buffer" argument. * *---------------------------------------------------------------------- */ int | | | | | | | | 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 | * The formatted characters are written into the storage pointer to by * the "buffer" argument. * *---------------------------------------------------------------------- */ int TclFormatInt( char *buffer, /* Points to the storage into which the * formatted characters are written. */ long n) /* The integer to format. */ { long intVal; int i; int numFormatted, j; const char *digits = "0123456789"; /* * Check first whether "n" is zero. */ if (n == 0) { buffer[0] = '0'; buffer[1] = 0; return 1; } /* * Check whether "n" is the maximum negative value. This is -2^(m-1) for * an m-bit word, and has no positive equivalent; negating it produces the * same value. */ intVal = -n; /* [Bug 3390638] Workaround for*/ if (n == -n || intVal == n) { /* broken compiler optimizers. */ return sprintf(buffer, "%ld", n); } |
︙ | ︙ | |||
3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 | /* * Now reverse the characters. */ for (j = 0; j < i; j++, i--) { char tmp = buffer[i]; buffer[i] = buffer[j]; buffer[j] = tmp; } return numFormatted; } /* | > | 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 | /* * Now reverse the characters. */ for (j = 0; j < i; j++, i--) { char tmp = buffer[i]; buffer[i] = buffer[j]; buffer[j] = tmp; } return numFormatted; } /* |
︙ | ︙ | |||
3378 3379 3380 3381 3382 3383 3384 | /* * Report a parse error. */ parseError: if (interp != NULL) { | < < < < < < | | | | 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 | /* * Report a parse error. */ parseError: if (interp != NULL) { bytes = Tcl_GetString(objPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad index \"%s\": must be integer?[+-]integer? or" " end?[+-]integer?", bytes)); if (!strncmp(bytes, "end-", 4)) { bytes += 4; } TclCheckBadOctal(interp, bytes); Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL); } |
︙ | ︙ | |||
3422 3423 3424 3425 3426 3427 3428 | *---------------------------------------------------------------------- */ static void UpdateStringOfEndOffset( register Tcl_Obj *objPtr) { | | | | 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 | *---------------------------------------------------------------------- */ static void UpdateStringOfEndOffset( register Tcl_Obj *objPtr) { char buffer[TCL_INTEGER_SPACE + 5]; register int len; memcpy(buffer, "end", 4); len = sizeof("end") - 1; if (objPtr->internalRep.longValue != 0) { buffer[len++] = '-'; len += TclFormatInt(buffer+len, -(objPtr->internalRep.longValue)); } objPtr->bytes = ckalloc((unsigned) len+1); memcpy(objPtr->bytes, buffer, (unsigned) len+1); |
︙ | ︙ | |||
3479 3480 3481 3482 3483 3484 3485 | * Check for a string rep of the right form. */ bytes = TclGetStringFromObj(objPtr, &length); if ((*bytes != 'e') || (strncmp(bytes, "end", (size_t)((length > 3) ? 3 : length)) != 0)) { if (interp != NULL) { | | < | | 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 | * Check for a string rep of the right form. */ bytes = TclGetStringFromObj(objPtr, &length); if ((*bytes != 'e') || (strncmp(bytes, "end", (size_t)((length > 3) ? 3 : length)) != 0)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad index \"%s\": must be end?[+-]integer?", bytes)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL); } return TCL_ERROR; } /* * Convert the string rep. |
︙ | ︙ | |||
3515 3516 3517 3518 3519 3520 3521 | } else { /* * Conversion failed. Report the error. */ badIndexFormat: if (interp != NULL) { | | < | | 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 | } else { /* * Conversion failed. Report the error. */ badIndexFormat: if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad index \"%s\": must be end?[+-]integer?", bytes)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL); } return TCL_ERROR; } /* * The conversion succeeded. Free the old internal rep and set the new |
︙ | ︙ | |||
3593 3594 3595 3596 3597 3598 3599 | if (interp != NULL) { /* * Don't reset the result here because we want this result to * be added to an existing error message as extra info. */ | > | < | 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 | if (interp != NULL) { /* * Don't reset the result here because we want this result to * be added to an existing error message as extra info. */ Tcl_AppendToObj(Tcl_GetObjResult(interp), " (looks like invalid octal number)", -1); } return 1; } } return 0; } |
︙ | ︙ | |||
3746 3747 3748 3749 3750 3751 3752 | * Fill the global string value. */ pgvPtr->epoch++; if (NULL != pgvPtr->value) { ckfree(pgvPtr->value); } else { | | | 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 | * Fill the global string value. */ pgvPtr->epoch++; if (NULL != pgvPtr->value) { ckfree(pgvPtr->value); } else { Tcl_CreateExitHandler(FreeProcessGlobalValue, pgvPtr); } bytes = Tcl_GetStringFromObj(newValue, &pgvPtr->numBytes); pgvPtr->value = ckalloc(pgvPtr->numBytes + 1); memcpy(pgvPtr->value, bytes, (unsigned) pgvPtr->numBytes + 1); if (pgvPtr->encoding) { Tcl_FreeEncoding(pgvPtr->encoding); } |
︙ | ︙ | |||
4210 4211 4212 4213 4214 4215 4216 | *exactPtr = (anchorLeft && anchorRight); } return TCL_OK; invalidGlob: if (interp != NULL) { | | | 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 | *exactPtr = (anchorLeft && anchorRight); } return TCL_OK; invalidGlob: if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1)); 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.
︙ | ︙ | |||
3061 3062 3063 3064 3065 3066 3067 | * Verify that it is indeed an array variable. This test comes after the * traces - the variable may actually become an array as an effect of said * traces. */ if ((varPtr == NULL) || !TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr)) { | > | | 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 | * Verify that it is indeed an array variable. This test comes after the * traces - the variable may actually become an array as an effect of said * traces. */ if ((varPtr == NULL) || !TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" isn't an array", varName)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY", varName, NULL); return TCL_ERROR; } /* * Make a new array search with a free name. */ |
︙ | ︙ | |||
3156 3157 3158 3159 3160 3161 3162 | * Verify that it is indeed an array variable. This test comes after the * traces - the variable may actually become an array as an effect of said * traces. */ if ((varPtr == NULL) || !TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr)) { | | | | 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 | * Verify that it is indeed an array variable. This test comes after the * traces - the variable may actually become an array as an effect of said * traces. */ if ((varPtr == NULL) || !TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" isn't an array", TclGetString(varNameObj))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY", TclGetString(varNameObj), NULL); return TCL_ERROR; } /* * Get the search. |
︙ | ︙ | |||
3262 3263 3264 3265 3266 3267 3268 | * Verify that it is indeed an array variable. This test comes after the * traces - the variable may actually become an array as an effect of said * traces. */ if ((varPtr == NULL) || !TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr)) { | | | | 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 | * Verify that it is indeed an array variable. This test comes after the * traces - the variable may actually become an array as an effect of said * traces. */ if ((varPtr == NULL) || !TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" isn't an array", TclGetString(varNameObj))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY", TclGetString(varNameObj), NULL); return TCL_ERROR; } /* * Get the search. |
︙ | ︙ | |||
3372 3373 3374 3375 3376 3377 3378 | * Verify that it is indeed an array variable. This test comes after the * traces - the variable may actually become an array as an effect of said * traces. */ if ((varPtr == NULL) || !TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr)) { | | | | 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 | * Verify that it is indeed an array variable. This test comes after the * traces - the variable may actually become an array as an effect of said * traces. */ if ((varPtr == NULL) || !TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" isn't an array", TclGetString(varNameObj))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY", TclGetString(varNameObj), NULL); return TCL_ERROR; } /* * Get the search. |
︙ | ︙ | |||
4015 4016 4017 4018 4019 4020 4021 | * Verify that it is indeed an array variable. This test comes after the * traces - the variable may actually become an array as an effect of said * traces. */ if ((varPtr == NULL) || !TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr)) { | | | > | | 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 | * Verify that it is indeed an array variable. This test comes after the * traces - the variable may actually become an array as an effect of said * traces. */ if ((varPtr == NULL) || !TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" isn't an array", TclGetString(varNameObj))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY", 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", -1)); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewStringObj(stats, -1)); ckfree(stats); return TCL_OK; } |
︙ | ︙ | |||
4313 4314 4315 4316 4317 4318 4319 | if (!(arrayPtr != NULL ? (TclIsVarInHash(arrayPtr) && TclGetVarNsPtr(arrayPtr)) : (TclIsVarInHash(otherPtr) && TclGetVarNsPtr(otherPtr))) && ((myFlags & (TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY)) || (varFramePtr == NULL) || !HasLocalVars(varFramePtr) || (strstr(TclGetString(myNamePtr), "::") != NULL))) { | | | | | 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 | if (!(arrayPtr != NULL ? (TclIsVarInHash(arrayPtr) && TclGetVarNsPtr(arrayPtr)) : (TclIsVarInHash(otherPtr) && TclGetVarNsPtr(otherPtr))) && ((myFlags & (TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY)) || (varFramePtr == NULL) || !HasLocalVars(varFramePtr) || (strstr(TclGetString(myNamePtr), "::") != NULL))) { Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf( "bad variable name \"%s\": upvar won't create " "namespace variable that refers to procedure variable", TclGetString(myNamePtr))); Tcl_SetErrorCode(interp, "TCL", "UPVAR", "INVERTED", NULL); return TCL_ERROR; } } return TclPtrObjMakeUpvar(interp, otherPtr, myNamePtr, myFlags, index); } |
︙ | ︙ | |||
4414 4415 4416 4417 4418 4419 4420 | if (p != NULL) { p += strlen(p)-1; if (*p == ')') { /* * myName looks like an array reference. */ | | | | > | 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 | if (p != NULL) { p += strlen(p)-1; if (*p == ')') { /* * myName looks like an array reference. */ Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf( "bad variable name \"%s\": upvar won't create a" " scalar variable that looks like an array element", myName)); Tcl_SetErrorCode(interp, "TCL", "UPVAR", "LOCAL_ELEMENT", NULL); return TCL_ERROR; } } /* |
︙ | ︙ | |||
4443 4444 4445 4446 4447 4448 4449 | Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME", TclGetString(myNamePtr), NULL); return TCL_ERROR; } } if (varPtr == otherPtr) { | | | | | | | | 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 | Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME", TclGetString(myNamePtr), NULL); return TCL_ERROR; } } if (varPtr == otherPtr) { Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_NewStringObj( "can't upvar from variable to itself", -1)); 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)); Tcl_SetErrorCode(interp, "TCL", "UPVAR", "TRACED", NULL); return TCL_ERROR; } else if (!TclIsVarUndefined(varPtr)) { Var *linkPtr; /* * The variable already existed. Make sure this variable "varPtr" * isn't the same as "otherPtr" (avoid circular links). Also, if it's * not an upvar then it's an error. If it is an upvar, then just * disconnect it from the thing it currently refers to. */ if (!TclIsVarLink(varPtr)) { Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf( "variable \"%s\" already exists", myName)); Tcl_SetErrorCode(interp, "TCL", "UPVAR", "EXISTS", NULL); return TCL_ERROR; } linkPtr = varPtr->value.linkPtr; if (linkPtr == otherPtr) { return TCL_OK; |
︙ | ︙ | |||
4964 4965 4966 4967 4968 4969 4970 | } if ((result == 0) && hasLevel) { /* * Synthesize an error message since TclObjGetFrame doesn't do this * for this particular case. */ | > | < | | | 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 | } if ((result == 0) && hasLevel) { /* * Synthesize an error message since TclObjGetFrame doesn't do this * for this particular case. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad level \"%s\"", TclGetString(levelObj))); Tcl_SetErrorCode(interp, "TCL", "VALUE", "LEVEL", NULL); return TCL_ERROR; } /* * We've now finished with parsing levels; skip to the variable names. */ objc -= hasLevel + 1; objv += hasLevel + 1; /* * Iterate over each (other variable, local variable) pair. Divide the * other variable name into two parts, then call MakeUpvar to do all the * work of linking it to the local variable. */ |
︙ | ︙ | |||
5056 5057 5058 5059 5060 5061 5062 | TclFreeIntRep(objPtr); objPtr->typePtr = &tclArraySearchType; objPtr->internalRep.twoPtrValue.ptr1 = INT2PTR(id); objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(offset); return TCL_OK; syntax: | > | < | 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 | TclFreeIntRep(objPtr); objPtr->typePtr = &tclArraySearchType; objPtr->internalRep.twoPtrValue.ptr1 = INT2PTR(id); objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(offset); return TCL_OK; syntax: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "illegal search identifier \"%s\"", string)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAYSEARCH", string, NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
5122 5123 5124 5125 5126 5127 5128 | /* * This test cannot be placed inside the Tcl_Obj machinery, since it is * dependent on the variable context. */ if (strcmp(string+offset, varName) != 0) { | | | | < | 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 | /* * This test cannot be placed inside the Tcl_Obj machinery, since it is * dependent on the variable context. */ if (strcmp(string+offset, varName) != 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "search identifier \"%s\" isn't for variable \"%s\"", string, varName)); goto badLookup; } /* * Search through the list of active searches on the interpreter to see if * the desired one exists. * |
︙ | ︙ | |||
5149 5150 5151 5152 5153 5154 5155 | for (searchPtr = Tcl_GetHashValue(hPtr); searchPtr != NULL; searchPtr = searchPtr->nextPtr) { if (searchPtr->id == id) { return searchPtr; } } } | > | | 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 | for (searchPtr = Tcl_GetHashValue(hPtr); searchPtr != NULL; searchPtr = searchPtr->nextPtr) { if (searchPtr->id == id) { return searchPtr; } } } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't find search \"%s\"", string)); badLookup: Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAYSEARCH", string, NULL); return NULL; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
5890 5891 5892 5893 5894 5895 5896 | varPtr = VarHashFindVar(&nsPtr[search]->varTable, simpleNamePtr); } } if (simpleName != name) { Tcl_DecrRefCount(simpleNamePtr); } if ((varPtr == NULL) && (flags & TCL_LEAVE_ERR_MSG)) { | | | | 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 | varPtr = VarHashFindVar(&nsPtr[search]->varTable, simpleNamePtr); } } if (simpleName != name) { Tcl_DecrRefCount(simpleNamePtr); } if ((varPtr == NULL) && (flags & TCL_LEAVE_ERR_MSG)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown variable \"%s\"", name)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", name, NULL); } return (Tcl_Var) varPtr; } /* *---------------------------------------------------------------------- |
︙ | ︙ |
Changes to generic/tclZlib.c.
︙ | ︙ | |||
573 574 575 576 577 578 579 | goto error; } Tcl_DStringInit(&cmdname); TclDStringAppendLiteral(&cmdname, "::tcl::zlib::streamcmd_"); TclDStringAppendObj(&cmdname, Tcl_GetObjResult(interp)); if (Tcl_GetCommandInfo(interp, Tcl_DStringValue(&cmdname), &cmdinfo) == 1) { | | | | 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | goto error; } 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", -1)); Tcl_SetErrorCode(interp, "TCL", "BUG", "EXISTING_CMD", NULL); Tcl_DStringFree(&cmdname); goto error; } Tcl_ResetResult(interp); /* |
︙ | ︙ | |||
896 897 898 899 900 901 902 | ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle; char *dataTmp = NULL; int e, size, outSize; Tcl_Obj *obj; if (zshPtr->streamEnd) { if (zshPtr->interp) { | | | | 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 | ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle; char *dataTmp = NULL; int e, size, outSize; Tcl_Obj *obj; if (zshPtr->streamEnd) { if (zshPtr->interp) { Tcl_SetObjResult(zshPtr->interp, Tcl_NewStringObj( "already past compressed stream end", -1)); 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); |
︙ | ︙ | |||
1081 1082 1083 1084 1085 1086 1087 | /* * State: We have not satisfied the request yet and there may be * more to inflate. */ if (zshPtr->stream.avail_in > 0) { if (zshPtr->interp) { | | | | | 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 | /* * State: We have not satisfied the request yet and there may be * more to inflate. */ if (zshPtr->stream.avail_in > 0) { if (zshPtr->interp) { Tcl_SetObjResult(zshPtr->interp, Tcl_NewStringObj( "unexpected zlib internal state during" " decompression", -1)); Tcl_SetErrorCode(zshPtr->interp, "TCL", "ZIP", "STATE", NULL); } Tcl_SetByteArrayLength(data, existing); return TCL_ERROR; } |
︙ | ︙ | |||
1892 1893 1894 1895 1896 1897 1898 | format = TCL_ZLIB_FORMAT_GZIP; break; case FMT_GUNZIP: mode = TCL_ZLIB_STREAM_INFLATE; format = TCL_ZLIB_FORMAT_GZIP; break; default: | | | | | | | | | | | | | 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 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 | format = TCL_ZLIB_FORMAT_GZIP; break; case FMT_GUNZIP: mode = TCL_ZLIB_STREAM_INFLATE; format = TCL_ZLIB_FORMAT_GZIP; break; default: Tcl_SetObjResult(interp, Tcl_NewStringObj("impossible!", -1)); return TCL_ERROR; } if (TclGetChannelFromObj(interp, objv[3], &chan, &chanMode, 0) != TCL_OK) { return TCL_ERROR; } /* * Sanity checks. */ if (mode == TCL_ZLIB_STREAM_DEFLATE && !(chanMode & TCL_WRITABLE)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "compression may only be applied to writable channels", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "UNREADABLE", NULL); return TCL_ERROR; } /* * Parse options. */ level = Z_DEFAULT_COMPRESSION; for (i=4 ; i<objc ; i++) { if (Tcl_GetIndexFromObj(interp, objv[i], pushOptions, "option", 0, &option) != TCL_OK) { return TCL_ERROR; } switch ((enum pushOptions) option) { case poHeader: if (++i > objc-1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "value missing for -header option", -1)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL); return TCL_ERROR; } headerObj = objv[i]; if (Tcl_DictObjSize(interp, headerObj, &dummy) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (in -header option)"); return TCL_ERROR; } break; case poLevel: if (++i > objc-1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "value missing for -level option", -1)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[i], (int *) &level) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (in -level option)"); return TCL_ERROR; } if (level < 0 || level > 9) { extraInfoStr = "\n (in -level option)"; goto badLevel; } break; case poLimit: if (++i > objc-1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "value missing for -limit option", -1)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[i], (int *) &limit) != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (in -limit option)"); return TCL_ERROR; |
︙ | ︙ | |||
1992 1993 1994 1995 1996 1997 1998 | return TCL_OK; } }; return TCL_ERROR; badLevel: | | > | | 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 | return TCL_OK; } }; return TCL_ERROR; badLevel: Tcl_SetObjResult(interp, Tcl_NewStringObj("level must be 0 to 9", -1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMPRESSIONLEVEL", NULL); if (extraInfoStr) { Tcl_AddErrorInfo(interp, extraInfoStr); } return TCL_ERROR; badBuffer: Tcl_SetObjResult(interp, Tcl_NewStringObj( "buffer size must be 32 to 65536", -1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "BUFFERSIZE", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
2082 2083 2084 2085 2086 2087 2088 | flush = -2; } else { flush = Z_FINISH; } break; case ao_buffer: /* -buffer */ if (i == objc-2) { | > | | < | | > | | | 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 | flush = -2; } else { 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", -1)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[i+1], &buffersize) != TCL_OK) { return TCL_ERROR; } if (buffersize < 1 || buffersize > 65536) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "buffer size must be 32 to 65536", -1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "BUFFERSIZE", NULL); return TCL_ERROR; } } if (flush == -2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-flush\", \"-fullflush\" and \"-finalize\" options" " are mutually exclusive", -1)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "EXCLUSIVE", NULL); return TCL_ERROR; } } if (flush == -1) { flush = 0; } |
︙ | ︙ | |||
2154 2155 2156 2157 2158 2159 2160 | if (flush > -1) { flush = -2; } else { flush = Z_FINISH; } break; case ao_buffer: | | | > | | | 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 | if (flush > -1) { flush = -2; } else { flush = Z_FINISH; } break; case ao_buffer: Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-buffer\" option not supported here", -1)); return TCL_ERROR; } if (flush == -2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-flush\", \"-fullflush\" and \"-finalize\" options" " are mutually exclusive", -1)); Tcl_SetErrorCode(interp, "TCL", "ZIP", "EXCLUSIVE", NULL); return TCL_ERROR; } } if (flush == -1) { flush = 0; } |
︙ | ︙ | |||
2310 2311 2312 2313 2314 2315 2316 | if (Tcl_WriteRaw(cd->parent, cd->outBuffer, cd->outAllocated - cd->outStream.avail_out) < 0) { /* TODO: is this the right way to do errors on close? * Note: when close is called from FinalizeIOSubsystem * then interp may be NULL */ if (!TclInThreadExit()) { if (interp) { | | | | | 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 | if (Tcl_WriteRaw(cd->parent, cd->outBuffer, cd->outAllocated - cd->outStream.avail_out) < 0) { /* TODO: is this the right way to do errors on close? * Note: when close is called from FinalizeIOSubsystem * then interp may be NULL */ if (!TclInThreadExit()) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error while finalizing file: %s", Tcl_PosixError(interp))); } } result = TCL_ERROR; break; } } } while (e != Z_STREAM_END); |
︙ | ︙ | |||
2577 2578 2579 2580 2581 2582 2583 | int flushType; if (value[0] == 'f' && strcmp(value, "full") == 0) { flushType = Z_FULL_FLUSH; } else if (value[0] == 's' && strcmp(value, "sync") == 0) { flushType = Z_SYNC_FLUSH; } else { | | | > | 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 | int flushType; if (value[0] == 'f' && strcmp(value, "full") == 0) { flushType = Z_FULL_FLUSH; } else if (value[0] == 's' && strcmp(value, "sync") == 0) { flushType = Z_SYNC_FLUSH; } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown -flush type \"%s\": must be full or sync", value)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "FLUSH", NULL); return TCL_ERROR; } /* * Try to actually do the flush now. */ |
︙ | ︙ | |||
2606 2607 2608 2609 2610 2611 2612 | return TCL_ERROR; } else if (cd->outStream.avail_out == 0) { break; } if (Tcl_WriteRaw(cd->parent, cd->outBuffer, cd->outStream.next_out - (Bytef *) cd->outBuffer) < 0) { | > | | | 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 | return TCL_ERROR; } else if (cd->outStream.avail_out == 0) { break; } if (Tcl_WriteRaw(cd->parent, cd->outBuffer, cd->outStream.next_out - (Bytef *) cd->outBuffer) < 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "problem flushing channel: %s", Tcl_PosixError(interp))); return TCL_ERROR; } } return TCL_OK; } if (setOptionProc == NULL) { |
︙ | ︙ | |||
3148 3149 3150 3151 3152 3153 3154 | Tcl_Interp *interp, int mode, int format, int level, Tcl_Obj *dictObj, Tcl_ZlibStream *zshandle) { | | | 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 | Tcl_Interp *interp, int mode, int format, int level, Tcl_Obj *dictObj, Tcl_ZlibStream *zshandle) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1)); Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL); return TCL_ERROR; } int Tcl_ZlibStreamClose( Tcl_ZlibStream zshandle) |
︙ | ︙ | |||
3214 3215 3216 3217 3218 3219 3220 | Tcl_ZlibDeflate( Tcl_Interp *interp, int format, Tcl_Obj *data, int level, Tcl_Obj *gzipHeaderDictObj) { | | | | 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 | Tcl_ZlibDeflate( Tcl_Interp *interp, int format, Tcl_Obj *data, int level, Tcl_Obj *gzipHeaderDictObj) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1)); 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) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1)); Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL); return TCL_ERROR; } unsigned int Tcl_ZlibCRC32( unsigned int crc, |
︙ | ︙ |
Changes to library/dde/pkgIndex.tcl.
|
| | | | | | 1 2 3 4 5 6 7 | if {([info commands ::tcl::pkgconfig] eq "") || ([info sharedlibextension] ne ".dll")} return if {[::tcl::pkgconfig get debug]} { package ifneeded dde 1.4.0b1 [list load [file join $dir tcldde14g.dll] dde] } else { package ifneeded dde 1.4.0b1 [list load [file join $dir tcldde14.dll] dde] } |
Changes to library/init.tcl.
︙ | ︙ | |||
685 686 687 688 689 690 691 | foreach var {PATH Path path} { if {[info exists env($var)]} { append path ";$env($var)" } } | > > | | | | | | < | 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 | foreach var {PATH Path path} { if {[info exists env($var)]} { append path ";$env($var)" } } foreach ext $execExtensions { unset -nocomplain checked foreach dir [split $path {;}] { # Skip already checked directories if {[info exists checked($dir)] || ($dir eq "")} { continue } set checked($dir) {} set file [file join $dir ${name}${ext}] if {[file exists $file] && ![file isdirectory $file]} { return [set auto_execs($name) [list $file]] } } } return "" |
︙ | ︙ |
Changes to library/reg/pkgIndex.tcl.
|
| | | | 1 2 3 4 5 6 7 8 9 | if {([info commands ::tcl::pkgconfig] eq "") || ([info sharedlibextension] ne ".dll")} return if {[::tcl::pkgconfig get debug]} { package ifneeded registry 1.3.0 \ [list load [file join $dir tclreg13g.dll] registry] } else { package ifneeded registry 1.3.0 \ [list load [file join $dir tclreg13.dll] registry] } |
Changes to macosx/tclMacOSXFCmd.c.
︙ | ︙ | |||
144 145 146 147 148 149 150 | finderinfo *finder = (finderinfo *) &finfo.data; off_t *rsrcForkSize = (off_t *) &finfo.data; const char *native; result = TclpObjStat(fileName, &statBuf); if (result != 0) { | > | | | | > | | | 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 | finderinfo *finder = (finderinfo *) &finfo.data; off_t *rsrcForkSize = (off_t *) &finfo.data; const char *native; result = TclpObjStat(fileName, &statBuf); if (result != 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); return TCL_ERROR; } if (S_ISDIR(statBuf.st_mode) && objIndex != MACOSX_HIDDEN_ATTRIBUTE) { /* * Directories only support attribute "-hidden". */ errno = EISDIR; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid attribute: %s", Tcl_PosixError(interp))); return TCL_ERROR; } bzero(&alist, sizeof(struct attrlist)); alist.bitmapcount = ATTR_BIT_MAP_COUNT; if (objIndex == MACOSX_RSRCLENGTH_ATTRIBUTE) { alist.fileattr = ATTR_FILE_RSRCLENGTH; } else { alist.commonattr = ATTR_CMN_FNDRINFO; } native = Tcl_FSGetNativePath(fileName); result = getattrlist(native, &alist, &finfo, sizeof(fileinfobuf), 0); if (result != 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read attributes of \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); return TCL_ERROR; } switch (objIndex) { case MACOSX_CREATOR_ATTRIBUTE: *attributePtrPtr = NewOSTypeObj( OSSwapBigToHostInt32(finder->creator)); |
︙ | ︙ | |||
195 196 197 198 199 200 201 | break; case MACOSX_RSRCLENGTH_ATTRIBUTE: *attributePtrPtr = Tcl_NewWideIntObj(*rsrcForkSize); break; } return TCL_OK; #else | > | | | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | break; case MACOSX_RSRCLENGTH_ATTRIBUTE: *attributePtrPtr = Tcl_NewWideIntObj(*rsrcForkSize); break; } return TCL_OK; #else Tcl_SetObjResult(interp, Tcl_NewStringObj( "Mac OS X file attributes not supported", -1)); Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL); return TCL_ERROR; #endif /* HAVE_GETATTRLIST */ } /* *--------------------------------------------------------------------------- * * TclMacOSXSetFileAttribute -- * |
︙ | ︙ | |||
237 238 239 240 241 242 243 | finderinfo *finder = (finderinfo *) &finfo.data; off_t *rsrcForkSize = (off_t *) &finfo.data; const char *native; result = TclpObjStat(fileName, &statBuf); if (result != 0) { | > | | | | > | | | 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 | finderinfo *finder = (finderinfo *) &finfo.data; off_t *rsrcForkSize = (off_t *) &finfo.data; const char *native; result = TclpObjStat(fileName, &statBuf); if (result != 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); return TCL_ERROR; } if (S_ISDIR(statBuf.st_mode) && objIndex != MACOSX_HIDDEN_ATTRIBUTE) { /* * Directories only support attribute "-hidden". */ errno = EISDIR; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid attribute: %s", Tcl_PosixError(interp))); return TCL_ERROR; } bzero(&alist, sizeof(struct attrlist)); alist.bitmapcount = ATTR_BIT_MAP_COUNT; if (objIndex == MACOSX_RSRCLENGTH_ATTRIBUTE) { alist.fileattr = ATTR_FILE_RSRCLENGTH; } else { alist.commonattr = ATTR_CMN_FNDRINFO; } native = Tcl_FSGetNativePath(fileName); result = getattrlist(native, &alist, &finfo, sizeof(fileinfobuf), 0); if (result != 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read attributes of \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); return TCL_ERROR; } if (objIndex != MACOSX_RSRCLENGTH_ATTRIBUTE) { OSType t; int h; |
︙ | ︙ | |||
302 303 304 305 306 307 308 | break; } result = setattrlist(native, &alist, &finfo.data, sizeof(finfo.data), 0); if (result != 0) { | > | | < | | | 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 | break; } result = setattrlist(native, &alist, &finfo.data, sizeof(finfo.data), 0); if (result != 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not set attributes of \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); return TCL_ERROR; } } else { Tcl_WideInt newRsrcForkSize; if (Tcl_GetWideIntFromObj(interp, attributePtr, &newRsrcForkSize) != TCL_OK) { return TCL_ERROR; } if (newRsrcForkSize != *rsrcForkSize) { Tcl_DString ds; /* * Only setting rsrclength to 0 to strip a file's resource fork is * supported. */ if (newRsrcForkSize != 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "setting nonzero rsrclength not supported", -1)); Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL); return TCL_ERROR; } /* * Construct path to resource fork. */ |
︙ | ︙ | |||
356 357 358 359 360 361 362 | result = close(fd); } } Tcl_DStringFree(&ds); if (result != 0) { | | | | < > | | 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 | result = close(fd); } } Tcl_DStringFree(&ds); if (result != 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not truncate resource fork of \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); return TCL_ERROR; } } } return TCL_OK; #else Tcl_SetObjResult(interp, Tcl_NewStringObj( "Mac OS X file attributes not supported", -1)); Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL); return TCL_ERROR; #endif } /* *--------------------------------------------------------------------------- |
︙ | ︙ | |||
636 637 638 639 640 641 642 | Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman"); string = Tcl_GetStringFromObj(objPtr, &length); Tcl_UtfToExternalDString(encoding, string, length, &ds); if (Tcl_DStringLength(&ds) > 4) { if (interp) { | > | < | 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 | Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman"); string = Tcl_GetStringFromObj(objPtr, &length); Tcl_UtfToExternalDString(encoding, string, length, &ds); if (Tcl_DStringLength(&ds) > 4) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected Macintosh OS type but got \"%s\": ", string)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "MAC_OSTYPE", NULL); } result = TCL_ERROR; } else { OSType osType; char bytes[4] = {'\0','\0','\0','\0'}; |
︙ | ︙ |
Changes to tests/assocd.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testgetassocdata [llength [info commands testgetassocdata]] testConstraint testsetassocdata [llength [info commands testsetassocdata]] testConstraint testdelassocdata [llength [info commands testdelassocdata]] test assocd-1.1 {testing setting assoc data} testsetassocdata { testsetassocdata a 1 } "" | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testgetassocdata [llength [info commands testgetassocdata]] testConstraint testsetassocdata [llength [info commands testsetassocdata]] testConstraint testdelassocdata [llength [info commands testdelassocdata]] test assocd-1.1 {testing setting assoc data} testsetassocdata { testsetassocdata a 1 } "" |
︙ | ︙ |
Changes to tests/async.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testasync [llength [info commands testasync]] testConstraint threaded [::tcl::pkgconfig get threaded] proc async1 {result code} { global aresult acode set aresult $result set acode $code | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testasync [llength [info commands testasync]] testConstraint threaded [::tcl::pkgconfig get threaded] proc async1 {result code} { global aresult acode set aresult $result set acode $code |
︙ | ︙ |
Changes to tests/basic.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 namespace import -force ::tcltest::* testConstraint testevalex [llength [info commands testevalex]] testConstraint testcmdtoken [llength [info commands testcmdtoken]] testConstraint testcreatecommand [llength [info commands testcreatecommand]] testConstraint exec [llength [info commands exec]] catch {namespace delete test_ns_basic} catch {interp delete test_interp} | > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 namespace import -force ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testevalex [llength [info commands testevalex]] testConstraint testcmdtoken [llength [info commands testcmdtoken]] testConstraint testcreatecommand [llength [info commands testcreatecommand]] testConstraint exec [llength [info commands exec]] catch {namespace delete test_ns_basic} catch {interp delete test_interp} |
︙ | ︙ |
Changes to tests/chanio.test.
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 | variable f variable i variable n variable v variable msg variable expected testConstraint testchannel [llength [info commands testchannel]] testConstraint exec [llength [info commands exec]] testConstraint openpipe 1 testConstraint fileevent [llength [info commands fileevent]] testConstraint fcopy [llength [info commands fcopy]] testConstraint testfevent [llength [info commands testfevent]] testConstraint testchannelevent [llength [info commands testchannelevent]] | > > > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | variable f variable i variable n variable v variable msg variable expected ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testchannel [llength [info commands testchannel]] testConstraint exec [llength [info commands exec]] testConstraint openpipe 1 testConstraint fileevent [llength [info commands fileevent]] testConstraint fcopy [llength [info commands fcopy]] testConstraint testfevent [llength [info commands testfevent]] testConstraint testchannelevent [llength [info commands testchannelevent]] |
︙ | ︙ |
Changes to tests/clock.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 | if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } if {[testConstraint win]} { | < < | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } if {[testConstraint win]} { if {[catch { ::tcltest::loadTestedCommands package require registry }]} { namespace eval ::tcl::clock {variable NoRegistry {}} } } package require msgcat 1.4 |
︙ | ︙ |
Changes to tests/cmdAH.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2.1 namespace import -force ::tcltest::* } testConstraint testchmod [llength [info commands testchmod]] testConstraint testsetplatform [llength [info commands testsetplatform]] testConstraint testvolumetype [llength [info commands testvolumetype]] testConstraint linkDirectory [expr { ![testConstraint win] || ([string index $tcl_platform(osVersion) 0] >= 5 && [lindex [file system [temporaryDirectory]] 1] eq "NTFS") | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2.1 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testchmod [llength [info commands testchmod]] testConstraint testsetplatform [llength [info commands testsetplatform]] testConstraint testvolumetype [llength [info commands testvolumetype]] testConstraint linkDirectory [expr { ![testConstraint win] || ([string index $tcl_platform(osVersion) 0] >= 5 && [lindex [file system [temporaryDirectory]] 1] eq "NTFS") |
︙ | ︙ |
Changes to tests/cmdIL.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } # Used for constraining memory leak tests testConstraint memory [llength [info commands memory]] testConstraint testobj [llength [info commands testobj]] test cmdIL-1.1 {Tcl_LsortObjCmd procedure} -returnCodes error -body { lsort } -result {wrong # args: should be "lsort ?-option value ...? list"} | > > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Used for constraining memory leak tests testConstraint memory [llength [info commands memory]] testConstraint testobj [llength [info commands testobj]] test cmdIL-1.1 {Tcl_LsortObjCmd procedure} -returnCodes error -body { lsort } -result {wrong # args: should be "lsort ?-option value ...? list"} |
︙ | ︙ |
Changes to tests/cmdInfo.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint testcmdinfo [llength [info commands testcmdinfo]] testConstraint testcmdtoken [llength [info commands testcmdtoken]] test cmdinfo-1.1 {command procedure and clientData} {testcmdinfo} { testcmdinfo create x1 testcmdinfo get x1 } {CmdProc1 original CmdDelProc1 original :: stringProc} | > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testcmdinfo [llength [info commands testcmdinfo]] testConstraint testcmdtoken [llength [info commands testcmdtoken]] test cmdinfo-1.1 {command procedure and clientData} {testcmdinfo} { testcmdinfo create x1 testcmdinfo get x1 } {CmdProc1 original CmdDelProc1 original :: stringProc} |
︙ | ︙ |
Changes to tests/compExpr-old.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} { testConstraint testmathfunctions 0 } else { testConstraint testmathfunctions 1 } # Big test for correct ordering of data in [expr] | > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} { testConstraint testmathfunctions 0 } else { testConstraint testmathfunctions 1 } # Big test for correct ordering of data in [expr] |
︙ | ︙ |
Changes to tests/compExpr.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} { testConstraint testmathfunctions 0 } else { testConstraint testmathfunctions 1 } # Constrain memory leak tests | > > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} { testConstraint testmathfunctions 0 } else { testConstraint testmathfunctions 1 } # Constrain memory leak tests |
︙ | ︙ |
Changes to tests/compile.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 namespace import -force ::tcltest::* testConstraint exec [llength [info commands exec]] testConstraint memory [llength [info commands memory]] testConstraint testevalex [llength [info commands testevalex]] # The following tests are very incomplete, although the rest of the # test suite covers this file fairly well. | > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 namespace import -force ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint exec [llength [info commands exec]] testConstraint memory [llength [info commands memory]] testConstraint testevalex [llength [info commands testevalex]] # The following tests are very incomplete, although the rest of the # test suite covers this file fairly well. |
︙ | ︙ |
Changes to tests/coroutine.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testnrelevels [llength [info commands testnrelevels]] testConstraint memory [llength [info commands memory]] set lambda [list {{start 0} {stop 10}} { # init set i $start set imax $stop | > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testnrelevels [llength [info commands testnrelevels]] testConstraint memory [llength [info commands memory]] set lambda [list {{start 0} {stop 10}} { # init set i $start set imax $stop |
︙ | ︙ |
Changes to tests/dcall.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testdcall [llength [info commands testdcall]] test dcall-1.1 {deletion callbacks} testdcall { lsort -increasing [testdcall 1 2 3] } {1 2 3} test dcall-1.2 {deletion callbacks} testdcall { testdcall | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testdcall [llength [info commands testdcall]] test dcall-1.1 {deletion callbacks} testdcall { lsort -increasing [testdcall 1 2 3] } {1 2 3} test dcall-1.2 {deletion callbacks} testdcall { testdcall |
︙ | ︙ |
Changes to tests/dstring.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest namespace import -force ::tcltest::* } testConstraint testdstring [llength [info commands testdstring]] if {[testConstraint testdstring]} { testdstring free } test dstring-1.1 {appending and retrieving} -constraints testdstring -setup { testdstring free | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testdstring [llength [info commands testdstring]] if {[testConstraint testdstring]} { testdstring free } test dstring-1.1 {appending and retrieving} -constraints testdstring -setup { testdstring free |
︙ | ︙ |
Changes to tests/encoding.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package require tcltest 2 namespace eval ::tcl::test::encoding { variable x namespace import -force ::tcltest::* proc toutf {args} { variable x lappend x "toutf $args" } proc fromutf {args} { variable x lappend x "fromutf $args" } proc runtests {} { variable x # Some tests require the testencoding command testConstraint testencoding [llength [info commands testencoding]] testConstraint exec [llength [info commands exec]] testConstraint testgetdefenc [llength [info commands testgetdefenc]] | > > > > > < | 10 11 12 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 | package require tcltest 2 namespace eval ::tcl::test::encoding { variable x namespace import -force ::tcltest::* catch { ::tcltest::loadTestedCommands package require -exact Tcltest [info patchlevel] } proc toutf {args} { variable x lappend x "toutf $args" } proc fromutf {args} { variable x lappend x "fromutf $args" } proc runtests {} { variable x # Some tests require the testencoding command testConstraint testencoding [llength [info commands testencoding]] testConstraint exec [llength [info commands exec]] testConstraint testgetdefenc [llength [info commands testgetdefenc]] # TclInitEncodingSubsystem is tested by the rest of this file # TclFinalizeEncodingSubsystem is not currently tested test encoding-1.1 {Tcl_GetEncoding: system encoding} -setup { set old [encoding system] } -constraints {testencoding} -body { |
︙ | ︙ | |||
414 415 416 417 418 419 420 | test encoding-24.1 {EscapeFreeProc on open channels} exec { runInSubprocess { set f [open [file join [file dirname [info script]] iso2022.txt]] fconfigure $f -encoding iso2022-jp gets $f } } {} | | > | | 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | test encoding-24.1 {EscapeFreeProc on open channels} exec { runInSubprocess { set f [open [file join [file dirname [info script]] iso2022.txt]] fconfigure $f -encoding iso2022-jp gets $f } } {} test encoding-24.2 {EscapeFreeProc on open channels} {exec} { # Bug #524674 output viewable [runInSubprocess { encoding system cp1252; # Bug #2891556 crash revelator fconfigure stdout -encoding iso2022-jp puts ab\u4e4e\u68d9g set env(TCL_FINALIZE_ON_EXIT) 1 exit }] } "ab\x1b\$B8C\x1b\$(DD%\x1b(Bg (ab\\u001b\$B8C\\u001b\$(DD%\\u001b(Bg)" test encoding-24.3 {EscapeFreeProc on open channels} {stdio} { # Bug #219314 - if we don't free escape encodings correctly on channel # closure, we go boom set file [makeFile { encoding system iso2022-jp |
︙ | ︙ |
Changes to tests/event.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # This file contains a collection of tests for the procedures in the file # tclEvent.c, which includes the "update", and "vwait" Tcl commands. Sourcing # this file into Tcl runs the tests and generates output for errors. No # output means no errors were found. # # Copyright (c) 1995-1997 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 namespace import -force ::tcltest::* testConstraint testfilehandler [llength [info commands testfilehandler]] testConstraint testexithandler [llength [info commands testexithandler]] testConstraint testfilewait [llength [info commands testfilewait]] testConstraint exec [llength [info commands exec]] test event-1.1 {Tcl_CreateFileHandler, reading} -setup { | > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # This file contains a collection of tests for the procedures in the file # tclEvent.c, which includes the "update", and "vwait" Tcl commands. Sourcing # this file into Tcl runs the tests and generates output for errors. No # output means no errors were found. # # Copyright (c) 1995-1997 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 namespace import -force ::tcltest::* catch { ::tcltest::loadTestedCommands package require -exact Tcltest [info patchlevel] set ::tcltestlib [lindex [package ifneeded Tcltest [info patchlevel]] 1] } testConstraint testfilehandler [llength [info commands testfilehandler]] testConstraint testexithandler [llength [info commands testexithandler]] testConstraint testfilewait [llength [info commands testfilewait]] testConstraint exec [llength [info commands exec]] test event-1.1 {Tcl_CreateFileHandler, reading} -setup { |
︙ | ︙ | |||
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 476 477 478 479 480 481 482 483 484 485 486 487 488 | # file/exec test than a bgerror test. # end of bgerror tests catch {rename bgerror {}} test event-8.1 {Tcl_CreateExitHandler procedure} {stdio testexithandler} { set child [open |[list [interpreter]] r+] puts $child "testexithandler create 41; testexithandler create 4" puts $child "testexithandler create 6; exit" flush $child set result [read $child] close $child return $result } {even 6 even 4 odd 41 } test event-9.1 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} { set child [open |[list [interpreter]] r+] puts $child "testexithandler create 41; testexithandler create 4" puts $child "testexithandler create 6; testexithandler delete 41" puts $child "testexithandler create 16; exit" flush $child set result [read $child] close $child return $result } {even 16 even 6 even 4 } test event-9.2 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} { set child [open |[list [interpreter]] r+] puts $child "testexithandler create 41; testexithandler create 4" puts $child "testexithandler create 6; testexithandler delete 4" puts $child "testexithandler create 16; exit" flush $child set result [read $child] close $child return $result } {even 16 even 6 odd 41 } test event-9.3 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} { set child [open |[list [interpreter]] r+] puts $child "testexithandler create 41; testexithandler create 4" puts $child "testexithandler create 6; testexithandler delete 6" puts $child "testexithandler create 16; exit" flush $child set result [read $child] close $child return $result } {even 16 even 4 odd 41 } test event-9.4 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} { set child [open |[list [interpreter]] r+] puts $child "testexithandler create 41; testexithandler delete 41" puts $child "testexithandler create 16; exit" flush $child set result [read $child] close $child return $result } {even 16 | > > > > > | 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 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 | # file/exec test than a bgerror test. # end of bgerror tests catch {rename bgerror {}} test event-8.1 {Tcl_CreateExitHandler procedure} {stdio testexithandler} { set child [open |[list [interpreter]] r+] puts $child "catch {load $::tcltestlib Tcltest}" puts $child "testexithandler create 41; testexithandler create 4" puts $child "testexithandler create 6; exit" flush $child set result [read $child] close $child return $result } {even 6 even 4 odd 41 } test event-9.1 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} { set child [open |[list [interpreter]] r+] puts $child "catch {load $::tcltestlib Tcltest}" puts $child "testexithandler create 41; testexithandler create 4" puts $child "testexithandler create 6; testexithandler delete 41" puts $child "testexithandler create 16; exit" flush $child set result [read $child] close $child return $result } {even 16 even 6 even 4 } test event-9.2 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} { set child [open |[list [interpreter]] r+] puts $child "catch {load $::tcltestlib Tcltest}" puts $child "testexithandler create 41; testexithandler create 4" puts $child "testexithandler create 6; testexithandler delete 4" puts $child "testexithandler create 16; exit" flush $child set result [read $child] close $child return $result } {even 16 even 6 odd 41 } test event-9.3 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} { set child [open |[list [interpreter]] r+] puts $child "catch {load $::tcltestlib Tcltest}" puts $child "testexithandler create 41; testexithandler create 4" puts $child "testexithandler create 6; testexithandler delete 6" puts $child "testexithandler create 16; exit" flush $child set result [read $child] close $child return $result } {even 16 even 4 odd 41 } test event-9.4 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} { set child [open |[list [interpreter]] r+] puts $child "catch {load $::tcltestlib Tcltest}" puts $child "testexithandler create 41; testexithandler delete 41" puts $child "testexithandler create 16; exit" flush $child set result [read $child] close $child return $result } {even 16 |
︙ | ︙ |
Changes to tests/execute.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } catch {namespace delete {*}[namespace children :: test_ns_*]} catch {rename foo ""} catch {unset x} catch {unset y} catch {unset msg} testConstraint testobj [expr { | > > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] catch {namespace delete {*}[namespace children :: test_ns_*]} catch {rename foo ""} catch {unset x} catch {unset y} catch {unset msg} testConstraint testobj [expr { |
︙ | ︙ |
Changes to tests/expr-old.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.1 namespace import -force ::tcltest::* } testConstraint testexprlong [llength [info commands testexprlong]] testConstraint testexprdouble [llength [info commands testexprdouble]] testConstraint testexprstring [llength [info commands testexprstring]] testConstraint longIs32bit [expr {int(0x80000000) < 0}] if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} { testConstraint testmathfunctions 0 | > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.1 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testexprlong [llength [info commands testexprlong]] testConstraint testexprdouble [llength [info commands testexprdouble]] testConstraint testexprstring [llength [info commands testexprstring]] testConstraint longIs32bit [expr {int(0x80000000) < 0}] if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} { testConstraint testmathfunctions 0 |
︙ | ︙ |
Changes to tests/expr.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.1 namespace import -force ::tcltest::* } testConstraint testmathfunctions [expr { ([catch {expr T1()} msg] != 1) || ($msg ne {invalid command name "tcl::mathfunc::T1"}) }] # Determine if "long int" type is a 32 bit number and if the wide # type is a 64 bit number on this machine. | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.1 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testmathfunctions [expr { ([catch {expr T1()} msg] != 1) || ($msg ne {invalid command name "tcl::mathfunc::T1"}) }] # Determine if "long int" type is a 32 bit number and if the wide # type is a 64 bit number on this machine. |
︙ | ︙ |
Changes to tests/fCmd.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } cd [temporaryDirectory] testConstraint testsetplatform [llength [info commands testsetplatform]] testConstraint testchmod [llength [info commands testchmod]] testConstraint winVista 0 testConstraint win2000orXP 0 # Don't know how to determine this constraint correctly | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] cd [temporaryDirectory] testConstraint testsetplatform [llength [info commands testsetplatform]] testConstraint testchmod [llength [info commands testchmod]] testConstraint winVista 0 testConstraint win2000orXP 0 # Don't know how to determine this constraint correctly |
︙ | ︙ |
Changes to tests/fileName.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint testsetplatform [llength [info commands testsetplatform]] testConstraint testtranslatefilename [llength [info commands testtranslatefilename]] testConstraint linkDirectory 1 testConstraint symbolicLinkFile 1 if {[testConstraint win]} { if {[string index $tcl_platform(osVersion) 0] < 5 \ || [lindex [file system [temporaryDirectory]] 1] ne "NTFS"} { | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testsetplatform [llength [info commands testsetplatform]] testConstraint testtranslatefilename [llength [info commands testtranslatefilename]] testConstraint linkDirectory 1 testConstraint symbolicLinkFile 1 if {[testConstraint win]} { if {[string index $tcl_platform(osVersion) 0] < 5 \ || [lindex [file system [temporaryDirectory]] 1] ne "NTFS"} { |
︙ | ︙ | |||
192 193 194 195 196 197 198 | test filename-4.12 {Tcl_SplitPath: unix} {testsetplatform} { testsetplatform unix file split ../.. } {.. ..} test filename-4.13 {Tcl_SplitPath: unix} {testsetplatform} { testsetplatform unix file split //foo | | | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | test filename-4.12 {Tcl_SplitPath: unix} {testsetplatform} { testsetplatform unix file split ../.. } {.. ..} test filename-4.13 {Tcl_SplitPath: unix} {testsetplatform} { testsetplatform unix file split //foo } "/ foo" test filename-4.14 {Tcl_SplitPath: unix} {testsetplatform} { testsetplatform unix file split foo//bar } {foo bar} test filename-4.15 {Tcl_SplitPath: unix} {testsetplatform} { testsetplatform unix file split ~foo |
︙ | ︙ | |||
429 430 431 432 433 434 435 | test filename-7.16 {Tcl_JoinPath: unix} {testsetplatform} { testsetplatform unix file join a . ./~b } {a/./~b} test filename-7.17 {Tcl_JoinPath: unix} {testsetplatform} { testsetplatform unix file join //a b | | | | 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | test filename-7.16 {Tcl_JoinPath: unix} {testsetplatform} { testsetplatform unix file join a . ./~b } {a/./~b} test filename-7.17 {Tcl_JoinPath: unix} {testsetplatform} { testsetplatform unix file join //a b } "/a/b" test filename-7.18 {Tcl_JoinPath: unix} {testsetplatform} { testsetplatform unix file join /// a b } "/a/b" test filename-9.1 {Tcl_JoinPath: win} {testsetplatform} { testsetplatform win file join a b } {a/b} test filename-9.2 {Tcl_JoinPath: win} {testsetplatform} { testsetplatform win |
︙ | ︙ |
Changes to tests/fileSystem.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | namespace import ::tcltest::* catch { file delete -force link.file file delete -force dir.link file delete -force [file join dir.dir linkinside.file] } # Test for commands defined in Tcltest executable testConstraint testfilesystem [llength [info commands ::testfilesystem]] testConstraint testsetplatform [llength [info commands ::testsetplatform]] testConstraint testsimplefilesystem [llength [info commands ::testsimplefilesystem]] cd [tcltest::temporaryDirectory] | > > > > > > > > > > > | 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 | namespace import ::tcltest::* catch { file delete -force link.file file delete -force dir.link file delete -force [file join dir.dir linkinside.file] } testConstraint loaddll 0 catch { ::tcltest::loadTestedCommands package require -exact Tcltest [info patchlevel] set ::ddever [package require dde] set ::ddelib [lindex [package ifneeded dde $::ddever] 1] set ::regver [package require registry] set ::reglib [lindex [package ifneeded registry $::regver] 1] testConstraint loaddll 0 } # Test for commands defined in Tcltest executable testConstraint testfilesystem [llength [info commands ::testfilesystem]] testConstraint testsetplatform [llength [info commands ::testsetplatform]] testConstraint testsimplefilesystem [llength [info commands ::testsimplefilesystem]] cd [tcltest::temporaryDirectory] |
︙ | ︙ | |||
301 302 303 304 305 306 307 | set old [pwd] } -constraints {win} -body { set drv C:/ cd [lindex [glob -type d -dir $drv *] 0] file norm [string range $drv 0 1] } -cleanup { cd $old | | | 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | set old [pwd] } -constraints {win} -body { set drv C:/ cd [lindex [glob -type d -dir $drv *] 0] file norm [string range $drv 0 1] } -cleanup { cd $old } -match regexp -result {.*[^/]} test filesystem-1.40 {file normalisation with repeated separators} { testPathEqual [file norm foo////bar] [file norm foo/bar] } ok test filesystem-1.41 {file normalisation with repeated separators} {win} { testPathEqual [file norm foo\\\\\\bar] [file norm foo/bar] } ok test filesystem-1.42 {file normalisation .. beyond root (Bug 1379287)} { |
︙ | ︙ | |||
469 470 471 472 473 474 475 | test filesystem-6.19 {empty file name} {file nativename ""} {} test filesystem-6.20 {empty file name} {file normalize ""} {} test filesystem-6.21 {empty file name} {file owned ""} 0 test filesystem-6.22 {empty file name} {file pathtype ""} relative test filesystem-6.23 {empty file name} {file readable ""} 0 test filesystem-6.24 {empty file name} -returnCodes error -body { file readlink "" | | | 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | test filesystem-6.19 {empty file name} {file nativename ""} {} test filesystem-6.20 {empty file name} {file normalize ""} {} test filesystem-6.21 {empty file name} {file owned ""} 0 test filesystem-6.22 {empty file name} {file pathtype ""} relative test filesystem-6.23 {empty file name} {file readable ""} 0 test filesystem-6.24 {empty file name} -returnCodes error -body { file readlink "" } -result {could not read link "": no such file or directory} test filesystem-6.25 {empty file name} -returnCodes error -body { file rename "" "" } -result {error renaming "": no such file or directory} test filesystem-6.26 {empty file name} {file rootname ""} {} test filesystem-6.27 {empty file name} -returnCodes error -body { file separator "" } -result {unrecognised path} |
︙ | ︙ | |||
497 498 499 500 501 502 503 | # Make sure the testfilesystem hasn't been registered. if {[testConstraint testfilesystem]} { while {![catch {testfilesystem 0}]} {} } test filesystem-7.1.1 {load from vfs} -setup { set dir [pwd] | | | < | | | < | | | 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 | # Make sure the testfilesystem hasn't been registered. if {[testConstraint testfilesystem]} { while {![catch {testfilesystem 0}]} {} } test filesystem-7.1.1 {load from vfs} -setup { set dir [pwd] } -constraints {win testsimplefilesystem loaddll} -body { # This may cause a crash on exit cd [file dirname $::reglib] testsimplefilesystem 1 # This loads dde via a complex copy-to-temp operation load simplefs:/[file tail $::ddelib] dde testsimplefilesystem 0 return ok # The real result of this test is what happens when Tcl exits. } -cleanup { cd $dir } -result ok test filesystem-7.1.2 {load from vfs, and then unload again} -setup { set dir [pwd] } -constraints {win testsimplefilesystem loaddll} -body { # This may cause a crash on exit cd [file dirname $::reglib] testsimplefilesystem 1 # This loads reg via a complex copy-to-temp operation load simplefs:/[file tail $::reglib] Registry unload simplefs:/[file tail $::reglib] testsimplefilesystem 0 return ok # The real result of this test is what happens when Tcl exits. } -cleanup { cd $dir } -result ok test filesystem-7.2 {cross-filesystem copy from vfs maintains mtime} -setup { |
︙ | ︙ |
Changes to tests/format.test.
︙ | ︙ | |||
545 546 547 548 549 550 551 | } {1 1 1 1} test format-18.2 {do not demote existing numeric values} {wideBiggerThanInt} { set a [expr {0xaaaaaaaaaa + 1}] set b 0xaaaaaaaaab list [format %08x $a] [expr {$a == $b}] } {aaaaaaab 1} | < | < < | | 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 | } {1 1 1 1} test format-18.2 {do not demote existing numeric values} {wideBiggerThanInt} { set a [expr {0xaaaaaaaaaa + 1}] set b 0xaaaaaaaaab list [format %08x $a] [expr {$a == $b}] } {aaaaaaab 1} test format-19.1 {regression test - tcl-core message by Brian Griffin on 26 0ctober 2004} -body { set x 0x8fedc654 list [expr { ~ $x }] [format %08x [expr { ~$x }]] } -match regexp -result {-2414724693 f*701239ab} test format-19.2 {Bug 1867855} { format %llx 0 } 0 test format-19.3 {Bug 2830354} { string length [format %340f 0] } 340 # Note that this test may fail in future versions test format-20.1 {Bug 2932421: plain %s caused intrep change of args} -body { set x [dict create a b c d] format %s $x # After this, obj in $x should be a dict with a non-NULL bytes field tcl::unsupported::representation $x } -match glob -result {value is a dict with *, string representation "*"} # cleanup catch {unset a} catch {unset b} catch {unset c} catch {unset d} ::tcltest::cleanupTests return # Local Variables: # mode: tcl # End: |
Changes to tests/get.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testgetint [llength [info commands testgetint]] testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] test get-1.1 {Tcl_GetInt procedure} testgetint { testgetint 44 { 22} } {66} | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testgetint [llength [info commands testgetint]] testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] test get-1.1 {Tcl_GetInt procedure} testgetint { testgetint 44 { 22} } {66} |
︙ | ︙ |
Changes to tests/indexObj.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint testindexobj [llength [info commands testindexobj]] testConstraint testparseargs [llength [info commands testparseargs]] test indexObj-1.1 {exact match} testindexobj { testindexobj 1 1 xyz abc def xyz alm } {2} test indexObj-1.2 {exact match} testindexobj { | > > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testindexobj [llength [info commands testindexobj]] testConstraint testparseargs [llength [info commands testparseargs]] test indexObj-1.1 {exact match} testindexobj { testindexobj 1 1 xyz abc def xyz alm } {2} test indexObj-1.2 {exact match} testindexobj { |
︙ | ︙ |
Changes to tests/info.test.
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # DO NOT DELETE THIS LINE if {{::tcltest} ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } # Set up namespaces needed to test operation of "info args", "info body", # "info default", and "info procs" with imported procedures. catch {namespace delete test_ns_info1 test_ns_info2} namespace eval test_ns_info1 { namespace export * | > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # DO NOT DELETE THIS LINE if {{::tcltest} ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Set up namespaces needed to test operation of "info args", "info body", # "info default", and "info procs" with imported procedures. catch {namespace delete test_ns_info1 test_ns_info2} namespace eval test_ns_info1 { namespace export * |
︙ | ︙ | |||
226 227 228 229 230 231 232 | test info-6.11 {info default option} { catch {namespace delete test_ns_info2} namespace eval test_ns_info2 { namespace import ::test_ns_info1::* list [info default p x foo] $foo [info default q y bar] $bar } } {0 {} 1 27} | < | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | test info-6.11 {info default option} { catch {namespace delete test_ns_info2} namespace eval test_ns_info2 { namespace import ::test_ns_info1::* list [info default p x foo] $foo [info default q y bar] $bar } } {0 {} 1 27} test info-7.1 {info exists option} -body { set value foo info exists value } -cleanup {unset value} -result 1 test info-7.2 {info exists option} -setup {catch {unset _nonexistent_}} -body { |
︙ | ︙ | |||
727 728 729 730 731 732 733 | while {$level} { lappend res [list $level [reduce [info frame $level]]] incr level -1 } return $res } | < < | 729 730 731 732 733 734 735 736 737 738 739 740 741 742 | while {$level} { lappend res [list $level [reduce [info frame $level]]] incr level -1 } return $res } test info-22.0 {info frame, levels} {!singleTestInterp} { info frame } 7 test info-22.1 {info frame, bad level relative} {!singleTestInterp} { # catch is another level!, i.e. we have 8, not 7 catch {info frame -8} msg set msg |
︙ | ︙ | |||
759 760 761 762 763 764 765 | reduce [info frame -6] } {type source line 758 file info.test cmd test\ info-22.6\ \{info\ frame,\ global,\ relative\}\ \{!singleTestInter level 0} test info-22.7 {info frame, global, absolute} {!singleTestInterp} { reduce [info frame 1] } {type source line 761 file info.test cmd test\ info-22.7\ \{info\ frame,\ global,\ absolute\}\ \{!singleTestInter level 0} test info-22.8 {info frame, basic trace} -match glob -body { join [lrange [etrace] 0 2] \n | | | 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 | reduce [info frame -6] } {type source line 758 file info.test cmd test\ info-22.6\ \{info\ frame,\ global,\ relative\}\ \{!singleTestInter level 0} test info-22.7 {info frame, global, absolute} {!singleTestInterp} { reduce [info frame 1] } {type source line 761 file info.test cmd test\ info-22.7\ \{info\ frame,\ global,\ absolute\}\ \{!singleTestInter level 0} test info-22.8 {info frame, basic trace} -match glob -body { join [lrange [etrace] 0 2] \n } -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} * {type source line 765 file info.test cmd etrace proc ::tcltest::RunTest} * {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}} unset -nocomplain msg test info-23.0.0 {eval'd info frame} {!singleTestInterp} { eval {info frame} } 8 |
︙ | ︙ | |||
799 800 801 802 803 804 805 | test info-23.5 {eval'd info frame, dynamic} -cleanup {unset script} -body { set script {info frame 0} eval $script } -result {type eval line 1 cmd {info frame 0} proc ::tcltest::RunTest} test info-23.6 {eval'd info frame, trace} -match glob -cleanup {unset script} -body { set script {etrace} join [lrange [eval $script] 0 2] \n | | | 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 | test info-23.5 {eval'd info frame, dynamic} -cleanup {unset script} -body { set script {info frame 0} eval $script } -result {type eval line 1 cmd {info frame 0} proc ::tcltest::RunTest} test info-23.6 {eval'd info frame, trace} -match glob -cleanup {unset script} -body { set script {etrace} join [lrange [eval $script] 0 2] \n } -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} * {type eval line 1 cmd etrace proc ::tcltest::RunTest} * {type source line 805 file info.test cmd {eval $script} proc ::tcltest::RunTest}} # ------------------------------------------------------------------------- # Procedures defined in scripts which are arguments to control # structures (like 'namespace eval', 'interp eval', 'if', 'while', |
︙ | ︙ | |||
1314 1315 1316 1317 1318 1319 1320 | c} set cmd [list foreach $foo {x y} { set res [join [lrange [etrace] 0 2] \n] break }] eval $cmd return $res | | | 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 | c} set cmd [list foreach $foo {x y} { set res [join [lrange [etrace] 0 2] \n] break }] eval $cmd return $res } -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} * {type eval line 2 cmd etrace proc ::tcltest::RunTest} * {type eval line 1 cmd foreac proc ::tcltest::RunTest}} -cleanup {unset foo cmd res b c} # ------------------------------------------------------------------------- # 6 cases. ## DV. direct-var - unchanged |
︙ | ︙ | |||
1355 1356 1357 1358 1359 1360 1361 | test info-38.1 {location information for uplevel, dv, direct-var} -match glob -body { set script { set y DV. etrace } join [lrange [uplevel \#0 $script] 0 2] \n | | | | | | 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 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 | test info-38.1 {location information for uplevel, dv, direct-var} -match glob -body { set script { set y DV. etrace } join [lrange [uplevel \#0 $script] 0 2] \n } -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} * {type eval line 3 cmd etrace proc ::tcltest::RunTest} * {type source line 1361 file info.test cmd {uplevel \\#0 $script} proc ::tcltest::RunTest}} -cleanup {unset script y} # 38.2 moved to bottom to not disturb other tests with the necessary changes to this one. test info-38.3 {location information for uplevel, dpv, direct-proc-var} -match glob -body { set script { set y DPV etrace } join [lrange [control y $script] 0 3] \n } -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} * {type eval line 3 cmd etrace proc ::control} * {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control} * {type source line 1380 file info.test cmd {control y $script} proc ::tcltest::RunTest}} -cleanup {unset script y} # 38.4 moved to bottom to not disturb other tests with the necessary changes to this one. test info-38.5 {location information for uplevel, ppv, proc-proc-var} -match glob -body { join [lrange [datav] 0 4] \n } -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0} * {type eval line 3 cmd etrace proc ::control} * {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control} * {type source line 1353 file info.test cmd {control y $script} proc ::datav level 1} * {type source line 1397 file info.test cmd datav proc ::tcltest::RunTest}} # 38.6 moved to bottom to not disturb other tests with the necessary changes to this one. testConstraint testevalex [llength [info commands testevalex]] test info-38.7 {location information for arg substitution} -constraints testevalex -match glob -body { join [lrange [testevalex {return -level 0 [etrace]}] 0 3] \n } -result {* {type source line 730 file info.test cmd {info frame \$level} proc ::etrace level 0} * {type eval line 1 cmd etrace proc ::tcltest::RunTest} * {type source line 1414 file info.test cmd {testevalex {return -level 0 \[etrace]}} proc ::tcltest::RunTest} * {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}} # ------------------------------------------------------------------------- # literal sharing |
︙ | ︙ |
Changes to tests/interp.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2.1 namespace import -force ::tcltest::* } testConstraint testinterpdelete [llength [info commands testinterpdelete]] set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload} foreach i [interp slaves] { interp delete $i } | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2.1 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testinterpdelete [llength [info commands testinterpdelete]] set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload} foreach i [interp slaves] { interp delete $i } |
︙ | ︙ |
Changes to tests/io.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[catch {package require tcltest 2}]} { puts stderr "Skipping tests in [info script]. tcltest 2 required." return } namespace eval ::tcl::test::io { namespace import ::tcltest::* variable umaskValue variable path variable f variable i | > > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[catch {package require tcltest 2}]} { puts stderr "Skipping tests in [info script]. tcltest 2 required." return } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] namespace eval ::tcl::test::io { namespace import ::tcltest::* variable umaskValue variable path variable f variable i |
︙ | ︙ |
Changes to tests/ioCmd.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } # Custom constraints used in this file testConstraint fcopy [llength [info commands fcopy]] testConstraint testchannel [llength [info commands testchannel]] testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}] #---------------------------------------------------------------------- | > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Custom constraints used in this file testConstraint fcopy [llength [info commands fcopy]] testConstraint testchannel [llength [info commands testchannel]] testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}] #---------------------------------------------------------------------- |
︙ | ︙ |
Changes to tests/ioTrans.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } # Custom constraints used in this file testConstraint testchannel [llength [info commands testchannel]] testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}] # testchannel cut|splice Both needed to test the reflection in threads. # thread::send | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Custom constraints used in this file testConstraint testchannel [llength [info commands testchannel]] testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}] # testchannel cut|splice Both needed to test the reflection in threads. # thread::send |
︙ | ︙ |
Changes to tests/iogt.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # Copyright (c) 2000 Andreas Kupries. # All rights reserved. if {[catch {package require tcltest 2.1}]} { puts stderr "Skipping tests in [info script]. tcltest 2.1 required." return } namespace eval ::tcl::test::iogt { namespace import ::tcltest::* testConstraint testchannel [llength [info commands testchannel]] set path(dummy) [makeFile {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-= } dummy] | > > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # Copyright (c) 2000 Andreas Kupries. # All rights reserved. if {[catch {package require tcltest 2.1}]} { puts stderr "Skipping tests in [info script]. tcltest 2.1 required." return } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] namespace eval ::tcl::test::iogt { namespace import ::tcltest::* testConstraint testchannel [llength [info commands testchannel]] set path(dummy) [makeFile {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-= } dummy] |
︙ | ︙ |
Changes to tests/lindex.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.2 namespace import -force ::tcltest::* } set minus - testConstraint testevalex [llength [info commands testevalex]] # Tests of Tcl_LindexObjCmd, NOT COMPILED test lindex-1.1 {wrong # args} testevalex { list [catch {testevalex lindex} result] $result | > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] set minus - testConstraint testevalex [llength [info commands testevalex]] # Tests of Tcl_LindexObjCmd, NOT COMPILED test lindex-1.1 {wrong # args} testevalex { list [catch {testevalex lindex} result] $result |
︙ | ︙ |
Changes to tests/link.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint testlink [llength [info commands testlink]] foreach i {int real bool string} { unset -nocomplain $i } test link-1.1 {reading C variables from Tcl} -constraints {testlink} -setup { | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testlink [llength [info commands testlink]] foreach i {int real bool string} { unset -nocomplain $i } test link-1.1 {reading C variables from Tcl} -constraints {testlink} -setup { |
︙ | ︙ |
Changes to tests/listObj.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testobj [llength [info commands testobj]] catch {unset x} test listobj-1.1 {Tcl_GetListObjType} emptyTest { # Test removed; tested an internal detail # that's no longer correct, and duplicated test obj-1.1 } {} | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testobj [llength [info commands testobj]] catch {unset x} test listobj-1.1 {Tcl_GetListObjType} emptyTest { # Test removed; tested an internal detail # that's no longer correct, and duplicated test obj-1.1 } {} |
︙ | ︙ |
Changes to tests/load.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } # Figure out what extension is used for shared libraries on this # platform. if {![info exists ext]} { set ext [info sharedlibextension] } # Tests require the existence of one of the DLLs in the dltest directory. set testDir [file join [file dirname [info nameofexecutable]] dltest] | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Figure out what extension is used for shared libraries on this # platform. if {![info exists ext]} { set ext [info sharedlibextension] } # Tests require the existence of one of the DLLs in the dltest directory. set testDir [file join [file dirname [info nameofexecutable]] dltest] |
︙ | ︙ | |||
193 194 195 196 197 198 199 | -body { child1 eval { teststaticpkg Loadninepointone 0 1 } child2 eval { teststaticpkg Loadninepointone 0 1 } list \ [child1 eval { info loaded {} }] \ [child2 eval { info loaded {} }] } \ | | | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | -body { child1 eval { teststaticpkg Loadninepointone 0 1 } child2 eval { teststaticpkg Loadninepointone 0 1 } list \ [child1 eval { info loaded {} }] \ [child2 eval { info loaded {} }] } \ -match glob -result {{{{} Loadninepointone} {* Tcltest}} {{{} Loadninepointone} {* Tcltest}}} \ -cleanup { interp delete child1 ; interp delete child2 } test load-10.1 {load from vfs} \ -constraints [list $dll $loaded testsimplefilesystem] \ -setup {set dir [pwd]; cd $testDir; testsimplefilesystem 1} \ -body {list [catch {load simplefs:/pkgd$ext pkgd} msg] $msg} \ -result {0 {}} \ |
︙ | ︙ |
Changes to tests/lset.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } proc failTrace {name1 name2 op} { error "trace failed" } testConstraint testevalex [llength [info commands testevalex]] set noRead {} | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] proc failTrace {name1 name2 op} { error "trace failed" } testConstraint testevalex [llength [info commands testevalex]] set noRead {} |
︙ | ︙ |
Changes to tests/misc.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testhashsystemhash [llength [info commands testhashsystemhash]] test misc-1.1 {error in variable ref. in command in array reference} { proc tstProc {} { global a set tst $a([winfo name $zz]) | > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testhashsystemhash [llength [info commands testhashsystemhash]] test misc-1.1 {error in variable ref. in command in array reference} { proc tstProc {} { global a set tst $a([winfo name $zz]) |
︙ | ︙ |
Changes to tests/namespace.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 namespace import -force ::tcltest::* testConstraint memory [llength [info commands memory]] # # REMARK: the tests for 'namespace upvar' are not done here. They are to be # found in the file 'upvar.test'. # # Clear out any namespaces called test_ns_* catch {namespace delete {*}[namespace children :: test_ns_*]} | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 namespace import -force ::tcltest::* testConstraint memory [llength [info commands memory]] ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # # REMARK: the tests for 'namespace upvar' are not done here. They are to be # found in the file 'upvar.test'. # # Clear out any namespaces called test_ns_* catch {namespace delete {*}[namespace children :: test_ns_*]} |
︙ | ︙ |
Changes to tests/notify.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint testevent [llength [info commands testevent]] test notify-1.1 {Tcl_QueueEvent and delivery of a single event} \ -constraints {testevent} \ -body { set delivered {} after 10 set done 1 | > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testevent [llength [info commands testevent]] test notify-1.1 {Tcl_QueueEvent and delivery of a single event} \ -constraints {testevent} \ -body { set delivered {} after 10 set done 1 |
︙ | ︙ |
Changes to tests/nre.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testnrelevels [llength [info commands testnrelevels]] # # The tests that risked blowing the C stack on failure have been removed: we # can now actually measure using testnrelevels. # | > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testnrelevels [llength [info commands testnrelevels]] # # The tests that risked blowing the C stack on failure have been removed: we # can now actually measure using testnrelevels. # |
︙ | ︙ |
Changes to tests/obj.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testobj [llength [info commands testobj]] testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} testobj { set r 1 foreach {t} { | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testobj [llength [info commands testobj]] testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} testobj { set r 1 foreach {t} { |
︙ | ︙ |
Changes to tests/parse.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required." return } namespace eval ::tcl::test::parse { namespace import ::tcltest::* testConstraint testparser [llength [info commands testparser]] testConstraint testevalobjv [llength [info commands testevalobjv]] testConstraint testevalex [llength [info commands testevalex]] testConstraint testparsevarname [llength [info commands testparsevarname]] testConstraint testparsevar [llength [info commands testparsevar]] testConstraint testasync [llength [info commands testasync]] testConstraint testcmdtrace [llength [info commands testcmdtrace]] | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required." return } namespace eval ::tcl::test::parse { namespace import ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testparser [llength [info commands testparser]] testConstraint testevalobjv [llength [info commands testevalobjv]] testConstraint testevalex [llength [info commands testevalex]] testConstraint testparsevarname [llength [info commands testparsevarname]] testConstraint testparsevar [llength [info commands testparsevar]] testConstraint testasync [llength [info commands testasync]] testConstraint testcmdtrace [llength [info commands testcmdtrace]] |
︙ | ︙ |
Changes to tests/parseExpr.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } # Note that the Tcl expression parser (tclCompExpr.c) does not check # the semantic validity of the expressions it parses. It does not check, # for example, that a math function actually exists, or that the operands # of "<<" are integers. testConstraint testexprparser [llength [info commands testexprparser]] | > > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Note that the Tcl expression parser (tclCompExpr.c) does not check # the semantic validity of the expressions it parses. It does not check, # for example, that a math function actually exists, or that the operands # of "<<" are integers. testConstraint testexprparser [llength [info commands testexprparser]] |
︙ | ︙ |
Changes to tests/parseOld.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testwordend [llength [info commands testwordend]] # Save the argv value for restoration later set savedArgv $argv proc fourArgs {a b c d} { global arg1 arg2 arg3 arg4 | > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testwordend [llength [info commands testwordend]] # Save the argv value for restoration later set savedArgv $argv proc fourArgs {a b c d} { global arg1 arg2 arg3 arg4 |
︙ | ︙ |
Changes to tests/platform.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testCPUID [llength [info commands testcpuid]] test platform-1.1 {TclpSetVariables: tcl_platform} { interp create i i eval {catch {unset tcl_platform(debug)}} i eval {catch {unset tcl_platform(threaded)}} set result [i eval {lsort [array names tcl_platform]}] | > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testCPUID [llength [info commands testcpuid]] test platform-1.1 {TclpSetVariables: tcl_platform} { interp create i i eval {catch {unset tcl_platform(debug)}} i eval {catch {unset tcl_platform(threaded)}} set result [i eval {lsort [array names tcl_platform]}] |
︙ | ︙ |
Changes to tests/reg.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # # Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 } # All tests require the testregexp command, return if this # command doesn't exist ::tcltest::testConstraint testregexp [llength [info commands testregexp]] ::tcltest::testConstraint localeRegexp 0 # This file uses some custom procedures, defined below, for regexp regression | > > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # # Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # All tests require the testregexp command, return if this # command doesn't exist ::tcltest::testConstraint testregexp [llength [info commands testregexp]] ::tcltest::testConstraint localeRegexp 0 # This file uses some custom procedures, defined below, for regexp regression |
︙ | ︙ |
Changes to tests/registry.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 | if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint reg 0 if {[testConstraint win]} { | | < < < | | > > > | 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 | if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint reg 0 if {[testConstraint win]} { if {![catch { ::tcltest::loadTestedCommands set ::regver [package require registry 1.3.0] }]} { testConstraint reg 1 } } # determine the current locale testConstraint english [expr { [llength [info commands testlocale]] && [string match "English*" [testlocale all ""]] }] test registry-1.0 {check if we are testing the right dll} {win reg} { set ::regver } {1.3.0} test registry-1.1 {argument parsing for registry command} {win reg} { list [catch {registry} msg] $msg } {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}} test registry-1.1a {argument parsing for registry command} {win reg} { list [catch {registry -32bit} msg] $msg } {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}} test registry-1.1b {argument parsing for registry command} {win reg} { |
︙ | ︙ | |||
501 502 503 504 505 506 507 | } "foo ba\u00c7r baz" test registry-6.20 {GetValue: values with Unicode strings with embedded nulls} {win reg} { registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u0000r baz} multi_sz set result [registry get HKEY_CURRENT_USER\\TclFoobar val1] registry delete HKEY_CURRENT_USER\\TclFoobar set result } "foo ba r baz" | | | 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 | } "foo ba\u00c7r baz" test registry-6.20 {GetValue: values with Unicode strings with embedded nulls} {win reg} { registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u0000r baz} multi_sz set result [registry get HKEY_CURRENT_USER\\TclFoobar val1] registry delete HKEY_CURRENT_USER\\TclFoobar set result } "foo ba r baz" test registry-6.21 {GetValue: very long value names and values} {pcOnly reg} { registry set HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383] [string repeat x 16383] multi_sz set result [registry get HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383]] registry delete HKEY_CURRENT_USER\\TclFoobar set result } [string repeat x 16383] test registry-7.1 {GetValueNames: bad key} -constraints {win reg english} -setup { |
︙ | ︙ |
Changes to tests/rename.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint testdel [llength [info commands testdel]] # Must eliminate the "unknown" command while the test is running, especially # if the test is being run in a program with its own special-purpose unknown # command. catch {rename unknown unknown.old} | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testdel [llength [info commands testdel]] # Must eliminate the "unknown" command while the test is running, especially # if the test is being run in a program with its own special-purpose unknown # command. catch {rename unknown unknown.old} |
︙ | ︙ |
Changes to tests/resolver.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 if {"::tcltest" in [namespace children]} { namespace import -force ::tcltest::* } testConstraint testinterpresolver [llength [info commands testinterpresolver]] test resolver-1.1 {cmdNameObj sharing vs. cmd resolver: namespace import} -setup { testinterpresolver up namespace eval ::ns1 { proc z {} { return Z } namespace export z | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 if {"::tcltest" in [namespace children]} { namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testinterpresolver [llength [info commands testinterpresolver]] test resolver-1.1 {cmdNameObj sharing vs. cmd resolver: namespace import} -setup { testinterpresolver up namespace eval ::ns1 { proc z {} { return Z } namespace export z |
︙ | ︙ |
Changes to tests/result.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } # Some tests require the testsaveresult command testConstraint testsaveresult [llength [info commands testsaveresult]] testConstraint testsetobjerrorcode [llength [info commands testsetobjerrorcode]] testConstraint testseterrorcode [llength [info commands testseterrorcode]] testConstraint testreturn [llength [info commands testreturn]] | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Some tests require the testsaveresult command testConstraint testsaveresult [llength [info commands testsaveresult]] testConstraint testsetobjerrorcode [llength [info commands testsetobjerrorcode]] testConstraint testseterrorcode [llength [info commands testseterrorcode]] testConstraint testreturn [llength [info commands testreturn]] |
︙ | ︙ |
Changes to tests/set.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint testset2 [llength [info commands testset2]] catch {unset x} catch {unset i} test set-1.1 {TclCompileSetCmd: missing variable name} { list [catch {set} msg] $msg | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testset2 [llength [info commands testset2]] catch {unset x} catch {unset i} test set-1.1 {TclCompileSetCmd: missing variable name} { list [catch {set} msg] $msg |
︙ | ︙ |
Changes to tests/string.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } # Some tests require the testobj command testConstraint testobj [expr {[info commands testobj] != {}}] testConstraint testindexobj [expr {[info commands testindexobj] != {}}] # Used for constraining memory leak tests testConstraint memory [llength [info commands memory]] | > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Some tests require the testobj command testConstraint testobj [expr {[info commands testobj] != {}}] testConstraint testindexobj [expr {[info commands testindexobj] != {}}] # Used for constraining memory leak tests testConstraint memory [llength [info commands memory]] |
︙ | ︙ | |||
1769 1770 1771 1772 1773 1774 1775 | tcl::prefix match -error "{}x" -exact str1 str2 } -returnCodes 1 -result {list element in braces followed by "x" instead of space} test string-26.3.1 {tcl::prefix, bad args} -body { tcl::prefix match -error "x" -exact str1 str2 } -returnCodes 1 -result {error options must have an even number of elements} test string-26.3.2 {tcl::prefix, bad args} -body { tcl::prefix match -error str1 str2 | | | | 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 | tcl::prefix match -error "{}x" -exact str1 str2 } -returnCodes 1 -result {list element in braces followed by "x" instead of space} test string-26.3.1 {tcl::prefix, bad args} -body { tcl::prefix match -error "x" -exact str1 str2 } -returnCodes 1 -result {error options must have an even number of elements} test string-26.3.2 {tcl::prefix, bad args} -body { tcl::prefix match -error str1 str2 } -returnCodes 1 -result {missing value for -error} test string-26.4 {tcl::prefix, bad args} -body { tcl::prefix match -message str1 str2 } -returnCodes 1 -result {missing value for -message} test string-26.5 {tcl::prefix} { tcl::prefix match {apa bepa cepa depa} cepa } cepa test string-26.6 {tcl::prefix} { tcl::prefix match {apa bepa cepa depa} be } bepa test string-26.7 {tcl::prefix} -body { |
︙ | ︙ |
Changes to tests/stringComp.test.
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } # Some tests require the testobj command testConstraint testobj [expr {[info commands testobj] != {}}] test stringComp-1.1 {error conditions} { proc foo {} {string gorp a b} list [catch {foo} msg] $msg | > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Some tests require the testobj command testConstraint testobj [expr {[info commands testobj] != {}}] test stringComp-1.1 {error conditions} { proc foo {} {string gorp a b} list [catch {foo} msg] $msg |
︙ | ︙ |
Changes to tests/stringObj.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testobj [llength [info commands testobj]] testConstraint testdstring [llength [info commands testdstring]] test stringObj-1.1 {string type registration} testobj { set t [testobj types] set first [string first "string" $t] set result [expr {$first != -1}] | > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testobj [llength [info commands testobj]] testConstraint testdstring [llength [info commands testdstring]] test stringObj-1.1 {string type registration} testobj { set t [testobj types] set first [string first "string" $t] set result [expr {$first != -1}] |
︙ | ︙ |
Changes to tests/tailcall.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testnrelevels [llength [info commands testnrelevels]] # # The tests that risked blowing the C stack on failure have been removed: we # can now actually measure using testnrelevels. # | > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testnrelevels [llength [info commands testnrelevels]] # # The tests that risked blowing the C stack on failure have been removed: we # can now actually measure using testnrelevels. # |
︙ | ︙ |
Changes to tests/thread.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.2 namespace import -force ::tcltest::* } # Some tests require the testthread command testConstraint testthread [expr {[info commands testthread] != {}}] # Some tests require the Thread package testConstraint thread [expr {0 == [catch {package require Thread 2.7}]}] | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Some tests require the testthread command testConstraint testthread [expr {[info commands testthread] != {}}] # Some tests require the Thread package testConstraint thread [expr {0 == [catch {package require Thread 2.7}]}] |
︙ | ︙ |
Changes to tests/trace.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testcmdtrace [llength [info commands testcmdtrace]] testConstraint testevalobjv [llength [info commands testevalobjv]] # Used for constraining memory leak tests testConstraint memory [llength [info commands memory]] proc getbytes {} { | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testcmdtrace [llength [info commands testcmdtrace]] testConstraint testevalobjv [llength [info commands testevalobjv]] # Used for constraining memory leak tests testConstraint memory [llength [info commands memory]] proc getbytes {} { |
︙ | ︙ |
Changes to tests/unixFCmd.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint testchmod [llength [info commands testchmod]] # These tests really need to be run from a writable directory, which # it is assumed [temporaryDirectory] is. set oldcwd [pwd] cd [temporaryDirectory] | > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testchmod [llength [info commands testchmod]] # These tests really need to be run from a writable directory, which # it is assumed [temporaryDirectory] is. set oldcwd [pwd] cd [temporaryDirectory] |
︙ | ︙ |
Changes to tests/unixFile.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testfindexecutable [llength [info commands testfindexecutable]] set oldpwd [pwd] cd [temporaryDirectory] catch { set oldPath $env(PATH) | > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testfindexecutable [llength [info commands testfindexecutable]] set oldpwd [pwd] cd [temporaryDirectory] catch { set oldPath $env(PATH) |
︙ | ︙ |
Changes to tests/unload.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } # Figure out what extension is used for shared libraries on this # platform. if {![info exists ext]} { set ext [info sharedlibextension] } # Tests require the existence of one of the DLLs in the dltest directory. | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Figure out what extension is used for shared libraries on this # platform. if {![info exists ext]} { set ext [info sharedlibextension] } # Tests require the existence of one of the DLLs in the dltest directory. |
︙ | ︙ |
Changes to tests/upvar.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint testupvar [llength [info commands testupvar]] test upvar-1.1 {reading variables with upvar} { proc p1 {a b} {set c 22; set d 33; p2} proc p2 {} {upvar a x1 b x2 c x3 d x4; set a abc; list $x1 $x2 $x3 $x4 $a} p1 foo bar } {foo bar 22 33 abc} | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testupvar [llength [info commands testupvar]] test upvar-1.1 {reading variables with upvar} { proc p1 {a b} {set c 22; set d 33; p2} proc p2 {} {upvar a x1 b x2 c x3 d x4; set a abc; list $x1 $x2 $x3 $x4 $a} p1 foo bar } {foo bar 22 33 abc} |
︙ | ︙ |
Changes to tests/utf.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } catch {unset x} test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} { set x \x01 } [bytestring "\x01"] test utf-1.2 {Tcl_UniCharToUtf: 2 byte sequences} { set x "\x00" | > > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] catch {unset x} test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} { set x \x01 } [bytestring "\x01"] test utf-1.2 {Tcl_UniCharToUtf: 2 byte sequences} { set x "\x00" |
︙ | ︙ |
Changes to tests/util.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint controversialNaN 1 testConstraint testdstring [llength [info commands testdstring]] testConstraint testconcatobj [llength [info commands testconcatobj]] testConstraint testdoubledigits [llength [info commands testdoubledigits]] # Big test for correct ordering of data in [expr] | > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint controversialNaN 1 testConstraint testdstring [llength [info commands testdstring]] testConstraint testconcatobj [llength [info commands testconcatobj]] testConstraint testdoubledigits [llength [info commands testdoubledigits]] # Big test for correct ordering of data in [expr] |
︙ | ︙ |
Changes to tests/var.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2.2 namespace import -force ::tcltest::* } testConstraint testupvar [llength [info commands testupvar]] testConstraint testgetvarfullname [llength [info commands testgetvarfullname]] testConstraint testsetnoerr [llength [info commands testsetnoerr]] catch {rename p ""} catch {namespace delete test_ns_var} catch {unset xx} | > > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {"::tcltest" ni [namespace children]} { package require tcltest 2.2 namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testupvar [llength [info commands testupvar]] testConstraint testgetvarfullname [llength [info commands testgetvarfullname]] testConstraint testsetnoerr [llength [info commands testsetnoerr]] catch {rename p ""} catch {namespace delete test_ns_var} catch {unset xx} |
︙ | ︙ |
Changes to tests/winDde.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 | if {"::tcltest" ni [namespace children]} { package require tcltest 2 #tcltest::configure -verbose {pass start} namespace import -force ::tcltest::* } | > > > | < < < | > | < | < < > < | < | 11 12 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 | if {"::tcltest" ni [namespace children]} { package require tcltest 2 #tcltest::configure -verbose {pass start} namespace import -force ::tcltest::* } testConstraint debug [::tcl::pkgconfig get debug] testConstraint dde 0 if {[testConstraint win]} { if {![catch { ::tcltest::loadTestedCommands set ::ddever [package require dde 1.4.0b1] set ::ddelib [lindex [package ifneeded dde $::ddever] 1]}]} { testConstraint dde 1 } } # ------------------------------------------------------------------------- # Setup a script for a test server # set scriptName [makeFile {} script1.tcl] proc createChildProcess {ddeServerName args} { file delete -force $::scriptName set f [open $::scriptName w+] puts $f [list set ddeServerName $ddeServerName] puts $f [list load $::ddelib dde] puts $f { # DDE child server - # if {"::tcltest" ni [namespace children]} { package require tcltest namespace import -force ::tcltest::* } |
︙ | ︙ | |||
101 102 103 104 105 106 107 108 109 110 111 112 113 114 | set f [open |[list [interpreter] $::scriptName] r] fconfigure $f -buffering line gets $f line return $f } # ------------------------------------------------------------------------- test winDde-1.1 {Settings the server's topic name} -constraints dde -body { list [dde servername foobar] [dde servername] [dde servername self] } -result {foobar foobar self} test winDde-2.1 {Checking for other services} -constraints dde -body { expr [llength [dde services {} {}]] >= 0 | > > > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | set f [open |[list [interpreter] $::scriptName] r] fconfigure $f -buffering line gets $f line return $f } # ------------------------------------------------------------------------- test winDde-1.0 {check if we are testing the right dll} {win dde} { set ::ddever } {1.4.0b1} test winDde-1.1 {Settings the server's topic name} -constraints dde -body { list [dde servername foobar] [dde servername] [dde servername self] } -result {foobar foobar self} test winDde-2.1 {Checking for other services} -constraints dde -body { expr [llength [dde services {} {}]] >= 0 |
︙ | ︙ | |||
136 137 138 139 140 141 142 | test winDde-3.2 {DDE execute -async locally} -constraints dde -body { set \xe1 "" dde execute -async TclEval self [list set \xe1 foo] update set \xe1 } -result foo test winDde-3.3 {DDE request locally} -constraints dde -body { | | | | | | | | | | | | | > > > > > > > > > > | 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 | test winDde-3.2 {DDE execute -async locally} -constraints dde -body { set \xe1 "" dde execute -async TclEval self [list set \xe1 foo] update set \xe1 } -result foo test winDde-3.3 {DDE request locally} -constraints dde -body { set \xe1 "" dde execute TclEval self [list set \xe1 foo] dde request TclEval self \xe1 } -result foo test winDde-3.4 {DDE eval locally} -constraints dde -body { set \xe1 "" dde eval self set \xe1 foo } -result foo test winDde-3.5 {DDE request locally} -constraints dde -body { set \xe1 "" dde execute TclEval self [list set \xe1 foo] dde request -binary TclEval self \xe1 } -result "foo\x00" # Set variable a to A with diaeresis (unicode C4) by relying on the fact # that utf8 is sent (e.g. "c3 84" on the wire) test winDde-3.6 {DDE request utf8} -constraints dde -body { set \xe1 "not set" dde execute TclEval self "set \xe1 \xc4" scan [set \xe1] %c } -result 196 # Set variable a to A with diaeresis (unicode C4) using binary execute # and compose utf-8 (e.g. "c3 84" ) manualy test winDde-3.7 {DDE request binary} -constraints dde -body { set \xe1 "not set" dde execute -binary TclEval self [list set \xc3\xa1 \xc3\x84\x00] scan [set \xe1] %c } -result 196 test winDde-3.8 {DDE poke locally} -constraints {dde debug} -body { set \xe1 "" dde poke TclEval self \xe1 \xc4 dde request TclEval self \xe1 } -result \xc4 test winDde-3.9 {DDE poke -binary locally} -constraints {dde debug} -body { set \xe1 "" dde poke -binary TclEval self \xe1 \xc3\x84\x00 dde request TclEval self \xe1 } -result \xc4 # ------------------------------------------------------------------------- test winDde-4.1 {DDE execute remotely} -constraints {dde stdio} -body { set \xe1 "" set name ch\xEDld-4.1 set child [createChildProcess $name] |
︙ | ︙ | |||
186 187 188 189 190 191 192 | dde execute -async TclEval $name [list set \xe1 foo] update dde execute TclEval $name {set done 1} update set \xe1 } -result "" test winDde-4.3 {DDE request remotely} -constraints {dde stdio} -body { | | | | | | | > > > > > > > > > > | 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 | dde execute -async TclEval $name [list set \xe1 foo] update dde execute TclEval $name {set done 1} update set \xe1 } -result "" test winDde-4.3 {DDE request remotely} -constraints {dde stdio} -body { set \xe1 "" set name ch\xEDld-4.3 set child [createChildProcess $name] dde execute TclEval $name [list set a foo] set \xe1 [dde request TclEval $name a] dde execute TclEval $name {set done 1} update set \xe1 } -result foo test winDde-4.4 {DDE eval remotely} -constraints {dde stdio} -body { set \xe1 "" set name ch\xEDld-4.4 set child [createChildProcess $name] set \xe1 [dde eval $name set \xe1 foo] dde execute TclEval $name {set done 1} update set \xe1 } -result foo test winDde-4.5 {DDE poke remotely} -constraints {dde debug stdio} -body { set \xe1 "" set name ch\xEDld-4.5 set child [createChildProcess $name] dde poke TclEval $name \xe1 foo set \xe1 [dde request TclEval $name \xe1] dde execute TclEval $name {set done 1} update set \xe1 } -result foo # ------------------------------------------------------------------------- test winDde-5.1 {check for bad arguments} -constraints dde -body { dde execute "" "" "" "" } -returnCodes error -result {wrong # args: should be "dde execute ?-async? ?-binary? serviceName topicName value"} test winDde-5.2 {check for bad arguments} -constraints dde -body { |
︙ | ︙ |
Changes to tests/winFCmd.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } # Initialise the test constraints testConstraint winVista 0 testConstraint win2000orXP 0 testConstraint winOlderThan2000 0 testConstraint testvolumetype [llength [info commands testvolumetype]] testConstraint testfile [llength [info commands testfile]] | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Initialise the test constraints testConstraint winVista 0 testConstraint win2000orXP 0 testConstraint winOlderThan2000 0 testConstraint testvolumetype [llength [info commands testvolumetype]] testConstraint testfile [llength [info commands testfile]] |
︙ | ︙ |
Changes to tests/winFile.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | if {[catch {package require tcltest 2.0.2}]} { puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required." return } namespace import -force ::tcltest::* testConstraint testvolumetype [llength [info commands testvolumetype]] testConstraint notNTFS 0 testConstraint win2000 0 if {[testConstraint testvolumetype]} { testConstraint notNTFS [expr {[testvolumetype] eq "NTFS"}] } | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | if {[catch {package require tcltest 2.0.2}]} { puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required." return } namespace import -force ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testvolumetype [llength [info commands testvolumetype]] testConstraint notNTFS 0 testConstraint win2000 0 if {[testConstraint testvolumetype]} { testConstraint notNTFS [expr {[testvolumetype] eq "NTFS"}] } |
︙ | ︙ |
Changes to tests/winNotify.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testeventloop [expr {[info commands testeventloop] != {}}] # There is no explicit test for InitNotifier or NotifierExitHandler test winNotify-1.1 {Tcl_SetTimer: positive timeout} {win} { set done 0 after 1000 { set done 1 } | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testeventloop [expr {[info commands testeventloop] != {}}] # There is no explicit test for InitNotifier or NotifierExitHandler test winNotify-1.1 {Tcl_SetTimer: positive timeout} {win} { set done 0 after 1000 { set done 1 } |
︙ | ︙ |
Changes to tests/winPipe.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest namespace import -force ::tcltest::* unset -nocomplain path set bindir [file join [pwd] [file dirname [info nameofexecutable]]] set cat32 [file join $bindir cat32.exe] testConstraint exec [llength [info commands exec]] testConstraint cat32 [file exists $cat32] testConstraint AllocConsole [catch {puts console1 ""}] testConstraint RealConsole [expr {![testConstraint AllocConsole]}] set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n append big $big append big $big append big $big append big $big append big $big | > > > > > > > > | 11 12 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 | # # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest namespace import -force ::tcltest::* unset -nocomplain path catch { ::tcltest::loadTestedCommands package require -exact Tcltest [info patchlevel] set ::tcltestlib [lindex [package ifneeded Tcltest [info patchlevel]] 1] } set bindir [file join [pwd] [file dirname [info nameofexecutable]]] set cat32 [file join $bindir cat32.exe] testConstraint exec [llength [info commands exec]] testConstraint cat32 [file exists $cat32] testConstraint AllocConsole [catch {puts console1 ""}] testConstraint RealConsole [expr {![testConstraint AllocConsole]}] testConstraint testexcept [llength [info commands testexcept]] set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n append big $big append big $big append big $big append big $big append big $big |
︙ | ︙ | |||
186 187 188 189 190 191 192 | fconfigure $f -buffering none -blocking 0 fileevent $f readable "readResults $f" set x 0 set result "" vwait x list $result $x [contents $path(stderr)] } "{$big} 1 stderr32" | | > | > | > | > | 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 | fconfigure $f -buffering none -blocking 0 fileevent $f readable "readResults $f" set x 0 set result "" vwait x list $result $x [contents $path(stderr)] } "{$big} 1 stderr32" test winpipe-4.2 {Tcl_WaitPid: return of exception codes, SIGFPE} {win exec testexcept} { set f [open "|[list [interpreter]]" w+] set pid [pid $f] puts $f "load $::tcltestlib Tcltest" puts $f "testexcept float_underflow" set status [catch {close $f}] list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2] } {1 1 SIGFPE} test winpipe-4.3 {Tcl_WaitPid: return of exception codes, SIGSEGV} {win exec testexcept} { set f [open "|[list [interpreter]]" w+] set pid [pid $f] puts $f "load $::tcltestlib Tcltest" puts $f "testexcept access_violation" set status [catch {close $f}] list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2] } {1 1 SIGSEGV} test winpipe-4.4 {Tcl_WaitPid: return of exception codes, SIGILL} {win exec testexcept} { set f [open "|[list [interpreter]]" w+] set pid [pid $f] puts $f "load $::tcltestlib Tcltest" puts $f "testexcept illegal_instruction" set status [catch {close $f}] list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2] } {1 1 SIGILL} test winpipe-4.5 {Tcl_WaitPid: return of exception codes, SIGINT} {win exec testexcept} { set f [open "|[list [interpreter]]" w+] set pid [pid $f] puts $f "load $::tcltestlib Tcltest" puts $f "testexcept ctrl+c" set status [catch {close $f}] list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2] } {1 1 SIGINT} set path(nothing) [makeFile {} nothing] close [open $path(nothing) w] |
︙ | ︙ |
Changes to tests/winTime.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } testConstraint testwinclock [llength [info commands testwinclock]] # The next two tests will crash on Windows if the check for negative # clock values is not done properly. test winTime-1.1 {TclpGetDate} {win} { set ::env(TZ) JST-9 | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testwinclock [llength [info commands testwinclock]] # The next two tests will crash on Windows if the check for negative # clock values is not done properly. test winTime-1.1 {TclpGetDate} {win} { set ::env(TZ) JST-9 |
︙ | ︙ |
Changes to unix/Makefile.in.
︙ | ︙ | |||
852 853 854 855 856 857 858 | @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.3.4.tm; @echo "Installing package platform 1.0.10 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.10.tm; @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform/shell-1.1.4.tm; | | | | 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 | @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.3.4.tm; @echo "Installing package platform 1.0.10 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.10.tm; @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform/shell-1.1.4.tm; @echo "Installing encoding files to $(SCRIPT_INSTALL_DIR)/encoding/"; @for i in $(TOP_DIR)/library/encoding/*.enc ; do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/encoding; \ done; @if [ -n "$(TCL_MODULE_PATH)" -a -f $(TOP_DIR)/library/tm.tcl ]; then \ echo "Customizing tcl module path"; \ echo "if {![interp issafe]} { ::tcl::tm::roots {$(TCL_MODULE_PATH)} }" >> \ "$(SCRIPT_INSTALL_DIR)"/tm.tcl; \ fi install-tzdata: ${NATIVE_TCLSH} @echo "Installing time zone files to $(SCRIPT_INSTALL_DIR)/tzdata/" @${NATIVE_TCLSH} $(TOOL_DIR)/installData.tcl \ $(TOP_DIR)/library/tzdata "$(SCRIPT_INSTALL_DIR)"/tzdata install-msgs: @for i in msgs; \ do \ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \ |
︙ | ︙ | |||
890 891 892 893 894 895 896 | do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ else true; \ fi; \ done; | | | | | 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 | do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ else true; \ fi; \ done; @echo "Installing and cross-linking top-level (.1) docs to $(MAN1_INSTALL_DIR)/"; @for i in $(TOP_DIR)/doc/*.1; do \ $(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MAN1_INSTALL_DIR)"; \ done @echo "Installing and cross-linking C API (.3) docs to $(MAN3_INSTALL_DIR)/"; @for i in $(TOP_DIR)/doc/*.3; do \ $(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MAN3_INSTALL_DIR)"; \ done @echo "Installing and cross-linking command (.n) docs to $(MANN_INSTALL_DIR)/"; @for i in $(TOP_DIR)/doc/*.n; do \ $(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MANN_INSTALL_DIR)"; \ done install-headers: @for i in "$(INCLUDE_INSTALL_DIR)"; \ do \ |
︙ | ︙ | |||
1697 1698 1699 1700 1701 1702 1703 | packages: configure-packages ${STUB_LIB_FILE} @for i in $(PKGS_DIR)/*; do \ if [ -d $$i ]; then \ pkg=`basename $$i`; \ if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ echo "Building package '$$pkg'"; \ | | | < < | | | | | 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 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 | packages: configure-packages ${STUB_LIB_FILE} @for i in $(PKGS_DIR)/*; do \ if [ -d $$i ]; then \ pkg=`basename $$i`; \ if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ echo "Building package '$$pkg'"; \ ( cd $(PKG_DIR)/$$pkg; $(MAKE); ) || exit $$?; \ fi; \ fi; \ done install-packages: packages @for i in $(PKGS_DIR)/*; do \ if [ -d $$i ]; then \ pkg=`basename $$i`; \ if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ echo "Installing package '$$pkg'"; \ ( cd $(PKG_DIR)/$$pkg; $(MAKE) install \ "DESTDIR=$(INSTALL_ROOT)"; ) || exit $$?; \ fi; \ fi; \ done test-packages: tcltest packages @for i in $(PKGS_DIR)/*; do \ if [ -d $$i ]; then \ pkg=`basename $$i`; \ if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ echo "Testing package '$$pkg'"; \ ( cd $(PKG_DIR)/$$pkg; $(MAKE) \ "@LD_LIBRARY_PATH_VAR@=../..:$${@LD_LIBRARY_PATH_VAR@}" \ "TCL_LIBRARY=${TCL_BUILDTIME_LIBRARY}" \ "TCLLIBPATH=../../pkgs" test \ "TCLSH_PROG=../../${TCLTEST_EXE}"; ) \ fi; \ fi; \ done clean-packages: @for i in $(PKGS_DIR)/*; do \ if [ -d $$i ]; then \ pkg=`basename $$i`; \ if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ ( cd $(PKG_DIR)/$$pkg; $(MAKE) clean; ) \ fi; \ fi; \ done distclean-packages: @for i in $(PKGS_DIR)/*; do \ if [ -d $$i ]; then \ pkg=`basename $$i`; \ if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ ( cd $(PKG_DIR)/$$pkg; $(MAKE) distclean; ) \ fi; \ rm -rf $(PKG_DIR)/$$pkg; \ fi; \ done; \ rm -rf $(PKG_DIR) dist-packages: configure-packages @rm -rf $(DISTROOT)/pkgs; \ mkdir -p $(DISTROOT)/pkgs; \ for i in $(PKGS_DIR)/*; do \ if [ -d $$i ]; then \ pkg=`basename $$i`; \ if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ ( cd $(PKG_DIR)/$$pkg; $(MAKE) dist \ "DIST_ROOT=$(DISTROOT)/pkgs"; ) || exit $$?; \ fi; \ fi; \ done #-------------------------------------------------------------------------- # Maintainer-only targets |
︙ | ︙ | |||
1926 1927 1928 1929 1930 1931 1932 | $(UNIX_DIR)/tclConfig.sh.in $(UNIX_DIR)/tclooConfig.sh \ $(UNIX_DIR)/install-sh \ $(UNIX_DIR)/README $(UNIX_DIR)/ldAix $(UNIX_DIR)/tcl.spec \ $(UNIX_DIR)/installManPage $(UNIX_DIR)/tclConfig.h.in \ $(UNIX_DIR)/tcl.pc.in $(DISTDIR)/unix chmod 775 $(DISTDIR)/unix/configure $(DISTDIR)/unix/configure.in chmod 775 $(DISTDIR)/unix/ldAix | < | 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 | $(UNIX_DIR)/tclConfig.sh.in $(UNIX_DIR)/tclooConfig.sh \ $(UNIX_DIR)/install-sh \ $(UNIX_DIR)/README $(UNIX_DIR)/ldAix $(UNIX_DIR)/tcl.spec \ $(UNIX_DIR)/installManPage $(UNIX_DIR)/tclConfig.h.in \ $(UNIX_DIR)/tcl.pc.in $(DISTDIR)/unix chmod 775 $(DISTDIR)/unix/configure $(DISTDIR)/unix/configure.in chmod 775 $(DISTDIR)/unix/ldAix mkdir $(DISTDIR)/generic cp -p $(GENERIC_DIR)/*.[cdh] $(DISTDIR)/generic cp -p $(GENERIC_DIR)/*.decls $(DISTDIR)/generic cp -p $(GENERIC_DIR)/README $(DISTDIR)/generic cp -p $(GENERIC_DIR)/tclGetDate.y $(DISTDIR)/generic cp -p $(TOP_DIR)/changes $(TOP_DIR)/ChangeLog $(TOP_DIR)/README* \ $(TOP_DIR)/ChangeLog.[12]??? $(TOP_DIR)/license.terms \ |
︙ | ︙ |
Changes to unix/configure.
︙ | ︙ | |||
19433 19434 19435 19436 19437 19438 19439 | libdir="${libdir}/Tcl.framework/Versions/\${VERSION}" TCL_LIBRARY="${libdir}/Resources/Scripts" includedir="${libdir}/Headers" PRIVATE_INCLUDE_DIR="${libdir}/PrivateHeaders" HTML_DIR="${libdir}/Resources/Documentation/Reference/Tcl" EXTRA_INSTALL="install-private-headers html-tcl" EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TclTOC.html' | | | | 19433 19434 19435 19436 19437 19438 19439 19440 19441 19442 19443 19444 19445 19446 19447 19448 | libdir="${libdir}/Tcl.framework/Versions/\${VERSION}" TCL_LIBRARY="${libdir}/Resources/Scripts" includedir="${libdir}/Headers" PRIVATE_INCLUDE_DIR="${libdir}/PrivateHeaders" HTML_DIR="${libdir}/Resources/Documentation/Reference/Tcl" EXTRA_INSTALL="install-private-headers html-tcl" EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TclTOC.html' EXTRA_INSTALL_BINARIES='@echo "Installing Info.plist to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Tcl-Info.plist "$(LIB_INSTALL_DIR)/Resources/Info.plist"' EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing license.terms to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA) "$(TOP_DIR)/license.terms" "$(LIB_INSTALL_DIR)/Resources"' EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Finalizing Tcl.framework" && rm -f "$(LIB_INSTALL_DIR)/../Current" && ln -s "$(VERSION)" "$(LIB_INSTALL_DIR)/../Current" && for f in "$(LIB_FILE)" tclConfig.sh Resources Headers PrivateHeaders; do rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/Current/$$f" "$(LIB_INSTALL_DIR)/../.."; done && f="$(STUB_LIB_FILE)" && rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/$(VERSION)/$$f" "$(LIB_INSTALL_DIR)/../.."' # Don't use AC_DEFINE for the following as the framework version define # needs to go into the Makefile even when using autoheader, so that we # can pick up a potential make override of VERSION. Also, don't put this # into CFLAGS as it should not go into tclConfig.sh EXTRA_CC_SWITCHES='-DTCL_FRAMEWORK_VERSION=\"$(VERSION)\"' else |
︙ | ︙ |
Changes to unix/configure.in.
︙ | ︙ | |||
216 217 218 219 220 221 222 | # use it when threads are enabled, c.f. bug # 711232 ac_cv_func_realpath=no fi AC_CHECK_FUNC(realpath, , [AC_DEFINE(NO_REALPATH, 1, [Do we have realpath()])]) SC_TCL_IPV6 | | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | # use it when threads are enabled, c.f. bug # 711232 ac_cv_func_realpath=no fi AC_CHECK_FUNC(realpath, , [AC_DEFINE(NO_REALPATH, 1, [Do we have realpath()])]) SC_TCL_IPV6 #-------------------------------------------------------------------- # Look for thread-safe variants of some library functions. #-------------------------------------------------------------------- if test "${TCL_THREADS}" = 1; then SC_TCL_GETPWUID_R SC_TCL_GETPWNAM_R SC_TCL_GETGRGID_R |
︙ | ︙ | |||
394 395 396 397 398 399 400 | AC_CHECK_TYPE([intptr_t], [ AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [ AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [ for tcl_cv_intptr_t in "int" "long" "long long" none; do if test "$tcl_cv_intptr_t" != none; then AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT], | | | | 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 | AC_CHECK_TYPE([intptr_t], [ AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [ AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [ for tcl_cv_intptr_t in "int" "long" "long long" none; do if test "$tcl_cv_intptr_t" != none; then AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT], [[sizeof (void *) <= sizeof ($tcl_cv_intptr_t)]])], [tcl_ok=yes], [tcl_ok=no]) test "$tcl_ok" = yes && break; fi done]) if test "$tcl_cv_intptr_t" != none; then AC_DEFINE_UNQUOTED([intptr_t], [$tcl_cv_intptr_t], [Signed integer type wide enough to hold a pointer.]) fi ]) AC_CHECK_TYPE([uintptr_t], [ AC_DEFINE([HAVE_UINTPTR_T], 1, [Do we have the uintptr_t type?])], [ AC_CACHE_CHECK([for pointer-size unsigned integer type], tcl_cv_uintptr_t, [ for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \ none; do if test "$tcl_cv_uintptr_t" != none; then AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT], [[sizeof (void *) <= sizeof ($tcl_cv_uintptr_t)]])], [tcl_ok=yes], [tcl_ok=no]) test "$tcl_ok" = yes && break; fi done]) if test "$tcl_cv_uintptr_t" != none; then AC_DEFINE_UNQUOTED([uintptr_t], [$tcl_cv_uintptr_t], [Unsigned integer type wide enough to hold a pointer.]) fi |
︙ | ︙ | |||
677 678 679 680 681 682 683 | AC_HELP_STRING([--with-tzdata], [install timezone data (default: autodetect)]), [tcl_ok=$withval], [tcl_ok=auto]) # # Any directories that get added here must also be added to the # search path in ::tcl::clock::Initialize (library/clock.tcl). # | | | 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | AC_HELP_STRING([--with-tzdata], [install timezone data (default: autodetect)]), [tcl_ok=$withval], [tcl_ok=auto]) # # Any directories that get added here must also be added to the # search path in ::tcl::clock::Initialize (library/clock.tcl). # case $tcl_ok in no) AC_MSG_RESULT([supplied by OS vendor]) ;; yes) # nothing to do here ;; auto*) |
︙ | ︙ | |||
704 705 706 707 708 709 710 | tcl_ok=no AC_MSG_RESULT([$dir]) else tcl_ok=yes fi ;; *) | | | 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 | tcl_ok=no AC_MSG_RESULT([$dir]) else tcl_ok=yes fi ;; *) AC_MSG_ERROR([invalid argument: $tcl_ok]) ;; esac if test $tcl_ok = yes then AC_MSG_RESULT([supplied by Tcl]) INSTALL_TZDATA=install-tzdata fi |
︙ | ︙ | |||
778 779 780 781 782 783 784 | #-------------------------------------------------------------------- TCL_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX} TCL_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX} eval "TCL_LIB_FILE=libtcl${LIB_SUFFIX}" # tclConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed | | | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | #-------------------------------------------------------------------- TCL_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX} TCL_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX} eval "TCL_LIB_FILE=libtcl${LIB_SUFFIX}" # tclConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed # since on some platforms TCL_LIB_FILE contains shell escapes. # (See also: TCL_TRIM_DOTS). eval "TCL_LIB_FILE=${TCL_LIB_FILE}" TCL_LIBRARY='$(prefix)/lib/tcl$(VERSION)' PRIVATE_INCLUDE_DIR='$(includedir)' HTML_DIR='$(DISTDIR)/html' |
︙ | ︙ | |||
837 838 839 840 841 842 843 | libdir="${libdir}/Tcl.framework/Versions/\${VERSION}" TCL_LIBRARY="${libdir}/Resources/Scripts" includedir="${libdir}/Headers" PRIVATE_INCLUDE_DIR="${libdir}/PrivateHeaders" HTML_DIR="${libdir}/Resources/Documentation/Reference/Tcl" EXTRA_INSTALL="install-private-headers html-tcl" EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TclTOC.html' | | | | 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 | libdir="${libdir}/Tcl.framework/Versions/\${VERSION}" TCL_LIBRARY="${libdir}/Resources/Scripts" includedir="${libdir}/Headers" PRIVATE_INCLUDE_DIR="${libdir}/PrivateHeaders" HTML_DIR="${libdir}/Resources/Documentation/Reference/Tcl" EXTRA_INSTALL="install-private-headers html-tcl" EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TclTOC.html' EXTRA_INSTALL_BINARIES='@echo "Installing Info.plist to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Tcl-Info.plist "$(LIB_INSTALL_DIR)/Resources/Info.plist"' EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing license.terms to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA) "$(TOP_DIR)/license.terms" "$(LIB_INSTALL_DIR)/Resources"' EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Finalizing Tcl.framework" && rm -f "$(LIB_INSTALL_DIR)/../Current" && ln -s "$(VERSION)" "$(LIB_INSTALL_DIR)/../Current" && for f in "$(LIB_FILE)" tclConfig.sh Resources Headers PrivateHeaders; do rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/Current/$$f" "$(LIB_INSTALL_DIR)/../.."; done && f="$(STUB_LIB_FILE)" && rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/$(VERSION)/$$f" "$(LIB_INSTALL_DIR)/../.."' # Don't use AC_DEFINE for the following as the framework version define # needs to go into the Makefile even when using autoheader, so that we # can pick up a potential make override of VERSION. Also, don't put this # into CFLAGS as it should not go into tclConfig.sh EXTRA_CC_SWITCHES='-DTCL_FRAMEWORK_VERSION=\"$(VERSION)\"' else |
︙ | ︙ |
Changes to unix/install-sh.
︙ | ︙ | |||
152 153 154 155 156 157 158 | shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; | | | | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -S) stripcmd="$stripprog $2" shift;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; |
︙ | ︙ |
Changes to unix/tclConfig.h.in.
︙ | ︙ | |||
9 10 11 12 13 14 15 | /* Define to 1 if you have the <AvailabilityMacros.h> header file. */ #undef HAVE_AVAILABILITYMACROS_H /* Define to 1 if the system has the type `blkcnt_t'. */ #undef HAVE_BLKCNT_T | | | > > > | 9 10 11 12 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 | /* Define to 1 if you have the <AvailabilityMacros.h> header file. */ #undef HAVE_AVAILABILITYMACROS_H /* Define to 1 if the system has the type `blkcnt_t'. */ #undef HAVE_BLKCNT_T /* Defined when compiler supports casting to union type. */ #undef HAVE_CAST_TO_UNION /* Define to 1 if you have the `chflags' function. */ #undef HAVE_CHFLAGS /* Define to 1 if you have the `copyfile' function. */ #undef HAVE_COPYFILE /* Define to 1 if you have the <copyfile.h> header file. */ #undef HAVE_COPYFILE_H /* Do we have access to Darwin CoreFoundation.framework? */ #undef HAVE_COREFOUNDATION /* Is the cpuid instruction usable? */ #undef HAVE_CPUID /* Define to 1 if you have the `freeaddrinfo' function. */ #undef HAVE_FREEADDRINFO /* Do we have fts functions? */ #undef HAVE_FTS |
︙ | ︙ | |||
266 267 268 269 270 271 272 273 274 275 276 277 278 279 | #undef MAC_OSX_TCL /* No Compiler support for module scope symbols */ #undef MODULE_SCOPE /* Default libtommath precision. */ #undef MP_PREC /* Use compat implementation of getaddrinfo() and friends */ #undef NEED_FAKE_RFC2553 /* Is Darwin CoreFoundation unavailable for 64-bit? */ #undef NO_COREFOUNDATION_64 | > > > | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | #undef MAC_OSX_TCL /* No Compiler support for module scope symbols */ #undef MODULE_SCOPE /* Default libtommath precision. */ #undef MP_PREC /* Is no debugging enabled? */ #undef NDEBUG /* Use compat implementation of getaddrinfo() and friends */ #undef NEED_FAKE_RFC2553 /* Is Darwin CoreFoundation unavailable for 64-bit? */ #undef NO_COREFOUNDATION_64 |
︙ | ︙ | |||
357 358 359 360 361 362 363 | /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* What encoding should be used for embedded configuration info? */ #undef TCL_CFGVAL_ENCODING | < < < | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* What encoding should be used for embedded configuration info? */ #undef TCL_CFGVAL_ENCODING /* Is this a 64-bit build? */ #undef TCL_CFG_DO64BIT /* Is this an optimized build? */ #undef TCL_CFG_OPTIMIZED /* Is bytecode debugging enabled? */ |
︙ | ︙ |
Changes to unix/tclLoadDl.c.
︙ | ︙ | |||
108 109 110 111 112 113 114 | /* * Write the string to a variable first to work around a compiler bug * in the Sun Forte 6 compiler. [Bug 1503729] */ const char *errorStr = dlerror(); | > | | | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | /* * Write the string to a variable first to work around a compiler bug * in the Sun Forte 6 compiler. [Bug 1503729] */ const char *errorStr = dlerror(); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't load file \"%s\": %s", Tcl_GetString(pathPtr), errorStr)); return TCL_ERROR; } newHandle = ckalloc(sizeof(*newHandle)); newHandle->clientData = handle; newHandle->findSymbolProcPtr = &FindSymbol; newHandle->unloadFileProcPtr = &UnloadFile; *unloadProcPtr = &UnloadFile; |
︙ | ︙ | |||
171 172 173 174 175 176 177 | TclDStringAppendLiteral(&newName, "_"); native = Tcl_DStringAppend(&newName, native, -1); proc = dlsym(handle, native); /* INTL: Native. */ Tcl_DStringFree(&newName); } Tcl_DStringFree(&ds); if (proc == NULL && interp != NULL) { | | | < | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | TclDStringAppendLiteral(&newName, "_"); native = Tcl_DStringAppend(&newName, native, -1); proc = dlsym(handle, native); /* INTL: Native. */ Tcl_DStringFree(&newName); } Tcl_DStringFree(&ds); if (proc == NULL && interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cannot find symbol \"%s\": %s", symbol, dlerror())); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol, NULL); } return proc; } /* |
︙ | ︙ |
Changes to unix/tclLoadDyld.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" #ifndef MODULE_SCOPE | | < | > > | | | | | < | < < < < | | < < < | > | < | | < < < | | < < < < < < < < < < < < > | 12 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 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 104 105 106 107 108 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" #ifndef MODULE_SCOPE # define MODULE_SCOPE extern #endif /* * Use preferred dlfcn API on 10.4 and later */ #ifndef TCL_DYLD_USE_DLFCN # ifdef NO_DLFCN_H # define TCL_DYLD_USE_DLFCN 0 # else # define TCL_DYLD_USE_DLFCN 1 # endif #endif /* * Use deprecated NSModule API only to support 10.3 and earlier: */ #ifndef TCL_DYLD_USE_NSMODULE # define TCL_DYLD_USE_NSMODULE 0 #endif /* * Use includes for the API we're using. */ #if TCL_DYLD_USE_DLFCN # include <dlfcn.h> #endif /* TCL_DYLD_USE_DLFCN */ #if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) #include <mach-o/dyld.h> #include <mach-o/fat.h> #include <mach-o/swap.h> #include <mach-o/arch.h> #include <libkern/OSByteOrder.h> #include <mach/mach.h> typedef struct Tcl_DyldModuleHandle { struct Tcl_DyldModuleHandle *nextPtr; NSModule module; } Tcl_DyldModuleHandle; #endif /* TCL_DYLD_USE_NSMODULE || TCL_LOAD_FROM_MEMORY */ typedef struct { void *dlHandle; #if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) const struct mach_header *dyldLibHeader; Tcl_DyldModuleHandle *modulePtr; #endif } Tcl_DyldLoadHandle; #if TCL_DYLD_USE_DLFCN || defined(TCL_LOAD_FROM_MEMORY) MODULE_SCOPE long tclMacOSXDarwinRelease; #endif /* * Static functions defined in this file. */ static void * FindSymbol(Tcl_Interp *interp, Tcl_LoadHandle loadHandle, const char *symbol); static void UnloadFile(Tcl_LoadHandle handle); /* *---------------------------------------------------------------------- * * DyldOFIErrorMsg -- * * Converts a numerical NSObjectFileImage error into an error message * string. * * Results: * Error message string. * * Side effects: * None. * *---------------------------------------------------------------------- */ #if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) static const char * DyldOFIErrorMsg( int err) { switch(err) { case NSObjectFileImageSuccess: return NULL; |
︙ | ︙ | |||
137 138 139 140 141 142 143 | return "bad object file format"; case NSObjectFileImageAccess: return "can't read object file"; default: return "unknown error"; } } | | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | return "bad object file format"; case NSObjectFileImageAccess: return "can't read object file"; default: return "unknown error"; } } #endif /* TCL_DYLD_USE_NSMODULE || TCL_LOAD_FROM_MEMORY */ /* *---------------------------------------------------------------------- * * TclpDlopen -- * * Dynamically loads a binary code file into memory and returns a handle |
︙ | ︙ | |||
172 173 174 175 176 177 178 | Tcl_FSUnloadFileProc **unloadProcPtr) /* Filled with address of Tcl_FSUnloadFileProc * function which should be used for this * file. */ { Tcl_DyldLoadHandle *dyldLoadHandle; Tcl_LoadHandle newHandle; | < < | < > > < < < < > | | | | | | < | < < < | | < | > | < < < < | > | < < < < < < < | < < < < < < < < < | < | < | < < | > | > > > > | | | > | | < | 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 | Tcl_FSUnloadFileProc **unloadProcPtr) /* Filled with address of Tcl_FSUnloadFileProc * function which should be used for this * file. */ { Tcl_DyldLoadHandle *dyldLoadHandle; Tcl_LoadHandle newHandle; void *dlHandle = NULL; #if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) const struct mach_header *dyldLibHeader = NULL; Tcl_DyldModuleHandle *modulePtr = NULL; #endif #if TCL_DYLD_USE_NSMODULE NSLinkEditErrors editError; int errorNumber; const char *errorName, *objFileImageErrMsg = NULL; #endif /* TCL_DYLD_USE_NSMODULE */ const char *errMsg = NULL; int result; Tcl_DString ds; const char *nativePath, *nativeFileName = NULL; /* * 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), -1, &ds); #if TCL_DYLD_USE_DLFCN /* * Use (RTLD_NOW|RTLD_LOCAL) always, see [Bug #3216070] */ dlHandle = dlopen(nativePath, RTLD_NOW | RTLD_LOCAL); if (!dlHandle) { /* * 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. * * Use (RTLD_NOW|RTLD_LOCAL) always, see [Bug #3216070] */ dlHandle = dlopen(nativeFileName, RTLD_NOW | RTLD_LOCAL); if (!dlHandle) { errMsg = dlerror(); } } #endif /* TCL_DYLD_USE_DLFCN */ if (!dlHandle) { #if TCL_DYLD_USE_NSMODULE dyldLibHeader = NSAddImage(nativePath, NSADDIMAGE_OPTION_RETURN_ON_ERROR); if (!dyldLibHeader) { NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); if (editError == NSLinkEditFileAccessError) { /* * The requested file was not found. 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. */ dyldLibHeader = NSAddImage(nativeFileName, NSADDIMAGE_OPTION_WITH_SEARCHING | NSADDIMAGE_OPTION_RETURN_ON_ERROR); if (!dyldLibHeader) { NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); } } else if ((editError == NSLinkEditFileFormatError && errorNumber == EBADMACHO) || editError == NSLinkEditOtherError){ NSObjectFileImageReturnCode err; NSObjectFileImage dyldObjFileImage; NSModule module; /* * The requested file was found but was not of type MH_DYLIB, * attempt to load it as a MH_BUNDLE. */ err = NSCreateObjectFileImageFromFile(nativePath, &dyldObjFileImage); if (err == NSObjectFileImageSuccess && dyldObjFileImage) { module = NSLinkModule(dyldObjFileImage, nativePath, NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(dyldObjFileImage); if (module) { modulePtr = ckalloc(sizeof(Tcl_DyldModuleHandle)); modulePtr->module = module; modulePtr->nextPtr = NULL; } else { NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); } } else { objFileImageErrMsg = DyldOFIErrorMsg(err); } } } #endif /* TCL_DYLD_USE_NSMODULE */ } if (dlHandle #if TCL_DYLD_USE_NSMODULE || dyldLibHeader || modulePtr #endif /* TCL_DYLD_USE_NSMODULE */ ) { dyldLoadHandle = ckalloc(sizeof(Tcl_DyldLoadHandle)); dyldLoadHandle->dlHandle = dlHandle; #if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) dyldLoadHandle->dyldLibHeader = dyldLibHeader; dyldLoadHandle->modulePtr = modulePtr; #endif /* TCL_DYLD_USE_NSMODULE || TCL_LOAD_FROM_MEMORY */ newHandle = ckalloc(sizeof(*newHandle)); newHandle->clientData = dyldLoadHandle; newHandle->findSymbolProcPtr = &FindSymbol; newHandle->unloadFileProcPtr = &UnloadFile; *unloadProcPtr = &UnloadFile; *loadHandle = newHandle; result = TCL_OK; } else { Tcl_Obj *errObj = Tcl_NewObj(); if (errMsg != NULL) { Tcl_AppendToObj(errObj, errMsg, -1); } #if TCL_DYLD_USE_NSMODULE if (objFileImageErrMsg) { Tcl_AppendPrintfToObj(errObj, "\nNSCreateObjectFileImageFromFile() error: %s", objFileImageErrMsg); } #endif /* TCL_DYLD_USE_NSMODULE */ Tcl_SetObjResult(interp, errObj); result = TCL_ERROR; } Tcl_DStringFree(&ds); return result; } /* *---------------------------------------------------------------------- * * FindSymbol -- |
︙ | ︙ | |||
368 369 370 371 372 373 374 | Tcl_DyldLoadHandle *dyldLoadHandle = loadHandle->clientData; Tcl_PackageInitProc *proc = NULL; const char *errMsg = NULL; Tcl_DString ds; const char *native; native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds); | < > | < < < < < > < < > | 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 | Tcl_DyldLoadHandle *dyldLoadHandle = loadHandle->clientData; Tcl_PackageInitProc *proc = NULL; const char *errMsg = NULL; Tcl_DString ds; const char *native; native = Tcl_UtfToExternalDString(NULL, symbol, -1, &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, -1); 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 * following is not needed. */ #ifdef DYLD_SUPPORTS_DYLIB_UNLOADING NSModule module = NSModuleForSymbol(nsSymbol); Tcl_DyldModuleHandle *modulePtr = dyldLoadHandle->modulePtr; while (modulePtr != NULL) { if (module == modulePtr->module) { break; } |
︙ | ︙ | |||
425 426 427 428 429 430 431 | #endif /* DYLD_SUPPORTS_DYLIB_UNLOADING */ } else { NSLinkEditErrors editError; int errorNumber; const char *errorName; NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); | < < < < < < < < < < < | | | 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 | #endif /* DYLD_SUPPORTS_DYLIB_UNLOADING */ } else { NSLinkEditErrors editError; int errorNumber; const char *errorName; NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); } } else if (dyldLoadHandle->modulePtr) { nsSymbol = NSLookupSymbolInModule( dyldLoadHandle->modulePtr->module, native); } if (nsSymbol) { proc = NSAddressOfSymbol(nsSymbol); } Tcl_DStringFree(&newName); #endif /* TCL_DYLD_USE_NSMODULE */ } Tcl_DStringFree(&ds); if (errMsg && (interp != NULL)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cannot find symbol \"%s\": %s", symbol, errMsg)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol, NULL); } return proc; } /* |
︙ | ︙ | |||
485 486 487 488 489 490 491 | UnloadFile( Tcl_LoadHandle loadHandle) /* loadHandle returned by a previous call to * TclpDlopen(). The loadHandle is a token * that represents the loaded file. */ { Tcl_DyldLoadHandle *dyldLoadHandle = loadHandle->clientData; | < < | | | < | < < < < < | < | < < < < < < | 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 | UnloadFile( Tcl_LoadHandle loadHandle) /* loadHandle returned by a previous call to * TclpDlopen(). The loadHandle is a token * that represents the loaded file. */ { Tcl_DyldLoadHandle *dyldLoadHandle = loadHandle->clientData; if (dyldLoadHandle->dlHandle) { #if TCL_DYLD_USE_DLFCN (void) dlclose(dyldLoadHandle->dlHandle); #endif /* TCL_DYLD_USE_DLFCN */ } else { #if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) Tcl_DyldModuleHandle *modulePtr = dyldLoadHandle->modulePtr; while (modulePtr != NULL) { void *ptr = modulePtr; (void) NSUnLinkModule(modulePtr->module, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); modulePtr = modulePtr->nextPtr; ckfree(ptr); } #endif /* TCL_DYLD_USE_NSMODULE */ } ckfree(dyldLoadHandle); ckfree(loadHandle); |
︙ | ︙ | |||
552 553 554 555 556 557 558 | * translated to local form if needed). */ Tcl_DString *bufPtr) /* Initialized empty dstring. Append package * name to this if possible. */ { return 0; } | < > | 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 | * translated to local form if needed). */ Tcl_DString *bufPtr) /* Initialized empty dstring. Append package * name to this if possible. */ { return 0; } /* *---------------------------------------------------------------------- * * TclpLoadMemoryGetBuffer -- * * Allocate a buffer that can be used with TclpLoadMemory() below. * * Results: * Pointer to allocated buffer or NULL if an error occurs. * * Side effects: * Buffer is allocated. * *---------------------------------------------------------------------- */ #ifdef TCL_LOAD_FROM_MEMORY MODULE_SCOPE void * TclpLoadMemoryGetBuffer( Tcl_Interp *interp, /* Used for error reporting. */ int size) /* Size of desired buffer. */ { void *buffer = NULL; |
︙ | ︙ | |||
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 | if (vm_allocate(mach_task_self(), (vm_address_t *) &buffer, size, 1)) { buffer = NULL; } } return buffer; } /* *---------------------------------------------------------------------- * * TclpLoadMemory -- * * Dynamically loads binary code file from memory and returns a handle to * the new code. * * Results: * A standard Tcl completion code. If an error occurs, an error message * is left in the interpreter's result. * * Side effects: * New code is loaded from memory. * *---------------------------------------------------------------------- */ MODULE_SCOPE int TclpLoadMemory( Tcl_Interp *interp, /* Used for error reporting. */ void *buffer, /* Buffer containing the desired code * (allocated with TclpLoadMemoryGetBuffer). */ int size, /* Allocation size of buffer. */ int codeSize, /* Size of code data read into buffer or -1 if | > > | 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 | if (vm_allocate(mach_task_self(), (vm_address_t *) &buffer, size, 1)) { buffer = NULL; } } return buffer; } #endif /* TCL_LOAD_FROM_MEMORY */ /* *---------------------------------------------------------------------- * * TclpLoadMemory -- * * Dynamically loads binary code file from memory and returns a handle to * the new code. * * Results: * A standard Tcl completion code. If an error occurs, an error message * is left in the interpreter's result. * * Side effects: * New code is loaded from memory. * *---------------------------------------------------------------------- */ #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). */ int size, /* Allocation size of buffer. */ int codeSize, /* Size of code data read into buffer or -1 if |
︙ | ︙ | |||
654 655 656 657 658 659 660 | # define mh_magic MH_MAGIC # define arch_abi 0 #else const struct mach_header_64 *mh = NULL; # define mh_size sizeof(struct mach_header_64) # define mh_magic MH_MAGIC_64 # define arch_abi CPU_ARCH_ABI64 | | < < < < < < | < < < < < | < < < < < > | | | < < < | < < | 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 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 675 676 677 678 679 680 681 682 683 684 685 686 687 688 | # define mh_magic MH_MAGIC # define arch_abi 0 #else const struct mach_header_64 *mh = NULL; # define mh_size sizeof(struct mach_header_64) # define mh_magic MH_MAGIC_64 # define arch_abi CPU_ARCH_ABI64 #endif /* __LP64__ */ if ((size_t) codeSize >= sizeof(struct fat_header) && fh->magic == OSSwapHostToBigInt32(FAT_MAGIC)) { uint32_t fh_nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch); /* * Fat binary, try to find mach_header for our architecture */ if ((size_t) codeSize >= sizeof(struct fat_header) + fh_nfat_arch * sizeof(struct fat_arch)) { void *fatarchs = (char*)buffer + sizeof(struct fat_header); const NXArchInfo *arch = NXGetLocalArchInfo(); struct fat_arch *fa; if (fh->magic != FAT_MAGIC) { swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder); } fa = NXFindBestFatArch(arch->cputype | arch_abi, arch->cpusubtype, fatarchs, fh_nfat_arch); if (fa) { mh = (void *)((char *) buffer + fa->offset); ms = fa->size; } else { err = NSObjectFileImageInappropriateFile; } if (fh->magic != FAT_MAGIC) { swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder); } } else { err = NSObjectFileImageInappropriateFile; } } else { /* * Thin binary */ mh = buffer; ms = codeSize; } if (ms && !(ms >= mh_size && mh->magic == mh_magic && mh->filetype == MH_BUNDLE)) { err = NSObjectFileImageInappropriateFile; } if (err == NSObjectFileImageSuccess) { err = NSCreateObjectFileImageFromMemory(buffer, codeSize, &dyldObjFileImage); if (err != NSObjectFileImageSuccess) { objFileImageErrMsg = DyldOFIErrorMsg(err); } } else { objFileImageErrMsg = DyldOFIErrorMsg(err); } } /* * If it went wrong (or we were asked to just deallocate), get rid of the * memory block and create an error message. */ if (dyldObjFileImage == NULL) { vm_deallocate(mach_task_self(), (vm_address_t) buffer, size); if (objFileImageErrMsg != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "NSCreateObjectFileImageFromMemory() error: ", objFileImageErrMsg)); } return TCL_ERROR; } /* * Extract the module we want from the image of the object file. */ module = NSLinkModule(dyldObjFileImage, "[Memory Based Bundle]", NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(dyldObjFileImage); if (!module) { NSLinkEditErrors editError; int errorNumber; const char *errorName, *errMsg; NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1)); return TCL_ERROR; } /* * Stash the module reference within the load handle we create and return. */ modulePtr = ckalloc(sizeof(Tcl_DyldModuleHandle)); modulePtr->module = module; modulePtr->nextPtr = NULL; dyldLoadHandle = ckalloc(sizeof(Tcl_DyldLoadHandle)); dyldLoadHandle->dlHandle = NULL; dyldLoadHandle->dyldLibHeader = NULL; dyldLoadHandle->modulePtr = modulePtr; newHandle = ckalloc(sizeof(*newHandle)); newHandle->clientData = dyldLoadHandle; newHandle->findSymbolProcPtr = &FindSymbol; newHandle->unloadFileProcPtr = &UnloadFile; *loadHandle = newHandle; |
︙ | ︙ |
Changes to unix/tclLoadNext.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | #include "tclInt.h" #include <mach-o/rld.h> #include <streams/streams.h> /* Static procedures defined within this file */ | | | | < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include "tclInt.h" #include <mach-o/rld.h> #include <streams/streams.h> /* Static procedures defined within this file */ static void * FindSymbol(Tcl_Interp *interp, Tcl_LoadHandle loadHandle, const char* symbol); static void UnloadFile(Tcl_LoadHandle loadHandle); /* *---------------------------------------------------------------------- * * TclpDlopen -- * * Dynamically loads a binary code file into memory and returns a handle |
︙ | ︙ | |||
89 90 91 92 93 94 95 | Tcl_DStringFree(&ds); } if (!result) { char *data; int len, maxlen; | | | | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | Tcl_DStringFree(&ds); } if (!result) { char *data; int len, maxlen; NXGetMemoryBuffer(errorStream, &data, &len, &maxlen); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't load file \"%s\": %s", fileName, data)); NXCloseMemory(errorStream, NX_FREEBUFFER); return TCL_ERROR; } NXCloseMemory(errorStream, NX_FREEBUFFER); newHandle = ckalloc(sizeof(Tcl_LoadHandle)); newHandle->clientData = INT2PTR(1); newHandle->findSymbolProcPtr = &FindSymbol; newHandle->unloadFileProcPtr = &UnloadFile; *loadHandle = newHandle; *unloadProcPtr = &UnloadFile; return TCL_OK; |
︙ | ︙ | |||
123 124 125 126 127 128 129 | * Returns a pointer to the function associated with 'symbol' if it is * found. Otherwise returns NULL and may leave an error message in the * interp's result. * *---------------------------------------------------------------------- */ | | > | | | | < | 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 | * Returns a pointer to the function associated with 'symbol' if it is * found. Otherwise returns NULL and may leave an error message in the * interp's result. * *---------------------------------------------------------------------- */ static void * FindSymbol( Tcl_Interp *interp, Tcl_LoadHandle loadHandle, const char *symbol) { Tcl_PackageInitProc *proc = NULL; if (symbol) { char sym[strlen(symbol) + 2]; sym[0] = '_'; sym[1] = 0; strcat(sym, symbol); rld_lookup(NULL, sym, (unsigned long *) &proc); } if (proc == NULL && interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cannot find symbol \"%s\"", symbol)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol, NULL); } return proc; } /* *---------------------------------------------------------------------- |
︙ | ︙ |
Changes to unix/tclLoadOSF.c.
︙ | ︙ | |||
31 32 33 34 35 36 37 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" #include <sys/types.h> #include <loader.h> | | > | > | | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" #include <sys/types.h> #include <loader.h> /* * Static functions defined within this file. */ static void * FindSymbol(Tcl_Interp *interp, Tcl_LoadHandle loadHandle, const char* symbol); static void UnloadFile(Tcl_LoadHandle handle); /* *---------------------------------------------------------------------- * * TclpDlopen -- * * Dynamically loads a binary code file into memory and returns a handle |
︙ | ︙ | |||
99 100 101 102 103 104 105 | native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds); lm = (Tcl_PackageInitProc *) load(native, LDR_NOFLAGS); Tcl_DStringFree(&ds); } if (lm == LDR_NULL_MODULE) { | > | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | native = Tcl_UtfToExternalDString(NULL, fileName, -1, &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", fileName, Tcl_PosixError(interp))); return TCL_ERROR; } *clientDataPtr = NULL; /* * My convention is to use a [OSF loader] package name the same as shlib, |
︙ | ︙ | |||
151 152 153 154 155 156 157 | static void * FindSymbol( Tcl_Interp *interp, Tcl_LoadHandle loadHandle, const char *symbol) { | | > | | | 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | static void * FindSymbol( Tcl_Interp *interp, Tcl_LoadHandle loadHandle, const char *symbol) { void *retval = ldr_lookup_package((char *) loadHandle, symbol); if (retval == NULL && interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cannot find symbol \"%s\"", symbol)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol, NULL); } return retval; } /* *---------------------------------------------------------------------- |
︙ | ︙ |
Changes to unix/tclLoadShl.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | */ #ifdef EXTERN # undef EXTERN #endif #include "tclInt.h" | | > | > | | < | < | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | */ #ifdef EXTERN # undef EXTERN #endif #include "tclInt.h" /* * Static functions defined within this file. */ static void * FindSymbol(Tcl_Interp *interp, Tcl_LoadHandle loadHandle, const char *symbol); static void UnloadFile(Tcl_LoadHandle handle); /* *---------------------------------------------------------------------- * * TclpDlopen -- * * Dynamically loads a binary code file into memory and returns a handle |
︙ | ︙ | |||
96 97 98 99 100 101 102 | native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds); handle = shl_load(native, BIND_DEFERRED|BIND_VERBOSE|DYNAMIC_PATH, 0L); Tcl_DStringFree(&ds); } if (handle == NULL) { | > | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | native = Tcl_UtfToExternalDString(NULL, fileName, -1, &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", fileName, Tcl_PosixError(interp))); return TCL_ERROR; } newHandle = ckalloc(sizeof(*newHandle)); newHandle->clientData = handle; newHandle->findSymbolProcPtr = &FindSymbol; newHandle->unloadFileProcPtr = *unloadProcPtr = &UnloadFile; *loadHandle = newHandle; |
︙ | ︙ | |||
132 133 134 135 136 137 138 | FindSymbol( Tcl_Interp *interp, Tcl_LoadHandle loadHandle, const char *symbol) { Tcl_DString newName; Tcl_PackageInitProc *proc = NULL; | | | | | | 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 | FindSymbol( Tcl_Interp *interp, Tcl_LoadHandle loadHandle, const char *symbol) { Tcl_DString newName; Tcl_PackageInitProc *proc = NULL; shl_t handle = (shl_t) loadHandle->clientData; /* * Some versions of the HP system software still use "_" at the beginning * 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, -1); if (shl_findsym(&handle, Tcl_DStringValue(&newName), (short) TYPE_PROCEDURE, (void *) &proc) != 0) { proc = NULL; } Tcl_DStringFree(&newName); } if (proc == NULL && interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cannot find symbol \"%s\": %s", symbol, Tcl_PosixError(interp))); } return proc; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
182 183 184 185 186 187 188 | static void UnloadFile( Tcl_LoadHandle loadHandle) /* loadHandle returned by a previous call to * TclpDlopen(). The loadHandle is a token * that represents the loaded file. */ { | | < | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | static void UnloadFile( Tcl_LoadHandle loadHandle) /* loadHandle returned by a previous call to * TclpDlopen(). The loadHandle is a token * that represents the loaded file. */ { shl_t handle = (shl_t) loadHandle->clientData; shl_unload(handle); ckfree(loadHandle); } /* *---------------------------------------------------------------------- * |
︙ | ︙ |
Changes to unix/tclUnixChan.c.
︙ | ︙ | |||
132 133 134 135 136 137 138 | int data; int stop; } TtyAttrs; #endif /* !SUPPORTS_TTY */ #define UNSUPPORTED_OPTION(detail) \ | | | | | | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | int data; int stop; } TtyAttrs; #endif /* !SUPPORTS_TTY */ #define UNSUPPORTED_OPTION(detail) \ if (interp) { \ Tcl_SetObjResult(interp, Tcl_ObjPrintf( \ "%s not supported for this platform", (detail))); \ Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL); \ } /* * Static routines for this file: */ static int FileBlockModeProc(ClientData instanceData, int mode); |
︙ | ︙ | |||
693 694 695 696 697 698 699 | return TCL_ERROR; #endif /* CRTSCTS */ } else if (strncasecmp(value, "DTRDSR", vlen) == 0) { UNSUPPORTED_OPTION("-handshake DTRDSR"); return TCL_ERROR; } else { if (interp) { | > | | < > | | | 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 | return TCL_ERROR; #endif /* CRTSCTS */ } else if (strncasecmp(value, "DTRDSR", vlen) == 0) { UNSUPPORTED_OPTION("-handshake DTRDSR"); return TCL_ERROR; } else { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -handshake: must be one of" " xonxoff, rtscts, dtrdsr or none", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE", "VALUE", NULL); } return TCL_ERROR; } SETIOSTATE(fsPtr->fd, &iostate); return TCL_OK; } /* * Option -xchar {\x11 \x13} */ if ((len > 1) && (strncmp(optionName, "-xchar", len) == 0)) { Tcl_DString ds; if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) { return TCL_ERROR; } else if (argc != 2) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -xchar: should be a list of" " two elements", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE", "VALUE", NULL); } ckfree(argv); return TCL_ERROR; } |
︙ | ︙ | |||
769 770 771 772 773 774 775 | int i; if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) { return TCL_ERROR; } if ((argc % 2) == 1) { if (interp) { | > | | | 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 | int i; if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) { return TCL_ERROR; } if ((argc % 2) == 1) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -ttycontrol: should be a list of" " signal,value pairs", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE", "VALUE", NULL); } ckfree(argv); return TCL_ERROR; } |
︙ | ︙ | |||
818 819 820 821 822 823 824 | #else /* !SETBREAK */ UNSUPPORTED_OPTION("-ttycontrol BREAK"); ckfree(argv); return TCL_ERROR; #endif /* SETBREAK */ } else { if (interp) { | | | | | 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 | #else /* !SETBREAK */ UNSUPPORTED_OPTION("-ttycontrol BREAK"); ckfree(argv); return TCL_ERROR; #endif /* SETBREAK */ } else { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad signal \"%s\" for -ttycontrol: must be" " DTR, RTS or BREAK", argv[i])); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE", "VALUE", NULL); } ckfree(argv); return TCL_ERROR; } } /* -ttycontrol options loop */ |
︙ | ︙ | |||
1384 1385 1386 1387 1388 1389 1390 | char parity; static const char *bad = "bad value for -mode"; i = sscanf(mode, "%d,%c,%d,%d%n", speedPtr, &parity, dataPtr, stopPtr, &end); if ((i != 4) || (mode[end] != '\0')) { if (interp != NULL) { | > | < | 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 | char parity; static const char *bad = "bad value for -mode"; i = sscanf(mode, "%d,%c,%d,%d%n", speedPtr, &parity, dataPtr, stopPtr, &end); if ((i != 4) || (mode[end] != '\0')) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s: should be baud,parity,data,stop", bad)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "SERIALMODE", NULL); } return TCL_ERROR; } /* * Only allow setting mark/space parity on platforms that support it Make |
︙ | ︙ | |||
1408 1409 1410 1411 1412 1413 1414 | #if defined(PAREXT) || defined(USE_TERMIO) strchr("noems", parity) #else strchr("noe", parity) #endif /* PAREXT|USE_TERMIO */ == NULL) { if (interp != NULL) { | > | | | | > | < > | | 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 1441 1442 1443 1444 1445 1446 1447 1448 | #if defined(PAREXT) || defined(USE_TERMIO) strchr("noems", parity) #else strchr("noe", parity) #endif /* PAREXT|USE_TERMIO */ == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s parity: should be %s", bad, #if defined(PAREXT) || defined(USE_TERMIO) "n, o, e, m, or s" #else "n, o, or e" #endif /* PAREXT|USE_TERMIO */ )); Tcl_SetErrorCode(interp, "TCL", "VALUE", "SERIALMODE", NULL); } return TCL_ERROR; } *parityPtr = parity; if ((*dataPtr < 5) || (*dataPtr > 8)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s data: should be 5, 6, 7, or 8", bad)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "SERIALMODE", NULL); } return TCL_ERROR; } if ((*stopPtr < 0) || (*stopPtr > 2)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s stop: should be 1 or 2", bad)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "SERIALMODE", NULL); } return TCL_ERROR; } return TCL_OK; } |
︙ | ︙ | |||
1579 1580 1581 1582 1583 1584 1585 | SET_BITS(mode, O_BINARY); #endif fd = TclOSopen(native, mode, permissions); if (fd < 0) { if (interp != NULL) { | > | | | 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 | SET_BITS(mode, O_BINARY); #endif fd = TclOSopen(native, mode, permissions); if (fd < 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open \"%s\": %s", TclGetString(pathPtr), Tcl_PosixError(interp))); } return NULL; } /* * Set close-on-exec flag on the fd so that child processes will not * inherit this fd. |
︙ | ︙ | |||
1838 1839 1840 1841 1842 1843 1844 | ClientData data; FILE *f; chan = Tcl_GetChannel(interp, chanID, &chanMode); if (chan == NULL) { return TCL_ERROR; } | | > | < | > | < | 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 | ClientData data; FILE *f; chan = Tcl_GetChannel(interp, chanID, &chanMode); if (chan == NULL) { return TCL_ERROR; } if (forWriting && !(chanMode & TCL_WRITABLE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" wasn't opened for writing", chanID)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "CHANNEL", "NOT_WRITABLE", NULL); return TCL_ERROR; } else if (!forWriting && !(chanMode & TCL_READABLE)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" wasn't opened for reading", chanID)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "CHANNEL", "NOT_READABLE", NULL); return TCL_ERROR; } /* * We allow creating a FILE * out of file based, pipe based and socket |
︙ | ︙ | |||
1877 1878 1879 1880 1881 1882 1883 | * The call to fdopen below is probably dangerous, since it will * truncate an existing file if the file is being opened for * writing.... */ f = fdopen(fd, (forWriting ? "w" : "r")); if (f == NULL) { | > | < | | | 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 1908 | * The call to fdopen below is probably dangerous, since it will * truncate an existing file if the file is being opened for * writing.... */ f = fdopen(fd, (forWriting ? "w" : "r")); if (f == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cannot get a FILE * for \"%s\"", chanID)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "CHANNEL", "FILE_FAILURE", NULL); return TCL_ERROR; } *filePtr = f; return TCL_OK; } } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" cannot be used to get a FILE *", chanID)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "CHANNEL", "NO_DESCRIPTOR", NULL); return TCL_ERROR; } #ifndef HAVE_COREFOUNDATION /* Darwin/Mac OS X CoreFoundation notifier is * in tclMacOSXNotify.c */ |
︙ | ︙ |
Changes to unix/tclUnixFCmd.c.
︙ | ︙ | |||
1316 1317 1318 1319 1320 1321 1322 | struct group *groupPtr; int result; result = TclpObjStat(fileName, &statBuf); if (result != 0) { if (interp != NULL) { | > | | < | 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 | struct group *groupPtr; int result; result = TclpObjStat(fileName, &statBuf); if (result != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } return TCL_ERROR; } groupPtr = TclpGetGrGid(statBuf.st_gid); if (groupPtr == NULL) { |
︙ | ︙ | |||
1370 1371 1372 1373 1374 1375 1376 | struct passwd *pwPtr; int result; result = TclpObjStat(fileName, &statBuf); if (result != 0) { if (interp != NULL) { | > | | < | 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 | struct passwd *pwPtr; int result; result = TclpObjStat(fileName, &statBuf); if (result != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } return TCL_ERROR; } pwPtr = TclpGetPwUid(statBuf.st_uid); if (pwPtr == NULL) { |
︙ | ︙ | |||
1421 1422 1423 1424 1425 1426 1427 | Tcl_StatBuf statBuf; int result; result = TclpObjStat(fileName, &statBuf); if (result != 0) { if (interp != NULL) { | > | | < | 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 | Tcl_StatBuf statBuf; int result; result = TclpObjStat(fileName, &statBuf); if (result != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } return TCL_ERROR; } *attributePtrPtr = Tcl_ObjPrintf( "%0#5lo", (long) (statBuf.st_mode & 0x00007FFF)); return TCL_OK; |
︙ | ︙ | |||
1474 1475 1476 1477 1478 1479 1480 | native = Tcl_UtfToExternalDString(NULL, string, length, &ds); groupPtr = TclpGetGrNam(native); /* INTL: Native. */ Tcl_DStringFree(&ds); if (groupPtr == NULL) { if (interp != NULL) { | > | > | < > | | < | 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 | native = Tcl_UtfToExternalDString(NULL, string, length, &ds); groupPtr = TclpGetGrNam(native); /* INTL: Native. */ Tcl_DStringFree(&ds); if (groupPtr == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not set group for file \"%s\":" " group \"%s\" does not exist", TclGetString(fileName), string)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SETGRP", "NO_GROUP", NULL); } return TCL_ERROR; } gid = groupPtr->gr_gid; } native = Tcl_FSGetNativePath(fileName); result = chown(native, (uid_t) -1, (gid_t) gid); /* INTL: Native. */ if (result != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not set group for file \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; } /* |
︙ | ︙ | |||
1540 1541 1542 1543 1544 1545 1546 | native = Tcl_UtfToExternalDString(NULL, string, length, &ds); pwPtr = TclpGetPwNam(native); /* INTL: Native. */ Tcl_DStringFree(&ds); if (pwPtr == NULL) { if (interp != NULL) { | > | > | < > | | < | 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 | native = Tcl_UtfToExternalDString(NULL, string, length, &ds); pwPtr = TclpGetPwNam(native); /* INTL: Native. */ Tcl_DStringFree(&ds); if (pwPtr == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not set owner for file \"%s\":" " user \"%s\" does not exist", TclGetString(fileName), string)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SETOWN", "NO_USER", NULL); } return TCL_ERROR; } uid = pwPtr->pw_uid; } native = Tcl_FSGetNativePath(fileName); result = chown(native, (uid_t) uid, (gid_t) -1); /* INTL: Native. */ if (result != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not set owner for file \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; } /* |
︙ | ︙ | |||
1626 1627 1628 1629 1630 1631 1632 | * We get the current mode of the file, in order to allow for ug+-=rwx * style chmod strings. */ result = TclpObjStat(fileName, &buf); if (result != 0) { if (interp != NULL) { | > | | < > | | > | | < | 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 | * We get the current mode of the file, in order to allow for ug+-=rwx * style chmod strings. */ result = TclpObjStat(fileName, &buf); if (result != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } return TCL_ERROR; } newMode = (mode_t) (buf.st_mode & 0x00007FFF); if (GetModeFromPermString(NULL, modeStringPtr, &newMode) != TCL_OK) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown permission string format \"%s\"", modeStringPtr)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "PERMISSION", NULL); } return TCL_ERROR; } } native = Tcl_FSGetNativePath(fileName); result = chmod(native, newMode); /* INTL: Native. */ if (result != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not set permissions for file \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; } #ifndef DJGPP |
︙ | ︙ | |||
2235 2236 2237 2238 2239 2240 2241 | Tcl_StatBuf statBuf; int result; result = TclpObjStat(fileName, &statBuf); if (result != 0) { if (interp != NULL) { | > | | < | | 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 | Tcl_StatBuf statBuf; int result; result = TclpObjStat(fileName, &statBuf); if (result != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } return TCL_ERROR; } *attributePtrPtr = Tcl_NewBooleanObj(statBuf.st_flags&UF_IMMUTABLE); return TCL_OK; } /* *--------------------------------------------------------------------------- * |
︙ | ︙ | |||
2282 2283 2284 2285 2286 2287 2288 | return TCL_ERROR; } result = TclpObjStat(fileName, &statBuf); if (result != 0) { if (interp != NULL) { | > | | < > | | < | 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 | return TCL_ERROR; } result = TclpObjStat(fileName, &statBuf); if (result != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } return TCL_ERROR; } if (readonly) { statBuf.st_flags |= UF_IMMUTABLE; } else { statBuf.st_flags &= ~UF_IMMUTABLE; } native = Tcl_FSGetNativePath(fileName); result = chflags(native, statBuf.st_flags); /* INTL: Native. */ if (result != 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not set flags for file \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; } #endif /* defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) */ |
︙ | ︙ |
Changes to unix/tclUnixFile.c.
︙ | ︙ | |||
306 307 308 309 310 311 312 | return TCL_OK; } d = opendir(native); /* INTL: Native. */ if (d == NULL) { Tcl_DStringFree(&ds); if (interp != NULL) { | | | | < | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | return TCL_OK; } d = opendir(native); /* INTL: Native. */ if (d == NULL) { Tcl_DStringFree(&ds); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read directory \"%s\": %s", Tcl_DStringValue(&dsOrig), Tcl_PosixError(interp))); } Tcl_DStringFree(&dsOrig); Tcl_DecrRefCount(fileNamePtr); return TCL_ERROR; } nativeDirLen = Tcl_DStringLength(&ds); |
︙ | ︙ | |||
467 468 469 470 471 472 473 | ((types->perm & TCL_GLOB_PERM_W) && (access(nativeEntry, W_OK) != 0)) || ((types->perm & TCL_GLOB_PERM_X) && (access(nativeEntry, X_OK) != 0)) #ifndef MAC_OSX_TCL || ((types->perm & TCL_GLOB_PERM_HIDDEN) && (*nativeName != '.')) | | | | | | < < | 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 | ((types->perm & TCL_GLOB_PERM_W) && (access(nativeEntry, W_OK) != 0)) || ((types->perm & TCL_GLOB_PERM_X) && (access(nativeEntry, X_OK) != 0)) #ifndef MAC_OSX_TCL || ((types->perm & TCL_GLOB_PERM_HIDDEN) && (*nativeName != '.')) #endif /* MAC_OSX_TCL */ ) { return 0; } } if (types->type != 0) { if (types->perm == 0) { /* * We haven't yet done a stat on the file. */ if (TclOSstat(nativeEntry, &buf) != 0) { /* * Posix error occurred. The only ok case is if this is a link * to a nonexistent file, and the user did 'glob -l'. So we * check that here: */ if ((types->type & TCL_GLOB_TYPE_LINK) && (TclOSlstat(nativeEntry, &buf) == 0) && S_ISLNK(buf.st_mode)) { return 1; } return 0; } } /* * In order bcdpsfl as in 'find -t' |
︙ | ︙ | |||
513 514 515 516 517 518 519 | #endif /* S_ISSOCK */ ((types->type & TCL_GLOB_TYPE_FILE) && S_ISREG(buf.st_mode))) { /* * Do nothing - this file is ok. */ } else { #ifdef S_ISLNK | | | | | < < | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | #endif /* S_ISSOCK */ ((types->type & TCL_GLOB_TYPE_FILE) && S_ISREG(buf.st_mode))) { /* * Do nothing - this file is ok. */ } else { #ifdef S_ISLNK if ((types->type & TCL_GLOB_TYPE_LINK) && (TclOSlstat(nativeEntry, &buf) == 0) && S_ISLNK(buf.st_mode)) { goto filetypeOK; } #endif /* S_ISLNK */ return 0; } } filetypeOK: |
︙ | ︙ | |||
714 715 716 717 718 719 720 | if (getwd(buffer) == NULL) { /* INTL: Native. */ return NULL; } #else if (getcwd(buffer, MAXPATHLEN+1) == NULL) { /* INTL: Native. */ return NULL; } | | | | 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 | if (getwd(buffer) == NULL) { /* INTL: Native. */ return NULL; } #else if (getcwd(buffer, MAXPATHLEN+1) == NULL) { /* INTL: Native. */ return NULL; } #endif /* USEGETWD */ if ((clientData == NULL) || strcmp(buffer, (const char *) clientData)) { char *newCd = ckalloc(strlen(buffer) + 1); strcpy(newCd, buffer); return newCd; } /* |
︙ | ︙ | |||
764 765 766 767 768 769 770 | { char buffer[MAXPATHLEN+1]; #ifdef USEGETWD if (getwd(buffer) == NULL) /* INTL: Native. */ #else if (getcwd(buffer, MAXPATHLEN+1) == NULL) /* INTL: Native. */ | | | | | | 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 | { char buffer[MAXPATHLEN+1]; #ifdef USEGETWD if (getwd(buffer) == NULL) /* INTL: Native. */ #else if (getcwd(buffer, MAXPATHLEN+1) == NULL) /* INTL: Native. */ #endif /* USEGETWD */ { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error getting working directory name: %s", Tcl_PosixError(interp))); } return NULL; } return Tcl_ExternalToUtfDString(NULL, buffer, -1, bufferPtr); } /* |
︙ | ︙ | |||
820 821 822 823 824 825 826 | return NULL; } Tcl_ExternalToUtfDString(NULL, link, length, linkPtr); return Tcl_DStringValue(linkPtr); #else return NULL; | | | 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 | return NULL; } Tcl_ExternalToUtfDString(NULL, link, length, linkPtr); return Tcl_DStringValue(linkPtr); #else return NULL; #endif /* !DJGPP */ } /* *---------------------------------------------------------------------- * * TclpObjStat -- * |
︙ | ︙ | |||
854 855 856 857 858 859 860 | return -1; } return TclOSstat(path, bufPtr); } #ifdef S_IFLNK | | | 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 | return -1; } return TclOSstat(path, bufPtr); } #ifdef S_IFLNK Tcl_Obj * TclpObjLink( Tcl_Obj *pathPtr, Tcl_Obj *toPtr, int linkAction) { if (toPtr != NULL) { const char *src = Tcl_FSGetNativePath(pathPtr); |
︙ | ︙ | |||
1176 1177 1178 1179 1180 1181 1182 1183 | int TclpUtime( Tcl_Obj *pathPtr, /* File to modify */ struct utimbuf *tval) /* New modification date structure */ { return utime(Tcl_FSGetNativePath(pathPtr), tval); } #ifdef __CYGWIN__ | > > > > > | > > > > > > | > > | | 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 | int TclpUtime( Tcl_Obj *pathPtr, /* File to modify */ struct utimbuf *tval) /* New modification date structure */ { return utime(Tcl_FSGetNativePath(pathPtr), tval); } #ifdef __CYGWIN__ int TclOSstat( const char *name, Tcl_StatBuf *statBuf) { struct stat buf; int result = stat(name, &buf); statBuf->st_mode = buf.st_mode; statBuf->st_ino = buf.st_ino; statBuf->st_dev = buf.st_dev; statBuf->st_rdev = buf.st_rdev; statBuf->st_nlink = buf.st_nlink; statBuf->st_uid = buf.st_uid; statBuf->st_gid = buf.st_gid; statBuf->st_size = buf.st_size; statBuf->st_atime = buf.st_atime; statBuf->st_mtime = buf.st_mtime; statBuf->st_ctime = buf.st_ctime; return result; } int TclOSlstat( const char *name, Tcl_StatBuf *statBuf) { struct stat buf; int result = lstat(name, &buf); statBuf->st_mode = buf.st_mode; statBuf->st_ino = buf.st_ino; statBuf->st_dev = buf.st_dev; statBuf->st_rdev = buf.st_rdev; statBuf->st_nlink = buf.st_nlink; statBuf->st_uid = buf.st_uid; statBuf->st_gid = buf.st_gid; statBuf->st_size = buf.st_size; statBuf->st_atime = buf.st_atime; statBuf->st_mtime = buf.st_mtime; statBuf->st_ctime = buf.st_ctime; return result; } #endif /* CYGWIN */ /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to unix/tclUnixNotfy.c.
︙ | ︙ | |||
92 93 94 95 96 97 98 | * notifierMutex lock before accessing these * fields. */ #ifdef __CYGWIN__ void *event; /* Any other thread alerts a notifier * that an event is ready to be processed * by sending this event. */ void *hwnd; /* Messaging window. */ | | | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | * notifierMutex lock before accessing these * fields. */ #ifdef __CYGWIN__ void *event; /* Any other thread alerts a notifier * that an event is ready to be processed * by sending this event. */ void *hwnd; /* Messaging window. */ #else Tcl_Condition waitCV; /* Any other thread alerts a notifier that an * event is ready to be processed by signaling * this condition variable. */ #endif /* __CYGWIN__ */ int eventReady; /* True if an event is ready to be processed. * Used as condition flag together with waitCV * above. */ #endif /* TCL_THREADS */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; #ifdef TCL_THREADS /* * The following static indicates the number of threads that have initialized |
︙ | ︙ | |||
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | * Static routines defined in this file. */ #ifdef TCL_THREADS static void NotifierThreadProc(ClientData clientData); #endif static int FileHandlerEventProc(Tcl_Event *evPtr, int flags); /* *---------------------------------------------------------------------- * * Tcl_InitNotifier -- * * Initializes the platform specific notifier state. * * Results: * Returns a handle to the notifier state for this thread. * * Side effects: * None. * *---------------------------------------------------------------------- */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 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 | * Static routines defined in this file. */ #ifdef TCL_THREADS static void NotifierThreadProc(ClientData clientData); #endif static int FileHandlerEventProc(Tcl_Event *evPtr, int flags); /* * Import of Windows API when building threaded with Cygwin. */ #if defined(TCL_THREADS) && defined(__CYGWIN__) typedef struct { void *hwnd; unsigned int *message; int wParam; int lParam; int time; int x; int y; } MSG; typedef struct { unsigned int style; void *lpfnWndProc; int cbClsExtra; int cbWndExtra; void *hInstance; void *hIcon; void *hCursor; void *hbrBackground; void *lpszMenuName; void *lpszClassName; } WNDCLASS; extern void __stdcall CloseHandle(void *); extern void *__stdcall CreateEventW(void *, unsigned char, unsigned char, void *); extern void * __stdcall CreateWindowExW(void *, void *, void *, DWORD, int, int, int, int, void *, void *, void *, void *); extern DWORD __stdcall DefWindowProcW(void *, int, void *, void *); extern unsigned char __stdcall DestroyWindow(void *); extern int __stdcall DispatchMessageW(const MSG *); extern unsigned char __stdcall GetMessageW(MSG *, void *, int, int); extern void __stdcall MsgWaitForMultipleObjects(DWORD, void *, unsigned char, DWORD, DWORD); extern unsigned char __stdcall PeekMessageW(MSG *, void *, int, int, int); extern unsigned char __stdcall PostMessageW(void *, unsigned int, void *, void *); extern void __stdcall PostQuitMessage(int); extern void *__stdcall RegisterClassW(const WNDCLASS *); extern unsigned char __stdcall ResetEvent(void *); extern unsigned char __stdcall TranslateMessage(const MSG *); /* * Threaded-cygwin specific functions in this file: */ static DWORD __stdcall NotifierProc(void *hwnd, unsigned int message, void *wParam, void *lParam); #endif /* TCL_THREADS && __CYGWIN__ */ /* *---------------------------------------------------------------------- * * Tcl_InitNotifier -- * * Initializes the platform specific notifier state. * * Results: * Returns a handle to the notifier state for this thread. * * Side effects: * None. * *---------------------------------------------------------------------- */ ClientData Tcl_InitNotifier(void) { if (tclNotifierHooks.initNotifierProc) { return tclNotifierHooks.initNotifierProc(); } else { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); |
︙ | ︙ | |||
399 400 401 402 403 404 405 | return; } else { #ifdef TCL_THREADS ThreadSpecificData *tsdPtr = clientData; Tcl_MutexLock(¬ifierMutex); tsdPtr->eventReady = 1; | | | | | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 | return; } else { #ifdef TCL_THREADS ThreadSpecificData *tsdPtr = clientData; Tcl_MutexLock(¬ifierMutex); tsdPtr->eventReady = 1; # ifdef __CYGWIN__ PostMessageW(tsdPtr->hwnd, 1024, 0, 0); # else Tcl_ConditionNotify(&tsdPtr->waitCV); # endif /* __CYGWIN__ */ Tcl_MutexUnlock(¬ifierMutex); #endif /* TCL_THREADS */ } } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
728 729 730 731 732 733 734 | return DefWindowProcW(hwnd, message, wParam, lParam); } /* * Process all of the runnable events. */ | | | | | 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 | return DefWindowProcW(hwnd, message, wParam, lParam); } /* * Process all of the runnable events. */ tsdPtr->eventReady = 1; Tcl_ServiceAll(); return 0; } #endif /* TCL_THREADS && __CYGWIN__ */ /* *---------------------------------------------------------------------- * * Tcl_WaitForEvent -- * * This function is called by Tcl_DoOneEvent to wait for new events on * the message queue. If the block time is 0, then Tcl_WaitForEvent just |
︙ | ︙ | |||
764 765 766 767 768 769 770 | return tclNotifierHooks.waitForEventProc(timePtr); } else { FileHandler *filePtr; int mask; Tcl_Time vTime; #ifdef TCL_THREADS int waitForFiles; | | | | | 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 | return tclNotifierHooks.waitForEventProc(timePtr); } else { FileHandler *filePtr; int mask; Tcl_Time vTime; #ifdef TCL_THREADS int waitForFiles; # ifdef __CYGWIN__ MSG msg; # endif /* __CYGWIN__ */ #else /* * Impl. notes: timeout & timeoutPtr are used if, and only if threads * are not enabled. They are the arguments for the regular select() * used when the core is not thread-enabled. */ |
︙ | ︙ | |||
788 789 790 791 792 793 794 | * check for, we return with a negative result rather than blocking * forever. */ if (timePtr != NULL) { /* * TIP #233 (Virtualized Time). Is virtual time in effect? And do | | | | | | | | | | | > | | < | | | | | | | 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 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 | * check for, we return with a negative result rather than blocking * forever. */ if (timePtr != NULL) { /* * TIP #233 (Virtualized Time). Is virtual time in effect? And do * we actually have something to scale? If yes to both then we * call the handler to do this scaling. */ if (timePtr->sec != 0 || timePtr->usec != 0) { vTime = *timePtr; tclScaleTimeProcPtr(&vTime, tclTimeClientData); timePtr = &vTime; } #ifndef TCL_THREADS timeout.tv_sec = timePtr->sec; timeout.tv_usec = timePtr->usec; timeoutPtr = &timeout; } else if (tsdPtr->numFdBits == 0) { /* * If there are no threads, no timeout, and no fds registered, * then there are no events possible and we must avoid deadlock. * Note that this is not entirely correct because there might be a * signal that could interrupt the select call, but we don't * handle that case if we aren't using threads. */ return -1; } else { timeoutPtr = NULL; #endif /* !TCL_THREADS */ } #ifdef TCL_THREADS /* * Place this thread on the list of interested threads, signal the * notifier thread, and wait for a response or a timeout. */ #ifdef __CYGWIN__ if (!tsdPtr->hwnd) { WNDCLASS class; class.style = 0; class.cbClsExtra = 0; class.cbWndExtra = 0; class.hInstance = TclWinGetTclInstance(); class.hbrBackground = NULL; class.lpszMenuName = NULL; class.lpszClassName = L"TclNotifier"; class.lpfnWndProc = NotifierProc; class.hIcon = NULL; class.hCursor = NULL; RegisterClassW(&class); tsdPtr->hwnd = CreateWindowExW(NULL, class.lpszClassName, class.lpszClassName, 0, 0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL); tsdPtr->event = CreateEventW(NULL, 1 /* manual */, 0 /* !signaled */, NULL); } #endif /* __CYGWIN */ Tcl_MutexLock(¬ifierMutex); if (timePtr != NULL && timePtr->sec == 0 && (timePtr->usec == 0 #if defined(__APPLE__) && defined(__LP64__) /* * On 64-bit Darwin, pthread_cond_timedwait() appears to have * a bug that causes it to wait forever when passed an * absolute time which has already been exceeded by the system * time; as a workaround, when given a very brief timeout, * just do a poll. [Bug 1457797] */ || timePtr->usec < 10 #endif /* __APPLE__ && __LP64__ */ )) { /* * Cannot emulate a polling select with a polling condition * variable. Instead, pretend to wait for files and tell the |
︙ | ︙ | |||
879 880 881 882 883 884 885 | waitForFiles = (tsdPtr->numFdBits > 0); tsdPtr->pollState = 0; } if (waitForFiles) { /* * Add the ThreadSpecificData structure of this thread to the list | | | | 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 | waitForFiles = (tsdPtr->numFdBits > 0); tsdPtr->pollState = 0; } if (waitForFiles) { /* * Add the ThreadSpecificData structure of this thread to the list * of ThreadSpecificData structures of all threads that are * waiting on file events. */ tsdPtr->nextPtr = waitingListPtr; if (waitingListPtr) { waitingListPtr->prevPtr = tsdPtr; } tsdPtr->prevPtr = 0; |
︙ | ︙ | |||
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 | FD_ZERO(&tsdPtr->readyMasks.writable); FD_ZERO(&tsdPtr->readyMasks.exception); if (!tsdPtr->eventReady) { #ifdef __CYGWIN__ if (!PeekMessageW(&msg, NULL, 0, 0, 0)) { DWORD timeout; if (timePtr) { timeout = timePtr->sec * 1000 + timePtr->usec / 1000; } else { timeout = 0xFFFFFFFF; } Tcl_MutexUnlock(¬ifierMutex); MsgWaitForMultipleObjects(1, &tsdPtr->event, 0, timeout, 1279); Tcl_MutexLock(¬ifierMutex); } #else Tcl_ConditionWait(&tsdPtr->waitCV, ¬ifierMutex, timePtr); | > | > > | | > | 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 | FD_ZERO(&tsdPtr->readyMasks.writable); FD_ZERO(&tsdPtr->readyMasks.exception); if (!tsdPtr->eventReady) { #ifdef __CYGWIN__ if (!PeekMessageW(&msg, NULL, 0, 0, 0)) { DWORD timeout; if (timePtr) { timeout = timePtr->sec * 1000 + timePtr->usec / 1000; } else { timeout = 0xFFFFFFFF; } Tcl_MutexUnlock(¬ifierMutex); MsgWaitForMultipleObjects(1, &tsdPtr->event, 0, timeout, 1279); Tcl_MutexLock(¬ifierMutex); } #else Tcl_ConditionWait(&tsdPtr->waitCV, ¬ifierMutex, timePtr); #endif /* __CYGWIN__ */ } tsdPtr->eventReady = 0; #ifdef __CYGWIN__ while (PeekMessageW(&msg, NULL, 0, 0, 0)) { /* * Retrieve and dispatch the message. */ DWORD result = GetMessageW(&msg, NULL, 0, 0); if (result == 0) { PostQuitMessage(msg.wParam); /* What to do here? */ } else if (result != (DWORD) -1) { TranslateMessage(&msg); DispatchMessageW(&msg); } } ResetEvent(tsdPtr->event); #endif /* __CYGWIN__ */ if (waitForFiles && tsdPtr->onList) { /* * Remove the ThreadSpecificData structure of this thread from the * waiting list. Alert the notifier thread to recompute its select * masks - skipping this caused a hang when trying to close a pipe * which the notifier thread was still doing a select on. */ |
︙ | ︙ | |||
1207 1208 1209 1210 1211 1212 1213 | tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; } tsdPtr->nextPtr = tsdPtr->prevPtr = NULL; tsdPtr->onList = 0; tsdPtr->pollState = 0; } #ifdef __CYGWIN__ | | | | | 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 | tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; } tsdPtr->nextPtr = tsdPtr->prevPtr = NULL; tsdPtr->onList = 0; tsdPtr->pollState = 0; } #ifdef __CYGWIN__ PostMessageW(tsdPtr->hwnd, 1024, 0, 0); #else Tcl_ConditionNotify(&tsdPtr->waitCV); #endif /* __CYGWIN__ */ } } Tcl_MutexUnlock(¬ifierMutex); /* * Consume the next byte from the notifier pipe if the pipe was |
︙ | ︙ | |||
1251 1252 1253 1254 1255 1256 1257 | Tcl_ConditionNotify(¬ifierCV); Tcl_MutexUnlock(¬ifierMutex); TclpThreadExit(0); } #endif /* TCL_THREADS */ | | | 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 | Tcl_ConditionNotify(¬ifierCV); Tcl_MutexUnlock(¬ifierMutex); TclpThreadExit(0); } #endif /* TCL_THREADS */ #endif /* !HAVE_COREFOUNDATION */ /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to unix/tclUnixPipe.c.
︙ | ︙ | |||
263 264 265 266 267 268 269 | result = TclpNativeToNormalized(fileName); close(fd); return result; } /* | | | | | | < | | < | | | > | < < | > > | | | 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 | result = TclpNativeToNormalized(fileName); close(fd); return result; } /* *---------------------------------------------------------------------------- * * TclpTempFileNameForLibrary -- * * Constructs a file name in the native file system where a dynamically * loaded library may be placed. * * Results: * Returns the constructed file name. If an error occurs, returns NULL * and leaves an error message in the interpreter result. * * On Unix, it works to load a shared object from a file of any name, so this * function is merely a thin wrapper around TclpTempFileName(). * *---------------------------------------------------------------------------- */ Tcl_Obj * TclpTempFileNameForLibrary( Tcl_Interp *interp, /* Tcl interpreter. */ Tcl_Obj *path) /* Path name of the library in the VFS. */ { Tcl_Obj *retval = TclpTempFileName(); if (retval == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't create temporary file: %s", Tcl_PosixError(interp))); } return retval; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
438 439 440 441 442 443 444 | /* * Create a pipe that the child can use to return error information if * anything goes wrong. */ if (TclpCreatePipe(&errPipeIn, &errPipeOut) == 0) { | | | | | > | 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 | /* * Create a pipe that the child can use to return error information if * anything goes wrong. */ if (TclpCreatePipe(&errPipeIn, &errPipeOut) == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't create pipe: %s", Tcl_PosixError(interp))); goto error; } /* * We need to allocate and convert this before the fork so it is properly * deallocated later */ dsArray = TclStackAlloc(interp, argc * sizeof(Tcl_DString)); newArgv = TclStackAlloc(interp, (argc+1) * sizeof(char *)); newArgv[argc] = NULL; for (i = 0; i < argc; i++) { newArgv[i] = Tcl_UtfToExternalDString(NULL, argv[i], -1, &dsArray[i]); } #ifdef USE_VFORK /* * After vfork(), do not call code in the child that changes global state, * because it is using the parent's memory space at that point and writes * might corrupt the parent: so ensure standard channels are initialized * in the parent, otherwise SetupStdFile() might initialize them in the * child. */ if (!inputFile) { Tcl_GetStdChannel(TCL_STDIN); } if (!outputFile) { Tcl_GetStdChannel(TCL_STDOUT); |
︙ | ︙ | |||
491 492 493 494 495 496 497 | if (!SetupStdFile(inputFile, TCL_STDIN) || !SetupStdFile(outputFile, TCL_STDOUT) || (!joinThisError && !SetupStdFile(errorFile, TCL_STDERR)) || (joinThisError && ((dup2(1,2) == -1) || (fcntl(2, F_SETFD, 0) != 0)))) { sprintf(errSpace, | | | | | | | > > | | 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 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | if (!SetupStdFile(inputFile, TCL_STDIN) || !SetupStdFile(outputFile, TCL_STDOUT) || (!joinThisError && !SetupStdFile(errorFile, TCL_STDERR)) || (joinThisError && ((dup2(1,2) == -1) || (fcntl(2, F_SETFD, 0) != 0)))) { sprintf(errSpace, "%dforked process couldn't set up input/output", errno); len = strlen(errSpace); if (len != (size_t) write(fd, errSpace, len)) { Tcl_Panic("TclpCreateProcess: unable to write to errPipeOut"); } _exit(1); } /* * Close the input side of the error pipe. */ RestoreSignals(); execvp(newArgv[0], newArgv); /* INTL: Native. */ sprintf(errSpace, "%dcouldn't execute \"%.150s\"", errno, argv[0]); len = strlen(errSpace); if (len != (size_t) write(fd, errSpace, len)) { Tcl_Panic("TclpCreateProcess: unable to write to errPipeOut"); } _exit(1); } /* * Free the mem we used for the fork */ for (i = 0; i < argc; i++) { Tcl_DStringFree(&dsArray[i]); } TclStackFree(interp, newArgv); TclStackFree(interp, dsArray); if (pid == -1) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't fork child process: %s", Tcl_PosixError(interp))); goto error; } /* * Read back from the error pipe to see if the child started up OK. The * info in the pipe (if any) consists of a decimal errno value followed by * an error message. */ TclpCloseFile(errPipeOut); errPipeOut = NULL; fd = GetFd(errPipeIn); count = read(fd, errSpace, (size_t) (sizeof(errSpace) - 1)); if (count > 0) { char *end; errSpace[count] = 0; errno = strtol(errSpace, &end, 10); Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s: %s", end, Tcl_PosixError(interp))); goto error; } TclpCloseFile(errPipeIn); *pidPtr = (Tcl_Pid) INT2PTR(pid); return TCL_OK; |
︙ | ︙ | |||
828 829 830 831 832 833 834 | Tcl_Channel *rchan, /* Returned read side. */ Tcl_Channel *wchan, /* Returned write side. */ int flags) /* Reserved for future use. */ { int fileNums[2]; if (pipe(fileNums) < 0) { | | | | 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 | Tcl_Channel *rchan, /* Returned read side. */ Tcl_Channel *wchan, /* Returned write side. */ int flags) /* Reserved for future use. */ { int fileNums[2]; if (pipe(fileNums) < 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("pipe creation failed: %s", Tcl_PosixError(interp))); return TCL_ERROR; } fcntl(fileNums[0], F_SETFD, FD_CLOEXEC); fcntl(fileNums[1], F_SETFD, FD_CLOEXEC); *rchan = Tcl_MakeFileChannel(INT2PTR(fileNums[0]), TCL_READABLE); |
︙ | ︙ | |||
870 871 872 873 874 875 876 877 | void TclGetAndDetachPids( Tcl_Interp *interp, /* Interpreter to append the PIDs to. */ Tcl_Channel chan) /* Handle for the pipeline. */ { PipeState *pipePtr; const Tcl_ChannelType *chanTypePtr; int i; | > < | > > | < | > | 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 | void TclGetAndDetachPids( Tcl_Interp *interp, /* Interpreter to append the PIDs to. */ Tcl_Channel chan) /* Handle for the pipeline. */ { PipeState *pipePtr; const Tcl_ChannelType *chanTypePtr; Tcl_Obj *pidsObj; int i; /* * Punt if the channel is not a command channel. */ chanTypePtr = Tcl_GetChannelType(chan); if (chanTypePtr != &pipeChannelType) { return; } pipePtr = Tcl_GetChannelInstanceData(chan); TclNewObj(pidsObj); for (i = 0; i < pipePtr->numPids; i++) { Tcl_ListObjAppendElement(NULL, pidsObj, Tcl_NewIntObj( PTR2INT(pipePtr->pidPtr[i]))); Tcl_DetachPids(1, &pipePtr->pidPtr[i]); } Tcl_SetObjResult(interp, pidsObj); if (pipePtr->numPids > 0) { ckfree(pipePtr->pidPtr); pipePtr->numPids = 0; } } /* |
︙ | ︙ | |||
1271 1272 1273 1274 1275 1276 1277 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Tcl_Channel chan; PipeState *pipePtr; int i; | | | 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* Argument strings. */ { Tcl_Channel chan; PipeState *pipePtr; int i; Tcl_Obj *resultPtr; if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?channelId?"); return TCL_ERROR; } if (objc == 1) { |
︙ | ︙ | |||
1297 1298 1299 1300 1301 1302 1303 | return TCL_OK; } /* * Extract the process IDs from the pipe structure. */ | | < | > | 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 | return TCL_OK; } /* * Extract the process IDs from the pipe structure. */ pipePtr = Tcl_GetChannelInstanceData(chan); resultPtr = Tcl_NewObj(); for (i = 0; i < pipePtr->numPids; i++) { Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewIntObj(PTR2INT(TclpGetPid(pipePtr->pidPtr[i])))); } Tcl_SetObjResult(interp, resultPtr); } return TCL_OK; } /* |
︙ | ︙ |
Changes to unix/tclUnixSock.c.
︙ | ︙ | |||
17 18 19 20 21 22 23 | * once, and so can be used without regard to side effects. */ #define SET_BITS(var, bits) ((var) |= (bits)) #define CLEAR_BITS(var, bits) ((var) &= ~(bits)) /* "sock" + a pointer in hex + \0 */ | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | * once, and so can be used without regard to side effects. */ #define SET_BITS(var, bits) ((var) |= (bits)) #define CLEAR_BITS(var, bits) ((var) &= ~(bits)) /* "sock" + a pointer in hex + \0 */ #define SOCK_CHAN_LENGTH (4 + sizeof(void *) * 2 + 1) #define SOCK_TEMPLATE "sock%lx" #undef SOCKET /* Possible conflict with win32 SOCKET */ /* * This is needed to comply with the strict aliasing rules of GCC, but it also * simplifies casting between the different sockaddr types. */ typedef union { |
︙ | ︙ | |||
54 55 56 57 58 59 60 | Tcl_Channel channel; /* Channel associated with this file. */ TcpFdList fds; /* The file descriptors of the sockets. */ int flags; /* ORed combination of the bitfields defined * below. */ /* * Only needed for server sockets */ | > | > | > > | | | | | | | | < < | | 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 104 | Tcl_Channel channel; /* Channel associated with this file. */ TcpFdList fds; /* The file descriptors of the sockets. */ int flags; /* ORed combination of the bitfields defined * below. */ /* * Only needed for server sockets */ Tcl_TcpAcceptProc *acceptProc; /* Proc to call on accept. */ ClientData acceptProcData; /* The data for the accept proc. */ /* * Only needed for client sockets */ struct addrinfo *addrlist; /* Addresses to connect to. */ struct addrinfo *addr; /* Iterator over addrlist. */ struct addrinfo *myaddrlist;/* Local address. */ struct addrinfo *myaddr; /* Iterator over myaddrlist. */ int filehandlers; /* Caches FileHandlers that get set up while * an async socket is not yet connected. */ int status; /* Cache status of async socket. */ int cachedBlocking; /* Cache blocking mode of async socket. */ }; /* * These bits may be ORed together into the "flags" field of a TcpState * structure. */ #define TCP_ASYNC_SOCKET (1<<0) /* Asynchronous socket. */ #define TCP_ASYNC_CONNECT (1<<1) /* Async connect in progress. */ /* * The following defines the maximum length of the listen queue. This is the * number of outstanding yet-to-be-serviced requests for a connection on a * server socket, more than this number of outstanding requests and the * connection request will fail. */ #ifndef SOMAXCONN # define SOMAXCONN 100 #elif (SOMAXCONN < 100) # undef SOMAXCONN # define SOMAXCONN 100 #endif /* SOMAXCONN < 100 */ /* * The following defines how much buffer space the kernel should maintain for * a socket. |
︙ | ︙ | |||
213 214 215 216 217 218 219 | } else { native = u.nodename; } } if (native == NULL) { native = tclEmptyStringRep; } | | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | } else { native = u.nodename; } } if (native == NULL) { native = tclEmptyStringRep; } #else /* !NO_UNAME */ /* * Uname doesn't exist; try gethostname instead. * * There is no portable macro for the maximum length of host names * returned by gethostbyname(). We should only trust SYS_NMLN if it is at * least 255 + 1 bytes to comply with DNS host name limits. * |
︙ | ︙ | |||
238 239 240 241 242 243 244 | # else char buffer[256]; # endif if (gethostname(buffer, sizeof(buffer)) > -1) { /* INTL: Native. */ native = buffer; } | | | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | # else char buffer[256]; # endif if (gethostname(buffer, sizeof(buffer)) > -1) { /* INTL: Native. */ native = buffer; } #endif /* NO_UNAME */ *encodingPtr = Tcl_GetEncoding(NULL, NULL); *lengthPtr = strlen(native); *valuePtr = ckalloc((*lengthPtr) + 1); memcpy(*valuePtr, native, (size_t)(*lengthPtr)+1); } |
︙ | ︙ | |||
340 341 342 343 344 345 346 | static int TcpBlockModeProc( ClientData instanceData, /* Socket state. */ int mode) /* The mode to set. Can be one of * TCL_MODE_BLOCKING or * TCL_MODE_NONBLOCKING. */ { | | | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | static int TcpBlockModeProc( ClientData instanceData, /* Socket state. */ int mode) /* The mode to set. Can be one of * TCL_MODE_BLOCKING or * TCL_MODE_NONBLOCKING. */ { TcpState *statePtr = instanceData; if (mode == TCL_MODE_BLOCKING) { CLEAR_BITS(statePtr->flags, TCP_ASYNC_SOCKET); } else { SET_BITS(statePtr->flags, TCP_ASYNC_SOCKET); } if (statePtr->flags & TCP_ASYNC_CONNECT) { |
︙ | ︙ | |||
439 440 441 442 443 444 445 | TcpInputProc( ClientData instanceData, /* Socket state. */ char *buf, /* Where to store data read. */ int bufSize, /* How much space is available in the * buffer? */ int *errorCodePtr) /* Where to store error code. */ { | | | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 | TcpInputProc( ClientData instanceData, /* Socket state. */ char *buf, /* Where to store data read. */ int bufSize, /* How much space is available in the * buffer? */ int *errorCodePtr) /* Where to store error code. */ { TcpState *statePtr = instanceData; int bytesRead; *errorCodePtr = 0; if (WaitForConnect(statePtr, errorCodePtr) != 0) { return -1; } bytesRead = recv(statePtr->fds.fd, buf, (size_t) bufSize, 0); |
︙ | ︙ | |||
489 490 491 492 493 494 495 | static int TcpOutputProc( ClientData instanceData, /* Socket state. */ const char *buf, /* The data buffer. */ int toWrite, /* How many bytes to write? */ int *errorCodePtr) /* Where to store error code. */ { | | | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | static int TcpOutputProc( ClientData instanceData, /* Socket state. */ const char *buf, /* The data buffer. */ int toWrite, /* How many bytes to write? */ int *errorCodePtr) /* Where to store error code. */ { TcpState *statePtr = instanceData; int written; *errorCodePtr = 0; if (WaitForConnect(statePtr, errorCodePtr) != 0) { return -1; } written = send(statePtr->fds.fd, buf, (size_t) toWrite, 0); |
︙ | ︙ | |||
528 529 530 531 532 533 534 | /* ARGSUSED */ static int TcpCloseProc( ClientData instanceData, /* The socket to close. */ Tcl_Interp *interp) /* For error reporting - unused. */ { | | | 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | /* ARGSUSED */ static int TcpCloseProc( ClientData instanceData, /* The socket to close. */ Tcl_Interp *interp) /* For error reporting - unused. */ { TcpState *statePtr = instanceData; int errorCode = 0; TcpFdList *fds; /* * Delete a file handler that may be active for this socket if this is a * server socket - the file handler was created automatically by Tcl as * part of the mechanism to accept new client connections. Channel |
︙ | ︙ | |||
589 590 591 592 593 594 595 | static int TcpClose2Proc( ClientData instanceData, /* The socket to close. */ Tcl_Interp *interp, /* For error reporting. */ int flags) /* Flags that indicate which side to close. */ { | | | | | 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 | static int TcpClose2Proc( ClientData instanceData, /* The socket to close. */ Tcl_Interp *interp, /* For error reporting. */ int flags) /* Flags that indicate which side to close. */ { TcpState *statePtr = instanceData; int errorCode = 0; int sd; /* * Shutdown the OS socket handle. */ switch(flags) { case TCL_CLOSE_READ: sd = SHUT_RD; break; case TCL_CLOSE_WRITE: sd = SHUT_WR; break; default: if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "socket close2proc called bidirectionally", -1)); } return TCL_ERROR; } if (shutdown(statePtr->fds.fd,sd) < 0) { errorCode = errno; } |
︙ | ︙ | |||
649 650 651 652 653 654 655 | Tcl_Interp *interp, /* For error reporting - can be NULL. */ const char *optionName, /* Name of the option to retrieve the value * for, or NULL to get all options and their * values. */ Tcl_DString *dsPtr) /* Where to store the computed value; * initialized by caller. */ { | | | < | | | 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 693 694 695 696 697 698 699 700 701 | Tcl_Interp *interp, /* For error reporting - can be NULL. */ const char *optionName, /* Name of the option to retrieve the value * for, or NULL to get all options and their * values. */ Tcl_DString *dsPtr) /* Where to store the computed value; * initialized by caller. */ { TcpState *statePtr = instanceData; char host[NI_MAXHOST], port[NI_MAXSERV]; size_t len = 0; int reverseDNS = 0; #define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS" if (optionName != NULL) { len = strlen(optionName); } if ((len > 1) && (optionName[1] == 'e') && (strncmp(optionName, "-error", len) == 0)) { socklen_t optlen = sizeof(int); int err, ret; if (statePtr->status == 0) { ret = getsockopt(statePtr->fds.fd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen); if (ret < 0) { err = errno; } } else { err = statePtr->status; statePtr->status = 0; } if (err != 0) { Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(err), -1); } return TCL_OK; } if (interp != NULL && Tcl_GetVar(interp, SUPPRESS_RDNS_VAR, 0) != NULL) { reverseDNS = NI_NUMERICHOST; } if ((len == 0) || ((len > 1) && (optionName[1] == 'p') && (strncmp(optionName, "-peername", len) == 0))) { address peername; socklen_t size = sizeof(peername); if (getpeername(statePtr->fds.fd, &peername.sa, &size) >= 0) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringStartSublist(dsPtr); |
︙ | ︙ | |||
717 718 719 720 721 722 723 | * (len==0), don't flag an error at that point because it could be * an fconfigure request on a server socket (which have no peer). * Same must be done on win&mac. */ if (len) { if (interp) { | > | | < | | 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 | * (len==0), don't flag an error at that point because it could be * an fconfigure request on a server socket (which have no peer). * Same must be done on win&mac. */ if (len) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get peername: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } } } if ((len == 0) || ((len > 1) && (optionName[1] == 's') && (strncmp(optionName, "-sockname", len) == 0))) { TcpFdList *fds; address sockname; socklen_t size; int found = 0; if (len == 0) { |
︙ | ︙ | |||
768 769 770 771 772 773 774 | || (IN6_IS_ADDR_V4MAPPED(&sockname.sa6.sin6_addr) && sockname.sa6.sin6_addr.s6_addr[12] == 0 && sockname.sa6.sin6_addr.s6_addr[13] == 0 && sockname.sa6.sin6_addr.s6_addr[14] == 0 && sockname.sa6.sin6_addr.s6_addr[15] == 0)) { flags |= NI_NUMERICHOST; } | | | | | 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 | || (IN6_IS_ADDR_V4MAPPED(&sockname.sa6.sin6_addr) && sockname.sa6.sin6_addr.s6_addr[12] == 0 && sockname.sa6.sin6_addr.s6_addr[13] == 0 && sockname.sa6.sin6_addr.s6_addr[14] == 0 && sockname.sa6.sin6_addr.s6_addr[15] == 0)) { flags |= NI_NUMERICHOST; } #endif /* NEED_FAKE_RFC2553 */ } getnameinfo(&sockname.sa, size, host, sizeof(host), port, sizeof(port), flags); Tcl_DStringAppendElement(dsPtr, host); Tcl_DStringAppendElement(dsPtr, port); } } if (found) { if (len) { return TCL_OK; } Tcl_DStringEndSublist(dsPtr); } else { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get sockname: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } } if (len > 0) { return Tcl_BadChannelOption(interp, optionName, "peername sockname"); |
︙ | ︙ | |||
821 822 823 824 825 826 827 | static void TcpWatchProc( ClientData instanceData, /* The socket state. */ int mask) /* Events of interest; an OR-ed combination of * TCL_READABLE, TCL_WRITABLE and * TCL_EXCEPTION. */ { | | | < | 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 851 852 853 | static void TcpWatchProc( ClientData instanceData, /* The socket state. */ int mask) /* Events of interest; an OR-ed combination of * TCL_READABLE, TCL_WRITABLE and * TCL_EXCEPTION. */ { TcpState *statePtr = instanceData; if (statePtr->acceptProc != NULL) { /* * Make sure we don't mess with server sockets since they will never * be readable or writable at the Tcl level. This keeps Tcl scripts * from interfering with the -accept behavior (bug #3394732). */ return; } if (statePtr->flags & TCP_ASYNC_CONNECT) { /* Async sockets use a FileHandler internally while connecting, so we * need to cache this request until the connection has succeeded. */ statePtr->filehandlers = mask; } else if (mask) { Tcl_CreateFileHandler(statePtr->fds.fd, mask, (Tcl_FileProc *) Tcl_NotifyChannel, statePtr->channel); } else { Tcl_DeleteFileHandler(statePtr->fds.fd); } } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
870 871 872 873 874 875 876 | /* ARGSUSED */ static int TcpGetHandleProc( ClientData instanceData, /* The socket state. */ int direction, /* Not used. */ ClientData *handlePtr) /* Where to store the handle. */ { | | | 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 | /* ARGSUSED */ static int TcpGetHandleProc( ClientData instanceData, /* The socket state. */ int direction, /* Not used. */ ClientData *handlePtr) /* Where to store the handle. */ { TcpState *statePtr = instanceData; *handlePtr = INT2PTR(statePtr->fds.fd); return TCL_OK; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
942 943 944 945 946 947 948 | int async = state->flags & TCP_ASYNC_CONNECT; if (async_callback) { goto reenter; } for (state->addr = state->addrlist; state->addr != NULL; | | < | > | 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 | int async = state->flags & TCP_ASYNC_CONNECT; if (async_callback) { goto reenter; } for (state->addr = state->addrlist; state->addr != NULL; state->addr = state->addr->ai_next) { status = -1; for (state->myaddr = state->myaddrlist; state->myaddr != NULL; state->myaddr = state->myaddr->ai_next) { int reuseaddr; /* * No need to try combinations of local and remote addresses of * different families. */ if (state->myaddr->ai_family != state->addr->ai_family) { continue; } /* * Close the socket if it is still open from the last unsuccessful * iteration. */ if (state->fds.fd >= 0) { close(state->fds.fd); state->fds.fd = -1; } state->fds.fd = socket(state->addr->ai_family, SOCK_STREAM, 0); if (state->fds.fd < 0) { |
︙ | ︙ | |||
987 988 989 990 991 992 993 | /* * Set kernel space buffering */ TclSockMinimumBuffers(INT2PTR(state->fds.fd), SOCKET_BUFSIZE); if (async) { | | > | | < | > > | > < > > | | | 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 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 | /* * Set kernel space buffering */ TclSockMinimumBuffers(INT2PTR(state->fds.fd), SOCKET_BUFSIZE); if (async) { status = TclUnixSetBlockingMode(state->fds.fd, TCL_MODE_NONBLOCKING); if (status < 0) { continue; } } reuseaddr = 1; (void) setsockopt(state->fds.fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuseaddr, sizeof(reuseaddr)); status = bind(state->fds.fd, state->myaddr->ai_addr, state->myaddr->ai_addrlen); if (status < 0) { continue; } /* * Attempt to connect. The connect may fail at present with an * EINPROGRESS but at a later time it will complete. The caller * will set up a file handler on the socket if she is interested * in being informed when the connect completes. */ status = connect(state->fds.fd, state->addr->ai_addr, state->addr->ai_addrlen); if (status < 0 && errno == EINPROGRESS) { Tcl_CreateFileHandler(state->fds.fd, TCL_WRITABLE|TCL_EXCEPTION, TcpAsyncCallback, state); return TCL_OK; reenter: Tcl_DeleteFileHandler(state->fds.fd); /* * Read the error state from the socket to see if the async * connection has succeeded or failed. As this clears the * error condition, we cache the status in the socket state * struct for later retrieval by [fconfigure -error]. */ optlen = sizeof(int); getsockopt(state->fds.fd, SOL_SOCKET, SO_ERROR, (char *) &status, &optlen); state->status = status; } if (status == 0) { CLEAR_BITS(state->flags, TCP_ASYNC_CONNECT); goto out; } } } out: if (async_callback) { /* * An asynchonous connection has finally succeeded or failed. */ TcpWatchProc(state, state->filehandlers); TclUnixSetBlockingMode(state->fds.fd, state->cachedBlocking); /* * We need to forward the writable event that brought us here, bcasue * upon reading of getsockopt(SO_ERROR), at least some OSes clear the * writable state from the socket, and so a subsequent select() on * behalf of a script level [fileevent] would not fire. It doesn't * hurt that this is also called in the successful case and will save * the event mechanism one roundtrip through select(). */ Tcl_NotifyChannel(state->channel, TCL_WRITABLE); } else if (status != 0) { /* * Failure for either a synchronous connection, or an async one that * failed before it could enter background mode, e.g. because an * invalid -myaddr was given. */ if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open socket: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; } /* |
︙ | ︙ | |||
1107 1108 1109 1110 1111 1112 1113 | const char *errorMsg = NULL; struct addrinfo *addrlist = NULL, *myaddrlist = NULL; char channelName[SOCK_CHAN_LENGTH]; /* * Do the name lookups for the local and remote addresses. */ | > | | > > | | 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 | const char *errorMsg = NULL; struct addrinfo *addrlist = NULL, *myaddrlist = NULL; char channelName[SOCK_CHAN_LENGTH]; /* * Do the name lookups for the local and remote addresses. */ if (!TclCreateSocketAddress(interp, &addrlist, host, port, 0, &errorMsg) || !TclCreateSocketAddress(interp, &myaddrlist, myaddr, myport, 1, &errorMsg)) { if (addrlist != NULL) { freeaddrinfo(addrlist); } if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open socket: %s", errorMsg)); } return NULL; } /* * Allocate a new TcpState for this socket. */ |
︙ | ︙ | |||
1137 1138 1139 1140 1141 1142 1143 | * Create a new client socket and wrap it in a channel. */ if (CreateClientSocket(interp, state) != TCL_OK) { TcpCloseProc(state, NULL); return NULL; } | | | | | 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 | * Create a new client socket and wrap it in a channel. */ if (CreateClientSocket(interp, state) != TCL_OK) { TcpCloseProc(state, NULL); return NULL; } sprintf(channelName, SOCK_TEMPLATE, (long) state); state->channel = Tcl_CreateChannel(&tcpChannelType, channelName, state, (TCL_READABLE | TCL_WRITABLE)); if (Tcl_SetChannelOption(interp, state->channel, "-translation", "auto crlf") == TCL_ERROR) { Tcl_Close(NULL, state->channel); return NULL; } return state->channel; } |
︙ | ︙ | |||
1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 | const char *errorMsg = NULL; TcpFdList *fds = NULL, *newfds; /* * Try to record and return the most meaningful error message, i.e. the * one from the first socket that went the farthest before it failed. */ enum { LOOKUP, SOCKET, BIND, LISTEN } howfar = LOOKUP; int my_errno = 0; if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1, &errorMsg)) { my_errno = errno; goto error; } for (addrPtr = addrlist; addrPtr != NULL; addrPtr = addrPtr->ai_next) { sock = socket(addrPtr->ai_family, addrPtr->ai_socktype, | > | | 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 | const char *errorMsg = NULL; TcpFdList *fds = NULL, *newfds; /* * Try to record and return the most meaningful error message, i.e. the * one from the first socket that went the farthest before it failed. */ enum { LOOKUP, SOCKET, BIND, LISTEN } howfar = LOOKUP; int my_errno = 0; if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1, &errorMsg)) { my_errno = errno; goto error; } for (addrPtr = addrlist; addrPtr != NULL; addrPtr = addrPtr->ai_next) { sock = socket(addrPtr->ai_family, addrPtr->ai_socktype, addrPtr->ai_protocol); if (sock == -1) { if (howfar < SOCKET) { howfar = SOCKET; my_errno = errno; } continue; } |
︙ | ︙ | |||
1314 1315 1316 1317 1318 1319 1320 | /* Missing on: Solaris 2.8 */ if (addrPtr->ai_family == AF_INET6) { int v6only = 1; (void) setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)); } | | | 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 | /* Missing on: Solaris 2.8 */ if (addrPtr->ai_family == AF_INET6) { int v6only = 1; (void) setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)); } #endif /* IPV6_V6ONLY */ status = bind(sock, addrPtr->ai_addr, addrPtr->ai_addrlen); if (status == -1) { if (howfar < BIND) { howfar = BIND; my_errno = errno; } |
︙ | ︙ | |||
1356 1357 1358 1359 1360 1361 1362 | * Allocate a new TcpState for this socket. */ statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); statePtr->acceptProc = acceptProc; statePtr->acceptProcData = acceptProcData; | | | 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 | * Allocate a new TcpState for this socket. */ statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); statePtr->acceptProc = acceptProc; statePtr->acceptProcData = acceptProcData; sprintf(channelName, SOCK_TEMPLATE, (long) statePtr); newfds = &statePtr->fds; } else { newfds = ckalloc(sizeof(TcpFdList)); memset(newfds, (int) 0, sizeof(TcpFdList)); fds->next = newfds; } newfds->fd = sock; |
︙ | ︙ | |||
1385 1386 1387 1388 1389 1390 1391 | } if (statePtr != NULL) { statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, statePtr, 0); return statePtr->channel; } if (interp != NULL) { | | > | | > | 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 | } if (statePtr != NULL) { statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, statePtr, 0); return statePtr->channel; } if (interp != NULL) { Tcl_Obj *errorObj = Tcl_NewStringObj("couldn't open socket: ", -1); if (errorMsg == NULL) { errno = my_errno; Tcl_AppendToObj(errorObj, Tcl_PosixError(interp), -1); } else { Tcl_AppendToObj(errorObj, errorMsg, -1); } Tcl_SetObjResult(interp, errorObj); } if (sock != -1) { close(sock); } return NULL; } |
︙ | ︙ | |||
1430 1431 1432 1433 1434 1435 1436 | TcpState *newSockState; /* State for new socket. */ address addr; /* The remote address */ socklen_t len; /* For accept interface */ char channelName[SOCK_CHAN_LENGTH]; char host[NI_MAXHOST], port[NI_MAXSERV]; len = sizeof(addr); | | | | | 1440 1441 1442 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 1478 1479 | TcpState *newSockState; /* State for new socket. */ address addr; /* The remote address */ socklen_t len; /* For accept interface */ char channelName[SOCK_CHAN_LENGTH]; char host[NI_MAXHOST], port[NI_MAXSERV]; len = sizeof(addr); newsock = accept(fds->fd, &addr.sa, &len); if (newsock < 0) { return; } /* * Set close-on-exec flag to prevent the newly accepted socket from being * inherited by child processes. */ (void) fcntl(newsock, F_SETFD, FD_CLOEXEC); newSockState = ckalloc(sizeof(TcpState)); memset(newSockState, 0, sizeof(TcpState)); newSockState->flags = 0; newSockState->fds.fd = newsock; sprintf(channelName, SOCK_TEMPLATE, (long) newSockState); newSockState->channel = Tcl_CreateChannel(&tcpChannelType, channelName, newSockState, (TCL_READABLE | TCL_WRITABLE)); Tcl_SetChannelOption(NULL, newSockState->channel, "-translation", "auto crlf"); if (fds->statePtr->acceptProc != NULL) { getnameinfo(&addr.sa, len, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV); fds->statePtr->acceptProc(fds->statePtr->acceptProcData, newSockState->channel, host, atoi(port)); } } /* |
︙ | ︙ |
Changes to win/Makefile.in.
︙ | ︙ | |||
133 134 135 136 137 138 139 | REG_DLL_FILE = tclreg$(REGVER)${DLLSUFFIX} REG_LIB_FILE = @LIBPREFIX@tclreg$(REGVER)${LIBSUFFIX} TEST_DLL_FILE = tcltest$(VER)${DLLSUFFIX} TEST_LIB_FILE = @LIBPREFIX@tcltest$(VER)${LIBSUFFIX} ZLIB_DLL_FILE = zlib1.dll SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@ | | < | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | REG_DLL_FILE = tclreg$(REGVER)${DLLSUFFIX} REG_LIB_FILE = @LIBPREFIX@tclreg$(REGVER)${LIBSUFFIX} TEST_DLL_FILE = tcltest$(VER)${DLLSUFFIX} TEST_LIB_FILE = @LIBPREFIX@tcltest$(VER)${LIBSUFFIX} ZLIB_DLL_FILE = zlib1.dll SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@ STATIC_LIBRARIES = $(TCL_LIB_FILE) TCLSH = tclsh$(VER)${EXESUFFIX} CAT32 = cat32$(EXEEXT) MAN2TCL = man2tcl$(EXEEXT) # For cross-compiled builds, TCL_EXE is the name of a tclsh executable that is # available *BEFORE* running make for the first time. Certain build targets # (make genstubs, make install) need it to be available on the PATH. This # executable should *NOT* be required just to do a normal build although |
︙ | ︙ | |||
399 400 401 402 403 404 405 | TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} @ZLIB_OBJS@ TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n] all: binaries libraries doc packages | | < < < < < | | | < < < < < < < < < < | < < < < < < < < < < | 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 450 451 452 453 454 455 456 457 458 459 | TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} @ZLIB_OBJS@ TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n] all: binaries libraries doc packages tcltest: $(TCLSH) $(TEST_DLL_FILE) binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ $(DDE_DLL_FILE) $(REG_DLL_FILE) $(TCLSH) libraries: doc: $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) $(CC) $(CFLAGS) $(TCLSH_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) $(CAT32): cat32.$(OBJEXT) $(CC) $(CFLAGS) cat32.$(OBJEXT) $(CC_EXENAME) $(LIBS) $(LDFLAGS_CONSOLE) # The following targets are configured by autoconf to generate either a shared # library or static library ${TCL_STUB_LIB_FILE}: ${STUB_OBJS} @$(RM) ${TCL_STUB_LIB_FILE} @MAKE_LIB@ ${STUB_OBJS} @POST_MAKE_LIB@ ${TCL_DLL_FILE}: ${TCL_OBJS} tcl.$(RES) @ZLIB_DLL_FILE@ @$(RM) ${TCL_DLL_FILE} $(TCL_LIB_FILE) @MAKE_DLL@ ${TCL_OBJS} tcl.$(RES) $(SHLIB_LD_LIBS) @VC_MANIFEST_EMBED_DLL@ ${TCL_LIB_FILE}: ${TCL_OBJS} ${DDE_OBJS} ${REG_OBJS} @$(RM) ${TCL_LIB_FILE} @MAKE_LIB@ ${TCL_OBJS} ${DDE_OBJS} ${REG_OBJS} @POST_MAKE_LIB@ # assume GNU make # To enable concurrent parallel make of tcl<x>.dll and tcl<x>.lib, the tcl<x>.dll # targets have to depend on tcl<x>.lib, this ensures that linking of tcl<x>.dll # does not execute concurrently with the renaming and recompiling of tcl<x>.lib ${DDE_DLL_FILE}: ${DDE_OBJS} ${TCL_STUB_LIB_FILE} @MAKE_DLL@ ${DDE_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS) ${REG_DLL_FILE}: ${REG_OBJS} ${TCL_STUB_LIB_FILE} @MAKE_DLL@ ${REG_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS) ${TEST_DLL_FILE}: ${TCLTEST_OBJS} ${TCL_STUB_LIB_FILE} @$(RM) ${TEST_DLL_FILE} ${TEST_LIB_FILE} @MAKE_DLL@ ${TCLTEST_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS) # use pre-built zlib1.dll ${ZLIB_DLL_FILE}: $(ZLIB_DIR)/win32/${ZLIB_DLL_FILE} |
︙ | ︙ | |||
715 716 717 718 719 720 721 | # Specifying TESTFLAGS on the command line is the standard way to pass args to # tcltest, i.e.: # % make test TESTFLAGS="-verbose bps -file fileName.test" test: test-tcl test-packages | | | > | | | | > | | | 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 | # Specifying TESTFLAGS on the command line is the standard way to pass args to # tcltest, i.e.: # % make test TESTFLAGS="-verbose bps -file fileName.test" test: test-tcl test-packages test-tcl: binaries $(TCLSH) $(CAT32) $(TEST_DLL_FILE) TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ ./$(TCLSH) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \ -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \ package ifneeded dde 1.4.0b1 [list load [file normalize ${DDE_DLL_FILE}] dde]; \ package ifneeded registry 1.3.0 [list load [file normalize ${REG_DLL_FILE}] registry]" | ./$(CAT32) # Useful target to launch a built tclsh with the proper path,... runtest: binaries $(TCLSH) $(TEST_DLL_FILE) @TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ ./$(TCLSH) $(TESTFLAGS) -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \ package ifneeded dde 1.4.0b1 [list load [file normalize ${DDE_DLL_FILE}] dde]; \ package ifneeded registry 1.3.0 [list load [file normalize ${REG_DLL_FILE}] registry]" $(SCRIPT) # This target can be used to run tclsh from the build directory via # `make shell SCRIPT=foo.tcl` shell: binaries @TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ ./$(TCLSH) $(SCRIPT) |
︙ | ︙ | |||
749 750 751 752 753 754 755 | ./config.status cleanhelp: $(RM) *.hlp *.cnt *.GID *.rtf man2tcl.exe clean: cleanhelp clean-packages $(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out | | | 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 | ./config.status cleanhelp: $(RM) *.hlp *.cnt *.GID *.rtf man2tcl.exe clean: cleanhelp clean-packages $(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out $(RM) $(TCLSH) $(CAT32) $(RM) *.pch *.ilk *.pdb distclean: distclean-packages clean $(RM) Makefile config.status config.cache config.log tclConfig.sh \ tcl.hpj config.status.lineno # |
︙ | ︙ |
Changes to win/README.
︙ | ︙ | |||
20 21 22 23 24 25 26 | and Visual C++ 6 or newer or | | | | | | | | | 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 | and Visual C++ 6 or newer or Linux + MinGW-w64 [http://mingw-w64.sourceforge.net/] (win32 or win64) or Cygwin + MinGW-w64 [http://cygwin.com/install.html] (win32 or win64) or Darwin + MinGW-w64 [http://mingw-w64.sourceforge.net/] (win32 or win64) or Msys + MinGW-w64 [http://mingw-w64.sourceforge.net/] (win32 or win64) or Msys + MinGW [http://www.mingw.org/download.shtml] (win32 only) In practice, this release is built with Visual C++ 6.0 and the TEA Makefile. If you are building with Visual C++, in the "win" subdirectory of the source release, you will find "makefile.vc". This is the makefile for the |
︙ | ︙ | |||
63 64 65 66 67 68 69 | If you are building with Linux, Cygwin or Msys, you can use the configure script that lives in the win subdirectory. The Linux/Cygwin/Msys based configure/build process works just like the UNIX one, so you will want to refer to ../unix/README for available configure options. If you want 64-bit executables (x86_64), you need to configure using | | | | | | | | 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 | If you are building with Linux, Cygwin or Msys, you can use the configure script that lives in the win subdirectory. The Linux/Cygwin/Msys based configure/build process works just like the UNIX one, so you will want to refer to ../unix/README for available configure options. If you want 64-bit executables (x86_64), you need to configure using the --enable-64bit option. Make sure that the x86_64-w64-mingw32 compiler is present. For Cygwin this compiler can be found in the "mingw64-x86_64-gcc-core" package, which can be installed through the normal Cygwin install process. If you only want 32-bit executables, the "mingw64-i686-gcc-core" package is what you need. For Linux, Darwin and Msys, you can download a suitable win32 or win64 compiler from [https://sourceforge.net/projects/mingw-w64/files/] Use the Makefile "install" target to install Tcl. It will install it according to the prefix options you provided in the correct directory structure. Note that in order to run tclsh85.exe, you must ensure that tcl85.dll is on your path, in the system directory, or in the directory containing tclsh86.exe. Note: Tcl no longer provides support for Win32s. 3. Test suite ------------- |
︙ | ︙ |
Changes to win/coffbase.txt.
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | itcl 0x10500000 0x00080000 itk 0x10580000 0x00080000 bltlite 0x10600000 0x00080000 blt 0x10680000 0x00080000 iocpsock 0x10700000 0x00080000 tls 0x10780000 0x00100000 winico 0x10880000 0x00010000 tile 0x10900000 0x00080000 memchan 0x109D0000 0x00010000 tdom 0x109E0000 0x00080000 tclvfs 0x10A70000 0x00010000 tkvideo 0x10B00000 0x00010000 tclsdl 0x10B20000 0x00080000 vqtcl 0x10C00000 0x00010000 tdbc 0x10C40000 0x00010000 ; ; insert new packages here ; snack 0x1E000000 0x00400000 sound 0x1E400000 0x00400000 snackogg 0x1E800000 0x00200000 | > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | itcl 0x10500000 0x00080000 itk 0x10580000 0x00080000 bltlite 0x10600000 0x00080000 blt 0x10680000 0x00080000 iocpsock 0x10700000 0x00080000 tls 0x10780000 0x00100000 winico 0x10880000 0x00010000 sample 0x108B0000 0x00010000 tile 0x10900000 0x00080000 memchan 0x109D0000 0x00010000 tdom 0x109E0000 0x00080000 tclvfs 0x10A70000 0x00010000 tkvideo 0x10B00000 0x00010000 tclsdl 0x10B20000 0x00080000 vqtcl 0x10C00000 0x00010000 tdbc 0x10C40000 0x00010000 thread 0x10C80000 0x00020000 ; ; insert new packages here ; snack 0x1E000000 0x00400000 sound 0x1E400000 0x00400000 snackogg 0x1E800000 0x00200000 |
Changes to win/configure.
︙ | ︙ | |||
836 837 838 839 840 841 842 | if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] | | | | | | 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 | if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-threads build with threads (default: on) --enable-shared build and link with shared libraries (default: on) --enable-64bit enable 64bit support (where applicable) --enable-wince enable Win/CE support (where applicable) --enable-symbols build with debugging symbols (default: off) --enable-embedded-manifest embed manifest if possible (default: yes) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-encoding encoding for configuration values --with-celib=DIR use Windows/CE support library from DIR Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> |
︙ | ︙ | |||
3064 3065 3066 3067 3068 3069 3070 | enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi; if test "$tcl_ok" = "yes"; then | | | | 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 | enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi; if test "$tcl_ok" = "yes"; then echo "$as_me:$LINENO: result: yes (default)" >&5 echo "${ECHO_T}yes (default)" >&6 TCL_THREADS=1 cat >>confdefs.h <<\_ACEOF #define TCL_THREADS 1 _ACEOF # USE_THREAD_ALLOC tells us to try the special thread-based # allocator that significantly reduces lock contention |
︙ | ︙ | |||
3594 3595 3596 3597 3598 3599 3600 | RC_DEFINE=--define RES=res.o MAKE_LIB="\${STLIB_LD} \$@" POST_MAKE_LIB="\${RANLIB} \$@" MAKE_EXE="\${CC} -o \$@" LIBPREFIX="lib" | < > | 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 | RC_DEFINE=--define RES=res.o MAKE_LIB="\${STLIB_LD} \$@" POST_MAKE_LIB="\${RANLIB} \$@" MAKE_EXE="\${CC} -o \$@" LIBPREFIX="lib" extra_cflags="$extra_cflags -pipe" extra_ldflags="$extra_ldflags -pipe" if test "${SHARED_BUILD}" = "0" ; then # static echo "$as_me:$LINENO: result: using static flags" >&5 echo "${ECHO_T}using static flags" >&6 runtime= LIBRARIES="\${STATIC_LIBRARIES}" |
︙ | ︙ |
Changes to win/configure.in.
︙ | ︙ | |||
215 216 217 218 219 220 221 | tcl_cv_intrinsics=no) ) if test "$tcl_cv_intrinsics" = "yes"; then AC_DEFINE(HAVE_INTRIN_H, 1, [Defined when the compilers supports intrinsics]) fi | | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | tcl_cv_intrinsics=no) ) if test "$tcl_cv_intrinsics" = "yes"; then AC_DEFINE(HAVE_INTRIN_H, 1, [Defined when the compilers supports intrinsics]) fi # See if the <wspiapi.h> header file is present AC_CACHE_CHECK(for wspiapi.h, tcl_cv_wspiapi_h, AC_TRY_COMPILE([ #include <wspiapi.h> ], [], tcl_cv_wspiapi_h=yes, |
︙ | ︙ |
Changes to win/makefile.vc.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # Copyright (c) 1995-1996 Sun Microsystems, Inc. # Copyright (c) 1998-2000 Ajuba Solutions. # Copyright (c) 2001-2005 ActiveState Corporation. # Copyright (c) 2001-2004 David Gravereaux. # Copyright (c) 2003-2008 Pat Thoyts. #------------------------------------------------------------------------------ | | | < | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # Copyright (c) 1995-1996 Sun Microsystems, Inc. # Copyright (c) 1998-2000 Ajuba Solutions. # Copyright (c) 2001-2005 ActiveState Corporation. # Copyright (c) 2001-2004 David Gravereaux. # Copyright (c) 2003-2008 Pat Thoyts. #------------------------------------------------------------------------------ # Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or # VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir) !if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR) MSG = ^ You need to run vcvars32.bat from Developer Studio or setenv.bat from the^ Platform SDK first to setup the environment. Jump to this line to read^ the build instructions. !error $(MSG) !endif |
︙ | ︙ | |||
68 69 70 71 72 73 74 | # help files (.chm) # # 4) Macros usable on the commandline: # INSTALLDIR=<path> # Sets where to install Tcl from the built binaries. # C:\Progra~1\Tcl is assumed when not specified. # | | | | | > > > > > > > > > | > < < < < < < | | < > | | < | > | | > | 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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | # help files (.chm) # # 4) Macros usable on the commandline: # INSTALLDIR=<path> # Sets where to install Tcl from the built binaries. # C:\Progra~1\Tcl is assumed when not specified. # # OPTS=loimpact,msvcrt,nothreads,pdbs,profile,static,staticpkg,symbols,thrdalloc,tclalloc,unchecked,none # Sets special options for the core. The default is for none. # Any combination of the above may be used (comma separated). # 'none' will over-ride everything to nothing. # # loimpact = Adds a flag for how NT treats the heap to keep memory # in use, low. This is said to impact alloc performance. # msvcrt = Affects the static option only to switch it from # using libcmt(d) as the C runtime [by default] to # msvcrt(d). This is useful for static embedding # support. # nothreads= Turns off full multithreading support. # pdbs = Build detached symbols for release builds. # profile = Adds profiling hooks. Map file is assumed. # static = Builds a static library of the core instead of a # dll. The static library will contain the dde and reg # extensions. External applications who want to use # this, need to link with the stub library as well as # the static Tcl library.The shell will be static (and # large), as well. # staticpkg = Affects the static option only to switch # tclshXX.exe to have the dde and reg extension linked # inside it. # symbols = Debug build. Links to the debug C runtime, disables # optimizations and creates pdb symbols files. # thrdalloc = Use the thread allocator (shared global free pool) # This is the default on threaded builds. # tclalloc = Use the old non-thread allocator # unchecked= Allows a symbols build to not use the debug # enabled runtime (msvcrt.dll not msvcrtd.dll # or libcmt.lib not libcmtd.lib). # # STATS=compdbg,memdbg,none # Sets optional memory and bytecode compiler debugging code added # to the core. The default is for none. Any combination of the # above may be used (comma separated). 'none' will over-ride # everything to nothing. # # compdbg = Enables byte compilation logging. # memdbg = Enables the debugging memory allocator. # # CHECKS=64bit,fullwarn,nodep,none # Sets special macros for checking compatability. # # 64bit = Enable 64bit portability warnings (if available) # fullwarn = Builds with full compiler and link warnings enabled. # Very verbose. # nodep = Turns off compatability macros to ensure the core # isn't being built with deprecated functions. # # MACHINE=(ALPHA|AMD64|IA64|IX86) # Set the machine type used for the compiler, linker, and # resource compiler. This hook is needed to tell the tools # when alternate platforms are requested. IX86 is the default # when not specified. If the CPU environment variable has been # set (ie: recent Platform SDK) then MACHINE is set from CPU. # # TMP_DIR=<path> # OUT_DIR=<path> # Hooks to allow the intermediate and output directories to be # changed. $(OUT_DIR) is assumed to be # $(BINROOT)\(Release|Debug) based on if symbols are requested. # $(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default. |
︙ | ︙ | |||
175 176 177 178 179 180 181 | !if !exist("makefile.vc") MSG = ^ You must run this makefile only from the directory it is in.^ Please `cd` to its location first. !error $(MSG) !endif | | | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | !if !exist("makefile.vc") MSG = ^ You must run this makefile only from the directory it is in.^ Please `cd` to its location first. !error $(MSG) !endif PROJECT = tcl !include "rules.vc" STUBPREFIX = $(PROJECT)stub DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION) VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION) DDEDOTVERSION = 1.4 |
︙ | ︙ | |||
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 | BIN_INSTALL_DIR = $(_INSTALLDIR)\bin DOC_INSTALL_DIR = $(_INSTALLDIR)\doc SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\tcl$(DOTVERSION) INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include TCLSHOBJS = \ $(TMP_DIR)\tclAppInit.obj \ !if $(TCL_USE_STATIC_PACKAGES) $(TMP_DIR)\tclWinReg.obj \ $(TMP_DIR)\tclWinDde.obj \ !endif $(TMP_DIR)\tclsh.res TCLTESTOBJS = \ $(TMP_DIR)\tclTest.obj \ $(TMP_DIR)\tclTestObj.obj \ $(TMP_DIR)\tclTestProcBodyObj.obj \ $(TMP_DIR)\tclThreadTest.obj \ $(TMP_DIR)\tclWinTest.obj \ !if $(TCL_USE_STATIC_PACKAGES) $(TMP_DIR)\tclWinReg.obj \ $(TMP_DIR)\tclWinDde.obj \ !endif $(TMP_DIR)\testMain.obj COREOBJS = \ $(TMP_DIR)\regcomp.obj \ $(TMP_DIR)\regerror.obj \ $(TMP_DIR)\regexec.obj \ | > > > > | 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 | BIN_INSTALL_DIR = $(_INSTALLDIR)\bin DOC_INSTALL_DIR = $(_INSTALLDIR)\doc SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\tcl$(DOTVERSION) INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include TCLSHOBJS = \ $(TMP_DIR)\tclAppInit.obj \ !if !$(STATIC_BUILD) !if $(TCL_USE_STATIC_PACKAGES) $(TMP_DIR)\tclWinReg.obj \ $(TMP_DIR)\tclWinDde.obj \ !endif !endif $(TMP_DIR)\tclsh.res TCLTESTOBJS = \ $(TMP_DIR)\tclTest.obj \ $(TMP_DIR)\tclTestObj.obj \ $(TMP_DIR)\tclTestProcBodyObj.obj \ $(TMP_DIR)\tclThreadTest.obj \ $(TMP_DIR)\tclWinTest.obj \ !if !$(STATIC_BUILD) !if $(TCL_USE_STATIC_PACKAGES) $(TMP_DIR)\tclWinReg.obj \ $(TMP_DIR)\tclWinDde.obj \ !endif !endif $(TMP_DIR)\testMain.obj COREOBJS = \ $(TMP_DIR)\regcomp.obj \ $(TMP_DIR)\regerror.obj \ $(TMP_DIR)\regexec.obj \ |
︙ | ︙ | |||
425 426 427 428 429 430 431 | $(TMP_DIR)\tclWinLoad.obj \ $(TMP_DIR)\tclWinNotify.obj \ $(TMP_DIR)\tclWinPipe.obj \ $(TMP_DIR)\tclWinSerial.obj \ $(TMP_DIR)\tclWinSock.obj \ $(TMP_DIR)\tclWinThrd.obj \ $(TMP_DIR)\tclWinTime.obj \ | | > > > < | 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | $(TMP_DIR)\tclWinLoad.obj \ $(TMP_DIR)\tclWinNotify.obj \ $(TMP_DIR)\tclWinPipe.obj \ $(TMP_DIR)\tclWinSerial.obj \ $(TMP_DIR)\tclWinSock.obj \ $(TMP_DIR)\tclWinThrd.obj \ $(TMP_DIR)\tclWinTime.obj \ !if $(STATIC_BUILD) $(TMP_DIR)\tclWinReg.obj \ $(TMP_DIR)\tclWinDde.obj \ !else $(TMP_DIR)\tcl.res !endif TCLOBJS = $(COREOBJS) $(ZLIBOBJS) $(TOMMATHOBJS) $(PLATFORMOBJS) TCLSTUBOBJS = \ $(TMP_DIR)\tclStubLib.obj \ $(TMP_DIR)\tclTomMathStubLib.obj \ $(TMP_DIR)\tclOOStubLib.obj |
︙ | ︙ | |||
561 562 563 564 565 566 567 | dlls: setup $(TCLREGLIB) $(TCLDDELIB) all: setup $(TCLSH) $(TCLSTUBLIB) dlls $(CAT32) pkgs tcltest: setup $(TCLTEST) dlls $(CAT32) install: install-binaries install-libraries install-docs install-pkgs test: test-core test-pkgs test-core: setup $(TCLTEST) dlls $(CAT32) | | | | | | | | | | | 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 | dlls: setup $(TCLREGLIB) $(TCLDDELIB) all: setup $(TCLSH) $(TCLSTUBLIB) dlls $(CAT32) pkgs tcltest: setup $(TCLTEST) dlls $(CAT32) install: install-binaries install-libraries install-docs install-pkgs test: test-core test-pkgs test-core: setup $(TCLTEST) dlls $(CAT32) set TCL_LIBRARY=$(ROOT:\=/)/library !if "$(OS)" == "Windows_NT" || "$(MSVCDIR)" == "IDE" $(DEBUGGER) $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile << package ifneeded dde 1.4.0b1 [list load "$(TCLDDELIB:\=/)" dde] package ifneeded registry 1.3.0 [list load "$(TCLREGLIB:\=/)" registry] << !else @echo Please wait while the tests are collected... $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile << > tests.log package ifneeded dde 1.4.0b1 "$(TCLDDELIB:\=/)" dde] package ifneeded registry 1.3.0 "$(TCLREGLIB:\=/)" registry] << type tests.log | more !endif runtest: setup $(TCLTEST) dlls $(CAT32) set TCL_LIBRARY=$(ROOT:\=/)/library $(DEBUGGER) $(TCLTEST) $(SCRIPT) runshell: setup $(TCLSH) dlls set TCL_LIBRARY=$(ROOT:\=/)/library $(DEBUGGER) $(TCLSH) $(SCRIPT) setup: @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR) @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR) !if !$(STATIC_BUILD) |
︙ | ︙ | |||
816 817 818 819 820 821 822 | !endif !if exist("$(HELPFILE)") @echo Installing Windows help @$(CPY) "$(HELPFILE)" "$(DOC_INSTALL_DIR)\" @$(CPY) "$(HELPCNT)" "$(DOC_INSTALL_DIR)\" !endif | < | 826 827 828 829 830 831 832 833 834 835 836 837 838 839 | !endif !if exist("$(HELPFILE)") @echo Installing Windows help @$(CPY) "$(HELPFILE)" "$(DOC_INSTALL_DIR)\" @$(CPY) "$(HELPCNT)" "$(DOC_INSTALL_DIR)\" !endif #--------------------------------------------------------------------- # Build tclConfig.sh for the TEA build system. #--------------------------------------------------------------------- tclConfig: $(OUT_DIR)\tclConfig.sh $(OUT_DIR)\tclConfig.sh: $(WINDIR)\tclConfig.sh.in |
︙ | ︙ | |||
1155 1156 1157 1158 1159 1160 1161 | @$(CPY) "$(ROOT)\library\encoding\*.enc" \ "$(SCRIPT_INSTALL_DIR)\encoding\" #" emacs fix install-tzdata: @echo Installing time zone data | | | | | | | | 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 | @$(CPY) "$(ROOT)\library\encoding\*.enc" \ "$(SCRIPT_INSTALL_DIR)\encoding\" #" emacs fix install-tzdata: @echo Installing time zone data @set TCL_LIBRARY=$(ROOT:\=/)/library @$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \ "$(ROOT:\=/)/library/tzdata" "$(SCRIPT_INSTALL_DIR)/tzdata" install-msgs: @echo Installing message catalogs @set TCL_LIBRARY=$(ROOT:\=/)/library @$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \ "$(ROOT:\=/)/library/msgs" "$(SCRIPT_INSTALL_DIR)/msgs" #--------------------------------------------------------------------- # Clean up #--------------------------------------------------------------------- tidy: !if "$(TCLLIB)" != "$(TCLIMPLIB)" |
︙ | ︙ |
Changes to win/nmakehlp.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * ---------------------------------------------------------------------------- */ #define _CRT_SECURE_NO_DEPRECATE #include <windows.h> #pragma comment (lib, "user32.lib") #pragma comment (lib, "kernel32.lib") #include <stdio.h> #include <math.h> /* * This library is required for x64 builds with _some_ versions of MSVC */ #if defined(_M_IA64) || defined(_M_AMD64) | > > > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * ---------------------------------------------------------------------------- */ #define _CRT_SECURE_NO_DEPRECATE #include <windows.h> #define NO_SHLWAPI_GDI #define NO_SHLWAPI_STREAM #define NO_SHLWAPI_REG #include <shlwapi.h> #pragma comment (lib, "user32.lib") #pragma comment (lib, "kernel32.lib") #pragma comment (lib, "shlwapi.lib") #include <stdio.h> #include <math.h> /* * This library is required for x64 builds with _some_ versions of MSVC */ #if defined(_M_IA64) || defined(_M_AMD64) |
︙ | ︙ | |||
33 34 35 36 37 38 39 | #define snprintf _snprintf #endif /* protos */ | | | | | > | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #define snprintf _snprintf #endif /* protos */ static int CheckForCompilerFeature(const char *option); static int CheckForLinkerFeature(const char *option); static int IsIn(const char *string, const char *substring); static int SubstituteFile(const char *substs, const char *filename); static int QualifyPath(const char *path); static const char *GetVersionFromFile(const char *filename, const char *match); static DWORD WINAPI ReadFromPipe(LPVOID args); /* globals */ #define CHUNK 25 #define STATICBUFFERSIZE 1000 typedef struct { HANDLE pipe; |
︙ | ︙ | |||
145 146 147 148 149 150 151 152 153 154 | argv[0]); WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL); return 0; } printf("%s\n", GetVersionFromFile(argv[2], argv[3])); return 0; } } chars = snprintf(msg, sizeof(msg) - 1, | > > > > > > > > > > > | | | 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 | argv[0]); WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL); return 0; } printf("%s\n", GetVersionFromFile(argv[2], argv[3])); return 0; case 'Q': if (argc != 3) { chars = snprintf(msg, sizeof(msg) - 1, "usage: %s -Q path\n" "Emit the fully qualified path\n" "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL); return 2; } return QualifyPath(argv[2]); } } chars = snprintf(msg, sizeof(msg) - 1, "usage: %s -c|-f|-l|-Q|-s|-V ...\n" "This is a little helper app to equalize shell differences between WinNT and\n" "Win9x and get nmake.exe to accomplish its job.\n", argv[0]); WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL); return 2; } static int CheckForCompilerFeature( const char *option) { STARTUPINFO si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES sa; DWORD threadID; |
︙ | ︙ | |||
241 242 243 244 245 246 247 | DWORD err = GetLastError(); int chars = snprintf(msg, sizeof(msg) - 1, "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS| FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars], (300-chars), 0); | | | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | DWORD err = GetLastError(); int chars = snprintf(msg, sizeof(msg) - 1, "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS| FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars], (300-chars), 0); WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL); return 2; } /* * Close our references to the write handles that have now been inherited. */ |
︙ | ︙ | |||
290 291 292 293 294 295 296 | || strstr(Err.buffer, "D4002") != NULL || strstr(Out.buffer, "D9002") != NULL || strstr(Err.buffer, "D9002") != NULL || strstr(Out.buffer, "D2021") != NULL || strstr(Err.buffer, "D2021") != NULL); } | | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | || strstr(Err.buffer, "D4002") != NULL || strstr(Out.buffer, "D9002") != NULL || strstr(Err.buffer, "D9002") != NULL || strstr(Out.buffer, "D2021") != NULL || strstr(Err.buffer, "D2021") != NULL); } static int CheckForLinkerFeature( const char *option) { STARTUPINFO si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES sa; DWORD threadID; |
︙ | ︙ | |||
369 370 371 372 373 374 375 | DWORD err = GetLastError(); int chars = snprintf(msg, sizeof(msg) - 1, "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS| FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars], (300-chars), 0); | | | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | DWORD err = GetLastError(); int chars = snprintf(msg, sizeof(msg) - 1, "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS| FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars], (300-chars), 0); WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL); return 2; } /* * Close our references to the write handles that have now been inherited. */ |
︙ | ︙ | |||
415 416 417 418 419 420 421 | return !(strstr(Out.buffer, "LNK1117") != NULL || strstr(Err.buffer, "LNK1117") != NULL || strstr(Out.buffer, "LNK4044") != NULL || strstr(Err.buffer, "LNK4044") != NULL); } | | | 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | return !(strstr(Out.buffer, "LNK1117") != NULL || strstr(Err.buffer, "LNK1117") != NULL || strstr(Out.buffer, "LNK4044") != NULL || strstr(Err.buffer, "LNK4044") != NULL); } static DWORD WINAPI ReadFromPipe( LPVOID args) { pipeinfo *pi = (pipeinfo *) args; char *lastBuf = pi->buffer; DWORD dwRead; BOOL ok; |
︙ | ︙ | |||
440 441 442 443 444 445 446 | } lastBuf += dwRead; goto again; return 0; /* makes the compiler happy */ } | | | | 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 484 485 486 | } lastBuf += dwRead; goto again; return 0; /* makes the compiler happy */ } static int IsIn( const char *string, const char *substring) { return (strstr(string, substring) != NULL); } /* * GetVersionFromFile -- * Looks for a match string in a file and then returns the version * following the match where a version is anything acceptable to * package provide or package ifneeded. */ static const char * GetVersionFromFile( const char *filename, const char *match) { size_t cbBuffer = 100; static char szBuffer[100]; char *szResult = NULL; |
︙ | ︙ | |||
561 562 563 564 565 566 567 | * Usage is something like: * nmakehlp -S << $** > $@ * @PACKAGE_NAME@ $(PACKAGE_NAME) * @PACKAGE_VERSION@ $(PACKAGE_VERSION) * << */ | | | 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 | * Usage is something like: * nmakehlp -S << $** > $@ * @PACKAGE_NAME@ $(PACKAGE_NAME) * @PACKAGE_VERSION@ $(PACKAGE_VERSION) * << */ static int SubstituteFile( const char *substitutions, const char *filename) { size_t cbBuffer = 1024; static char szBuffer[1024], szCopy[1024]; char *szResult = NULL; |
︙ | ︙ | |||
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 | } list_free(&substPtr); } fclose(fp); return 0; } /* * Local variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * indent-tabs-mode: t * tab-width: 8 * End: */ | > > > > > > > > > > > > > > > > > > > > > > > > | 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 693 694 | } list_free(&substPtr); } fclose(fp); return 0; } /* * QualifyPath -- * * This composes the current working directory with a provided path * and returns the fully qualified and normalized path. * Mostly needed to setup paths for testing. */ static int QualifyPath( const char *szPath) { char szCwd[MAX_PATH + 1]; char szTmp[MAX_PATH + 1]; char *p; GetCurrentDirectory(MAX_PATH, szCwd); while ((p = strchr(szPath, '/')) && *p) *p = '\\'; PathCombine(szTmp, szCwd, szPath); PathCanonicalize(szCwd, szTmp); printf("%s\n", szCwd); return 0; } /* * Local variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * indent-tabs-mode: t * tab-width: 8 * End: */ |
Changes to win/rules.vc.
1 2 3 4 5 6 7 8 9 10 | #------------------------------------------------------------------------------ # rules.vc -- # # Microsoft Visual C++ makefile include for decoding the commandline # macros. This file does not need editing to build Tcl. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # Copyright (c) 2001-2003 David Gravereaux. | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #------------------------------------------------------------------------------ # rules.vc -- # # Microsoft Visual C++ makefile include for decoding the commandline # macros. This file does not need editing to build Tcl. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # Copyright (c) 2001-2003 David Gravereaux. # Copyright (c) 2003-2008 Patrick Thoyts #------------------------------------------------------------------------------ !ifndef _RULES_VC _RULES_VC = 1 cc32 = $(CC) # built-in default. link32 = link |
︙ | ︙ | |||
239 240 241 242 243 244 245 246 247 | !if [nmakehlp -f $(OPTS) "staticpkg"] !message *** Doing staticpkg TCL_USE_STATIC_PACKAGES = 1 !else TCL_USE_STATIC_PACKAGES = 0 !endif !if [nmakehlp -f $(OPTS) "nothreads"] TCL_THREADS = 0 !else | > < | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | !if [nmakehlp -f $(OPTS) "staticpkg"] !message *** Doing staticpkg TCL_USE_STATIC_PACKAGES = 1 !else TCL_USE_STATIC_PACKAGES = 0 !endif !if [nmakehlp -f $(OPTS) "nothreads"] !message *** Compile explicitly for non-threaded tcl TCL_THREADS = 0 !else TCL_THREADS = 1 USE_THREAD_ALLOC= 1 !endif !if [nmakehlp -f $(OPTS) "symbols"] !message *** Doing symbols DEBUG = 1 !else |
︙ | ︙ | |||
283 284 285 286 287 288 289 | LOIMPACT = 0 !endif !if [nmakehlp -f $(OPTS) "thrdalloc"] !message *** Doing thrdalloc USE_THREAD_ALLOC = 1 !endif !if [nmakehlp -f $(OPTS) "tclalloc"] | | | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | LOIMPACT = 0 !endif !if [nmakehlp -f $(OPTS) "thrdalloc"] !message *** Doing thrdalloc USE_THREAD_ALLOC = 1 !endif !if [nmakehlp -f $(OPTS) "tclalloc"] !message *** Doing tclalloc USE_THREAD_ALLOC = 0 !endif !if [nmakehlp -f $(OPTS) "unchecked"] !message *** Doing unchecked UNCHECKED = 1 !else UNCHECKED = 0 |
︙ | ︙ | |||
594 595 596 597 598 599 600 | !if !exist($(TCLSH)) && $(TCL_THREADS) TCLSH = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe" !endif TCLSTUBLIB = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib" TCLIMPLIB = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib" TCL_LIBRARY = $(_TCLDIR)\lib TCLREGLIB = "$(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib" | | | | 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 | !if !exist($(TCLSH)) && $(TCL_THREADS) TCLSH = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe" !endif TCLSTUBLIB = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib" TCLIMPLIB = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib" TCL_LIBRARY = $(_TCLDIR)\lib TCLREGLIB = "$(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib" TCLDDELIB = "$(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib" COFFBASE = \must\have\tcl\sources\to\build\this\target TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target TCL_INCLUDES = -I"$(_TCLDIR)\include" !else TCLSH = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe" !if !exist($(TCLSH)) && $(TCL_THREADS) TCLSH = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe" !endif TCLSTUBLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib" TCLIMPLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib" TCL_LIBRARY = $(_TCLDIR)\library TCLREGLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib" TCLDDELIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib" COFFBASE = "$(_TCLDIR)\win\coffbase.txt" TCLTOOLSDIR = $(_TCLDIR)\tools TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win" !endif !endif |
︙ | ︙ |
Changes to win/tcl.m4.
︙ | ︙ | |||
207 208 209 210 211 212 213 | # Sets the following vars: # SHARED_BUILD Value of 1 or 0 #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_SHARED], [ AC_MSG_CHECKING([how to build libraries]) AC_ARG_ENABLE(shared, | | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | # Sets the following vars: # SHARED_BUILD Value of 1 or 0 #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_SHARED], [ AC_MSG_CHECKING([how to build libraries]) AC_ARG_ENABLE(shared, [ --enable-shared build and link with shared libraries (default: on)], [tcl_ok=$enableval], [tcl_ok=yes]) if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes |
︙ | ︙ | |||
246 247 248 249 250 251 252 | # # Defines the following vars: # TCL_THREADS #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_THREADS], [ AC_MSG_CHECKING(for building with threads) | | | | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | # # Defines the following vars: # TCL_THREADS #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_THREADS], [ AC_MSG_CHECKING(for building with threads) AC_ARG_ENABLE(threads, [ --enable-threads build with threads (default: on)], [tcl_ok=$enableval], [tcl_ok=yes]) if test "$tcl_ok" = "yes"; then AC_MSG_RESULT([yes (default)]) TCL_THREADS=1 AC_DEFINE(TCL_THREADS) # USE_THREAD_ALLOC tells us to try the special thread-based # allocator that significantly reduces lock contention AC_DEFINE(USE_THREAD_ALLOC) else TCL_THREADS=0 |
︙ | ︙ | |||
293 294 295 296 297 298 299 | # Sets to $(LDFLAGS_OPTIMIZE) if false # DBGX Debug library extension # #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_SYMBOLS], [ AC_MSG_CHECKING([for build with symbols]) | | | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | # Sets to $(LDFLAGS_OPTIMIZE) if false # DBGX Debug library extension # #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_SYMBOLS], [ AC_MSG_CHECKING([for build with symbols]) AC_ARG_ENABLE(symbols, [ --enable-symbols build with debugging symbols (default: off)], [tcl_ok=$enableval], [tcl_ok=no]) # FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT. if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)' LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)' DBGX="" AC_DEFINE(NDEBUG, 1, [Is no debugging enabled?]) AC_MSG_RESULT([no]) |
︙ | ︙ | |||
529 530 531 532 533 534 535 | RC_DEFINE=--define RES=res.o MAKE_LIB="\${STLIB_LD} \[$]@" POST_MAKE_LIB="\${RANLIB} \[$]@" MAKE_EXE="\${CC} -o \[$]@" LIBPREFIX="lib" | < > | 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | RC_DEFINE=--define RES=res.o MAKE_LIB="\${STLIB_LD} \[$]@" POST_MAKE_LIB="\${RANLIB} \[$]@" MAKE_EXE="\${CC} -o \[$]@" LIBPREFIX="lib" extra_cflags="$extra_cflags -pipe" extra_ldflags="$extra_ldflags -pipe" if test "${SHARED_BUILD}" = "0" ; then # static AC_MSG_RESULT([using static flags]) runtime= LIBRARIES="\${STATIC_LIBRARIES}" EXESUFFIX="s\${DBGX}.exe" |
︙ | ︙ | |||
1067 1068 1069 1070 1071 1072 1073 | # # Will define the following vars: # TCL_CFGVAL_ENCODING # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_CFG_ENCODING], [ | | | 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 | # # Will define the following vars: # TCL_CFGVAL_ENCODING # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_CFG_ENCODING], [ AC_ARG_WITH(encoding, [ --with-encoding encoding for configuration values], with_tcencoding=${withval}) if test x"${with_tcencoding}" != x ; then AC_DEFINE_UNQUOTED(TCL_CFGVAL_ENCODING,"${with_tcencoding}") else # Default encoding on windows is not "iso8859-1" AC_DEFINE(TCL_CFGVAL_ENCODING,"cp1252") fi |
︙ | ︙ |
Changes to win/tclWinChan.c.
︙ | ︙ | |||
936 937 938 939 940 941 942 | DWORD err = GetLastError(); if ((err & 0xffffL) == ERROR_OPEN_FAILED) { err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND; } TclWinConvertError(err); if (interp != (Tcl_Interp *) NULL) { | > | | > | | < | 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 | DWORD err = GetLastError(); if ((err & 0xffffL) == ERROR_OPEN_FAILED) { err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND; } TclWinConvertError(err); if (interp != (Tcl_Interp *) NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open \"%s\": %s", TclGetString(pathPtr), Tcl_PosixError(interp))); } return NULL; } channel = NULL; switch (FileGetType(handle)) { case FILE_TYPE_SERIAL: /* * Reopen channel for OVERLAPPED operation. Normally this shouldn't * fail, because the channel exists. */ handle = TclWinSerialReopen(handle, nativeName, accessMode); if (handle == INVALID_HANDLE_VALUE) { TclWinConvertError(GetLastError()); if (interp != (Tcl_Interp *) NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't reopen serial \"%s\": %s", TclGetString(pathPtr), Tcl_PosixError(interp))); } return NULL; } channel = TclWinOpenSerialChannel(handle, channelName, channelPermissions); break; case FILE_TYPE_CONSOLE: |
︙ | ︙ | |||
991 992 993 994 995 996 997 | default: /* * The handle is of an unknown type, probably /dev/nul equivalent or * possibly a closed handle. */ channel = NULL; | | | > | 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 | default: /* * The handle is of an unknown type, probably /dev/nul equivalent or * possibly a closed handle. */ channel = NULL; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open \"%s\": bad file type", TclGetString(pathPtr))); Tcl_SetErrorCode(interp, "TCL", "VALUE", "CHANNEL", "BAD_TYPE", NULL); break; } return channel; } |
︙ | ︙ |
Changes to win/tclWinDde.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | #undef STATIC_BUILD #undef USE_TCL_STUBS #define USE_TCL_STUBS #include "tclInt.h" #include <dde.h> #include <ddeml.h> | | > > > > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #undef STATIC_BUILD #undef USE_TCL_STUBS #define USE_TCL_STUBS #include "tclInt.h" #include <dde.h> #include <ddeml.h> #ifdef UNICODE # if !defined(NDEBUG) /* test POKE server Implemented for UNICODE in debug mode only */ # undef CBF_FAIL_POKES # define CBF_FAIL_POKES 0 # endif #else # undef CP_WINUNICODE # define CP_WINUNICODE CP_WINANSI # undef Tcl_WinTCharToUtf # define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c) # undef Tcl_WinUtfToTChar # define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c) #endif |
︙ | ︙ | |||
86 87 88 89 90 91 92 | */ static HSZ ddeServiceGlobal = 0; static DWORD ddeInstance; /* The application instance handle given to us * by DdeInitialize. */ static int ddeIsServer = 0; | | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | */ static HSZ ddeServiceGlobal = 0; static DWORD ddeInstance; /* The application instance handle given to us * by DdeInitialize. */ static int ddeIsServer = 0; #define TCL_DDE_VERSION "1.4.0b1" #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 |
︙ | ︙ | |||
153 154 155 156 157 158 159 | { if (!Tcl_InitStubs(interp, "8.1", 0)) { return TCL_ERROR; } #ifdef UNICODE if (TclWinGetPlatformId() < VER_PLATFORM_WIN32_NT) { | > | | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | { if (!Tcl_InitStubs(interp, "8.1", 0)) { return TCL_ERROR; } #ifdef UNICODE if (TclWinGetPlatformId() < VER_PLATFORM_WIN32_NT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "Win32s and Windows 9x are not supported platforms", -1)); return TCL_ERROR; } #endif Tcl_CreateObjCommand(interp, "dde", DdeObjCmd, NULL, NULL); Tcl_CreateExitHandler(DdeExitProc, NULL); return Tcl_PkgProvide(interp, TCL_DDE_PACKAGE_NAME, TCL_DDE_VERSION); } |
︙ | ︙ | |||
781 782 783 784 785 786 787 788 789 790 791 792 793 794 | Tcl_DStringFree(&ds); } } Tcl_DStringFree(&dString); } return ddeReturn; case XTYP_EXECUTE: { /* * Execute this script. The results will be saved into a list object * which will be retreived later. See ExecuteRemoteObject. */ Tcl_Obj *returnPackagePtr; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 845 846 847 848 | Tcl_DStringFree(&ds); } } Tcl_DStringFree(&dString); } return ddeReturn; #if !CBF_FAIL_POKES case XTYP_POKE: /* * This is a poke for a Tcl variable, only implemented in * debug/UNICODE mode. */ ddeReturn = DDE_FNOTPROCESSED; if ((uFmt != CF_TEXT) && (uFmt != CF_UNICODETEXT)) { return ddeReturn; } for (convPtr = tsdPtr->currentConversations; (convPtr != NULL) && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) { /* * Empty loop body. */ } if (convPtr && !Tcl_IsSafe(convPtr->riPtr->interp)) { Tcl_DString ds; Tcl_Obj *variableObjPtr; 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, -1, &ds); utilString = (TCHAR *) DdeAccessData(hData, &dlen); if (uFmt == CF_TEXT) { variableObjPtr = Tcl_NewStringObj((char *)utilString, -1); } else { variableObjPtr = Tcl_NewUnicodeObj(utilString, -1); } Tcl_SetVar2Ex(convPtr->riPtr->interp, Tcl_DStringValue(&ds), NULL, variableObjPtr, TCL_GLOBAL_ONLY); Tcl_DStringFree(&ds); Tcl_DStringFree(&dString); ddeReturn = (HDDEDATA) DDE_FACK; } return ddeReturn; #endif case XTYP_EXECUTE: { /* * Execute this script. The results will be saved into a list object * which will be retreived later. See ExecuteRemoteObject. */ Tcl_Obj *returnPackagePtr; |
︙ | ︙ | |||
943 944 945 946 947 948 949 | ddeConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL); DdeFreeStringHandle(ddeInstance, ddeService); DdeFreeStringHandle(ddeInstance, ddeTopic); if (ddeConv == (HCONV) NULL) { if (interp != NULL) { | > | | > > > | 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 | 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, -1, &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; return TCL_OK; |
︙ | ︙ | |||
1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 | } switch ((enum DdeSubcommands) index) { case DDE_SERVERNAME: serviceName = DdeSetServerName(interp, serviceName, flags, handlerPtr); if (serviceName != NULL) { Tcl_SetObjResult(interp, Tcl_NewUnicodeObj((Tcl_UniChar *) serviceName, -1)); } else { Tcl_ResetResult(interp); } break; case DDE_EXECUTE: { int dataLength; | > > > > | 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 | } 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, -1)); #else Tcl_SetObjResult(interp, Tcl_NewStringObj(serviceName, -1)); #endif } else { Tcl_ResetResult(interp); } break; case DDE_EXECUTE: { int dataLength; |
︙ | ︙ | |||
1479 1480 1481 1482 1483 1484 1485 | } else { SetDdeError(interp); result = TCL_ERROR; } break; } case DDE_REQUEST: { | > > > > | > | 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 | } 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", -1)); Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL); result = TCL_ERROR; goto cleanup; |
︙ | ︙ | |||
1533 1534 1535 1536 1537 1538 1539 | result = TCL_ERROR; } } break; } case DDE_POKE: { | > > > > | > | 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 | 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", -1)); Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL); result = TCL_ERROR; |
︙ | ︙ | |||
1634 1635 1636 1637 1638 1639 1640 | * compile an object, producing a bytecode structure that refers * to other objects owned by the target interp. If the target * interp is then deleted, the bytecode structure would be * referring to deallocated objects. */ if (Tcl_IsSafe(riPtr->interp) && riPtr->handlerPtr == NULL) { | | | | | 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 | * compile an object, producing a bytecode structure that refers * to other objects owned by the target interp. If the target * 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", -1)); Tcl_SetErrorCode(interp, "TCL", "DDE", "SECURITY_CHECK", NULL); result = TCL_ERROR; } if (result == TCL_OK) { if (objc == 1) |
︙ | ︙ |
Changes to win/tclWinFCmd.c.
︙ | ︙ | |||
1526 1527 1528 1529 1530 1531 1532 | static void StatError( Tcl_Interp *interp, /* The interp that has the error */ Tcl_Obj *fileName) /* The name of the file which caused the * error. */ { TclWinConvertError(GetLastError()); | | | | 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 | static void StatError( Tcl_Interp *interp, /* The interp that has the error */ Tcl_Obj *fileName) /* The name of the file which caused the * error. */ { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf("could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } /* *---------------------------------------------------------------------- * * GetWinFileAttributes -- * |
︙ | ︙ | |||
1645 1646 1647 1648 1649 1650 1651 | int pathc, i; Tcl_Obj *splitPath; splitPath = Tcl_FSSplitPath(fileName, &pathc); if (splitPath == NULL || pathc == 0) { if (interp != NULL) { | > | | < | 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 | int pathc, i; Tcl_Obj *splitPath; splitPath = Tcl_FSSplitPath(fileName, &pathc); if (splitPath == NULL || pathc == 0) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not read \"%s\": no such file or directory", Tcl_GetString(fileName))); errno = ENOENT; Tcl_PosixError(interp); } goto cleanup; } /* |
︙ | ︙ | |||
1937 1938 1939 1940 1941 1942 1943 | static int CannotSetAttribute( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file. */ Tcl_Obj *attributePtr) /* The new value of the attribute. */ { | > | | < | 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 | static int CannotSetAttribute( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file. */ Tcl_Obj *attributePtr) /* The new value of the attribute. */ { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cannot set attribute \"%s\" for file \"%s\": attribute is readonly", tclpFileAttrStrings[objIndex], Tcl_GetString(fileName))); errno = EINVAL; Tcl_PosixError(interp); return TCL_ERROR; } /* *--------------------------------------------------------------------------- |
︙ | ︙ |
Changes to win/tclWinFile.c.
︙ | ︙ | |||
1044 1045 1046 1047 1048 1049 1050 | Tcl_DStringFree(&dsOrig); return TCL_OK; } TclWinConvertError(err); if (interp != NULL) { | | | | < | 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 | Tcl_DStringFree(&dsOrig); return TCL_OK; } TclWinConvertError(err); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read directory \"%s\": %s", Tcl_DStringValue(&dsOrig), Tcl_PosixError(interp))); } Tcl_DStringFree(&dsOrig); return TCL_ERROR; } Tcl_DStringFree(&ds); /* |
︙ | ︙ | |||
1862 1863 1864 1865 1866 1867 1868 | TCHAR buffer[MAX_PATH]; char *p; WCHAR *native; if (GetCurrentDirectory(MAX_PATH, buffer) == 0) { TclWinConvertError(GetLastError()); if (interp != NULL) { | > | | | 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 | TCHAR buffer[MAX_PATH]; char *p; WCHAR *native; if (GetCurrentDirectory(MAX_PATH, buffer) == 0) { TclWinConvertError(GetLastError()); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error getting working directory name: %s", Tcl_PosixError(interp))); } return NULL; } /* * Watch for the weird Windows c:\\UNC syntax. */ |
︙ | ︙ |
Changes to win/tclWinLoad.c.
︙ | ︙ | |||
87 88 89 90 91 92 93 | hInstance = LoadLibraryEx(nativeName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); Tcl_DStringFree(&ds); } if (hInstance == NULL) { DWORD lastError = GetLastError(); | < | | | | | | | | | | | | > | 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 | hInstance = LoadLibraryEx(nativeName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); Tcl_DStringFree(&ds); } if (hInstance == NULL) { DWORD lastError = GetLastError(); Tcl_Obj *errMsg = Tcl_ObjPrintf("couldn't load library \"%s\": ", Tcl_GetString(pathPtr)); /* * Check for possible DLL errors. This doesn't work quite right, * because Windows seems to only return ERROR_MOD_NOT_FOUND for just * about any problem, but it's better than nothing. It'd be even * better if there was a way to get what DLLs */ switch (lastError) { 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", -1); 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.", -1); break; case ERROR_INVALID_DLL: Tcl_SetErrorCode(interp, "WIN_LOAD", "INVALID_DLL", NULL); Tcl_AppendToObj(errMsg, "this library or a dependent library" " is damaged", -1); break; case ERROR_DLL_INIT_FAILED: Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_INIT_FAILED", NULL); Tcl_AppendToObj(errMsg, "the library initialization" " routine failed", -1); break; default: TclWinConvertError(lastError); Tcl_AppendToObj(errMsg, Tcl_PosixError(interp), -1); } Tcl_SetObjResult(interp, errMsg); return TCL_ERROR; } /* * Succeded; package everything up for Tcl. */ |
︙ | ︙ | |||
186 187 188 189 190 191 192 | Tcl_DStringInit(&ds); TclDStringAppendLiteral(&ds, "_"); sym2 = Tcl_DStringAppend(&ds, symbol, -1); proc = (Tcl_PackageInitProc *) GetProcAddress(hInstance, sym2); Tcl_DStringFree(&ds); } if (proc == NULL && interp != NULL) { | > | | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | Tcl_DStringInit(&ds); TclDStringAppendLiteral(&ds, "_"); sym2 = Tcl_DStringAppend(&ds, symbol, -1); 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); } return proc; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
282 283 284 285 286 287 288 | { Tcl_Obj *fileName; /* Name of the temp file. */ Tcl_Obj *tail; /* Tail of the source path. */ Tcl_MutexLock(&dllDirectoryNameMutex); if (dllDirectoryName == NULL) { if (InitDLLDirectoryName() == TCL_ERROR) { | > | | | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | { Tcl_Obj *fileName; /* Name of the temp file. */ Tcl_Obj *tail; /* Tail of the source path. */ Tcl_MutexLock(&dllDirectoryNameMutex); if (dllDirectoryName == NULL) { if (InitDLLDirectoryName() == TCL_ERROR) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't create temporary directory: %s", Tcl_PosixError(interp))); Tcl_MutexUnlock(&dllDirectoryNameMutex); return NULL; } } Tcl_MutexUnlock(&dllDirectoryNameMutex); /* |
︙ | ︙ |
Changes to win/tclWinPipe.c.
︙ | ︙ | |||
1026 1027 1028 1029 1030 1031 1032 | } } else { DuplicateHandle(hProcess, inputHandle, hProcess, &startInfo.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS); } if (startInfo.hStdInput == INVALID_HANDLE_VALUE) { TclWinConvertError(GetLastError()); | > | | | 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 | } } else { DuplicateHandle(hProcess, inputHandle, hProcess, &startInfo.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS); } if (startInfo.hStdInput == INVALID_HANDLE_VALUE) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't duplicate input handle: %s", Tcl_PosixError(interp))); goto end; } if (outputHandle == INVALID_HANDLE_VALUE) { /* * If handle was not set, output should be sent to an infinitely deep * sink. Under Windows 95, some 16 bit applications cannot have stdout |
︙ | ︙ | |||
1061 1062 1063 1064 1065 1066 1067 | } } else { DuplicateHandle(hProcess, outputHandle, hProcess, &startInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); } if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) { TclWinConvertError(GetLastError()); | > | | > | | | 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 | } } else { DuplicateHandle(hProcess, outputHandle, hProcess, &startInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); } if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't duplicate output handle: %s", Tcl_PosixError(interp))); goto end; } if (errorHandle == INVALID_HANDLE_VALUE) { /* * If handle was not set, errors should be sent to an infinitely deep * sink. */ startInfo.hStdError = CreateFileA("NUL:", GENERIC_WRITE, 0, &secAtts, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } else { DuplicateHandle(hProcess, errorHandle, hProcess, &startInfo.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS); } if (startInfo.hStdError == INVALID_HANDLE_VALUE) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't duplicate error handle: %s", Tcl_PosixError(interp))); goto end; } /* * If we do not have a console window, then we must run DOS and WIN32 * console mode applications as detached processes. This tells the loader * that the child application should not inherit the console, and that it |
︙ | ︙ | |||
1125 1126 1127 1128 1129 1130 1131 | if (HasConsole()) { createFlags = 0; } else { createFlags = DETACHED_PROCESS; } if (applType == APPL_DOS) { | | | | 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 | if (HasConsole()) { createFlags = 0; } else { createFlags = DETACHED_PROCESS; } if (applType == APPL_DOS) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "DOS application process not supported on this platform", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "DOS_APP", NULL); goto end; } } /* |
︙ | ︙ | |||
1154 1155 1156 1157 1158 1159 1160 | * Additionally, when calling a 16-bit dos or windows application, all * path names must use the short, cryptic, path format (e.g., using * ab~1.def instead of "a b.default"). */ BuildCommandLine(execPath, argc, argv, &cmdLine); | | | | | | | 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 | * Additionally, when calling a 16-bit dos or windows application, all * path names must use the short, cryptic, path format (e.g., using * ab~1.def instead of "a b.default"). */ BuildCommandLine(execPath, argc, argv, &cmdLine); if (CreateProcess(NULL, (TCHAR *) Tcl_DStringValue(&cmdLine), NULL, NULL, TRUE, (DWORD) createFlags, NULL, NULL, &startInfo, &procInfo) == 0) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s", argv[0], Tcl_PosixError(interp))); goto end; } /* * This wait is used to force the OS to give some time to the DOS process. */ |
︙ | ︙ | |||
1405 1406 1407 1408 1409 1410 1411 | } break; } Tcl_DStringFree(&nameBuf); if (applType == APPL_NONE) { TclWinConvertError(GetLastError()); | | | | 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 | } break; } Tcl_DStringFree(&nameBuf); if (applType == APPL_NONE) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s", originalName, Tcl_PosixError(interp))); return APPL_NONE; } if ((applType == APPL_DOS) || (applType == APPL_WIN3X)) { /* * Replace long path name of executable with short path name for * 16-bit applications. Otherwise the application may not be able to |
︙ | ︙ | |||
1669 1670 1671 1672 1673 1674 1675 | sec.nLength = sizeof(SECURITY_ATTRIBUTES); sec.lpSecurityDescriptor = NULL; sec.bInheritHandle = FALSE; if (!CreatePipe(&readHandle, &writeHandle, &sec, 0)) { TclWinConvertError(GetLastError()); | | | | 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 | sec.nLength = sizeof(SECURITY_ATTRIBUTES); sec.lpSecurityDescriptor = NULL; sec.bInheritHandle = FALSE; if (!CreatePipe(&readHandle, &writeHandle, &sec, 0)) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "pipe creation failed: %s", Tcl_PosixError(interp))); return TCL_ERROR; } *rchan = Tcl_MakeFileChannel((ClientData) readHandle, TCL_READABLE); Tcl_RegisterChannel(interp, *rchan); *wchan = Tcl_MakeFileChannel((ClientData) writeHandle, TCL_WRITABLE); |
︙ | ︙ | |||
1707 1708 1709 1710 1711 1712 1713 1714 | void TclGetAndDetachPids( Tcl_Interp *interp, Tcl_Channel chan) { PipeInfo *pipePtr; const Tcl_ChannelType *chanTypePtr; int i; | > < | > > > | < | > | 1710 1711 1712 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 | void TclGetAndDetachPids( Tcl_Interp *interp, Tcl_Channel chan) { PipeInfo *pipePtr; const Tcl_ChannelType *chanTypePtr; Tcl_Obj *pidsObj; int i; /* * Punt if the channel is not a command channel. */ chanTypePtr = Tcl_GetChannelType(chan); if (chanTypePtr != &pipeChannelType) { return; } pipePtr = Tcl_GetChannelInstanceData(chan); TclNewObj(pidsObj); for (i = 0; i < pipePtr->numPids; i++) { Tcl_ListObjAppendElement(NULL, pidsObj, Tcl_NewWideIntObj((unsigned) TclpGetPid(pipePtr->pidPtr[i]))); Tcl_DetachPids(1, &pipePtr->pidPtr[i]); } Tcl_SetObjResult(interp, pidsObj); if (pipePtr->numPids > 0) { ckfree(pipePtr->pidPtr); pipePtr->numPids = 0; } } /* |
︙ | ︙ | |||
1871 1872 1873 1874 1875 1876 1877 | pipePtr->validMask &= ~TCL_READABLE; pipePtr->readFile = NULL; } if ((!flags || flags & TCL_CLOSE_WRITE) && (pipePtr->writeFile != NULL)) { if (pipePtr->writeThread) { /* | | | | > > > > > > > > > > > > | > > | 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 1906 1907 1908 1909 1910 | pipePtr->validMask &= ~TCL_READABLE; pipePtr->readFile = NULL; } if ((!flags || flags & TCL_CLOSE_WRITE) && (pipePtr->writeFile != NULL)) { if (pipePtr->writeThread) { /* * Wait for the writer thread to finish the current buffer, then * terminate the thread and close the handles. If the channel is * nonblocking but blocked during exit, bail out since the worker * thread is not interruptible and we want TIP#398-fast-exit. */ if (TclInExit() && (pipePtr->flags & PIPE_ASYNC)) { /* give it a chance to leave honorably */ SetEvent(pipePtr->stopWriter); if (WaitForSingleObject(pipePtr->writable, 0) == WAIT_TIMEOUT) { return EAGAIN; } } else { WaitForSingleObject(pipePtr->writable, INFINITE); } /* * The thread may already have closed on it's own. Check its exit * code. */ GetExitCodeThread(pipePtr->writeThread, &exitCode); |
︙ | ︙ | |||
2624 2625 2626 2627 2628 2629 2630 | Tcl_Obj *const *objv) /* Argument strings. */ { Tcl_Channel chan; const Tcl_ChannelType *chanTypePtr; PipeInfo *pipePtr; int i; Tcl_Obj *resultPtr; | < < | < | > | 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 | Tcl_Obj *const *objv) /* Argument strings. */ { Tcl_Channel chan; const Tcl_ChannelType *chanTypePtr; PipeInfo *pipePtr; int i; Tcl_Obj *resultPtr; if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?channelId?"); return TCL_ERROR; } if (objc == 1) { Tcl_SetObjResult(interp, Tcl_NewWideIntObj((unsigned) getpid())); } else { chan = Tcl_GetChannel(interp, Tcl_GetStringFromObj(objv[1], NULL), NULL); if (chan == (Tcl_Channel) NULL) { return TCL_ERROR; } chanTypePtr = Tcl_GetChannelType(chan); if (chanTypePtr != &pipeChannelType) { return TCL_OK; } pipePtr = (PipeInfo *) Tcl_GetChannelInstanceData(chan); resultPtr = Tcl_NewObj(); for (i = 0; i < pipePtr->numPids; i++) { Tcl_ListObjAppendElement(/*interp*/ NULL, resultPtr, Tcl_NewWideIntObj((unsigned) TclpGetPid(pipePtr->pidPtr[i]))); } Tcl_SetObjResult(interp, resultPtr); } return TCL_OK; } /* |
︙ | ︙ | |||
2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 | waitResult = WaitForMultipleObjects(2, wEvents, FALSE, INFINITE); if (waitResult != (WAIT_OBJECT_0 + 1)) { /* * The start event was not signaled. It might be the stop event or * an error, so exit. */ break; } buf = infoPtr->writeBuf; toWrite = infoPtr->toWrite; | > > > > | 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 | waitResult = WaitForMultipleObjects(2, wEvents, FALSE, INFINITE); if (waitResult != (WAIT_OBJECT_0 + 1)) { /* * The start event was not signaled. It might be the stop event or * an error, so exit. */ if (waitResult == WAIT_OBJECT_0) { SetEvent(infoPtr->writable); } break; } buf = infoPtr->writeBuf; toWrite = infoPtr->toWrite; |
︙ | ︙ |
Changes to win/tclWinPort.h.
︙ | ︙ | |||
10 11 12 13 14 15 16 | * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef _TCLWINPORT #define _TCLWINPORT | | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef _TCLWINPORT #define _TCLWINPORT #if !defined(_WIN64) && defined(BUILD_tcl) /* See [Bug 3354324]: file mtime sets wrong time */ # define _USE_32BIT_TIME_T #endif /* * We must specify the lower version we intend to support. * * WINVER = 0x0500 means Windows 2000 and above |
︙ | ︙ |
Changes to win/tclWinReg.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #undef STATIC_BUILD | | | | | | | | | | < < < < < < < < | 9 10 11 12 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #undef STATIC_BUILD #undef USE_TCL_STUBS #define USE_TCL_STUBS #include "tclInt.h" #ifdef _MSC_VER # pragma comment (lib, "advapi32.lib") #endif #include <stdlib.h> #ifndef UNICODE # undef Tcl_WinTCharToUtf # define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c) # undef Tcl_WinUtfToTChar # define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c) #endif /* !UNICODE */ /* * Ensure that we can say which registry is being accessed. */ #ifndef KEY_WOW64_64KEY # define KEY_WOW64_64KEY (0x0100) #endif #ifndef KEY_WOW64_32KEY # define KEY_WOW64_32KEY (0x0200) #endif /* * The maximum length of a sub-key name. */ #ifndef MAX_KEY_LENGTH # define MAX_KEY_LENGTH 256 #endif /* * TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the * Registry_Init declaration is in the source file itself, which is only * accessed when we are building a library. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT /* * The following macros convert between different endian ints. */ #define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) #define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) |
︙ | ︙ | |||
169 170 171 172 173 174 175 | int Registry_Init( Tcl_Interp *interp) { Tcl_Command cmd; | | | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | int Registry_Init( Tcl_Interp *interp) { Tcl_Command cmd; if (Tcl_InitStubs(interp, "8.5", 0) == NULL) { return TCL_ERROR; } cmd = Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd, interp, DeleteCmd); Tcl_SetAssocData(interp, REGISTRY_ASSOC_KEY, NULL, cmd); return Tcl_PkgProvide(interp, "registry", "1.3.0"); |
︙ | ︙ | |||
531 532 533 534 535 536 537 | } valueName = Tcl_GetStringFromObj(valueNameObj, &length); Tcl_WinUtfToTChar(valueName, length, &ds); result = RegDeleteValue(key, (const TCHAR *)Tcl_DStringValue(&ds)); Tcl_DStringFree(&ds); if (result != ERROR_SUCCESS) { | > | | < | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 | } valueName = Tcl_GetStringFromObj(valueNameObj, &length); Tcl_WinUtfToTChar(valueName, length, &ds); result = RegDeleteValue(key, (const TCHAR *)Tcl_DStringValue(&ds)); Tcl_DStringFree(&ds); if (result != ERROR_SUCCESS) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unable to delete value \"%s\" from key \"%s\": ", Tcl_GetString(valueNameObj), Tcl_GetString(keyNameObj))); AppendSystemError(interp, result); result = TCL_ERROR; } else { result = TCL_OK; } RegCloseKey(key); return result; |
︙ | ︙ | |||
571 572 573 574 575 576 577 | Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *keyNameObj, /* Key to enumerate. */ Tcl_Obj *patternObj, /* Optional match pattern. */ REGSAM mode) /* Mode flags to pass. */ { const char *pattern; /* Pattern being matched against subkeys */ HKEY key; /* Handle to the key being examined */ | | > | 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 | Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *keyNameObj, /* Key to enumerate. */ Tcl_Obj *patternObj, /* Optional match pattern. */ REGSAM mode) /* Mode flags to pass. */ { const char *pattern; /* Pattern being matched against subkeys */ HKEY key; /* Handle to the key being examined */ TCHAR buffer[MAX_KEY_LENGTH]; /* Buffer to hold the subkey name */ DWORD bufSize; /* Size of the buffer */ DWORD index; /* Position of the current subkey */ char *name; /* Subkey name */ Tcl_Obj *resultPtr; /* List of subkeys being accumulated */ int result = TCL_OK; /* Return value from this command */ Tcl_DString ds; /* Buffer to translate subkey name to UTF-8 */ |
︙ | ︙ | |||
607 608 609 610 611 612 613 | bufSize = MAX_KEY_LENGTH; result = RegEnumKeyEx(key, index, buffer, &bufSize, NULL, NULL, NULL, NULL); if (result != ERROR_SUCCESS) { if (result == ERROR_NO_MORE_ITEMS) { result = TCL_OK; } else { | | | | | 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 | bufSize = MAX_KEY_LENGTH; result = RegEnumKeyEx(key, index, buffer, &bufSize, NULL, NULL, NULL, NULL); if (result != ERROR_SUCCESS) { if (result == ERROR_NO_MORE_ITEMS) { result = TCL_OK; } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unable to enumerate subkeys of \"%s\": ", Tcl_GetString(keyNameObj))); AppendSystemError(interp, result); result = TCL_ERROR; } break; } Tcl_WinTCharToUtf(buffer, bufSize * sizeof(TCHAR), &ds); name = Tcl_DStringValue(&ds); |
︙ | ︙ | |||
690 691 692 693 694 695 696 | nativeValue = Tcl_WinUtfToTChar(valueName, length, &ds); result = RegQueryValueEx(key, nativeValue, NULL, &type, NULL, NULL); Tcl_DStringFree(&ds); RegCloseKey(key); if (result != ERROR_SUCCESS) { | > | | < | 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 | nativeValue = Tcl_WinUtfToTChar(valueName, length, &ds); result = RegQueryValueEx(key, nativeValue, NULL, &type, NULL, NULL); Tcl_DStringFree(&ds); RegCloseKey(key); if (result != ERROR_SUCCESS) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unable to get type of value \"%s\" from key \"%s\": ", Tcl_GetString(valueNameObj), Tcl_GetString(keyNameObj))); AppendSystemError(interp, result); return TCL_ERROR; } /* * Set the type into the result. Watch out for unknown types. If we don't * know about the type, just use the numeric value. |
︙ | ︙ | |||
776 777 778 779 780 781 782 | while (result == ERROR_MORE_DATA) { /* * The Windows docs say that in this error case, we just need to * expand our buffer and request more data. Required for * HKEY_PERFORMANCE_DATA */ | | > | | < | 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 | while (result == ERROR_MORE_DATA) { /* * The Windows docs say that in this error case, we just need to * expand our buffer and request more data. Required for * HKEY_PERFORMANCE_DATA */ length = Tcl_DStringLength(&data) * (2 / sizeof(TCHAR)); Tcl_DStringSetLength(&data, (int) length * sizeof(TCHAR)); result = RegQueryValueEx(key, nativeValue, NULL, &type, (BYTE *) Tcl_DStringValue(&data), &length); } Tcl_DStringFree(&buf); RegCloseKey(key); if (result != ERROR_SUCCESS) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unable to get value \"%s\" from key \"%s\": ", Tcl_GetString(valueNameObj), Tcl_GetString(keyNameObj))); AppendSystemError(interp, result); Tcl_DStringFree(&data); return TCL_ERROR; } /* * If the data is a 32-bit quantity, store it as an integer object. If it |
︙ | ︙ | |||
813 814 815 816 817 818 819 | /* * Multistrings are stored as an array of null-terminated strings, * terminated by two null characters. Also do a bounds check in case * we get bogus data. */ | | < > | | 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 | /* * Multistrings are stored as an array of null-terminated strings, * 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, -1, &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), -1, &buf); Tcl_DStringResult(interp, &buf); |
︙ | ︙ | |||
1107 1108 1109 1110 1111 1112 1113 | } } } } else { rootName = name; } if (!rootName) { | | | | 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 | } } } } else { rootName = name; } if (!rootName) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad key \"%s\": must start with a valid root", name)); Tcl_SetErrorCode(interp, "WIN_REG", "NO_ROOT_KEY", NULL); return TCL_ERROR; } /* * Split the root into root and subkey portions. */ |
︙ | ︙ | |||
1222 1223 1224 1225 1226 1227 1228 | if (mode && regDeleteKeyExProc) { result = regDeleteKeyExProc(startKey, keyName, mode, 0); } else { result = RegDeleteKey(startKey, keyName); } break; } else if (result == ERROR_SUCCESS) { | | | | 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 | if (mode && regDeleteKeyExProc) { result = regDeleteKeyExProc(startKey, keyName, mode, 0); } else { result = RegDeleteKey(startKey, keyName); } break; } else if (result == ERROR_SUCCESS) { result = RecursiveDeleteKey(hKey, (const TCHAR *) Tcl_DStringValue(&subkey), mode); } } Tcl_DStringFree(&subkey); RegCloseKey(hKey); return result; } |
︙ | ︙ | |||
1290 1291 1292 1293 1294 1295 1296 | if (Tcl_GetIntFromObj(interp, dataObj, &value) != TCL_OK) { RegCloseKey(key); Tcl_DStringFree(&nameBuf); return TCL_ERROR; } | | | | 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 | if (Tcl_GetIntFromObj(interp, dataObj, &value) != TCL_OK) { RegCloseKey(key); Tcl_DStringFree(&nameBuf); return TCL_ERROR; } 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; int objc, i; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, dataObj, &objc, &objv) != TCL_OK) { |
︙ | ︙ | |||
1325 1326 1327 1328 1329 1330 1331 | */ Tcl_DStringAppend(&data, "", 1); /* NUL-terminated string */ } Tcl_WinUtfToTChar(Tcl_DStringValue(&data), Tcl_DStringLength(&data)+1, &buf); | | | | | | 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 | */ Tcl_DStringAppend(&data, "", 1); /* NUL-terminated string */ } Tcl_WinUtfToTChar(Tcl_DStringValue(&data), Tcl_DStringLength(&data)+1, &buf); result = RegSetValueEx(key, (TCHAR *) valueName, 0, (DWORD) type, (BYTE *) Tcl_DStringValue(&buf), (DWORD) Tcl_DStringLength(&buf)); Tcl_DStringFree(&data); Tcl_DStringFree(&buf); } else if (type == REG_SZ || type == REG_EXPAND_SZ) { Tcl_DString buf; const char *data = Tcl_GetStringFromObj(dataObj, &length); data = (char *) Tcl_WinUtfToTChar(data, length, &buf); /* * Include the null in the length, padding if needed for Unicode. */ Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf)+1); length = Tcl_DStringLength(&buf) + 1; result = RegSetValueEx(key, (TCHAR *) valueName, 0, (DWORD) type, (BYTE *) data, (DWORD) length); Tcl_DStringFree(&buf); } else { BYTE *data; /* * Store binary data in the registry. */ data = (BYTE *) Tcl_GetByteArrayFromObj(dataObj, &length); result = RegSetValueEx(key, (TCHAR *) valueName, 0, (DWORD) type, data, (DWORD) length); } Tcl_DStringFree(&nameBuf); RegCloseKey(key); if (result != ERROR_SUCCESS) { |
︙ | ︙ | |||
1525 1526 1527 1528 1529 1530 1531 | */ static DWORD ConvertDWORD( DWORD type, /* Either REG_DWORD or REG_DWORD_BIG_ENDIAN */ DWORD value) /* The value to be converted. */ { | | > | | 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 | */ static DWORD ConvertDWORD( DWORD type, /* Either REG_DWORD or REG_DWORD_BIG_ENDIAN */ DWORD value) /* The value to be converted. */ { const DWORD order = 1; DWORD localType; /* * Check to see if the low bit is in the first byte. */ localType = (*((const char *) &order) == 1) ? REG_DWORD : REG_DWORD_BIG_ENDIAN; return (type != localType) ? (DWORD) SWAPLONG(value) : value; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to win/tclWinSerial.c.
︙ | ︙ | |||
1669 1670 1671 1672 1673 1674 1675 | /* * Option -mode baud,parity,databits,stopbits */ if ((len > 2) && (strncmp(optionName, "-mode", len) == 0)) { if (!GetCommState(infoPtr->handle, &dcb)) { | < < | < < < | | > < < | < < < < < | < < < | 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 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 | /* * 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, -1, &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", value)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "SERIALMODE", NULL); } return TCL_ERROR; } /* * Default settings for serial communications. */ dcb.fBinary = TRUE; dcb.fErrorChar = FALSE; dcb.fNull = FALSE; dcb.fAbortOnError = FALSE; if (!SetCommState(infoPtr->handle, &dcb)) { goto setStateFailed; } return TCL_OK; } /* * Option -handshake none|xonxoff|rtscts|dtrdsr */ if ((len > 1) && (strncmp(optionName, "-handshake", len) == 0)) { if (!GetCommState(infoPtr->handle, &dcb)) { goto getStateFailed; } /* * Reset all handshake options. DTR and RTS are ON by default. */ dcb.fOutX = dcb.fInX = FALSE; |
︙ | ︙ | |||
1755 1756 1757 1758 1759 1760 1761 | dcb.fOutxCtsFlow = TRUE; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; } else if (strncasecmp(value, "DTRDSR", vlen) == 0) { dcb.fOutxDsrFlow = TRUE; dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; } else { if (interp != NULL) { | | | | < < | < < < < < | < < < > | | < | 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 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 | dcb.fOutxCtsFlow = TRUE; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; } else if (strncasecmp(value, "DTRDSR", vlen) == 0) { dcb.fOutxDsrFlow = TRUE; dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; } else { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad value \"%s\" for -handshake: must be one of" " xonxoff, rtscts, dtrdsr or none", value)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "HANDSHAKE", NULL); } return TCL_ERROR; } if (!SetCommState(infoPtr->handle, &dcb)) { goto setStateFailed; } return TCL_OK; } /* * Option -xchar {\x11 \x13} */ if ((len > 1) && (strncmp(optionName, "-xchar", len) == 0)) { if (!GetCommState(infoPtr->handle, &dcb)) { goto getStateFailed; } if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) { 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", -1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "XCHAR", NULL); } ckfree(argv); return TCL_ERROR; } /* |
︙ | ︙ | |||
1833 1834 1835 1836 1837 1838 1839 | goto badXchar; } dcb.XoffChar = (char) character; } ckfree(argv); if (!SetCommState(infoPtr->handle, &dcb)) { | < < | < < < | | | > | > | > | | | | | 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 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 | goto badXchar; } dcb.XoffChar = (char) character; } ckfree(argv); if (!SetCommState(infoPtr->handle, &dcb)) { goto setStateFailed; } return TCL_OK; } /* * Option -ttycontrol {DTR 1 RTS 0 BREAK 0} */ if ((len > 4) && (strncmp(optionName, "-ttycontrol", len) == 0)) { int i, result = TCL_OK; if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) { return TCL_ERROR; } if ((argc % 2) == 1) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad value \"%s\" for -ttycontrol: should be " "a list of signal,value pairs", value)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "TTYCONTROL", NULL); } ckfree(argv); return TCL_ERROR; } for (i = 0; i < argc - 1; i += 2) { if (Tcl_GetBoolean(interp, argv[i+1], &flag) == TCL_ERROR) { result = TCL_ERROR; 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", -1)); 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", -1)); 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", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE", "TTY_SIGNAL", NULL); } result = TCL_ERROR; break; } } else { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad signal name \"%s\" for -ttycontrol: must be" " DTR, RTS or BREAK", argv[i])); Tcl_SetErrorCode(interp, "TCL", "VALUE", "TTY_SIGNAL", NULL); } result = TCL_ERROR; break; } } |
︙ | ︙ | |||
1945 1946 1947 1948 1949 1950 1951 | inSize = atoi(argv[0]); outSize = atoi(argv[1]); } ckfree(argv); if ((argc < 1) || (argc > 2) || (inSize <= 0) || (outSize <= 0)) { if (interp != NULL) { | | | | > | | < < | < < < < < | < < < | 1919 1920 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 | inSize = atoi(argv[0]); outSize = atoi(argv[1]); } ckfree(argv); if ((argc < 1) || (argc > 2) || (inSize <= 0) || (outSize <= 0)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad value \"%s\" for -sysbuffer: should be " "a list of one or two integers > 0", value)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "SYS_BUFFER", NULL); } return TCL_ERROR; } if (!SetupComm(infoPtr->handle, inSize, outSize)) { if (interp != NULL) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't setup comm buffers: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } infoPtr->sysBufRead = inSize; infoPtr->sysBufWrite = outSize; /* * Adjust the handshake limits. Yes, the XonXoff limits seem to * influence even hardware handshake. */ if (!GetCommState(infoPtr->handle, &dcb)) { goto getStateFailed; } dcb.XonLim = (WORD) (infoPtr->sysBufRead*1/2); dcb.XoffLim = (WORD) (infoPtr->sysBufRead*1/4); if (!SetCommState(infoPtr->handle, &dcb)) { goto setStateFailed; } return TCL_OK; } /* * Option -pollinterval msec */ |
︙ | ︙ | |||
2016 2017 2018 2019 2020 2021 2022 | if (Tcl_GetInt(interp, value, &msec) != TCL_OK) { return TCL_ERROR; } tout.ReadTotalTimeoutConstant = msec; if (!SetCommTimeouts(infoPtr->handle, &tout)) { if (interp != NULL) { TclWinConvertError(GetLastError()); | > | | > > > > > > > > > > > > > > > > | 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 | if (Tcl_GetInt(interp, value, &msec) != TCL_OK) { return TCL_ERROR; } tout.ReadTotalTimeoutConstant = msec; if (!SetCommTimeouts(infoPtr->handle, &tout)) { if (interp != NULL) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't set comm timeouts: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; } return Tcl_BadChannelOption(interp, optionName, "mode handshake pollinterval sysbuffer timeout ttycontrol xchar"); getStateFailed: if (interp != NULL) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get comm state: %s", Tcl_PosixError(interp))); } return TCL_ERROR; setStateFailed: if (interp != NULL) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't set comm state: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } /* *---------------------------------------------------------------------- * * SerialGetOptionProc -- * |
︙ | ︙ | |||
2085 2086 2087 2088 2089 2090 2091 | char parity; const char *stop; char buf[2 * TCL_INTEGER_SPACE + 16]; if (!GetCommState(infoPtr->handle, &dcb)) { if (interp != NULL) { TclWinConvertError(GetLastError()); | | | | 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 | char parity; const char *stop; char buf[2 * TCL_INTEGER_SPACE + 16]; if (!GetCommState(infoPtr->handle, &dcb)) { if (interp != NULL) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get comm state: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } valid = 1; parity = 'n'; if (dcb.Parity <= 4) { |
︙ | ︙ | |||
2155 2156 2157 2158 2159 2160 2161 | if (len==0 || (len>1 && strncmp(optionName, "-xchar", len) == 0)) { char buf[4]; valid = 1; if (!GetCommState(infoPtr->handle, &dcb)) { if (interp != NULL) { TclWinConvertError(GetLastError()); | | | | 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 | if (len==0 || (len>1 && strncmp(optionName, "-xchar", len) == 0)) { char buf[4]; valid = 1; if (!GetCommState(infoPtr->handle, &dcb)) { if (interp != NULL) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get comm state: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } sprintf(buf, "%c", dcb.XonChar); Tcl_DStringAppendElement(dsPtr, buf); sprintf(buf, "%c", dcb.XoffChar); Tcl_DStringAppendElement(dsPtr, buf); |
︙ | ︙ | |||
2233 2234 2235 2236 2237 2238 2239 | if (len>4 && strncmp(optionName, "-ttystatus", len)==0) { DWORD status; if (!GetCommModemStatus(infoPtr->handle, &status)) { if (interp != NULL) { TclWinConvertError(GetLastError()); | | | < > | | < | 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 | if (len>4 && strncmp(optionName, "-ttystatus", len)==0) { DWORD status; if (!GetCommModemStatus(infoPtr->handle, &status)) { if (interp != NULL) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get tty status: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } valid = 1; SerialModemStatusStr(status, dsPtr); } if (valid) { return TCL_OK; } return Tcl_BadChannelOption(interp, optionName, "mode pollinterval lasterror queue sysbuffer ttystatus xchar"); } /* *---------------------------------------------------------------------- * * SerialThreadActionProc -- * |
︙ | ︙ |
Changes to win/tclWinSock.c.
︙ | ︙ | |||
554 555 556 557 558 559 560 | InitSockets(); Tcl_MutexUnlock(&socketMutex); if (SocketsEnabled()) { return TCL_OK; } if (interp != NULL) { | > | < | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 | InitSockets(); Tcl_MutexUnlock(&socketMutex); if (SocketsEnabled()) { return TCL_OK; } if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "sockets are not available on this system", -1)); } return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
924 925 926 927 928 929 930 | sd = SD_RECEIVE; break; case TCL_CLOSE_WRITE: sd = SD_SEND; break; default: if (interp) { | | | | 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 | sd = SD_RECEIVE; break; case TCL_CLOSE_WRITE: sd = SD_SEND; break; default: if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "Socket close2proc called bidirectionally", -1)); } return TCL_ERROR; } if (shutdown(infoPtr->sockets->fd, sd) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); errorCode = Tcl_GetErrno(); |
︙ | ︙ | |||
1276 1277 1278 1279 1280 1281 1282 | SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, (LPARAM) infoPtr); return infoPtr; } if (interp != NULL) { | > | < | < < < | 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 | SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, (LPARAM) infoPtr); return infoPtr; } if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open socket: %s", (errorMsg ? errorMsg : Tcl_PosixError(interp)))); } if (sock != INVALID_SOCKET) { closesocket(sock); } return NULL; } |
︙ | ︙ | |||
1925 1926 1927 1928 1929 1930 1931 | * Check that WinSock is initialized; do not call it if not, to prevent * 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) { | > | | 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 | * Check that WinSock is initialized; do not call it if not, to prevent * 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", -1)); } return TCL_ERROR; } #ifdef TCL_FEATURE_KEEPALIVE_NAGLE sock = infoPtr->sockets->fd; |
︙ | ︙ | |||
1948 1949 1950 1951 1952 1953 1954 | val = TRUE; } rtn = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const char *) &val, sizeof(BOOL)); if (rtn != 0) { TclWinConvertError(WSAGetLastError()); if (interp) { | > | | > | | | 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 | val = TRUE; } rtn = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const char *) &val, sizeof(BOOL)); if (rtn != 0) { TclWinConvertError(WSAGetLastError()); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't set socket option: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; } else if (!strcasecmp(optionName, "-nagle")) { BOOL val = FALSE; int boolVar, rtn; if (Tcl_GetBoolean(interp, value, &boolVar) != TCL_OK) { return TCL_ERROR; } if (!boolVar) { val = TRUE; } rtn = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *) &val, sizeof(BOOL)); if (rtn != 0) { TclWinConvertError(WSAGetLastError()); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't set socket option: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } return TCL_OK; } return Tcl_BadChannelOption(interp, optionName, "keepalive nagle"); |
︙ | ︙ | |||
2028 2029 2030 2031 2032 2033 2034 | * Check that WinSock is initialized; do not call it if not, to prevent * 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) { | > | | 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 | * Check that WinSock is initialized; do not call it if not, to prevent * 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", -1)); } return TCL_ERROR; } sock = infoPtr->sockets->fd; if (optionName != NULL) { len = strlen(optionName); |
︙ | ︙ | |||
2095 2096 2097 2098 2099 2100 2101 | * an fconfigure request on a server socket (such sockets have no * peer). {Copied from unix/tclUnixChan.c} */ if (len) { TclWinConvertError((DWORD) WSAGetLastError()); if (interp) { | > | | | 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 | * an fconfigure request on a server socket (such sockets have no * peer). {Copied from unix/tclUnixChan.c} */ if (len) { TclWinConvertError((DWORD) WSAGetLastError()); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get peername: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } } } if ((len == 0) || ((len > 1) && (optionName[1] == 's') && |
︙ | ︙ | |||
2160 2161 2162 2163 2164 2165 2166 | Tcl_DStringEndSublist(dsPtr); } else { return TCL_OK; } } else { if (interp) { TclWinConvertError((DWORD) WSAGetLastError()); | | | | 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 | Tcl_DStringEndSublist(dsPtr); } else { return TCL_OK; } } else { if (interp) { TclWinConvertError((DWORD) WSAGetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get sockname: %s", Tcl_PosixError(interp))); } return TCL_ERROR; } } #ifdef TCL_FEATURE_KEEPALIVE_NAGLE if (len == 0 || !strncmp(optionName, "-keepalive", len)) { |
︙ | ︙ |