Compare commits

...
Author SHA1 Message Date
dkf d4654f8568 I hate YAML. 2019-07-17 14:10:30 +00:00
dkf 332f3e88d2 Of course, Cygwin doesn't install a working build environment by default... 2019-07-16 11:57:01 +00:00
dkf 49935f618a Switch to using cygwin; apparently that's expected for our GCC-on-Win builds 2019-07-15 14:15:15 +00:00
dkf 12b79cb977 Print what VPATH actually is 2019-07-13 11:44:59 +00:00
dkf 3a5183b88e Travis windows debugging 2019-07-12 06:41:25 +00:00
dkf d129d1a6e9 Add CI (Travis) builds and testing for Windows, both with MSVC and GCC. 2019-07-10 08:49:57 +00:00
dkf b032f6d67b Add CI (Travis) builds and testing for Windows, both with MSVC and GCC. 2019-07-10 08:28:31 +00:00
dkf 777a642667 merge core-8-5-branch 2019-07-10 08:25:48 +00:00
dkf eaaa675e99 More tweaking to work around YAML parsing issues and fix an irrelevant test failure with static builds on Windows 2019-07-09 08:39:27 +00:00
jan.nijtmans 5d106cabda Merge 8.5 2019-07-08 20:18:38 +00:00
jan.nijtmans 4b7f867f90 Simplify previous commit: Just always use Tcl_WideInt 2019-07-08 19:02:56 +00:00
sebres a4c8e24f4c amend to [c14252171d]: fixes [4718b41c56] for x64 (and x86 with 64-bit predefined time_t resp. CRT library) 2019-07-08 15:00:12 +00:00
dkf 309510e33e Tweak the build a bit more, and use YAML a bit better 2019-07-08 10:57:56 +00:00
dkf 58c45c0f97 Updated win/configure to use current version of autoconf 2019-07-07 15:20:26 +00:00
jan.nijtmans fdf2dd144f Merge 8.5 2019-07-05 22:53:07 +00:00
jan.nijtmans 97bf1ced2b Merge 8.5 2019-07-05 22:51:15 +00:00
jan.nijtmans 28f17c0d70 Add "name" entries to travis build configuration 2019-07-05 22:49:31 +00:00
jan.nijtmans 9d0dfc6f26 Fix [4718b41c56d8c135]: windows x86 & x64: file mtime overflows in modification date. Only fixed for x64, because for x86 it isn't possible without breaking API compatibility 2019-07-05 11:23:56 +00:00
jan.nijtmans 4d25168772 Fix [4718b41c56d8c135]: windows x86 & x64: file mtime overflows in modification date.
Only fixed for x64, because for x86 it isn't possible without breaking API compatibility.
2019-07-05 09:29:55 +00:00
dkf 912f1a8816 The next round of trying to get Windows builds working 2019-07-05 08:39:59 +00:00
dkf 24829b80ac Might as well try direct gcc on Windows too. 2019-07-04 09:57:31 +00:00
dkf 12c3fbcb0c More tinkering with the build. Can override scripts in the matrix, but need magic to find nmake. 2019-07-04 09:45:24 +00:00
dkf a33b0950be Tcl_ObjectDeleted was only partially documented. Oops. 2019-07-03 20:10:17 +00:00
dkf 9740bc1662 There are no cats in America, and no tabs in YAML files 2019-07-03 13:24:16 +00:00
dkf 8751d32304 So... you can't directly override a script in the matrix section of .travis.yml 2019-07-02 09:13:59 +00:00
José Ignacio Marín b0ffd31845 Update TZ info to tzdata2019b. 2019-07-02 07:24:11 +00:00
dkf ac198c7f44 This is a trial of doing a classic Windows build-and-test on Travis 2019-07-01 20:33:55 +00:00
dgp 150fb8061f Avoid valgrind issues with uninitialized memory 2019-07-01 19:29:55 +00:00
dgp d17af2c703 Avoid valgrind issues with "uninitialized memory" 2019-07-01 19:21:06 +00:00
jan.nijtmans 41be9233e9 Trying to fix C4761 warning with VC++ 6.0 2019-06-29 21:29:46 +00:00
sebres 574c3c0027 winFCmd.test: fixes EXDEV related constraint and paths in test cases (covering move/rename across devices) 2019-06-27 16:20:05 +00:00
jan.nijtmans d25a0dae48 Fix [15d851e394]: Fix spelling in comment of tclCmdIL.c 2019-06-27 13:38:09 +00:00
jan.nijtmans c4459402a9 UNEXEC win/tclWinFile.c 2019-06-26 08:27:51 +00:00
jan.nijtmans 7c0afa7cd6 Merge 8.5 2019-06-26 08:26:01 +00:00
jan.nijtmans 595cb86379 Remove EXECUTE flag for tclWinFile.c. More eol-spacing cleanup (keeping tests-pref/* among other the same in multiple branches) 2019-06-26 08:21:19 +00:00
jan.nijtmans 5ef1c629df Makef tclTomMath.h work with VC++ 6.0 2019-06-25 22:27:43 +00:00
sebres 9392d9001a restore userenv, used in 8.6 2019-06-25 18:59:09 +00:00
sebres e113eb82e5 merge 8.5 2019-06-25 18:02:12 +00:00
sebres 334b8029ed nmakehlp: fixed const qualifier 2019-06-25 17:45:23 +00:00
sebres be26adf83b fixed build with MSVC 6.0 2019-06-25 16:09:33 +00:00
jan.nijtmans 9489b8b506 Squelch C4244 warning on any MSVC compiler. 2019-06-25 06:56:26 +00:00
sebres 8ab0ae062e closes [f8a33ce3db5d8cc2]: Tcl_Exit uses system exit as fallback if Tcl-subsystems are not (yet) initialized (or initialization fails). 2019-06-21 19:22:07 +00:00
dkf 2f8cb2ab85 [6bdadfba7d] Stop crash with multi-lappend and failing writes 2019-06-20 19:40:30 +00:00
dgp a9083528ab [8b9854c3d8] Undo regression in [info level 0] after ensemble dispatch. 2019-06-17 18:00:29 +00:00
jan.nijtmans 96f1d4ec34 Merge 8.5 2019-06-15 22:31:51 +00:00
jan.nijtmans c1ee80eccf Use mp_init_set() in stead of mp_init_set_int() when the constant is sufficiently small. This is slightly better optimized. 2019-06-15 22:30:59 +00:00
dgp 526c432322 Mark test namespace-54.6 as knownBug.
The real bug here is Tcl's failure to forbid ":" as a namespace name.
2019-06-13 20:43:04 +00:00
dgp 1ebe878444 Fix Bug 8b9854c3d8. Now 4 test failures require examination. 2019-06-13 17:58:48 +00:00
dgp 1cd98b93bd Unique test name. 2019-06-13 17:37:46 +00:00
dgp 5645bb01ff Test namespace-56.4 detects Bug 8b9854c3d8. Branch open to fix it. 2019-06-13 17:20:45 +00:00
jan.nijtmans e69d76af16 Fix [25deec4e46]: Tcl fails to compile with icc due to typedef conflict 2019-06-11 15:31:29 +00:00
jan.nijtmans 6420ec98e8 Fix [25deec4e46]: Tcl fails to compile with icc due to typedef conflict 2019-06-11 15:30:27 +00:00
dkf 44d4c7f793 General improvements to the expr manpage 2019-06-10 19:43:59 +00:00
dkf 1cab268c94 General improvements to the expr manpage 2019-06-10 19:27:31 +00:00
dgp 39fba10b45 More localized documentation of lazy operators. 2019-06-10 18:44:18 +00:00
dgp 5f72a5554c More bytecodes are non-throwing. 2019-06-10 18:33:28 +00:00
dgp 3fe6dfccc1 Remove declarations that are never defined. 2019-06-10 18:31:09 +00:00
dgp 774c2050f1 Remove declarations that are never defined. 2019-06-10 18:24:05 +00:00
dkf ab3a73bf75 minor cleanup of source code formatting 2019-06-09 11:28:58 +00:00
jan.nijtmans d23bb9578a In tools/*, use the single-argument version of "expr" always. Making it robust against TIP #526. Those tools generally are the same among all Tcl versions. 2019-05-31 23:13:21 +00:00
jan.nijtmans be861c2430 Rename mp_get_bit to s_mp_get_bit, rename mp_tc_div_2d to mp_signed_rsh, remove mp_tc_(add|or|xor) functions in favor of mp_(add|or|xor) which can now handle twos-complement. Following ongoing changes in libtommath development. 2019-05-31 11:28:39 +00:00
jan.nijtmans 984c717026 Merge 8.5 2019-05-29 23:08:11 +00:00
jan.nijtmans 7a1b66b00d Update some libtommath functions to the latest trunk versions. Small step forward in the upgrade to (upcoming) libtommath 1.2.
Advantage: simplify Tcl code accessing those functions.
2019-05-29 22:48:50 +00:00
jan.nijtmans 6c6bec6689 Fix build status in README.md 2019-05-28 22:48:52 +00:00
jan.nijtmans 372248583f Rename README to README.md, and reformat 2019-05-28 22:17:37 +00:00
jan.nijtmans 4ff1524f2a Merge 8.5 2019-05-28 21:41:23 +00:00
jan.nijtmans 4e994192a1 Eliminate a set of libtommath-related files that don't do anything. There's no sense in it, keeping track of those files in the Tcl repository. 2019-05-28 21:38:58 +00:00
jan.nijtmans c70641a878 Fix "make dist" for the README -> README.md renaming 2019-05-27 21:18:01 +00:00
jan.nijtmans b15a6a700f end-of-line spacing 2019-05-24 20:10:14 +00:00
jan.nijtmans ffdd95d4a3 Missing keyword: "static" 2019-05-24 20:03:03 +00:00
sebres d249b0629d merge 8.5 2019-05-24 16:56:29 +00:00
sebres cb9018a721 fixes typo ("net" instead of outdated term "nett") 2019-05-24 16:49:32 +00:00
sebres e298c2595d merge 8.5 (timerate unsigned calc) 2019-05-21 18:01:07 +00:00
sebres 3ab1f672a4 timerate: be more precise using unsigned wide (for total execution time), avoid signed vs unsigned comparison warning (if compiled with VS). 2019-05-21 17:52:14 +00:00
dgp 7db84b0155 Knock VOID back down 2019-05-21 16:42:11 +00:00
sebres e2f5de73e3 fixed mistake in optimization of [3f693cdfe9c875c4] (bypass of compareKeysProc if keys pointers/objects are equal) - it should compare given key with entry key (not with a hash entry) 2019-05-21 11:34:13 +00:00
sebres 57c23073f7 small amend (no cast needed) 2019-05-21 11:29:09 +00:00
sebres 245ed0c3c3 cherry-picing of [3f693cdfe9c875c4] to be more compatible across version, resolve mistake with "key objects/pointers comparison by the hash entry" firstly introduced there. 2019-05-21 11:22:36 +00:00
dgp 543703d4ee comment typo 2019-05-17 18:33:49 +00:00
sebres 1f5c7c693b merge 8.5 2019-05-16 18:19:25 +00:00
sebres 2865a8da13 small amend to [ac566e9df84daeab] with rollback of done/continue optimization 2019-05-16 18:17:52 +00:00
sebres 8af3fb7317 merge 8.5 (timerate fix to avoid impact of object duplication on shared interp result by the measurement) 2019-05-16 17:56:37 +00:00
sebres ccc592df50 timerate: allow continue from measurement cycle (used for conditional flow control of iterations);
more gentle evaluation behaviour, similar to a cycle now (also avoids extra overhead to set result to interp, etc.);
todo: rewrite optimization of INST_DONE using last-instruction pointer or optimization flags for compile of iteration (if sebres's perf-branch gets merged).
2019-05-16 17:49:25 +00:00
jan.nijtmans de4f571baa Merge 8.5 2019-05-14 19:13:01 +00:00
jan.nijtmans 8094d33e43 DIGIT_BIT -> MP_DIGIT_BIT, since DIGIT_BIT is deprecated in future libtommath versions. So, better stop using it at all.
Also add some other defines/typdefs for future libtommath compatibility.
2019-05-14 18:42:59 +00:00
dgp 9ca29b09ae merge 8.5 2019-05-11 12:49:46 +00:00
dgp 95d2a7f7c0 Revised documented advice that made obsolete reference to interp->result. 2019-05-11 12:48:53 +00:00
jan.nijtmans d232a6d28e Minor compiler warning 2019-05-09 15:32:51 +00:00
dgp 5419f8e0ba For historical/hysterical reasons, the (unused??) public routines Tcl_UpVar()
and Tcl_UpVar2() accept random garbage for a level argument (treat it as 1)
while the [upvar] command has come to reject such values as bad levels.
Add a test to call it to our attention if we ever change that disparity
so we do so only on purpose.
2019-05-08 18:06:23 +00:00
jan.nijtmans f218c1f1eb (cherry-pick from8.6): Japanese Reiwa (令和) era 2019-05-07 07:19:10 +00:00
dgp 84f4682378 close fork 2019-05-04 22:44:47 +00:00
dgp 06124df7de merge 8.5 2019-05-04 18:32:39 +00:00
dgp 4909a5cc24 Plug memleak when deleting a namespace destroys a linked Tcl var. 2019-05-04 18:25:40 +00:00
Kevin B Kenny 55b6550aaa Japanese Reiwa (令和) era 2019-05-04 14:49:58 +00:00
dkf cd6fdc6976 Make sure we test [2c154a40be] explicitly. Part of [cc191552c] 2019-05-04 07:10:34 +00:00
dgp 48891ff56a memleak demo test 2019-05-03 18:54:46 +00:00
dgp 5ee08fdf00 memleak demo test 2019-05-03 18:50:13 +00:00
dkf e42fbc68b9 Added primitive to allow working coroutine deep introspection 2019-04-23 14:24:53 +00:00
dkf ba3eca6d7e Minor code style cleanup. 2019-04-23 13:47:52 +00:00
dkf eaf90743ee timerate: code style, doc style 2019-04-23 06:43:08 +00:00
dkf 1e9a4512c7 timerate: code style, doc style 2019-04-23 06:28:28 +00:00
sebres 407ebf2899 merge 8.5 2019-04-17 20:00:37 +00:00
sebres 0cced28f38 extend performance test-suite, allow several (repeatable) execution of _test_run (if encosed in _test_start/_test_out_total) to produce same summary; provide possibility for measure of single iterators, etc.
small code review
2019-04-17 19:59:13 +00:00
dgp 05509bdd77 Revise coroutines tests so they do not leave behind frame footprints that
can interfere with other tests.
2019-04-17 14:34:42 +00:00
dgp 68c28bd274 Isolate tests of [info frame] results from testing environment. 2019-04-17 14:28:51 +00:00
dgp f720f4cad5 Isolate tests of [info frame] results from testing environment. 2019-04-17 14:25:59 +00:00
93 changed files with 6165 additions and 27181 deletions
+113 -53
View File
@@ -3,29 +3,36 @@ language: c
matrix:
include:
- os: linux
# Testing on Linux with various compilers
- name: "Linux/Clang/Shared"
os: linux
dist: xenial
compiler: clang
env:
- BUILD_DIR=unix
- os: linux
- name: "Linux/Clang/Static"
os: linux
dist: xenial
compiler: clang
env:
- CFGOPT=--disable-shared
- BUILD_DIR=unix
- os: linux
- name: "Linux/GCC/Shared"
os: linux
dist: xenial
compiler: gcc
env:
- BUILD_DIR=unix
- os: linux
- name: "Linux/GCC/Static"
os: linux
dist: xenial
compiler: gcc
env:
- CFGOPT=--disable-shared
- BUILD_DIR=unix
- os: linux
# Older versions of GCC...
- name: "Linux/GCC 4.9/Shared"
os: linux
dist: xenial
compiler: gcc-4.9
addons:
@@ -36,7 +43,8 @@ matrix:
- g++-4.9
env:
- BUILD_DIR=unix
- os: linux
- name: "Linux/GCC 5/Shared"
os: linux
dist: xenial
compiler: gcc-5
addons:
@@ -47,7 +55,8 @@ matrix:
- g++-5
env:
- BUILD_DIR=unix
- os: linux
- name: "Linux/GCC 6/Shared"
os: linux
dist: xenial
compiler: gcc-6
addons:
@@ -58,7 +67,8 @@ matrix:
- g++-6
env:
- BUILD_DIR=unix
- os: linux
- name: "Linux/GCC 7/Shared"
os: linux
dist: xenial
compiler: gcc-7
addons:
@@ -69,35 +79,43 @@ matrix:
- g++-7
env:
- BUILD_DIR=unix
- os: osx
# Testing on Mac, various styles
- name: "macOS/Xcode 8/Shared/Unix-like"
os: osx
osx_image: xcode8
env:
- BUILD_DIR=unix
- os: osx
- name: "macOS/Xcode 8/Shared/Mac-like"
os: osx
osx_image: xcode8
env:
- BUILD_DIR=macosx
- NO_DIRECT_CONFIGURE=1
- os: osx
install: []
script: &mactest
- make all
# The styles=develop avoids some weird problems on OSX
- make test styles=develop
- name: "macOS/Xcode 9/Shared/Mac-like"
os: osx
osx_image: xcode9
env:
- BUILD_DIR=macosx
- NO_DIRECT_CONFIGURE=1
- os: osx
install: []
script: *mactest
- name: "macOS/Xcode 10/Shared/Mac-like"
os: osx
osx_image: xcode10.2
env:
- BUILD_DIR=macosx
- NO_DIRECT_CONFIGURE=1
### C builds not currently supported on Windows instances
# - os: windows
# env:
# - BUILD_DIR=win
### ... so proxy with a Mingw cross-compile
# Test with mingw-w64 (32 bit)
- os: linux
install: []
script: *mactest
# Test with mingw-w64 (32 bit) cross-compile
# Doesn't run tests because wine is only an imperfect Windows emulation
- name: "Linux-cross-Windows-32/GCC/Shared/no test"
os: linux
dist: xenial
compiler: i686-w64-mingw32-gcc
addons:
addons: &mingw32
apt:
packages:
- gcc-mingw-w64-base
@@ -109,28 +127,28 @@ matrix:
env:
- BUILD_DIR=win
- CFGOPT=--host=i686-w64-mingw32
- NO_DIRECT_TEST=1
- os: linux
script: &crosstest
- make all
- make tcltest
# Include a high visibility marker that tests are skipped outright
- >
echo "`tput setaf 3`SKIPPED TEST: CROSS COMPILING`tput sgr0`"
- name: "Linux-cross-Windows-32/GCC/Static/no test"
os: linux
dist: xenial
compiler: i686-w64-mingw32-gcc
addons:
apt:
packages:
- gcc-mingw-w64-base
- binutils-mingw-w64-i686
- gcc-mingw-w64-i686
- gcc-mingw-w64
- gcc-multilib
- wine
addons: *mingw32
env:
- BUILD_DIR=win
- CFGOPT="--host=i686-w64-mingw32 --disable-shared"
- NO_DIRECT_TEST=1
script: *crosstest
# Test with mingw-w64 (64 bit)
- os: linux
# Doesn't run tests because wine is only an imperfect Windows emulation
- name: "Linux-cross-Windows-64/GCC/Shared/no test"
os: linux
dist: xenial
compiler: x86_64-w64-mingw32-gcc
addons:
addons: &mingw64
apt:
packages:
- gcc-mingw-w64-base
@@ -141,29 +159,71 @@ matrix:
env:
- BUILD_DIR=win
- CFGOPT="--host=x86_64-w64-mingw32 --enable-64bit"
- NO_DIRECT_TEST=1
- os: linux
script: *crosstest
- name: "Linux-cross-Windows-64/GCC/Static/no test"
os: linux
dist: xenial
compiler: x86_64-w64-mingw32-gcc
addons:
apt:
packages:
- gcc-mingw-w64-base
- binutils-mingw-w64-x86-64
- gcc-mingw-w64-x86-64
- gcc-mingw-w64
- wine
addons: *mingw64
env:
- BUILD_DIR=win
- CFGOPT="--host=x86_64-w64-mingw32 --enable-64bit --disable-shared"
- NO_DIRECT_TEST=1
script: *crosstest
# Test on Windows with GCC native
- name: "Windows/GCC/Shared"
os: windows
compiler: gcc
env:
- BUILD_DIR=win
- CFGOPT="--enable-64bit --enable-threads"
before_install: &cygwinSetup
- choco install cyg-get
- cyg-get make
- cd ${BUILD_DIR}
install:
- ./configure ${CFGOPT} --prefix=$HOME
# for debugging only
- cat Makefile
- name: "Windows/GCC/Unshared"
os: windows
compiler: gcc
env:
- BUILD_DIR=win
- CFGOPT="--enable-64bit --enable-threads --disable-shared"
before_install: *cygwinSetup
# Test on Windows with MSVC native
- name: "Windows/MSVC/Shared"
os: windows
compiler: cl
env: &vcenv
- BUILD_DIR=win
- VCDIR="/C/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Auxiliary/Build"
before_install: &vcpreinst
- PATH="$PATH:$VCDIR"
- cd ${BUILD_DIR}
install: []
script: &vctest
- cmd.exe /C 'vcvarsall.bat x64 && nmake -f makefile.vc all'
- cmd.exe /C 'vcvarsall.bat x64 && nmake -f makefile.vc tcltest'
- cmd.exe /C 'vcvarsall.bat x64 && nmake -f makefile.vc test'
- name: "Windows/MSVC/Unshared"
os: windows
compiler: cl
env: *vcenv
before_install: *vcpreinst
install: []
script: &vctest
- cmd.exe /C 'vcvarsall.bat x64 && nmake OPTS=static -f makefile.vc all'
- cmd.exe /C 'vcvarsall.bat x64 && nmake OPTS=static -f makefile.vc tcltest'
- cmd.exe /C 'vcvarsall.bat x64 && nmake OPTS=static -f makefile.vc test'
before_install:
- export ERROR_ON_FAILURES=1
- cd ${BUILD_DIR}
install:
- test -n "$NO_DIRECT_CONFIGURE" || ./configure ${CFGOPT}
- ./configure ${CFGOPT} --prefix=$HOME
before_script:
- export ERROR_ON_FAILURES=1
script:
- make
# The styles=develop avoids some weird problems on OSX
- test -n "$NO_DIRECT_TEST" || make test styles=develop
- make all
- make tcltest
- make test
-185
View File
@@ -1,185 +0,0 @@
README: Tcl
This is the Tcl 8.6.9 source distribution.
http://sourceforge.net/projects/tcl/files/Tcl/
You can get any source release of Tcl from the URL above.
Contents
--------
1. Introduction
2. Documentation
3. Compiling and installing Tcl
4. Development tools
5. Tcl newsgroup
6. The Tcler's Wiki
7. Mailing lists
8. Support and Training
9. Tracking Development
10. Thank You
1. Introduction
---------------
Tcl provides a powerful platform for creating integration applications that
tie together diverse applications, protocols, devices, and frameworks.
When paired with the Tk toolkit, Tcl provides the fastest and most powerful
way to create GUI applications that run on PCs, Unix, and Mac OS X.
Tcl can also be used for a variety of web-related tasks and for creating
powerful command languages for applications.
Tcl is maintained, enhanced, and distributed freely by the Tcl community.
Source code development and tracking of bug reports and feature requests
takes place at:
http://core.tcl-lang.org/
Tcl/Tk release and mailing list services are hosted by SourceForge:
http://sourceforge.net/projects/tcl/
with the Tcl Developer Xchange hosted at:
http://www.tcl-lang.org/
Tcl is a freely available open source package. You can do virtually
anything you like with it, such as modifying it, redistributing it,
and selling it either in whole or in part. See the file
"license.terms" for complete information.
2. Documentation
----------------
Extensive documentation is available at our website.
The home page for this release, including new features, is
http://www.tcl-lang.org/software/tcltk/8.6.html
Detailed release notes can be found at the file distributions page
by clicking on the relevant version.
http://sourceforge.net/projects/tcl/files/Tcl/
Information about Tcl itself can be found at
http://www.tcl-lang.org/about/
There have been many Tcl books on the market. Many are mentioned in the Wiki:
http://wiki.tcl-lang.org/_/ref?N=25206
To view the complete set of reference manual entries for Tcl 8.6 online,
visit the URL:
http://www.tcl-lang.org/man/tcl8.6/
2a. Unix Documentation
----------------------
The "doc" subdirectory in this release contains a complete set of
reference manual entries for Tcl. Files with extension ".1" are for
programs (for example, tclsh.1); files with extension ".3" are for C
library procedures; and files with extension ".n" describe Tcl
commands. The file "doc/Tcl.n" gives a quick summary of the Tcl
language syntax. To print any of the man pages on Unix, cd to the
"doc" directory and invoke your favorite variant of troff using the
normal -man macros, for example
ditroff -man Tcl.n
to print Tcl.n. If Tcl has been installed correctly and your "man" program
supports it, you should be able to access the Tcl manual entries using the
normal "man" mechanisms, such as
man Tcl
2b. Windows Documentation
-------------------------
The "doc" subdirectory in this release contains a complete set of Windows
help files for Tcl. Once you install this Tcl release, a shortcut to the
Windows help Tcl documentation will appear in the "Start" menu:
Start | Programs | Tcl | Tcl Help
3. Compiling and installing Tcl
-------------------------------
There are brief notes in the unix/README, win/README, and macosx/README about
compiling on these different platforms. There is additional information
about building Tcl from sources at
http://www.tcl-lang.org/doc/howto/compile.html
4. Development tools
---------------------------
ActiveState produces a high quality set of commercial quality development
tools that is available to accelerate your Tcl application development.
Tcl Dev Kit builds on the earlier TclPro toolset and provides a debugger,
static code checker, single-file wrapping utility, bytecode compiler and
more. More information can be found at
http://www.ActiveState.com/Tcl
5. Tcl newsgroup
----------------
There is a USENET news group, "comp.lang.tcl", intended for the exchange of
information about Tcl, Tk, and related applications. The newsgroup is a
great place to ask general information questions. For bug reports, please
see the "Support and bug fixes" section below.
6. Tcl'ers Wiki
---------------
A Wiki-based open community site covering all aspects of Tcl/Tk is at:
http://wiki.tcl-lang.org/
It is dedicated to the Tcl programming language and its extensions. A
wealth of useful information can be found there. It contains code
snippets, references to papers, books, and FAQs, as well as pointers to
development tools, extensions, and applications. You can also recommend
additional URLs by editing the wiki yourself.
7. Mailing lists
----------------
Several mailing lists are hosted at SourceForge to discuss development or
use issues (like Macintosh and Windows topics). For more information and
to subscribe, visit:
http://sourceforge.net/projects/tcl/
and go to the Mailing Lists page.
8. Support and Training
------------------------
We are very interested in receiving bug reports, patches, and suggestions
for improvements. We prefer that you send this information to us as
tickets entered into our tracker at:
http://core.tcl-lang.org/tcl/reportlist
We will log and follow-up on each bug, although we cannot promise a
specific turn-around time. Enhancements may take longer and may not happen
at all unless there is widespread support for them (we're trying to
slow the rate at which Tcl/Tk turns into a kitchen sink). It's very
difficult to make incompatible changes to Tcl/Tk at this point, due to
the size of the installed base.
The Tcl community is too large for us to provide much individual support
for users. If you need help we suggest that you post questions to
comp.lang.tcl. We read the newsgroup and will attempt to answer esoteric
questions for which no one else is likely to know the answer. In addition,
see the following Web site for links to other organizations that offer
Tcl/Tk training:
http://wiki.tcl-lang.org/training
9. Tracking Development
-----------------------
Tcl is developed in public. To keep an eye on how Tcl is changing, see
http://core.tcl-lang.org/
10. Thank You
-------------
We'd like to express our thanks to the Tcl community for all the
helpful suggestions, bug reports, and patches we have received.
Tcl/Tk has improved vastly and will continue to do so with your help.
+148
View File
@@ -0,0 +1,148 @@
# README: Tcl
This is the **Tcl 8.6.9** source distribution.
You can get any source release of Tcl from [our distribution
site](https://sourceforge.net/projects/tcl/files/Tcl/).
[![Build Status](https://travis-ci.org/tcltk/tcl.svg?branch=core-8-6-branch)](https://travis-ci.org/tcltk/tcl)
## Contents
1. [Introduction](#intro)
2. [Documentation](#doc)
3. [Compiling and installing Tcl](#build)
4. [Development tools](#devtools)
5. [Tcl newsgroup](#complangtcl)
6. [The Tcler's Wiki](#wiki)
7. [Mailing lists](#email)
8. [Support and Training](#support)
9. [Tracking Development](#watch)
10. [Thank You](#thanks)
## <a id="intro">1.</a> Introduction
Tcl provides a powerful platform for creating integration applications that
tie together diverse applications, protocols, devices, and frameworks.
When paired with the Tk toolkit, Tcl provides the fastest and most powerful
way to create GUI applications that run on PCs, Unix, and Mac OS X.
Tcl can also be used for a variety of web-related tasks and for creating
powerful command languages for applications.
Tcl is maintained, enhanced, and distributed freely by the Tcl community.
Source code development and tracking of bug reports and feature requests
takes place at [core.tcl-lang.org](https://core.tcl-lang.org/).
Tcl/Tk release and mailing list services are [hosted by
SourceForge](https://sourceforge.net/projects/tcl/)
with the Tcl Developer Xchange hosted at
[www.tcl-lang.org](https://www.tcl-lang.org).
Tcl is a freely available open source package. You can do virtually
anything you like with it, such as modifying it, redistributing it,
and selling it either in whole or in part. See the file
`license.terms` for complete information.
## <a id="doc">2.</a> Documentation
Extensive documentation is available at our website.
The home page for this release, including new features, is
[here](https://www.tcl.tk/software/tcltk/8.6.html).
Detailed release notes can be found at the
[file distributions page](https://sourceforge.net/projects/tcl/files/Tcl/)
by clicking on the relevant version.
Information about Tcl itself can be found at the [Developer
Xchange](https://www.tcl-lang.org/about/).
There have been many Tcl books on the market. Many are mentioned in
[the Wiki](https://wiki.tcl-lang.org/_/ref?N=25206).
The complete set of reference manual entries for Tcl 8.6 is [online,
here](https://www.tcl-lang.org/man/tcl8.6/).
### <a id="doc.unix">2a.</a> Unix Documentation
The `doc` subdirectory in this release contains a complete set of
reference manual entries for Tcl. Files with extension "`.1`" are for
programs (for example, `tclsh.1`); files with extension "`.3`" are for C
library procedures; and files with extension "`.n`" describe Tcl
commands. The file "`doc/Tcl.n`" gives a quick summary of the Tcl
language syntax. To print any of the man pages on Unix, cd to the
"doc" directory and invoke your favorite variant of troff using the
normal -man macros, for example
groff -man -Tpdf Tcl.n >output.pdf
to print Tcl.n to PDF. If Tcl has been installed correctly and your "man" program
supports it, you should be able to access the Tcl manual entries using the
normal "man" mechanisms, such as
man Tcl
### <a id="doc.win">2b.</a> Windows Documentation
The "doc" subdirectory in this release contains a complete set of Windows
help files for Tcl. Once you install this Tcl release, a shortcut to the
Windows help Tcl documentation will appear in the "Start" menu:
Start | Programs | Tcl | Tcl Help
## <a id="build">3.</a> Compiling and installing Tcl
There are brief notes in the `unix/README`, `win/README`, and `macosx/README`
about compiling on these different platforms. There is additional information
about building Tcl from sources
[online](https://www.tcl-lang.org/doc/howto/compile.html).
## <a id="devtools">4.</a> Development tools
ActiveState produces a high quality set of commercial quality development
tools that is available to accelerate your Tcl application development.
Tcl Dev Kit builds on the earlier TclPro toolset and provides a debugger,
static code checker, single-file wrapping utility, bytecode compiler and
more. More information can be found at
http://www.ActiveState.com/Tcl
## <a id="complangtcl">5.</a> Tcl newsgroup
There is a USENET news group, "`comp.lang.tcl`", intended for the exchange of
information about Tcl, Tk, and related applications. The newsgroup is a
great place to ask general information questions. For bug reports, please
see the "Support and bug fixes" section below.
## <a id="wiki">6.</a> Tcl'ers Wiki
There is a [wiki-based open community site](https://wiki.tcl-lang.org/)
covering all aspects of Tcl/Tk.
It is dedicated to the Tcl programming language and its extensions. A
wealth of useful information can be found there. It contains code
snippets, references to papers, books, and FAQs, as well as pointers to
development tools, extensions, and applications. You can also recommend
additional URLs by editing the wiki yourself.
## <a id="email">7.</a> Mailing lists
Several mailing lists are hosted at SourceForge to discuss development or use
issues (like Macintosh and Windows topics). For more information and to
subscribe, visit [here](https://sourceforge.net/projects/tcl/) and go to the
Mailing Lists page.
## <a id="support">8.</a> Support and Training
We are very interested in receiving bug reports, patches, and suggestions for
improvements. We prefer that you send this information to us as tickets
entered into [our issue tracker](https://core.tcl-lang.org/tcl/reportlist).
We will log and follow-up on each bug, although we cannot promise a
specific turn-around time. Enhancements may take longer and may not happen
at all unless there is widespread support for them (we're trying to
slow the rate at which Tcl/Tk turns into a kitchen sink). It's very
difficult to make incompatible changes to Tcl/Tk at this point, due to
the size of the installed base.
The Tcl community is too large for us to provide much individual support for
users. If you need help we suggest that you post questions to `comp.lang.tcl`
or ask a question on [Stack
Overflow](https://stackoverflow.com/questions/tagged/tcl). We read the
newsgroup and will attempt to answer esoteric questions for which no one else
is likely to know the answer. In addition, see the wiki for [links to other
organizations](https://wiki.tcl-lang.org/training) that offer Tcl/Tk training.
## <a id="watch">9.</a> Tracking Development
Tcl is developed in public. You can keep an eye on how Tcl is changing at
[core.tcl-lang.org](https://core.tcl-lang.org/).
## <a id="thanks">10.</a> Thank You
We'd like to express our thanks to the Tcl community for all the
helpful suggestions, bug reports, and patches we have received.
Tcl/Tk has improved vastly and will continue to do so with your help.
+16 -2
View File
@@ -79,7 +79,9 @@ The number of elements in the \fIobjv\fR array.
The arguments to the command to create the instance of the class.
.AP int skip in
The number of arguments at the start of the argument array, \fIobjv\fR, that
are not arguments to any constructors.
are not arguments to any constructors. This allows the generation of correct
error messages even when complicated calling patterns are used (e.g., via the
\fBnext\fR command).
.AP Tcl_ObjectMetadataType *metaTypePtr in
The type of \fImetadata\fR being set with \fBTcl_ClassSetMetadata\fR or
retrieved with \fBTcl_ClassGetMetadata\fR.
@@ -109,7 +111,9 @@ may be retrieved using the \fBTcl_GetObjectCommand\fR function, the name of
the object (and hence the name of the command) with \fBTcl_GetObjectName\fR,
and the namespace may be retrieved using the \fBTcl_GetObjectNamespace\fR
function. Note that the Tcl_Obj reference returned by \fBTcl_GetObjectName\fR
is a shared reference.
is a shared reference. You can also get whether the object has been marked for
deletion with \fBTcl_ObjectDeleted\fR (it returns true if deletion of the
object has begun); this can be useful during the processing of methods.
.PP
Instances of classes are created using \fBTcl_NewObjectInstance\fR, which
creates an object from any class (and which is internally called by both
@@ -121,6 +125,16 @@ created object, or NULL if the creation failed (when an error message will be
left in the interpreter result). In addition, objects may be copied by using
\fBTcl_CopyObjectInstance\fR which creates a copy of an object without running
any constructors.
.PP
Note that the lifetime management of objects is handled internally within
TclOO, and does not use \fBTcl_Preserve\fR. \fIIt is not safe to put a
Tcl_Object handle in a C structure with a lifespan different to the object;\fR
you should use the object's command name (as retrieved with
\fBTcl_GetObjectName\fR) instead. It is safe to use a Tcl_Object handle for
the lifespan of a call of a method on that object; handles do not become
invalid while there is an outstanding call on their object (even if the only
operation guaranteed to be safe on them is \fBTcl_ObjectDeleted\fR; the other
operations are only guaranteed to work on non-deleted objects).
.SH "OBJECT AND CLASS METADATA"
.PP
Every object and every class may have arbitrary amounts of metadata attached
+4 -4
View File
@@ -331,11 +331,11 @@ trace procedures will always be invoked.
.SH "RESTRICTIONS"
.PP
A trace procedure can be called at any time, even when there
is a partially formed result in the interpreter's result area. If
are partially formed results stored in the interpreter. If
the trace procedure does anything that could damage this result (such
as calling \fBTcl_Eval\fR) then it must save the original values of
the interpreter's \fBresult\fR and \fBfreeProc\fR fields and restore
them before it returns.
as calling \fBTcl_Eval\fR) then it must use the \fBTcl_SaveInterpState\fR
and related routines to save and restore the original state of
the interpreter before it returns.
.SH "UNDEFINED VARIABLES"
.PP
It is legal to set a trace on an undefined variable.
+29 -6
View File
@@ -106,7 +106,7 @@ Then the command on the left side of each of the lines below
will produce the value on the right side of the line:
.PP
.CS
.ta 6c
.ta 9c
\fBexpr\fR 3.1 + $a \fI6.1\fR
\fBexpr\fR 2 + "$a.$b" \fI5.6\fR
\fBexpr\fR 4*[llength "6 2"] \fI8\fR
@@ -201,18 +201,23 @@ Bit-wise OR. Valid for integer operands only.
Logical AND. Produces a 1 result if both operands are non-zero,
0 otherwise.
Valid for boolean and numeric (integers or floating-point) operands only.
This operator evaluates lazily; it only evaluates its second operand if it
must in order to determine its result.
.TP 20
\fB||\fR
.
Logical OR. Produces a 0 result if both operands are zero, 1 otherwise.
Valid for boolean and numeric (integers or floating-point) operands only.
This operator evaluates lazily; it only evaluates its second operand if it
must in order to determine its result.
.TP 20
\fIx\fB?\fIy\fB:\fIz\fR
\fIx \fB?\fI y \fB:\fI z\fR
.
If-then-else, as in C. If \fIx\fR
evaluates to non-zero, then the result is the value of \fIy\fR.
Otherwise the result is the value of \fIz\fR.
The \fIx\fR operand must have a boolean or numeric value.
This operator evaluates lazily; it evaluates only one of \fIy\fR or \fIz\fR.
.PP
See the C manual for more details on the results
produced by each operator.
@@ -222,6 +227,7 @@ of the \fBpow\fR function (after any type conversions.)
All of the binary operators but exponentiation group left-to-right
within the same precedence level; exponentiation groups right-to-left. For example, the command
.PP
.PP
.CS
\fBexpr\fR {4*2 < 7}
.CE
@@ -259,7 +265,7 @@ before invoking the \fBexpr\fR command.
.PP
When the expression parser encounters a mathematical function
such as \fBsin($x)\fR, it replaces it with a call to an ordinary
Tcl function in the \fBtcl::mathfunc\fR namespace. The processing
Tcl command in the \fBtcl::mathfunc\fR namespace. The processing
of an expression such as:
.PP
.CS
@@ -391,9 +397,11 @@ set b {$a + 2}
.CE
.PP
return 11, not a multiple of 4.
This is because the Tcl parser will first substitute \fB$a + 2\fR for
the variable \fBb\fR,
then the \fBexpr\fR command will evaluate the expression \fB$a + 2*4\fR.
This is because the Tcl parser will first substitute
.QW "\fB$a + 2\fR"
for the variable \fBb\fR,
then the \fBexpr\fR command will evaluate the expression
.QW "\fB$a + 2*4\fR" .
.PP
Most expressions do not require a second round of substitutions.
Either they are enclosed in braces or, if not,
@@ -407,6 +415,21 @@ The most expensive code is required for
unbraced expressions that contain command substitutions.
These expressions must be implemented by generating new code
each time the expression is executed.
.PP
If it is necessary to include a non-constant expression string within the
wider context of an otherwise-constant expression, the most efficient
technique is to put the varying part inside a recursive \fBexpr\fR, as this at
least allows for the compilation of the outer part, though it does mean that
the varying part must itself be evaluated as a separate expression. Thus, in
this example the result is 20 and the outer expression benefits from fully
cached bytecode compilation.
.PP
.CS
set a 3
set b {$a + 2}
\fBexpr\fR {[\fBexpr\fR $b] * 4}
.CE
.PP
When the expression is unbraced to allow the substitution of a function or
operator, consider using the commands documented in the \fBmathfunc\fR(n) or
\fBmathop\fR(n) manual pages directly instead.
+65 -48
View File
@@ -9,16 +9,26 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
timerate \- Time-related execution resp. performance measurement of a script
timerate \- Calibrated performance measurements of script execution time
.SH SYNOPSIS
\fBtimerate \fIscript\fR \fI?time ?max-count??\fR
\fBtimerate \fIscript\fR ?\fItime\fR? ?\fImax-count\fR?
.sp
\fBtimerate \fI?-direct?\fR \fI?-overhead double?\fR \fIscript\fR \fI?time ?max-count??\fR
\fBtimerate \fR?\fB\-direct\fR? ?\fB\-overhead\fI double\fR? \fIscript\fR ?\fItime\fR? ?\fImax-count\fR?
.sp
\fBtimerate \fI?-calibrate?\fR \fI?-direct?\fR \fIscript\fR \fI?time ?max-count??\fR
\fBtimerate \fR?\fB\-calibrate\fR? ?\fB\-direct\fR? \fIscript\fR ?\fItime\fR? ?\fImax-count\fR?
.BE
.SH DESCRIPTION
.PP
The \fBtimerate\fR command does calibrated performance measurement of a Tcl
command or script, \fIscript\fR. The \fIscript\fR should be written so that it
can be executed multiple times during the performance measurement process.
Time is measured in elapsed time using the finest timer resolution as possible,
not CPU time; if \fIscript\fR interacts with the OS, the cost of that
interaction is included.
This command may be used to provide information as to how well a script or
Tcl command is performing, and can help determine bottlenecks and fine-tune
application performance.
.PP
The first and second form will evaluate \fIscript\fR until the interval
\fItime\fR given in milliseconds elapses, or for 1000 milliseconds (1 second)
if \fItime\fR is not specified.
@@ -28,47 +38,48 @@ by the maximal number of iterations to evaluate the script.
If \fImax-count\fR is specified, the evalution will stop either this count of
iterations is reached or the time is exceeded.
.sp
It will then return a canonical tcl-list of the form
It will then return a canonical tcl-list of the form:
.PP
.CS
\fB0.095977 \(mcs/# 52095836 # 10419167 #/sec 5000.000 nett-ms\fR
\fB0.095977 \(mcs/# 52095836 # 10419167 #/sec 5000.000 net-ms\fR
.CE
.PP
which indicates:
.IP \(bu
.IP \(bu 3
the average amount of time required per iteration, in microseconds ([\fBlindex\fR $result 0])
.IP \(bu
.IP \(bu 3
the count how many times it was executed ([\fBlindex\fR $result 2])
.IP \(bu
.IP \(bu 3
the estimated rate per second ([\fBlindex\fR $result 4])
.IP \(bu
.IP \(bu 3
the estimated real execution time without measurement overhead ([\fBlindex\fR $result 6])
.PP
Time is measured in elapsed time using the finest timer resolution as possible,
not CPU time.
This command may be used to provide information as to how well the script or a
tcl-command is performing and can help determine bottlenecks and fine-tune
application performance.
The following options may be supplied to the \fBtimerate\fR command:
.TP
\fI-calibrate\fR
\fB\-calibrate\fR
.
To measure very fast scripts as exact as posible the calibration process
To measure very fast scripts as exactly as possible, a calibration process
may be required.
The \fI-calibrate\fR option is used to calibrate timerate, calculating the
estimated overhead of the given script as the default overhead for future
invocations of the \fBtimerate\fR command. If the \fItime\fR parameter is not
specified, the calibrate procedure runs for up to 10 seconds.
The \fB\-calibrate\fR option is used to calibrate \fBtimerate\fR itself,
calculating the estimated overhead of the given script as the default overhead
for future invocations of the \fBtimerate\fR command. If the \fItime\fR
parameter is not specified, the calibrate procedure runs for up to 10 seconds.
.RS
.PP
Note that calibration is not thread safe in the current implementation.
.RE
.TP
\fI-overhead double\fR
\fB\-overhead \fIdouble\fR
.
The \fI-overhead\fR parameter supplies an estimate (in microseconds) of the
The \fB\-overhead\fR parameter supplies an estimate (in microseconds) of the
measurement overhead of each iteration of the tested script. This quantity
will be subtracted from the measured time prior to reporting results.
will be subtracted from the measured time prior to reporting results. This can
be useful for removing the cost of interpreter state reset commands from the
script being measured.
.TP
\fI-direct\fR
\fB\-direct\fR
.
The \fI-direct\fR option causes direct execution of the supplied script,
The \fB-direct\fR option causes direct execution of the supplied script,
without compilation, in a manner similar to the \fBtime\fR command. It can be
used to measure the cost of \fBTcl_EvalObjEx\fR, of the invocation of canonical
lists, and of the uncompiled versions of bytecoded commands.
@@ -76,31 +87,33 @@ lists, and of the uncompiled versions of bytecoded commands.
As opposed to the \fBtime\fR commmand, which runs the tested script for a fixed
number of iterations, the timerate command runs it for a fixed time.
Additionally, the compiled variant of the script will be used during the entire
measurement, as if the script were part of a compiled procedure, if the \fI-direct\fR
measurement, as if the script were part of a compiled procedure, if the \fB\-direct\fR
option is not specified. The fixed time period and possibility of compilation allow
for more precise results and prevent very long execution times by slow scripts, making
it practical for measuring scripts with highly uncertain execution times.
.SH EXAMPLE
.SH EXAMPLES
Estimate how fast it takes for a simple Tcl \fBfor\fR loop (including
operations on variable \fIi\fR) to count to a ten:
operations on variable \fIi\fR) to count to ten:
.PP
.CS
# calibrate:
timerate -calibrate {}
# measure:
timerate { for {set i 0} {$i<10} {incr i} {} } 5000
\fI# calibrate\fR
\fBtimerate\fR -calibrate {}
\fI# measure\fR
\fBtimerate\fR { for {set i 0} {$i<10} {incr i} {} } 5000
.CE
.PP
Estimate how fast it takes for a simple Tcl \fBfor\fR loop, ignoring the
overhead for to perform ten iterations, ignoring the overhead of the management
of the variable that controls the loop:
overhead of the management of the variable that controls the loop:
.PP
.CS
# calibrate for overhead of variable operations:
set i 0; timerate -calibrate {expr {$i<10}; incr i} 1000
# measure:
timerate { for {set i 0} {$i<10} {incr i} {} } 5000
\fI# calibrate for overhead of variable operations\fR
set i 0; \fBtimerate\fR -calibrate {expr {$i<10}; incr i} 1000
\fI# measure\fR
\fBtimerate\fR {
for {set i 0} {$i<10} {incr i} {}
} 5000
.CE
.PP
Estimate the speed of calculating the hour of the day using \fBclock format\fR only,
@@ -108,14 +121,18 @@ ignoring overhead of the portion of the script that prepares the time for it to
calculate:
.PP
.CS
# calibrate:
timerate -calibrate {}
# estimate overhead:
\fI# calibrate\fR
\fBtimerate\fR -calibrate {}
\fI# estimate overhead\fR
set tm 0
set ovh [lindex [timerate { incr tm [expr {24*60*60}] }] 0]
# measure using esimated overhead:
set ovh [lindex [\fBtimerate\fR {
incr tm [expr {24*60*60}]
}] 0]
\fI# measure using estimated overhead\fR
set tm 0
timerate -overhead $ovh {
\fBtimerate\fR -overhead $ovh {
clock format $tm -format %H
incr tm [expr {24*60*60}]; # overhead for this is ignored
} 5000
@@ -123,7 +140,7 @@ timerate -overhead $ovh {
.SH "SEE ALSO"
time(n)
.SH KEYWORDS
script, timerate, time
performance measurement, script, time
.\" Local Variables:
.\" mode: nroff
.\" End:
+2 -1
View File
@@ -513,6 +513,7 @@ static const unsigned char NonThrowingByteCodes[] = {
INST_PUSH1, INST_PUSH4, INST_POP, INST_DUP, /* 1-4 */
INST_JUMP1, INST_JUMP4, /* 34-35 */
INST_END_CATCH, INST_PUSH_RESULT, INST_PUSH_RETURN_CODE, /* 70-72 */
INST_STR_EQ, INST_STR_NEQ, INST_STR_CMP, INST_STR_LEN, /* 73-76 */
INST_LIST, /* 79 */
INST_OVER, /* 95 */
INST_PUSH_RETURN_OPTIONS, /* 108 */
@@ -2255,7 +2256,7 @@ GetListIndexOperand(
if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &value) != TCL_OK) {
return TCL_ERROR;
}
/* Convert to an integer, advance to the next token and return. */
/*
* NOTE: Indexing a list with an index before it yields the
+147 -47
View File
@@ -158,6 +158,7 @@ static Tcl_NRPostProc Dispatch;
static Tcl_ObjCmdProc NRCoroInjectObjCmd;
static Tcl_NRPostProc NRPostInvoke;
static Tcl_ObjCmdProc CoroTypeObjCmd;
MODULE_SCOPE const TclStubs tclStubs;
@@ -845,8 +846,11 @@ Tcl_CreateInterp(void)
TclNRAssembleObjCmd, NULL, NULL);
cmdPtr->compileProc = &TclCompileAssembleCmd;
/* Coroutine monkeybusiness */
Tcl_NRCreateCommand(interp, "::tcl::unsupported::inject", NULL,
NRCoroInjectObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tcl::unsupported::corotype",
CoroTypeObjCmd, NULL, NULL);
/* Create an unsupported command for timerate */
Tcl_CreateObjCommand(interp, "::tcl::unsupported::timerate",
@@ -2109,14 +2113,16 @@ Tcl_CreateCommand(
break;
}
/* An existing command conflicts. Try to delete it.. */
/*
* An existing command conflicts. Try to delete it...
*/
cmdPtr = Tcl_GetHashValue(hPtr);
/*
* Be careful to preserve
* any existing import links so we can restore them down below. That
* way, you can redefine a command and its import status will remain
* intact.
* Be careful to preserve any existing import links so we can restore
* them down below. That way, you can redefine a command and its
* import status will remain intact.
*/
cmdPtr->refCount++;
@@ -2136,16 +2142,15 @@ Tcl_CreateCommand(
if (!isNew) {
/*
* If the deletion callback recreated the command, just throw away
* the new command (if we try to delete it again, we could get
* stuck in an infinite loop).
* If the deletion callback recreated the command, just throw away the
* new command (if we try to delete it again, we could get stuck in an
* infinite loop).
*/
ckfree(Tcl_GetHashValue(hPtr));
}
if (!deleted) {
/*
* Command resolvers (per-interp, per-namespace) might have resolved
* to a command for the given namespace scope with this command not
@@ -2324,16 +2329,18 @@ TclCreateObjCommandInNs (
break;
}
/*
* An existing command conflicts. Try to delete it...
*/
/* An existing command conflicts. Try to delete it.. */
cmdPtr = Tcl_GetHashValue(hPtr);
/*
* [***] This is wrong. See Tcl Bug a16752c252.
* However, this buggy behavior is kept under particular
* circumstances to accommodate deployed binaries of the
* "tclcompiler" program. http://sourceforge.net/projects/tclpro/
* that crash if the bug is fixed.
* However, this buggy behavior is kept under particular circumstances
* to accommodate deployed binaries of the "tclcompiler" program
* <http://sourceforge.net/projects/tclpro/> that crash if the bug is
* fixed.
*/
if (cmdPtr->objProc == TclInvokeStringCommand
@@ -2357,7 +2364,10 @@ TclCreateObjCommandInNs (
cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
}
/* Make sure namespace doesn't get deallocated. */
/*
* Make sure namespace doesn't get deallocated.
*/
cmdPtr->nsPtr->refCount++;
Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
@@ -4315,15 +4325,22 @@ EvalObjvCore(
reresolve:
assert(cmdPtr == NULL);
if (preCmdPtr) {
/* Caller gave it to us */
/*
* Caller gave it to us.
*/
if (!(preCmdPtr->flags & CMD_IS_DELETED)) {
/* So long as it exists, use it. */
/*
* So long as it exists, use it.
*/
cmdPtr = preCmdPtr;
} else if (flags & TCL_EVAL_NORESOLVE) {
/*
* When it's been deleted, and we're told not to attempt
* resolving it ourselves, all we can do is raise an error.
* When it's been deleted, and we're told not to attempt resolving
* it ourselves, all we can do is raise an error.
*/
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"attempt to invoke a deleted command"));
Tcl_SetErrorCode(interp, "TCL", "EVAL", "DELETEDCOMMAND", NULL);
@@ -4339,14 +4356,12 @@ EvalObjvCore(
if (enterTracesDone || iPtr->tracePtr
|| (cmdPtr->flags & CMD_HAS_EXEC_TRACES)) {
Tcl_Obj *commandPtr = TclGetSourceFromFrame(
flags & TCL_EVAL_SOURCE_IN_FRAME ? iPtr->cmdFramePtr : NULL,
objc, objv);
Tcl_IncrRefCount(commandPtr);
if (!enterTracesDone) {
int code = TEOV_RunEnterTraces(interp, &cmdPtr, commandPtr,
objc, objv);
@@ -4354,10 +4369,10 @@ EvalObjvCore(
* Send any exception from enter traces back as an exception
* raised by the traced command.
* TODO: Is this a bug? Letting an execution trace BREAK or
* CONTINUE or RETURN in the place of the traced command?
* Would either converting all exceptions to TCL_ERROR, or
* just swallowing them be better? (Swallowing them has the
* problem of permanently hiding program errors.)
* CONTINUE or RETURN in the place of the traced command? Would
* either converting all exceptions to TCL_ERROR, or just
* swallowing them be better? (Swallowing them has the problem of
* permanently hiding program errors.)
*/
if (code != TCL_OK) {
@@ -4366,9 +4381,8 @@ EvalObjvCore(
}
/*
* If the enter traces made the resolved cmdPtr unusable, go
* back and resolve again, but next time don't run enter
* traces again.
* If the enter traces made the resolved cmdPtr unusable, go back
* and resolve again, but next time don't run enter traces again.
*/
if (cmdPtr == NULL) {
@@ -4379,9 +4393,9 @@ EvalObjvCore(
}
/*
* Schedule leave traces. Raise the refCount on the resolved
* cmdPtr, so that when it passes to the leave traces we know
* it's still valid.
* Schedule leave traces. Raise the refCount on the resolved cmdPtr,
* so that when it passes to the leave traces we know it's still
* valid.
*/
cmdPtr->refCount++;
@@ -4449,8 +4463,6 @@ TclNRRunCallbacks(
* are to be run. */
{
Interp *iPtr = (Interp *) interp;
NRE_callback *callbackPtr;
Tcl_NRPostProc *procPtr;
/*
* If the interpreter has a non-empty string result, the result object is
@@ -4466,11 +4478,14 @@ TclNRRunCallbacks(
(void) Tcl_GetObjResult(interp);
}
/* This is the trampoline. */
/*
* This is the trampoline.
*/
while (TOP_CB(interp) != rootPtr) {
callbackPtr = TOP_CB(interp);
procPtr = callbackPtr->procPtr;
NRE_callback *callbackPtr = TOP_CB(interp);
Tcl_NRPostProc *procPtr = callbackPtr->procPtr;
TOP_CB(interp) = callbackPtr->nextPtr;
result = procPtr(callbackPtr->data, interp, result);
TCLNR_FREE(interp, callbackPtr);
@@ -6676,14 +6691,17 @@ TclNRInvoke(
}
cmdPtr = Tcl_GetHashValue(hPtr);
/* Avoid the exception-handling brain damage when numLevels == 0 . */
/*
* Avoid the exception-handling brain damage when numLevels == 0
*/
iPtr->numLevels++;
Tcl_NRAddCallback(interp, NRPostInvoke, NULL, NULL, NULL, NULL);
/*
* Normal command resolution of objv[0] isn't going to find cmdPtr.
* That's the whole point of **hidden** commands. So tell the
* Eval core machinery not to even try (and risk finding something wrong).
* That's the whole point of **hidden** commands. So tell the Eval core
* machinery not to even try (and risk finding something wrong).
*/
return TclNREvalObjv(interp, objc, objv, TCL_EVAL_NORESOLVE, cmdPtr);
@@ -7749,7 +7767,7 @@ ExprRandFunc(
iPtr->flags |= RAND_SEED_INITIALIZED;
/*
* To ensure different seeds in different threads (bug #416643),
* To ensure different seeds in different threads (bug #416643),
* take into consideration the thread this interp is running in.
*/
@@ -8065,13 +8083,21 @@ TclDTraceInfo(
Tcl_DictObjGet(NULL, info, *k++, &val);
args[i] = val ? TclGetString(val) : NULL;
}
/* no "proc" -> use "lambda" */
/*
* no "proc" -> use "lambda"
*/
if (!args[2]) {
Tcl_DictObjGet(NULL, info, *k, &val);
args[2] = val ? TclGetString(val) : NULL;
}
k++;
/* no "class" -> use "object" */
/*
* no "class" -> use "object"
*/
if (!args[5]) {
Tcl_DictObjGet(NULL, info, *k, &val);
args[5] = val ? TclGetString(val) : NULL;
@@ -8424,8 +8450,10 @@ TclNRTailcallObjCmd(
Tcl_Obj *listPtr, *nsObjPtr;
Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
/* The tailcall data is in a Tcl list: the first element is the
* namespace, the rest the command to be tailcalled. */
/*
* The tailcall data is in a Tcl list: the first element is the
* namespace, the rest the command to be tailcalled.
*/
nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
listPtr = Tcl_NewListObj(objc, objv);
@@ -8875,6 +8903,75 @@ TclNREvalList(
return TclNREvalObjv(interp, objc, objv, 0, NULL);
}
/*
*----------------------------------------------------------------------
*
* CoroTypeObjCmd --
*
* Implementation of [::tcl::unsupported::corotype] command.
*
*----------------------------------------------------------------------
*/
static int
CoroTypeObjCmd(
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[])
{
Command *cmdPtr;
CoroutineData *corPtr;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "coroName");
return TCL_ERROR;
}
/*
* Look up the coroutine.
*/
cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[1]);
if ((!cmdPtr) || (cmdPtr->nreProc != TclNRInterpCoroutine)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"can only get coroutine type of a coroutine", -1));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COROUTINE",
TclGetString(objv[1]), NULL);
return TCL_ERROR;
}
/*
* An active coroutine is "active". Can't tell what it might do in the
* future.
*/
corPtr = cmdPtr->objClientData;
if (!COR_IS_SUSPENDED(corPtr)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("active", -1));
return TCL_OK;
}
/*
* Inactive coroutines are classified by the (effective) command used to
* suspend them, which matters when you're injecting a probe.
*/
switch (corPtr->nargs) {
case COROUTINE_ARGUMENTS_SINGLE_OPTIONAL:
Tcl_SetObjResult(interp, Tcl_NewStringObj("yield", -1));
return TCL_OK;
case COROUTINE_ARGUMENTS_ARBITRARY:
Tcl_SetObjResult(interp, Tcl_NewStringObj("yieldto", -1));
return TCL_OK;
default:
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"unknown coroutine type", -1));
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "BAD_TYPE", NULL);
return TCL_ERROR;
}
}
/*
*----------------------------------------------------------------------
*
@@ -9108,9 +9205,12 @@ TclNRCoroutineObjCmd(
TclNRAddCallback(interp, NRCoroutineExitCallback, corPtr,
NULL, NULL, NULL);
/* ensure that the command is looked up in the correct namespace */
/*
* Ensure that the command is looked up in the correct namespace.
*/
iPtr->lookupNsPtr = lookupNsPtr;
Tcl_NREvalObj(interp, Tcl_NewListObj(objc-2, objv+2), 0);
Tcl_NREvalObj(interp, Tcl_NewListObj(objc - 2, objv + 2), 0);
iPtr->numLevels--;
SAVE_CONTEXT(corPtr->running);
+82 -62
View File
@@ -318,10 +318,10 @@ Tcl_DbNewByteArrayObj(
void
Tcl_SetByteArrayObj(
Tcl_Obj *objPtr, /* Object to initialize as a ByteArray. */
const unsigned char *bytes, /* The array of bytes to use as the new
value. May be NULL even if length > 0. */
const unsigned char *bytes, /* The array of bytes to use as the new value.
* May be NULL even if length > 0. */
int length) /* Length of the array of bytes, which must
be >= 0. */
* be >= 0. */
{
ByteArray *byteArrayPtr;
@@ -639,7 +639,10 @@ TclAppendBytesToByteArray(
"TclAppendBytesToByteArray");
}
if (len == 0) {
/* Append zero bytes is a no-op. */
/*
* Append zero bytes is a no-op.
*/
return;
}
if (objPtr->typePtr != &tclByteArrayType) {
@@ -661,12 +664,18 @@ TclAppendBytesToByteArray(
int attempt;
if (needed <= INT_MAX/2) {
/* Try to allocate double the total space that is needed. */
/*
* Try to allocate double the total space that is needed.
*/
attempt = 2 * needed;
ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
}
if (ptr == NULL) {
/* Try to allocate double the increment that is needed (plus). */
/*
* Try to allocate double the increment that is needed (plus).
*/
unsigned int limit = INT_MAX - needed;
unsigned int extra = len + TCL_MIN_GROWTH;
int growth = (int) ((extra > limit) ? limit : extra);
@@ -675,7 +684,10 @@ TclAppendBytesToByteArray(
ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
}
if (ptr == NULL) {
/* Last chance: Try to allocate exactly what is needed. */
/*
* Last chance: Try to allocate exactly what is needed.
*/
attempt = needed;
ptr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
}
@@ -750,7 +762,7 @@ BinaryFormatCmd(
int count; /* Count associated with current format
* character. */
int flags; /* Format field flags */
const char *format; /* Pointer to current position in format
const char *format; /* Pointer to current position in format
* string. */
Tcl_Obj *resultPtr = NULL; /* Object holding result buffer. */
unsigned char *buffer; /* Start of result buffer. */
@@ -936,9 +948,9 @@ BinaryFormatCmd(
memset(buffer, 0, (size_t) length);
/*
* Pack the data into the result object. Note that we can skip the
* error checking during this pass, since we have already parsed the
* string once.
* Pack the data into the result object. Note that we can skip the error
* checking during this pass, since we have already parsed the string
* once.
*/
arg = 2;
@@ -1151,7 +1163,7 @@ BinaryFormatCmd(
}
arg++;
for (i = 0; i < count; i++) {
if (FormatNumber(interp, cmd, listv[i], &cursor)!=TCL_OK) {
if (FormatNumber(interp, cmd, listv[i], &cursor) != TCL_OK) {
Tcl_DecrRefCount(resultPtr);
return TCL_ERROR;
}
@@ -1255,7 +1267,7 @@ BinaryScanCmd(
int count; /* Count associated with current format
* character. */
int flags; /* Format field flags */
const char *format; /* Pointer to current position in format
const char *format; /* Pointer to current position in format
* string. */
Tcl_Obj *resultPtr = NULL; /* Object holding result buffer. */
unsigned char *buffer; /* Start of result buffer. */
@@ -1314,7 +1326,7 @@ BinaryScanCmd(
if (cmd == 'A') {
while (size > 0) {
if (src[size-1] != '\0' && src[size-1] != ' ') {
if (src[size - 1] != '\0' && src[size - 1] != ' ') {
break;
}
size--;
@@ -1920,7 +1932,7 @@ FormatNumber(
* valid range for float.
*/
if (fabs(dvalue) > (double)FLT_MAX) {
if (fabs(dvalue) > (double) FLT_MAX) {
fvalue = (dvalue >= 0.0) ? FLT_MAX : -FLT_MAX;
} else {
fvalue = (float) dvalue;
@@ -2041,9 +2053,9 @@ ScanNumber(
int type, /* Format character from "binary scan" */
int flags, /* Format field flags */
Tcl_HashTable **numberCachePtrPtr)
/* Place to look for cache of scanned
* value objects, or NULL if too many
* different numbers have been scanned. */
/* Place to look for cache of scanned value
* objects, or NULL if too many different
* numbers have been scanned. */
{
long value;
float fvalue;
@@ -2117,6 +2129,7 @@ ScanNumber(
/*
* Check to see if the value was sign extended properly on systems
* where an int is more than 32-bits.
*
* We avoid caching unsigned integers as we cannot distinguish between
* 32bit signed and unsigned in the hash (short and char are ok).
*/
@@ -2124,9 +2137,9 @@ ScanNumber(
if (flags & BINARY_UNSIGNED) {
return Tcl_NewWideIntObj((Tcl_WideInt)(unsigned long)value);
}
if ((value & (((unsigned) 1)<<31)) && (value > 0)) {
value -= (((unsigned) 1)<<31);
value -= (((unsigned) 1)<<31);
if ((value & (((unsigned) 1) << 31)) && (value > 0)) {
value -= (((unsigned) 1) << 31);
value -= (((unsigned) 1) << 31);
}
returnNumericObject:
@@ -2326,8 +2339,8 @@ BinaryEncodeHex(
data = Tcl_GetByteArrayFromObj(objv[1], &count);
cursor = Tcl_SetByteArrayLength(resultObj, count * 2);
for (offset = 0; offset < count; ++offset) {
*cursor++ = HexDigits[((data[offset] >> 4) & 0x0f)];
*cursor++ = HexDigits[(data[offset] & 0x0f)];
*cursor++ = HexDigits[(data[offset] >> 4) & 0x0f];
*cursor++ = HexDigits[data[offset] & 0x0f];
}
Tcl_SetObjResult(interp, resultObj);
return TCL_OK;
@@ -2367,7 +2380,7 @@ BinaryDecodeHex(
Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
return TCL_ERROR;
}
for (i = 1; i < objc-1; ++i) {
for (i = 1; i < objc - 1; ++i) {
if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
TCL_EXACT, &index) != TCL_OK) {
return TCL_ERROR;
@@ -2381,13 +2394,13 @@ BinaryDecodeHex(
TclNewObj(resultObj);
datastart = data = (unsigned char *)
TclGetStringFromObj(objv[objc-1], &count);
TclGetStringFromObj(objv[objc - 1], &count);
dataend = data + count;
size = (count + 1) / 2;
begin = cursor = Tcl_SetByteArrayLength(resultObj, size);
while (data < dataend) {
value = 0;
for (i=0 ; i<2 ; i++) {
for (i = 0 ; i < 2 ; i++) {
if (data >= dataend) {
value <<= 4;
break;
@@ -2410,7 +2423,7 @@ BinaryDecodeHex(
if (c > 16) {
c += ('A' - 'a');
}
value |= (c & 0xf);
value |= c & 0xf;
}
if (i < 2) {
cut++;
@@ -2481,22 +2494,22 @@ BinaryEncode64(
const char *wrapchar = "\n";
int wrapcharlen = 1;
int offset, i, index, size, outindex = 0, count = 0;
enum {OPT_MAXLEN, OPT_WRAPCHAR };
enum { OPT_MAXLEN, OPT_WRAPCHAR };
static const char *const optStrings[] = { "-maxlen", "-wrapchar", NULL };
if (objc < 2 || objc%2 != 0) {
if (objc < 2 || objc % 2 != 0) {
Tcl_WrongNumArgs(interp, 1, objv,
"?-maxlen len? ?-wrapchar char? data");
return TCL_ERROR;
}
for (i = 1; i < objc-1; i += 2) {
for (i = 1; i < objc - 1; i += 2) {
if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
TCL_EXACT, &index) != TCL_OK) {
return TCL_ERROR;
}
switch (index) {
case OPT_MAXLEN:
if (Tcl_GetIntFromObj(interp, objv[i+1], &maxlen) != TCL_OK) {
if (Tcl_GetIntFromObj(interp, objv[i + 1], &maxlen) != TCL_OK) {
return TCL_ERROR;
}
if (maxlen < 0) {
@@ -2508,7 +2521,7 @@ BinaryEncode64(
}
break;
case OPT_WRAPCHAR:
wrapchar = Tcl_GetStringFromObj(objv[i+1], &wrapcharlen);
wrapchar = Tcl_GetStringFromObj(objv[i + 1], &wrapcharlen);
if (wrapcharlen == 0) {
maxlen = 0;
}
@@ -2517,9 +2530,9 @@ BinaryEncode64(
}
resultObj = Tcl_NewObj();
data = Tcl_GetByteArrayFromObj(objv[objc-1], &count);
data = Tcl_GetByteArrayFromObj(objv[objc - 1], &count);
if (count > 0) {
size = (((count * 4) / 3) + 3) & ~3; /* ensure 4 byte chunks */
size = (((count * 4) / 3) + 3) & ~3; /* ensure 4 byte chunks */
if (maxlen > 0 && size > maxlen) {
int adjusted = size + (wrapcharlen * (size / maxlen));
@@ -2530,15 +2543,15 @@ BinaryEncode64(
}
cursor = Tcl_SetByteArrayLength(resultObj, size);
limit = cursor + size;
for (offset = 0; offset < count; offset+=3) {
for (offset = 0; offset < count; offset += 3) {
unsigned char d[3] = {0, 0, 0};
for (i = 0; i < 3 && offset+i < count; ++i) {
for (i = 0; i < 3 && offset + i < count; ++i) {
d[i] = data[offset + i];
}
OUTPUT(B64Digits[d[0] >> 2]);
OUTPUT(B64Digits[((d[0] & 0x03) << 4) | (d[1] >> 4)]);
if (offset+1 < count) {
if (offset + 1 < count) {
OUTPUT(B64Digits[((d[1] & 0x0f) << 2) | (d[2] >> 6)]);
} else {
OUTPUT(B64Digits[64]);
@@ -2591,19 +2604,20 @@ BinaryEncodeUu(
enum { OPT_MAXLEN, OPT_WRAPCHAR };
static const char *const optStrings[] = { "-maxlen", "-wrapchar", NULL };
if (objc < 2 || objc%2 != 0) {
if (objc < 2 || objc % 2 != 0) {
Tcl_WrongNumArgs(interp, 1, objv,
"?-maxlen len? ?-wrapchar char? data");
return TCL_ERROR;
}
for (i = 1; i < objc-1; i += 2) {
for (i = 1; i < objc - 1; i += 2) {
if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
TCL_EXACT, &index) != TCL_OK) {
return TCL_ERROR;
}
switch (index) {
case OPT_MAXLEN:
if (Tcl_GetIntFromObj(interp, objv[i+1], &lineLength) != TCL_OK) {
if (Tcl_GetIntFromObj(interp, objv[i + 1],
&lineLength) != TCL_OK) {
return TCL_ERROR;
}
if (lineLength < 3 || lineLength > 85) {
@@ -2615,7 +2629,7 @@ BinaryEncodeUu(
}
break;
case OPT_WRAPCHAR:
wrapchar = Tcl_GetByteArrayFromObj(objv[i+1], &wrapcharlen);
wrapchar = Tcl_GetByteArrayFromObj(objv[i + 1], &wrapcharlen);
break;
}
}
@@ -2627,7 +2641,7 @@ BinaryEncodeUu(
resultObj = Tcl_NewObj();
offset = 0;
data = Tcl_GetByteArrayFromObj(objv[objc-1], &count);
data = Tcl_GetByteArrayFromObj(objv[objc - 1], &count);
rawLength = (lineLength - 1) * 3 / 4;
start = cursor = Tcl_SetByteArrayLength(resultObj,
(lineLength + wrapcharlen) *
@@ -2648,11 +2662,11 @@ BinaryEncodeUu(
lineLen = rawLength;
}
*cursor++ = UueDigits[lineLen];
for (i=0 ; i<lineLen ; i++) {
for (i = 0 ; i < lineLen ; i++) {
n <<= 8;
n |= data[offset++];
for (bits += 8; bits > 6 ; bits -= 6) {
*cursor++ = UueDigits[(n >> (bits-6)) & 0x3f];
*cursor++ = UueDigits[(n >> (bits - 6)) & 0x3f];
}
}
if (bits > 0) {
@@ -2660,7 +2674,7 @@ BinaryEncodeUu(
*cursor++ = UueDigits[(n >> (bits + 2)) & 0x3f];
bits = 0;
}
for (j=0 ; j<wrapcharlen ; ++j) {
for (j = 0 ; j < wrapcharlen ; ++j) {
*cursor++ = wrapchar[j];
}
}
@@ -2669,7 +2683,7 @@ BinaryEncodeUu(
* Fix the length of the output bytearray.
*/
Tcl_SetByteArrayLength(resultObj, cursor-start);
Tcl_SetByteArrayLength(resultObj, cursor - start);
Tcl_SetObjResult(interp, resultObj);
return TCL_OK;
}
@@ -2702,14 +2716,14 @@ BinaryDecodeUu(
unsigned char *begin, *cursor;
int i, index, size, count = 0, strict = 0, lineLen;
unsigned char c;
enum {OPT_STRICT };
enum { OPT_STRICT };
static const char *const optStrings[] = { "-strict", NULL };
if (objc < 2 || objc > 3) {
Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
return TCL_ERROR;
}
for (i = 1; i < objc-1; ++i) {
for (i = 1; i < objc - 1; ++i) {
if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
TCL_EXACT, &index) != TCL_OK) {
return TCL_ERROR;
@@ -2723,7 +2737,7 @@ BinaryDecodeUu(
TclNewObj(resultObj);
datastart = data = (unsigned char *)
TclGetStringFromObj(objv[objc-1], &count);
TclGetStringFromObj(objv[objc - 1], &count);
dataend = data + count;
size = ((count + 3) & ~3) * 3 / 4;
begin = cursor = Tcl_SetByteArrayLength(resultObj, size);
@@ -2755,7 +2769,7 @@ BinaryDecodeUu(
* Now we read a four-character grouping.
*/
for (i=0 ; i<4 ; i++) {
for (i = 0 ; i < 4 ; i++) {
if (data < dataend) {
d[i] = c = *data++;
if (c < 32 || c > 96) {
@@ -2873,7 +2887,7 @@ BinaryDecode64(
Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
return TCL_ERROR;
}
for (i = 1; i < objc-1; ++i) {
for (i = 1; i < objc - 1; ++i) {
if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
TCL_EXACT, &index) != TCL_OK) {
return TCL_ERROR;
@@ -2887,7 +2901,7 @@ BinaryDecode64(
TclNewObj(resultObj);
datastart = data = (unsigned char *)
TclGetStringFromObj(objv[objc-1], &count);
TclGetStringFromObj(objv[objc - 1], &count);
dataend = data + count;
size = ((count + 3) & ~3) * 3 / 4;
begin = cursor = Tcl_SetByteArrayLength(resultObj, size);
@@ -2915,8 +2929,11 @@ BinaryDecode64(
c = '=';
} else {
if (strict && i <= 1) {
/* single resp. unfulfilled char (each 4th next single char)
* is rather bad64 error case in strict mode */
/*
* Single resp. unfulfilled char (each 4th next single
* char) is rather bad64 error case in strict mode.
*/
goto bad64;
}
cut += 3;
@@ -2932,10 +2949,10 @@ BinaryDecode64(
if (cut) {
if (c == '=' && i > 1) {
value <<= 6;
cut++;
value <<= 6;
cut++;
} else if (!strict && TclIsSpaceProc(c)) {
i--;
i--;
} else {
goto bad64;
}
@@ -2949,11 +2966,15 @@ BinaryDecode64(
value = (value << 6) | 0x3e;
} else if (c == '/') {
value = (value << 6) | 0x3f;
} else if (c == '=' && (
!strict || i > 1) /* "=" and "a=" is rather bad64 error case in strict mode */
) {
} else if (c == '=' && (!strict || i > 1)) {
/*
* "=" and "a=" is rather bad64 error case in strict mode.
*/
value <<= 6;
if (i) cut++;
if (i) {
cut++;
}
} else if (strict || !TclIsSpaceProc(c)) {
goto bad64;
} else {
@@ -3000,4 +3021,3 @@ BinaryDecode64(
* fill-column: 78
* End:
*/
+13 -18
View File
@@ -1383,7 +1383,7 @@ FileAttrAccessTimeCmd(
}
#if defined(_WIN32)
/* We use a value of 0 to indicate the access time not available */
if (buf.st_atime == 0) {
if (Tcl_GetAccessTimeFromStat(&buf) == 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"could not get access time for file \"%s\"",
TclGetString(objv[1])));
@@ -1392,19 +1392,14 @@ FileAttrAccessTimeCmd(
#endif
if (objc == 3) {
/*
* Need separate variable for reading longs from an object on 64-bit
* platforms. [Bug 698146]
*/
Tcl_WideInt newTime;
long newTime;
if (TclGetLongFromObj(interp, objv[2], &newTime) != TCL_OK) {
if (Tcl_GetWideIntFromObj(interp, objv[2], &newTime) != TCL_OK) {
return TCL_ERROR;
}
tval.actime = newTime;
tval.modtime = buf.st_mtime;
tval.modtime = Tcl_GetModificationTimeFromStat(&buf);
if (Tcl_FSUtime(objv[1], &tval) != 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
@@ -1424,7 +1419,7 @@ FileAttrAccessTimeCmd(
}
}
Tcl_SetObjResult(interp, Tcl_NewLongObj((long) buf.st_atime));
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tcl_GetAccessTimeFromStat(&buf)));
return TCL_OK;
}
@@ -1465,7 +1460,7 @@ FileAttrModifyTimeCmd(
}
#if defined(_WIN32)
/* We use a value of 0 to indicate the modification time not available */
if (buf.st_mtime == 0) {
if (Tcl_GetModificationTimeFromStat(&buf) == 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"could not get modification time for file \"%s\"",
TclGetString(objv[1])));
@@ -1478,13 +1473,13 @@ FileAttrModifyTimeCmd(
* platforms. [Bug 698146]
*/
long newTime;
Tcl_WideInt newTime;
if (TclGetLongFromObj(interp, objv[2], &newTime) != TCL_OK) {
if (Tcl_GetWideIntFromObj(interp, objv[2], &newTime) != TCL_OK) {
return TCL_ERROR;
}
tval.actime = buf.st_atime;
tval.actime = Tcl_GetAccessTimeFromStat(&buf);
tval.modtime = newTime;
if (Tcl_FSUtime(objv[1], &tval) != 0) {
@@ -1504,7 +1499,7 @@ FileAttrModifyTimeCmd(
}
}
Tcl_SetObjResult(interp, Tcl_NewLongObj((long) buf.st_mtime));
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tcl_GetModificationTimeFromStat(&buf)));
return TCL_OK;
}
@@ -2535,9 +2530,9 @@ StoreStatData(
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
STORE_ARY("blksize", Tcl_NewLongObj((long)statPtr->st_blksize));
#endif
STORE_ARY("atime", Tcl_NewLongObj((long)statPtr->st_atime));
STORE_ARY("mtime", Tcl_NewLongObj((long)statPtr->st_mtime));
STORE_ARY("ctime", Tcl_NewLongObj((long)statPtr->st_ctime));
STORE_ARY("atime", Tcl_NewWideIntObj(Tcl_GetAccessTimeFromStat(statPtr)));
STORE_ARY("mtime", Tcl_NewWideIntObj(Tcl_GetModificationTimeFromStat(statPtr)));
STORE_ARY("ctime", Tcl_NewWideIntObj(Tcl_GetChangeTimeFromStat(statPtr)));
mode = (unsigned short) statPtr->st_mode;
STORE_ARY("mode", Tcl_NewIntObj(mode));
STORE_ARY("type", Tcl_NewStringObj(GetTypeFromMode(mode), -1));
+2 -2
View File
@@ -1960,7 +1960,7 @@ InfoProcsCmd(
/*
* If "info procs" worked like "info commands", returning the commands
* also seen in the global namespace, then you would include this
* code. As this could break backwards compatibilty with 8.0-8.2, we
* code. As this could break backwards compatibility with 8.0-8.2, we
* decided not to "fix" it in 8.3, leaving the behavior slightly
* different.
*/
@@ -3937,7 +3937,7 @@ Tcl_LsortObjCmd(
/*
* Do not shrink the actual memory block used; that doesn't
* work with TclStackAlloc-allocated memory. [Bug 2918962]
*
*
* TODO: Consider a pointer increment to replace this
* array shift.
*/
+324 -160
View File
@@ -4275,11 +4275,12 @@ Tcl_TimeObjCmd(
*
* This object-based procedure is invoked to process the "timerate" Tcl
* command.
*
* This is similar to command "time", except the execution limited by
* given time (in milliseconds) instead of repetition count.
*
* Example:
* timerate {after 5} 1000 ; # equivalent for `time {after 5} [expr 1000/5]`
* timerate {after 5} 1000; # equivalent to: time {after 5} [expr 1000/5]
*
* Results:
* A standard Tcl object result.
@@ -4297,39 +4298,41 @@ Tcl_TimeRateObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
static double measureOverhead = 0; /* global measure-overhead */
static double measureOverhead = 0;
/* global measure-overhead */
double overhead = -1; /* given measure-overhead */
register Tcl_Obj *objPtr;
register int result, i;
Tcl_Obj *calibrate = NULL, *direct = NULL;
Tcl_WideUInt count = 0; /* Holds repetition count */
Tcl_WideInt maxms = WIDE_MIN;
TclWideMUInt count = 0; /* Holds repetition count */
Tcl_WideInt maxms = WIDE_MIN;
/* Maximal running time (in milliseconds) */
Tcl_WideUInt maxcnt = WIDE_MAX;
TclWideMUInt maxcnt = WIDE_MAX;
/* Maximal count of iterations. */
Tcl_WideUInt threshold = 1; /* Current threshold for check time (faster
TclWideMUInt threshold = 1; /* Current threshold for check time (faster
* repeat count without time check) */
Tcl_WideUInt maxIterTm = 1; /* Max time of some iteration as max threshold
* additionally avoid divide to zero (never < 1) */
TclWideMUInt maxIterTm = 1; /* Max time of some iteration as max
* threshold, additionally avoiding divide to
* zero (i.e., never < 1) */
unsigned short factor = 50; /* Factor (4..50) limiting threshold to avoid
* growth of execution time. */
register Tcl_WideInt start, middle, stop;
#ifndef TCL_WIDE_CLICKS
Tcl_Time now;
#endif
#endif /* !TCL_WIDE_CLICKS */
static const char *const options[] = {
"-direct", "-overhead", "-calibrate", "--", NULL
};
enum options {
TMRT_EV_DIRECT, TMRT_OVERHEAD, TMRT_CALIBRATE, TMRT_LAST
};
NRE_callback *rootPtr;
ByteCode *codePtr = NULL;
ByteCode *codePtr = NULL;
int codeOptimized = 0;
for (i = 1; i < objc - 1; i++) {
int index;
int index;
if (Tcl_GetIndexFromObj(NULL, objv[i], options, "option", TCL_EXACT,
&index) != TCL_OK) {
break;
@@ -4356,9 +4359,11 @@ Tcl_TimeRateObjCmd(
}
}
if (i >= objc || i < objc-3) {
usage:
Tcl_WrongNumArgs(interp, 1, objv, "?-direct? ?-calibrate? ?-overhead double? command ?time ?max-count??");
if (i >= objc || i < objc - 3) {
usage:
Tcl_WrongNumArgs(interp, 1, objv,
"?-direct? ?-calibrate? ?-overhead double? "
"command ?time ?max-count??");
return TCL_ERROR;
}
objPtr = objv[i++];
@@ -4369,6 +4374,7 @@ usage:
}
if (i < objc) { /* max-count*/
Tcl_WideInt v;
result = Tcl_GetWideIntFromObj(interp, objv[i], &v);
if (result != TCL_OK) {
return result;
@@ -4377,10 +4383,15 @@ usage:
}
}
/* if calibrate */
/*
* If we are doing calibration.
*/
if (calibrate) {
/*
* If no time specified for the calibration.
*/
/* if no time specified for the calibration */
if (maxms == WIDE_MIN) {
Tcl_Obj *clobjv[6];
Tcl_WideInt maxCalTime = 5000;
@@ -4389,18 +4400,24 @@ usage:
clobjv[0] = objv[0];
i = 1;
if (direct) {
clobjv[i++] = direct;
clobjv[i++] = direct;
}
clobjv[i++] = objPtr;
/* reset last measurement overhead */
measureOverhead = (double)0;
/*
* Reset last measurement overhead.
*/
measureOverhead = (double) 0;
/*
* Self-call with 100 milliseconds to warm-up, before entering the
* calibration cycle.
*/
/* self-call with 100 milliseconds to warm-up,
* before entering the calibration cycle */
TclNewLongObj(clobjv[i], 100);
Tcl_IncrRefCount(clobjv[i]);
result = Tcl_TimeRateObjCmd(dummy, interp, i+1, clobjv);
result = Tcl_TimeRateObjCmd(NULL, interp, i + 1, clobjv);
Tcl_DecrRefCount(clobjv[i]);
if (result != TCL_OK) {
return result;
@@ -4410,241 +4427,385 @@ usage:
clobjv[i++] = calibrate;
clobjv[i++] = objPtr;
/* set last measurement overhead to max */
measureOverhead = (double)UWIDE_MAX;
/*
* Set last measurement overhead to max.
*/
measureOverhead = (double) UWIDE_MAX;
/*
* Run the calibration cycle until it is more precise.
*/
/* calibration cycle until it'll be preciser */
maxms = -1000;
do {
lastMeasureOverhead = measureOverhead;
TclNewLongObj(clobjv[i], (int)maxms);
TclNewLongObj(clobjv[i], (int) maxms);
Tcl_IncrRefCount(clobjv[i]);
result = Tcl_TimeRateObjCmd(dummy, interp, i+1, clobjv);
result = Tcl_TimeRateObjCmd(NULL, interp, i + 1, clobjv);
Tcl_DecrRefCount(clobjv[i]);
if (result != TCL_OK) {
return result;
}
maxCalTime += maxms;
/* increase maxms for preciser calibration */
maxms -= (-maxms / 4);
/* as long as new value more as 0.05% better */
} while ( (measureOverhead >= lastMeasureOverhead
/*
* Increase maxms for more precise calibration.
*/
maxms -= -maxms / 4;
/*
* As long as new value more as 0.05% better
*/
} while ((measureOverhead >= lastMeasureOverhead
|| measureOverhead / lastMeasureOverhead <= 0.9995)
&& maxCalTime > 0
);
&& maxCalTime > 0);
return result;
}
if (maxms == 0) {
/* reset last measurement overhead */
/*
* Reset last measurement overhead
*/
measureOverhead = 0;
Tcl_SetObjResult(interp, Tcl_NewLongObj(0));
return TCL_OK;
}
/* if time is negative - make current overhead more precise */
/*
* If time is negative, make current overhead more precise.
*/
if (maxms > 0) {
/* set last measurement overhead to max */
measureOverhead = (double)UWIDE_MAX;
/*
* Set last measurement overhead to max.
*/
measureOverhead = (double) UWIDE_MAX;
} else {
maxms = -maxms;
}
}
if (maxms == WIDE_MIN) {
maxms = 1000;
maxms = 1000;
}
if (overhead == -1) {
overhead = measureOverhead;
}
/* be sure that resetting of result will not smudge the further measurement */
/*
* Ensure that resetting of result will not smudge the further
* measurement.
*/
Tcl_ResetResult(interp);
/* compile object */
/*
* Compile object if needed.
*/
if (!direct) {
if (TclInterpReady(interp) != TCL_OK) {
return TCL_ERROR;
}
codePtr = TclCompileObj(interp, objPtr, NULL, 0);
TclPreserveByteCode(codePtr);
/*
* Replace last compiled done instruction with continue: it's a part of
* iteration, this way evaluation will be more similar to a cycle (also
* avoids extra overhead to set result to interp, etc.)
*/
if (codePtr->codeStart[codePtr->numCodeBytes-1] == INST_DONE) {
codePtr->codeStart[codePtr->numCodeBytes-1] = INST_CONTINUE;
codeOptimized = 1;
}
}
/* get start and stop time */
/*
* Get start and stop time.
*/
#ifdef TCL_WIDE_CLICKS
start = middle = TclpGetWideClicks();
/* time to stop execution (in wide clicks) */
/*
* Time to stop execution (in wide clicks).
*/
stop = start + (maxms * 1000 / TclpWideClickInMicrosec());
#else
Tcl_GetTime(&now);
start = now.sec; start *= 1000000; start += now.usec;
start = now.sec;
start *= 1000000;
start += now.usec;
middle = start;
/* time to stop execution (in microsecs) */
/*
* Time to stop execution (in microsecs).
*/
stop = start + maxms * 1000;
#endif
#endif /* TCL_WIDE_CLICKS */
/* start measurement */
if (maxcnt > 0)
while (1) {
/* eval single iteration */
count++;
/*
* Start measurement.
*/
if (!direct) {
/* precompiled */
rootPtr = TOP_CB(interp);
result = TclNRExecuteByteCode(interp, codePtr);
result = TclNRRunCallbacks(interp, result, rootPtr);
} else {
/* eval */
result = TclEvalObjEx(interp, objPtr, 0, NULL, 0);
}
if (result != TCL_OK) {
/* allow break from measurement cycle (used for conditional stop) */
if (result != TCL_BREAK) {
goto done;
if (maxcnt > 0) {
while (1) {
/*
* Evaluate a single iteration.
*/
count++;
if (!direct) { /* precompiled */
rootPtr = TOP_CB(interp);
result = TclNRExecuteByteCode(interp, codePtr);
result = TclNRRunCallbacks(interp, result, rootPtr);
} else { /* eval */
result = TclEvalObjEx(interp, objPtr, 0, NULL, 0);
}
/* force stop immediately */
threshold = 1;
maxcnt = 0;
result = TCL_OK;
}
/*
* Allow break and continue from measurement cycle (used for
* conditional stop and flow control of iterations).
*/
/* don't check time up to threshold */
if (--threshold > 0) continue;
/* check stop time reached, estimate new threshold */
#ifdef TCL_WIDE_CLICKS
middle = TclpGetWideClicks();
#else
Tcl_GetTime(&now);
middle = now.sec; middle *= 1000000; middle += now.usec;
#endif
if (middle >= stop || count >= maxcnt) {
break;
}
/* don't calculate threshold by few iterations, because sometimes first
* iteration(s) can be too fast or slow (cached, delayed clean up, etc) */
if (count < 10) {
threshold = 1; continue;
}
/* average iteration time in microsecs */
threshold = (middle - start) / count;
if (threshold > maxIterTm) {
maxIterTm = threshold;
/* interations seems to be longer */
if (threshold > (maxIterTm * 2)) {
if ((factor *= 2) > 50) factor = 50;
} else {
if (factor < 50) factor++;
switch (result) {
case TCL_OK:
break;
case TCL_BREAK:
/*
* Force stop immediately.
*/
threshold = 1;
maxcnt = 0;
case TCL_CONTINUE:
result = TCL_OK;
break;
default:
goto done;
}
} else if (factor > 4) {
/* interations seems to be shorter */
if (threshold < (maxIterTm / 2)) {
if ((factor /= 2) < 4) factor = 4;
} else {
factor--;
/*
* Don't check time up to threshold.
*/
if (--threshold > 0) {
continue;
}
/*
* Check stop time reached, estimate new threshold.
*/
#ifdef TCL_WIDE_CLICKS
middle = TclpGetWideClicks();
#else
Tcl_GetTime(&now);
middle = now.sec;
middle *= 1000000;
middle += now.usec;
#endif /* TCL_WIDE_CLICKS */
if (middle >= stop || count >= maxcnt) {
break;
}
/*
* Don't calculate threshold by few iterations, because sometimes
* first iteration(s) can be too fast or slow (cached, delayed
* clean up, etc).
*/
if (count < 10) {
threshold = 1;
continue;
}
/*
* Average iteration time in microsecs.
*/
threshold = (middle - start) / count;
if (threshold > maxIterTm) {
maxIterTm = threshold;
/*
* Iterations seem to be longer.
*/
if (threshold > maxIterTm * 2) {
factor *= 2;
if (factor > 50) {
factor = 50;
}
} else {
if (factor < 50) {
factor++;
}
}
} else if (factor > 4) {
/*
* Iterations seem to be shorter.
*/
if (threshold < (maxIterTm / 2)) {
factor /= 2;
if (factor < 4) {
factor = 4;
}
} else {
factor--;
}
}
/*
* As relation between remaining time and time since last check,
* maximal some % of time (by factor), so avoid growing of the
* execution time if iterations are not consistent, e.g. was
* continuously on time).
*/
threshold = ((stop - middle) / maxIterTm) / factor + 1;
if (threshold > 100000) { /* fix for too large threshold */
threshold = 100000;
}
/*
* Consider max-count
*/
if (threshold > maxcnt - count) {
threshold = maxcnt - count;
}
}
/* as relation between remaining time and time since last check,
* maximal some % of time (by factor), so avoid growing of the execution time
* if iterations are not consistent, e. g. wax continuously on time) */
threshold = ((stop - middle) / maxIterTm) / factor + 1;
if (threshold > 100000) { /* fix for too large threshold */
threshold = 100000;
}
/* consider max-count */
if (threshold > maxcnt - count) {
threshold = maxcnt - count;
}
}
{
Tcl_Obj *objarr[8], **objs = objarr;
Tcl_WideInt val;
const char *fmt;
TclWideMUInt usec, val;
int digits;
middle -= start; /* execution time in microsecs */
/*
* Absolute execution time in microseconds or in wide clicks.
*/
usec = (TclWideMUInt)(middle - start);
#ifdef TCL_WIDE_CLICKS
/* convert execution time in wide clicks to microsecs */
middle *= TclpWideClickInMicrosec();
#endif
#ifdef TCL_WIDE_CLICKS
/*
* convert execution time (in wide clicks) to microsecs.
*/
if (!count) { /* no iterations - avoid divide by zero */
usec *= TclpWideClickInMicrosec();
#endif /* TCL_WIDE_CLICKS */
if (!count) { /* no iterations - avoid divide by zero */
objs[0] = objs[2] = objs[4] = Tcl_NewWideIntObj(0);
goto retRes;
}
/* if not calibrate */
/*
* If not calibrating...
*/
if (!calibrate) {
/* minimize influence of measurement overhead */
/*
* Minimize influence of measurement overhead.
*/
if (overhead > 0) {
/* estimate the time of overhead (microsecs) */
Tcl_WideUInt curOverhead = overhead * count;
if ((Tcl_WideUInt)middle > curOverhead) {
middle -= curOverhead;
/*
* Estimate the time of overhead (microsecs).
*/
TclWideMUInt curOverhead = overhead * count;
if (usec > curOverhead) {
usec -= curOverhead;
} else {
middle = 0;
usec = 0;
}
}
} else {
/* calibration - obtaining new measurement overhead */
if (measureOverhead > (double)middle / count) {
measureOverhead = (double)middle / count;
/*
* Calibration: obtaining new measurement overhead.
*/
if (measureOverhead > ((double) usec) / count) {
measureOverhead = ((double) usec) / count;
}
objs[0] = Tcl_NewDoubleObj(measureOverhead);
TclNewLiteralStringObj(objs[1], "\xC2\xB5s/#-overhead"); /* mics */
objs += 2;
}
val = middle / count; /* microsecs per iteration */
val = usec / count; /* microsecs per iteration */
if (val >= 1000000) {
objs[0] = Tcl_NewWideIntObj(val);
} else {
if (val < 10) { fmt = "%.6f"; } else
if (val < 100) { fmt = "%.4f"; } else
if (val < 1000) { fmt = "%.3f"; } else
if (val < 10000) { fmt = "%.2f"; } else
{ fmt = "%.1f"; };
objs[0] = Tcl_ObjPrintf(fmt, ((double)middle)/count);
if (val < 10) {
digits = 6;
} else if (val < 100) {
digits = 4;
} else if (val < 1000) {
digits = 3;
} else if (val < 10000) {
digits = 2;
} else {
digits = 1;
}
objs[0] = Tcl_ObjPrintf("%.*f", digits, ((double) usec)/count);
}
objs[2] = Tcl_NewWideIntObj(count); /* iterations */
/* calculate speed as rate (count) per sec */
if (!middle) middle++; /* +1 ms, just to avoid divide by zero */
/*
* Calculate speed as rate (count) per sec
*/
if (!usec) {
usec++; /* Avoid divide by zero. */
}
if (count < (WIDE_MAX / 1000000)) {
val = (count * 1000000) / middle;
val = (count * 1000000) / usec;
if (val < 100000) {
if (val < 100) { fmt = "%.3f"; } else
if (val < 1000) { fmt = "%.2f"; } else
{ fmt = "%.1f"; };
objs[4] = Tcl_ObjPrintf(fmt, ((double)(count * 1000000)) / middle);
if (val < 100) {
digits = 3;
} else if (val < 1000) {
digits = 2;
} else {
digits = 1;
}
objs[4] = Tcl_ObjPrintf("%.*f",
digits, ((double) (count * 1000000)) / usec);
} else {
objs[4] = Tcl_NewWideIntObj(val);
}
} else {
objs[4] = Tcl_NewWideIntObj((count / middle) * 1000000);
objs[4] = Tcl_NewWideIntObj((count / usec) * 1000000);
}
retRes:
/* estimated net execution time (in millisecs) */
/*
* Estimated net execution time (in millisecs).
*/
if (!calibrate) {
if (middle >= 1) {
objs[6] = Tcl_ObjPrintf("%.3f", (double)middle / 1000);
if (usec >= 1) {
objs[6] = Tcl_ObjPrintf("%.3f", (double)usec / 1000);
} else {
objs[6] = Tcl_NewWideIntObj(0);
}
TclNewLiteralStringObj(objs[7], "nett-ms");
TclNewLiteralStringObj(objs[7], "net-ms");
}
/*
* Construct the result as a list because many programs have always parsed
* as such (extracting the first element, typically).
*/
* Construct the result as a list because many programs have always
* parsed as such (extracting the first element, typically).
*/
TclNewLiteralStringObj(objs[1], "\xC2\xB5s/#"); /* mics/# */
TclNewLiteralStringObj(objs[3], "#");
@@ -4652,12 +4813,15 @@ usage:
Tcl_SetObjResult(interp, Tcl_NewListObj(8, objarr));
}
done:
done:
if (codePtr != NULL) {
if ( codeOptimized
&& codePtr->codeStart[codePtr->numCodeBytes-1] == INST_CONTINUE
) {
codePtr->codeStart[codePtr->numCodeBytes-1] = INST_DONE;
}
TclReleaseByteCode(codePtr);
}
return result;
}
+2 -2
View File
@@ -35,7 +35,7 @@ static int IndexTailVarIfKnown(Tcl_Interp *interp,
* TclGetIndexFromToken --
*
* Parse a token to determine if an index value is known at
* compile time.
* compile time.
*
* Returns:
* TCL_OK if parsing succeeded, and TCL_ERROR if it failed.
@@ -1536,7 +1536,7 @@ TclCompileLreplaceCmd(
emptyPrefix = 0;
}
if ((idx1 == suffixStart) && (parsePtr->numWords == 4)) {
/*
* This is a "no-op". Example: [lreplace {a b c} 2 0]
+7 -7
View File
@@ -1002,13 +1002,13 @@ TclCompileStringReplaceCmd(
if (parsePtr->numWords < 4 || parsePtr->numWords > 5) {
return TCL_ERROR;
}
/* Bytecode to compute/push string argument being replaced */
valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
CompileWord(envPtr, valueTokenPtr, interp, 1);
/*
* Check for first index known and useful at compile time.
* Check for first index known and useful at compile time.
*/
tokenPtr = TokenAfter(valueTokenPtr);
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER,
@@ -1017,7 +1017,7 @@ TclCompileStringReplaceCmd(
}
/*
* Check for last index known and useful at compile time.
* Check for last index known and useful at compile time.
*/
tokenPtr = TokenAfter(tokenPtr);
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER,
@@ -1025,7 +1025,7 @@ TclCompileStringReplaceCmd(
goto genericReplace;
}
/*
/*
* [string replace] is an odd bird. For many arguments it is
* a conventional substring replacer. However it also goes out
* of its way to become a no-op for many cases where it would be
@@ -1108,12 +1108,12 @@ TclCompileStringReplaceCmd(
* Finally we need, third:
*
* (first <= last)
*
*
* Considered in combination with the constraints we already have,
* we see that we can proceed when (first == TCL_INDEX_BEFORE)
* or (last == TCL_INDEX_AFTER). These also permit simplification
* of the prefix|replace|suffix construction. The other constraints,
* though, interfere with getting a guarantee that first <= last.
* though, interfere with getting a guarantee that first <= last.
*/
if ((first == TCL_INDEX_BEFORE) && (last >= TCL_INDEX_START)) {
@@ -1141,7 +1141,7 @@ TclCompileStringReplaceCmd(
/* FLOW THROUGH TO genericReplace */
} else {
/*
/*
* When we have no replacement string to worry about, we may
* have more luck, because the forbidden empty string replacements
* are harmless when they are replaced by another empty string.
+9 -5
View File
@@ -649,12 +649,12 @@ TclNamespaceEnsembleCmd(
Tcl_Command
TclCreateEnsembleInNs(
Tcl_Interp *interp,
Tcl_Interp *interp,
const char *name, /* Simple name of command to create (no */
/* namespace components). */
Tcl_Namespace /* Name of namespace to create the command in. */
*nameNsPtr,
Tcl_Namespace /* Name of namespace to create the command in. */
*nameNsPtr,
Tcl_Namespace
*ensembleNsPtr, /* Name of the namespace for the ensemble. */
int flags
@@ -2694,7 +2694,11 @@ BuildEnsembleConfig(
if (isNew) {
Tcl_Obj *cmdObj, *cmdPrefixObj;
cmdObj = Tcl_NewStringObj(nsCmdName, -1);
TclNewObj(cmdObj);
Tcl_AppendStringsToObj(cmdObj,
ensemblePtr->nsPtr->fullName,
(ensemblePtr->nsPtr->parentPtr ? "::" : ""),
nsCmdName, NULL);
cmdPrefixObj = Tcl_NewListObj(1, &cmdObj);
Tcl_SetHashValue(hPtr, cmdPrefixObj);
Tcl_IncrRefCount(cmdPrefixObj);
+14 -9
View File
@@ -944,16 +944,20 @@ Tcl_Exit(
currentAppExitPtr = appExitPtr;
Tcl_MutexUnlock(&exitMutex);
/*
* Warning: this function SHOULD NOT return, as there is code that depends
* on Tcl_Exit never returning. In fact, we will Tcl_Panic if anyone
* returns, so critical is this dependcy.
*
* If subsystems are not (yet) initialized, proper Tcl-finalization is
* impossible, so fallback to system exit, see bug-[f8a33ce3db5d8cc2].
*/
if (currentAppExitPtr) {
/*
* Warning: this code SHOULD NOT return, as there is code that depends
* on Tcl_Exit never returning. In fact, we will Tcl_Panic if anyone
* returns, so critical is this dependcy.
*/
currentAppExitPtr(INT2PTR(status));
Tcl_Panic("AppExitProc returned unexpectedly");
} else {
} else if (subsystemsInitialized) {
if (TclFullFinalizationRequested()) {
@@ -986,9 +990,10 @@ Tcl_Exit(
FinalizeThread(/* quick */ 1);
}
TclpExit(status);
Tcl_Panic("OS exit failed!");
}
TclpExit(status);
Tcl_Panic("OS exit failed!");
}
/*
+22 -15
View File
@@ -3716,31 +3716,36 @@ TEBCresume(
{
int createdNewObj = 0;
Tcl_Obj *valueToAssign;
if (!objResultPtr) {
objResultPtr = valuePtr;
valueToAssign = valuePtr;
} else if (TclListObjLength(interp, objResultPtr, &len)!=TCL_OK) {
TRACE_ERROR(interp);
goto gotError;
} else {
if (Tcl_IsShared(objResultPtr)) {
objResultPtr = Tcl_DuplicateObj(objResultPtr);
valueToAssign = Tcl_DuplicateObj(objResultPtr);
createdNewObj = 1;
} else {
valueToAssign = objResultPtr;
}
if (Tcl_ListObjReplace(interp, objResultPtr, len,0, objc,objv)
!= TCL_OK) {
if (Tcl_ListObjReplace(interp, valueToAssign, len, 0,
objc, objv) != TCL_OK) {
if (createdNewObj) {
TclDecrRefCount(valueToAssign);
}
goto errorInLappendListPtr;
}
}
DECACHE_STACK_INFO();
Tcl_IncrRefCount(valueToAssign);
objResultPtr = TclPtrSetVarIdx(interp, varPtr, arrayPtr, part1Ptr,
part2Ptr, objResultPtr, TCL_LEAVE_ERR_MSG, opnd);
part2Ptr, valueToAssign, TCL_LEAVE_ERR_MSG, opnd);
TclDecrRefCount(valueToAssign);
CACHE_STACK_INFO();
if (!objResultPtr) {
errorInLappendListPtr:
if (createdNewObj) {
TclDecrRefCount(objResultPtr);
}
TRACE_ERROR(interp);
goto gotError;
}
@@ -5247,7 +5252,7 @@ TEBCresume(
/* Decode index value operands. */
/*
/*
assert ( toIdx != TCL_INDEX_AFTER);
*
* Extra safety for legacy bytecodes:
@@ -8226,6 +8231,7 @@ FinalizeOONextFilter(
*
* Helpers to calculate small powers of integers whose result is long or wide.
*/
#if (LONG_MAX == 0x7fffffff)
static inline long
LongPwrSmallExpon(long l1, long exponent) {
@@ -8259,8 +8265,9 @@ LongPwrSmallExpon(long l1, long exponent) {
lResult *= lResult; /* b**8 */
break;
}
return lResult;
return lResult;
}
#endif
static inline Tcl_WideInt
WidePwrSmallExpon(Tcl_WideInt w1, long exponent) {
@@ -8640,7 +8647,7 @@ ExecuteExtendedBinaryMathOp(
if (opcode == INST_LSHIFT) {
mp_mul_2d(&big1, shift, &bigResult);
} else {
mp_tc_div_2d(&big1, shift, &bigResult);
mp_signed_rsh(&big1, shift, &bigResult);
}
mp_clear(&big1);
BIG_RESULT(&bigResult);
@@ -8657,15 +8664,15 @@ ExecuteExtendedBinaryMathOp(
switch (opcode) {
case INST_BITAND:
mp_tc_and(&big1, &big2, &bigResult);
mp_and(&big1, &big2, &bigResult);
break;
case INST_BITOR:
mp_tc_or(&big1, &big2, &bigResult);
mp_or(&big1, &big2, &bigResult);
break;
case INST_BITXOR:
mp_tc_xor(&big1, &big2, &bigResult);
mp_xor(&big1, &big2, &bigResult);
break;
}
@@ -8994,7 +9001,7 @@ ExecuteExtendedBinaryMathOp(
}
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
mp_init(&bigResult);
mp_expt_d(&big1, w2, &bigResult);
mp_expt_d(&big1, (mp_digit)w2, &bigResult);
mp_clear(&big1);
BIG_RESULT(&bigResult);
}
+5 -1
View File
@@ -326,7 +326,10 @@ CreateHashEntry(
continue;
}
#endif
if (((void *) key == hPtr) || compareKeysProc((void *) key, hPtr)) {
/* if keys pointers or values are equal */
if ((key == hPtr->key.oneWordValue)
|| compareKeysProc((void *) key, hPtr)
) {
if (newPtr) {
*newPtr = 0;
}
@@ -836,6 +839,7 @@ AllocStringEntry(
allocsize = sizeof(hPtr->key);
}
hPtr = ckalloc(TclOffset(Tcl_HashEntry, key) + allocsize);
memset(hPtr, 0, sizeof(Tcl_HashEntry) + allocsize - sizeof(hPtr->key));
memcpy(hPtr->key.string, string, size);
hPtr->clientData = 0;
return hPtr;
+5 -5
View File
@@ -327,9 +327,9 @@ Tcl_Stat(
oldStyleBuf->st_uid = buf.st_uid;
oldStyleBuf->st_gid = buf.st_gid;
oldStyleBuf->st_size = (off_t) buf.st_size;
oldStyleBuf->st_atime = buf.st_atime;
oldStyleBuf->st_mtime = buf.st_mtime;
oldStyleBuf->st_ctime = buf.st_ctime;
oldStyleBuf->st_atime = Tcl_GetAccessTimeFromStat(&buf);
oldStyleBuf->st_mtime = Tcl_GetModificationTimeFromStat(&buf);
oldStyleBuf->st_ctime = Tcl_GetChangeTimeFromStat(&buf);
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
oldStyleBuf->st_blksize = buf.st_blksize;
#endif
@@ -4392,8 +4392,8 @@ TclCrossFilesystemCopy(
*/
if (Tcl_FSLstat(source, &sourceStatBuf) == 0) {
tval.actime = sourceStatBuf.st_atime;
tval.modtime = sourceStatBuf.st_mtime;
tval.actime = Tcl_GetAccessTimeFromStat(&sourceStatBuf);
tval.modtime = Tcl_GetModificationTimeFromStat(&sourceStatBuf);
Tcl_FSUtime(target, &tval);
}
+10 -19
View File
@@ -49,7 +49,7 @@
#include <string.h>
#endif
#if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \
|| defined(__cplusplus) || defined(_MSC_VER)
|| defined(__cplusplus) || defined(_MSC_VER) || defined(__ICC)
#include <stddef.h>
#else
typedef int ptrdiff_t;
@@ -3053,6 +3053,8 @@ MODULE_SCOPE int TclMergeReturnOptions(Tcl_Interp *interp, int objc,
MODULE_SCOPE Tcl_Obj * TclNoErrorStack(Tcl_Interp *interp, Tcl_Obj *options);
MODULE_SCOPE int TclNokia770Doubles(void);
MODULE_SCOPE void TclNsDecrRefCount(Namespace *nsPtr);
MODULE_SCOPE void TclNsDecrRefCount(Namespace *nsPtr);
MODULE_SCOPE int TclNamespaceDeleted(Namespace *nsPtr);
MODULE_SCOPE void TclObjVarErrMsg(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
Tcl_Obj *part2Ptr, const char *operation,
const char *reason, int index);
@@ -3200,6 +3202,13 @@ MODULE_SCOPE void TclInitThreadStorage(void);
MODULE_SCOPE void TclFinalizeThreadDataThread(void);
MODULE_SCOPE void TclFinalizeThreadStorage(void);
/* TclWideMUInt -- wide integer used for measurement calculations: */
#if (!defined(_WIN32) || !defined(_MSC_VER) || (_MSC_VER >= 1400))
# define TclWideMUInt Tcl_WideUInt
#else
/* older MSVS may not allow conversions between unsigned __int64 and double) */
# define TclWideMUInt Tcl_WideInt
#endif
#ifdef TCL_WIDE_CLICKS
MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void);
MODULE_SCOPE double TclpWideClicksToNanoseconds(Tcl_WideInt clicks);
@@ -3942,39 +3951,21 @@ MODULE_SCOPE int TclDivOpCmd(ClientData clientData,
MODULE_SCOPE int TclCompileDivOpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclLessOpCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
MODULE_SCOPE int TclCompileLessOpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclLeqOpCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
MODULE_SCOPE int TclCompileLeqOpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclGreaterOpCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
MODULE_SCOPE int TclCompileGreaterOpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclGeqOpCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
MODULE_SCOPE int TclCompileGeqOpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclEqOpCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
MODULE_SCOPE int TclCompileEqOpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclStreqOpCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
MODULE_SCOPE int TclCompileStreqOpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+17 -1
View File
@@ -23,6 +23,7 @@
typedef struct Link {
Tcl_Interp *interp; /* Interpreter containing Tcl variable. */
Namespace *nsPtr; /* Namespace containing Tcl variable */
Tcl_Obj *varName; /* Name of variable (must be global). This is
* needed during trace callbacks, since the
* actual variable may be aliased at that time
@@ -113,6 +114,8 @@ Tcl_LinkVar(
{
Tcl_Obj *objPtr;
Link *linkPtr;
Namespace *dummy;
const char *name;
int code;
linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL,
@@ -125,6 +128,7 @@ Tcl_LinkVar(
linkPtr = ckalloc(sizeof(Link));
linkPtr->interp = interp;
linkPtr->nsPtr = NULL;
linkPtr->varName = Tcl_NewStringObj(varName, -1);
Tcl_IncrRefCount(linkPtr->varName);
linkPtr->addr = addr;
@@ -141,11 +145,17 @@ Tcl_LinkVar(
ckfree(linkPtr);
return TCL_ERROR;
}
TclGetNamespaceForQualName(interp, varName, NULL, TCL_GLOBAL_ONLY,
&(linkPtr->nsPtr), &dummy, &dummy, &name);
linkPtr->nsPtr->refCount++;
code = Tcl_TraceVar2(interp, varName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
LinkTraceProc, linkPtr);
if (code != TCL_OK) {
Tcl_DecrRefCount(linkPtr->varName);
TclNsDecrRefCount(linkPtr->nsPtr);
ckfree(linkPtr);
}
return code;
@@ -184,6 +194,9 @@ Tcl_UnlinkVar(
TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
LinkTraceProc, linkPtr);
Tcl_DecrRefCount(linkPtr->varName);
if (linkPtr->nsPtr) {
TclNsDecrRefCount(linkPtr->nsPtr);
}
ckfree(linkPtr);
}
@@ -277,8 +290,11 @@ LinkTraceProc(
*/
if (flags & TCL_TRACE_UNSETS) {
if (Tcl_InterpDeleted(interp)) {
if (Tcl_InterpDeleted(interp) || TclNamespaceDeleted(linkPtr->nsPtr)) {
Tcl_DecrRefCount(linkPtr->varName);
if (linkPtr->nsPtr) {
TclNsDecrRefCount(linkPtr->nsPtr);
}
ckfree(linkPtr);
} else if (flags & TCL_TRACE_DESTROYED) {
Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+7 -7
View File
@@ -136,8 +136,8 @@ NewListIntRep(
*
* AttemptNewList --
*
* Like NewListIntRep, but additionally sets an error message on failure.
*
* Like NewListIntRep, but additionally sets an error message on failure.
*
*----------------------------------------------------------------------
*/
@@ -234,12 +234,12 @@ Tcl_NewListObj(
*----------------------------------------------------------------------
*
* Tcl_DbNewListObj --
*
*
* Like 'Tcl_NewListObj', but it calls Tcl_DbCkalloc directly with the
* file name and line number from its caller. This simplifies debugging
* since the [memory active] command will report the correct file
* name and line number when reporting objects that haven't been freed.
*
*
* When TCL_MEM_DEBUG is not defined, 'Tcl_NewListObj' is called instead.
*
*----------------------------------------------------------------------
@@ -695,7 +695,7 @@ Tcl_ListObjAppendElement(
* object should be treated as readonly and its 'refCount' is _not_
* incremented. The caller must do that if it holds on to the
* reference.
*
*
* TCL_ERROR
*
* 'listPtr' is not a valid list. An an error message is left in the
@@ -1331,9 +1331,9 @@ TclLsetList(
* reference. The caller is expected to store the result in the
* variable and decrement its reference count. (INST_STORE_* does
* exactly this.)
*
*
* NULL
*
*
* An error occurred. If 'listPtr' was duplicated, the reference
* count on the duplicate is decremented so that it is 0, causing any
* memory allocated by this function to be freed.
+7
View File
@@ -1071,6 +1071,13 @@ Tcl_DeleteNamespace(
}
TclNsDecrRefCount(nsPtr);
}
int
TclNamespaceDeleted(
Namespace *nsPtr)
{
return (nsPtr->flags & NS_DYING) ? 1 : 0;
}
/*
*----------------------------------------------------------------------
+110 -57
View File
@@ -365,14 +365,14 @@ InitFoundation(
*/
Tcl_DStringInit(&buffer);
for (i=0 ; defineCmds[i].name ; i++) {
for (i = 0 ; defineCmds[i].name ; i++) {
TclDStringAppendLiteral(&buffer, "::oo::define::");
Tcl_DStringAppend(&buffer, defineCmds[i].name, -1);
Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer),
defineCmds[i].objProc, INT2PTR(defineCmds[i].flag), NULL);
Tcl_DStringFree(&buffer);
}
for (i=0 ; objdefCmds[i].name ; i++) {
for (i = 0 ; objdefCmds[i].name ; i++) {
TclDStringAppendLiteral(&buffer, "::oo::objdefine::");
Tcl_DStringAppend(&buffer, objdefCmds[i].name, -1);
Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer),
@@ -387,30 +387,50 @@ InitFoundation(
* spliced manually.
*/
/* Stand up a phony class for bootstrapping. */
/*
* Stand up a phony class for bootstrapping.
*/
fPtr->objectCls = &fakeCls;
/* referenced in TclOOAllocClass to increment the refCount. */
/*
* Referenced in TclOOAllocClass to increment the refCount.
*/
fakeCls.thisPtr = &fakeObject;
fPtr->objectCls = TclOOAllocClass(interp,
AllocObject(interp, "object", (Namespace *)fPtr->ooNs, NULL));
/* Corresponding TclOODecrRefCount in KillFoudation */
/*
* Corresponding TclOODecrRefCount in KillFoudation.
*/
AddRef(fPtr->objectCls->thisPtr);
/* This is why it is unnecessary in this routine to replace the
/*
* This is why it is unnecessary in this routine to replace the
* incremented reference count of fPtr->objectCls that was swallowed by
* fakeObject. */
* fakeObject.
*/
fPtr->objectCls->superclasses.num = 0;
ckfree(fPtr->objectCls->superclasses.list);
fPtr->objectCls->superclasses.list = NULL;
/* special initialization for the primordial objects */
/*
* Special initialization for the primordial objects.
*/
fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT;
fPtr->objectCls->flags |= ROOT_OBJECT;
fPtr->classCls = TclOOAllocClass(interp,
AllocObject(interp, "class", (Namespace *)fPtr->ooNs, NULL));
/* Corresponding TclOODecrRefCount in KillFoudation */
/*
* Corresponding TclOODecrRefCount in KillFoudation.
*/
AddRef(fPtr->classCls->thisPtr);
/*
@@ -421,7 +441,10 @@ InitFoundation(
* KillFoundation.
*/
/* Rewire bootstrapped objects. */
/*
* Rewire bootstrapped objects.
*/
fPtr->objectCls->thisPtr->selfCls = fPtr->classCls;
AddRef(fPtr->classCls->thisPtr);
TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls);
@@ -433,17 +456,20 @@ InitFoundation(
fPtr->classCls->thisPtr->flags |= ROOT_CLASS;
fPtr->classCls->flags |= ROOT_CLASS;
/* Standard initialization for new Objects */
/*
* Standard initialization for new Objects.
*/
TclOOAddToSubclasses(fPtr->classCls, fPtr->objectCls);
/*
* Basic method declarations for the core classes.
*/
for (i=0 ; objMethods[i].name ; i++) {
for (i = 0 ; objMethods[i].name ; i++) {
TclOONewBasicMethod(interp, fPtr->objectCls, &objMethods[i]);
}
for (i=0 ; clsMethods[i].name ; i++) {
for (i = 0 ; clsMethods[i].name ; i++) {
TclOONewBasicMethod(interp, fPtr->classCls, &clsMethods[i]);
}
@@ -467,7 +493,7 @@ InitFoundation(
TclNewLiteralStringObj(namePtr, "new");
Tcl_NewInstanceMethod(interp, (Tcl_Object) fPtr->classCls->thisPtr,
namePtr /* keeps ref */, 0 /* ==private */, NULL, NULL);
namePtr /* keeps ref */, 0 /* private */, NULL, NULL);
fPtr->classCls->constructorPtr = (Method *) Tcl_NewMethod(interp,
(Tcl_Class) fPtr->classCls, NULL, 0, &classConstructor, NULL);
@@ -651,10 +677,8 @@ AllocObject(
Tcl_ResetResult(interp);
}
configNamespace:
((Namespace *)oPtr->namespacePtr)->refCount++;
((Namespace *) oPtr->namespacePtr)->refCount++;
/*
* Make the namespace know about the helper commands. This grants access
@@ -692,7 +716,7 @@ AllocObject(
/*
* An object starts life with a refCount of 2 to mark the two stages of
* destruction it occur: A call to ObjectRenamedTrace(), and a call to
* ObjectNamespaceDeleted().
* ObjectNamespaceDeleted().
*/
oPtr->refCount = 2;
@@ -847,10 +871,14 @@ TclOODeleteDescendants(
if (clsPtr->mixinSubs.num > 0) {
while (clsPtr->mixinSubs.num > 0) {
mixinSubclassPtr = clsPtr->mixinSubs.list[clsPtr->mixinSubs.num-1];
/* This condition also covers the case where mixinSubclassPtr ==
mixinSubclassPtr =
clsPtr->mixinSubs.list[clsPtr->mixinSubs.num - 1];
/*
* This condition also covers the case where mixinSubclassPtr ==
* clsPtr
*/
if (!Deleted(mixinSubclassPtr->thisPtr)
&& !(mixinSubclassPtr->thisPtr->flags & DONT_DELETE)) {
Tcl_DeleteCommandFromToken(interp,
@@ -869,7 +897,7 @@ TclOODeleteDescendants(
if (clsPtr->subclasses.num > 0) {
while (clsPtr->subclasses.num > 0) {
subclassPtr = clsPtr->subclasses.list[clsPtr->subclasses.num-1];
subclassPtr = clsPtr->subclasses.list[clsPtr->subclasses.num - 1];
if (!Deleted(subclassPtr->thisPtr) && !IsRoot(subclassPtr)
&& !(subclassPtr->thisPtr->flags & DONT_DELETE)) {
Tcl_DeleteCommandFromToken(interp,
@@ -890,8 +918,12 @@ TclOODeleteDescendants(
if (clsPtr->instances.num > 0) {
while (clsPtr->instances.num > 0) {
instancePtr = clsPtr->instances.list[clsPtr->instances.num-1];
/* This condition also covers the case where instancePtr == oPtr */
instancePtr = clsPtr->instances.list[clsPtr->instances.num - 1];
/*
* This condition also covers the case where instancePtr == oPtr
*/
if (!Deleted(instancePtr) && !IsRoot(instancePtr) &&
!(instancePtr->flags & DONT_DELETE)) {
Tcl_DeleteCommandFromToken(interp, instancePtr->command);
@@ -905,7 +937,6 @@ TclOODeleteDescendants(
clsPtr->instances.size = 0;
}
}
/*
* ----------------------------------------------------------------------
@@ -924,7 +955,7 @@ TclOOReleaseClassContents(
Object *oPtr) /* The object representing the class. */
{
FOREACH_HASH_DECLS;
int i;
int i;
Class *clsPtr = oPtr->classPtr, *tmpClsPtr;
Method *mPtr;
Foundation *fPtr = oPtr->fPtr;
@@ -1065,7 +1096,8 @@ ObjectNamespaceDeleted(
int i;
if (Deleted(oPtr)) {
/* To do: Can ObjectNamespaceDeleted ever be called twice? If not,
/*
* TODO: Can ObjectNamespaceDeleted ever be called twice? If not,
* this guard could be removed.
*/
return;
@@ -1078,7 +1110,10 @@ ObjectNamespaceDeleted(
*/
oPtr->flags |= OBJECT_DELETED;
/* Let the dominoes fall */
/*
* Let the dominoes fall!
*/
if (oPtr->classPtr) {
TclOODeleteDescendants(interp, oPtr);
}
@@ -1089,12 +1124,13 @@ ObjectNamespaceDeleted(
* in that case when the destructor is partially deleted before the uses
* of it have gone. [Bug 2949397]
*/
if (!Tcl_InterpDeleted(interp) && !(oPtr->flags & DESTRUCTOR_CALLED)) {
CallContext *contextPtr =
TclOOGetCallContext(oPtr, NULL, DESTRUCTOR, NULL);
int result;
Tcl_InterpState state;
oPtr->flags |= DESTRUCTOR_CALLED;
if (contextPtr != NULL) {
@@ -1113,12 +1149,12 @@ ObjectNamespaceDeleted(
/*
* Instruct everyone to no longer use any allocated fields of the object.
* Also delete the command that refers to the object at this point (if
* it still exists) because otherwise its pointer to the object
* points into freed memory.
* Also delete the command that refers to the object at this point (if it
* still exists) because otherwise its pointer to the object points into
* freed memory.
*/
if (((Command *)oPtr->command)->flags && CMD_IS_DELETED) {
if (((Command *) oPtr->command)->flags && CMD_IS_DELETED) {
/*
* Something has already started the command deletion process. We can
* go ahead and clean up the the namespace,
@@ -1128,6 +1164,7 @@ ObjectNamespaceDeleted(
* The namespace must have been deleted directly. Delete the command
* as well.
*/
Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command);
}
@@ -1140,7 +1177,7 @@ ObjectNamespaceDeleted(
* methods on the object.
*/
/* To do: Should this be protected with a * !IsRoot() condition? */
/* TODO: Should this be protected with a !IsRoot() condition? */
TclOORemoveFromInstances(oPtr, oPtr->selfCls);
if (oPtr->mixins.num > 0) {
@@ -1196,7 +1233,7 @@ ObjectNamespaceDeleted(
/*
* Because an object can be a class that is an instance of itself, the
* class object's class structure should only be cleaned after most of
* the cleanup on the object is done.
* the cleanup on the object is done.
*
* The class of objects needs some special care; if it is deleted (and
* we're not killing the whole interpreter) we force the delete of the
@@ -1249,10 +1286,13 @@ int TclOODecrRefCount(Object *oPtr) {
return 0;
}
/* setting the "empty" location to NULL makes debugging a little easier */
#define REMOVEBODY { \
/*
* Setting the "empty" location to NULL makes debugging a little easier.
*/
#define REMOVEBODY { \
for (; idx < num - 1; idx++) { \
list[idx] = list[idx+1]; \
list[idx] = list[idx + 1]; \
} \
list[idx] = NULL; \
return; \
@@ -1690,7 +1730,6 @@ TclNRNewObjectInstance(
TclPushTailcallPoint(interp);
return TclOOInvokeContext(contextPtr, interp, objc, objv);
}
Object *
TclNewObjectInstanceCommon(
@@ -1705,21 +1744,17 @@ TclNewObjectInstanceCommon(
const char *simpleName = NULL;
Namespace *nsPtr = NULL, *dummy,
*inNsPtr = (Namespace *)TclGetCurrentNamespace(interp);
int isNew;
if (nameStr) {
TclGetNamespaceForQualName(interp, nameStr, inNsPtr, TCL_CREATE_NS_IF_UNKNOWN,
&nsPtr, &dummy, &dummy, &simpleName);
TclGetNamespaceForQualName(interp, nameStr, inNsPtr,
TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy, &dummy, &simpleName);
/*
* Disallow creation of an object over an existing command.
*/
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, simpleName, &isNew);
if (isNew) {
/* Just kidding */
Tcl_DeleteHashEntry(hPtr);
} else {
hPtr = Tcl_FindHashEntry(&nsPtr->cmdTable, simpleName);
if (hPtr) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't create object \"%s\": command already exists with"
" that name", nameStr));
@@ -1736,6 +1771,7 @@ TclNewObjectInstanceCommon(
oPtr->selfCls = classPtr;
AddRef(classPtr->thisPtr);
TclOOAddToInstances(oPtr, classPtr);
/*
* Check to see if we're really creating a class. If so, allocate the
* class structure as well.
@@ -1757,8 +1793,6 @@ TclNewObjectInstanceCommon(
return oPtr;
}
static int
FinalizeAlloc(
ClientData data[],
@@ -1794,13 +1828,21 @@ FinalizeAlloc(
(void) TclOOObjectName(interp, oPtr);
Tcl_DeleteCommandFromToken(interp, oPtr->command);
}
/* This decrements the refcount of oPtr */
/*
* This decrements the refcount of oPtr.
*/
TclOODeleteContext(contextPtr);
return TCL_ERROR;
}
Tcl_RestoreInterpState(interp, state);
*objectPtr = (Tcl_Object) oPtr;
/* This decrements the refcount of oPtr */
/*
* This decrements the refcount of oPtr.
*/
TclOODeleteContext(contextPtr);
return TCL_OK;
}
@@ -1885,7 +1927,11 @@ Tcl_CopyObjectInstance(
if (mixinPtr && mixinPtr != o2Ptr->selfCls) {
TclOOAddToInstances(o2Ptr, mixinPtr);
}
/* For the reference just created in DUPLICATE */
/*
* For the reference just created in DUPLICATE.
*/
AddRef(mixinPtr->thisPtr);
}
@@ -1915,7 +1961,8 @@ Tcl_CopyObjectInstance(
*/
o2Ptr->flags = oPtr->flags & ~(
OBJECT_DELETED | ROOT_OBJECT | ROOT_CLASS | FILTER_HANDLING);
OBJECT_DELETED | ROOT_OBJECT | ROOT_CLASS | FILTER_HANDLING);
/*
* Copy the object's metadata.
*/
@@ -1979,9 +2026,11 @@ Tcl_CopyObjectInstance(
FOREACH(superPtr, cls2Ptr->superclasses) {
TclOOAddToSubclasses(cls2Ptr, superPtr);
/* For the new item in cls2Ptr->superclasses that memcpy just
* created
/*
* For the new item in cls2Ptr->superclasses that memcpy just
* created.
*/
AddRef(superPtr->thisPtr);
}
@@ -2018,7 +2067,11 @@ Tcl_CopyObjectInstance(
DUPLICATE(cls2Ptr->mixins, clsPtr->mixins, Class *);
FOREACH(mixinPtr, cls2Ptr->mixins) {
TclOOAddToMixinSubs(cls2Ptr, mixinPtr);
/* For the copy just created in DUPLICATE */
/*
* For the copy just created in DUPLICATE.
*/
AddRef(mixinPtr->thisPtr);
}
@@ -2619,7 +2672,7 @@ Tcl_ObjectContextInvokeNext(
int savedSkip = contextPtr->skip;
int result;
if (contextPtr->index+1 >= contextPtr->callPtr->numChain) {
if (contextPtr->index + 1 >= contextPtr->callPtr->numChain) {
/*
* We're at the end of the chain; generate an error message unless the
* interpreter is being torn down, in which case we might be getting
@@ -2688,7 +2741,7 @@ TclNRObjectContextInvokeNext(
{
register CallContext *contextPtr = (CallContext *) context;
if (contextPtr->index+1 >= contextPtr->callPtr->numChain) {
if (contextPtr->index + 1 >= contextPtr->callPtr->numChain) {
/*
* We're at the end of the chain; generate an error message unless the
* interpreter is being torn down, in which case we might be getting
+22 -11
View File
@@ -110,7 +110,11 @@ TclOODeleteContext(
TclOODeleteChain(contextPtr->callPtr);
if (oPtr != NULL) {
TclStackFree(oPtr->fPtr->interp, contextPtr);
/* Corresponding AddRef() in TclOO.c/TclOOObjectCmdCore */
/*
* Corresponding AddRef() in TclOO.c/TclOOObjectCmdCore
*/
TclOODecrRefCount(oPtr);
}
}
@@ -265,7 +269,7 @@ TclOOInvokeContext(
if (contextPtr->index == 0) {
int i;
for (i=0 ; i<contextPtr->callPtr->numChain ; i++) {
for (i = 0 ; i < contextPtr->callPtr->numChain ; i++) {
AddRef(contextPtr->callPtr->chain[i].mPtr);
}
@@ -343,7 +347,7 @@ FinalizeMethodRefs(
CallContext *contextPtr = data[0];
int i;
for (i=0 ; i<contextPtr->callPtr->numChain ; i++) {
for (i = 0 ; i < contextPtr->callPtr->numChain ; i++) {
TclOODelMethodRef(contextPtr->callPtr->chain[i].mPtr);
}
return result;
@@ -568,7 +572,10 @@ TclOOGetSortedClassMethodList(
return i;
}
/* Comparator for GetSortedMethodList */
/*
* Comparator for GetSortedMethodList
*/
static int
CmpStr(
const void *ptr1,
@@ -577,7 +584,7 @@ CmpStr(
const char **strPtr1 = (const char **) ptr1;
const char **strPtr2 = (const char **) ptr2;
return TclpUtfNcmp2(*strPtr1, *strPtr2, strlen(*strPtr1)+1);
return TclpUtfNcmp2(*strPtr1, *strPtr2, strlen(*strPtr1) + 1);
}
/*
@@ -824,7 +831,7 @@ AddMethodToCallChain(
* any leading filters.
*/
for (i=cbPtr->filterLength ; i<callPtr->numChain ; i++) {
for (i = cbPtr->filterLength ; i < callPtr->numChain ; i++) {
if (callPtr->chain[i].mPtr == mPtr &&
callPtr->chain[i].isFilter == (doneFilters != NULL)) {
/*
@@ -836,8 +843,8 @@ AddMethodToCallChain(
Class *declCls = callPtr->chain[i].filterDeclarer;
for (; i+1<callPtr->numChain ; i++) {
callPtr->chain[i] = callPtr->chain[i+1];
for (; i + 1 < callPtr->numChain ; i++) {
callPtr->chain[i] = callPtr->chain[i + 1];
}
callPtr->chain[i].mPtr = mPtr;
callPtr->chain[i].isFilter = (doneFilters != NULL);
@@ -854,7 +861,7 @@ AddMethodToCallChain(
if (callPtr->numChain == CALL_CHAIN_STATIC_SIZE) {
callPtr->chain =
ckalloc(sizeof(struct MInvoke) * (callPtr->numChain+1));
ckalloc(sizeof(struct MInvoke) * (callPtr->numChain + 1));
memcpy(callPtr->chain, callPtr->staticChain,
sizeof(struct MInvoke) * callPtr->numChain);
} else if (callPtr->numChain > CALL_CHAIN_STATIC_SIZE) {
@@ -1172,7 +1179,11 @@ TclOOGetCallContext(
returnContext:
contextPtr = TclStackAlloc(oPtr->fPtr->interp, sizeof(CallContext));
contextPtr->oPtr = oPtr;
/* Corresponding TclOODecrRefCount() in TclOODeleteContext */
/*
* Corresponding TclOODecrRefCount() in TclOODeleteContext
*/
AddRef(oPtr);
contextPtr->callPtr = callPtr;
contextPtr->skip = 2;
@@ -1528,7 +1539,7 @@ TclOORenderCallChain(
*/
objv = TclStackAlloc(interp, callPtr->numChain * sizeof(Tcl_Obj *));
for (i=0 ; i<callPtr->numChain ; i++) {
for (i = 0 ; i < callPtr->numChain ; i++) {
struct MInvoke *miPtr = &callPtr->chain[i];
descObjs[0] = miPtr->isFilter
+61 -37
View File
@@ -40,6 +40,12 @@ struct DeclaredSlot {
{TCL_OO_METHOD_VERSION_CURRENT, "core method: " name " Setter", \
setter, NULL, NULL}}
/*
* A [string match] pattern used to determine if a method should be exported.
*/
#define PUBLIC_PATTERN "[a-z]*"
/*
* Forward declarations.
*/
@@ -232,7 +238,7 @@ TclOOObjectSetFilters(
} else {
filtersList = ckrealloc(oPtr->filters.list, size);
}
for (i=0 ; i<numFilters ; i++) {
for (i = 0 ; i < numFilters ; i++) {
filtersList[i] = filters[i];
Tcl_IncrRefCount(filters[i]);
}
@@ -290,7 +296,7 @@ TclOOClassSetFilters(
} else {
filtersList = ckrealloc(classPtr->filters.list, size);
}
for (i=0 ; i<numFilters ; i++) {
for (i = 0 ; i < numFilters ; i++) {
filtersList[i] = filters[i];
Tcl_IncrRefCount(filters[i]);
}
@@ -352,7 +358,11 @@ TclOOObjectSetMixins(
FOREACH(mixinPtr, oPtr->mixins) {
if (mixinPtr != oPtr->selfCls) {
TclOOAddToInstances(oPtr, mixinPtr);
/* For the new copy created by memcpy */
/*
* For the new copy created by memcpy().
*/
AddRef(mixinPtr->thisPtr);
}
}
@@ -403,7 +413,11 @@ TclOOClassSetMixins(
memcpy(classPtr->mixins.list, mixins, sizeof(Class *) * numMixins);
FOREACH(mixinPtr, classPtr->mixins) {
TclOOAddToMixinSubs(classPtr, mixinPtr);
/* For the new copy created by memcpy */
/*
* For the new copy created by memcpy.
*/
AddRef(mixinPtr->thisPtr);
}
}
@@ -556,15 +570,16 @@ TclOOUnknownDefinition(
* Got one match, and only one match!
*/
Tcl_Obj **newObjv = TclStackAlloc(interp, sizeof(Tcl_Obj*)*(objc-1));
Tcl_Obj **newObjv =
TclStackAlloc(interp, sizeof(Tcl_Obj*) * (objc - 1));
int result;
newObjv[0] = Tcl_NewStringObj(matchedStr, -1);
Tcl_IncrRefCount(newObjv[0]);
if (objc > 2) {
memcpy(newObjv+1, objv+2, sizeof(Tcl_Obj *) * (objc-2));
memcpy(newObjv + 1, objv + 2, sizeof(Tcl_Obj *) * (objc - 2));
}
result = Tcl_EvalObjv(interp, objc-1, newObjv, 0);
result = Tcl_EvalObjv(interp, objc - 1, newObjv, 0);
Tcl_DecrRefCount(newObjv[0]);
TclStackFree(interp, newObjv);
return result;
@@ -666,7 +681,9 @@ InitDefineContext(
return TCL_ERROR;
}
/* framePtrPtr is needed to satisfy GCC 3.3's strict aliasing rules */
/*
* framePtrPtr is needed to satisfy GCC 3.3's strict aliasing rules.
*/
(void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
namespacePtr, FRAME_IS_OO_DEFINE);
@@ -837,17 +854,20 @@ MagicDefinitionInvoke(
obj2Ptr = Tcl_NewObj();
cmd = FindCommand(interp, objv[cmdIndex], nsPtr);
if (cmd == NULL) {
/* punt this case! */
/*
* Punt this case!
*/
Tcl_AppendObjToObj(obj2Ptr, objv[cmdIndex]);
} else {
Tcl_GetCommandFullName(interp, cmd, obj2Ptr);
}
Tcl_ListObjAppendElement(NULL, objPtr, obj2Ptr);
/* TODO: overflow? */
Tcl_ListObjReplace(NULL, objPtr, 1, 0, objc-offset, objv+offset);
Tcl_ListObjReplace(NULL, objPtr, 1, 0, objc - offset, objv + offset);
Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
result = Tcl_EvalObjv(interp, objc-cmdIndex, objs, TCL_EVAL_INVOKE);
result = Tcl_EvalObjv(interp, objc - cmdIndex, objs, TCL_EVAL_INVOKE);
if (isRoot) {
TclResetRewriteEnsemble(interp, 1);
}
@@ -1277,7 +1297,7 @@ TclOODefineDeleteMethodObjCmd(
return TCL_ERROR;
}
for (i=1 ; i<objc ; i++) {
for (i = 1; i < objc; i++) {
/*
* Delete the method structure from the appropriate hash table.
*/
@@ -1401,7 +1421,7 @@ TclOODefineExportObjCmd(
return TCL_ERROR;
}
for (i=1 ; i<objc ; i++) {
for (i = 1; i < objc; i++) {
/*
* Exporting is done by adding the PUBLIC_METHOD flag to the method
* record. If there is no such method in this object or class (i.e.
@@ -1492,14 +1512,14 @@ TclOODefineForwardObjCmd(
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*")
isPublic = Tcl_StringMatch(TclGetString(objv[1]), PUBLIC_PATTERN)
? PUBLIC_METHOD : 0;
/*
* Create the method structure.
*/
prefixObj = Tcl_NewListObj(objc-2, objv+2);
prefixObj = Tcl_NewListObj(objc - 2, objv + 2);
if (isInstanceForward) {
mPtr = TclOONewForwardInstanceMethod(interp, oPtr, isPublic, objv[1],
prefixObj);
@@ -1550,7 +1570,7 @@ TclOODefineMethodObjCmd(
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*")
isPublic = Tcl_StringMatch(TclGetString(objv[1]), PUBLIC_PATTERN)
? PUBLIC_METHOD : 0;
/*
@@ -1668,7 +1688,7 @@ TclOODefineUnexportObjCmd(
return TCL_ERROR;
}
for (i=1 ; i<objc ; i++) {
for (i = 1; i < objc; i++) {
/*
* Unexporting is done by removing the PUBLIC_METHOD flag from the
* method record. If there is no such method in this object or class
@@ -1803,7 +1823,7 @@ TclOODefineSlots(
Tcl_IncrRefCount(setName);
for (slotInfoPtr = slots ; slotInfoPtr->name ; slotInfoPtr++) {
Tcl_Object slotObject = Tcl_NewObjectInstance(fPtr->interp,
(Tcl_Class) slotCls, slotInfoPtr->name, NULL,-1,NULL,0);
(Tcl_Class) slotCls, slotInfoPtr->name, NULL, -1, NULL, 0);
if (slotObject == NULL) {
continue;
@@ -1874,7 +1894,7 @@ ClassFilterSet(
int filterc;
Tcl_Obj **filterv;
if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) {
Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
"filterList");
return TCL_ERROR;
@@ -1957,7 +1977,7 @@ ClassMixinSet(
Tcl_Obj **mixinv;
Class **mixins;
if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) {
Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
"mixinList");
return TCL_ERROR;
@@ -1978,7 +1998,7 @@ ClassMixinSet(
mixins = TclStackAlloc(interp, sizeof(Class *) * mixinc);
for (i=0 ; i<mixinc ; i++) {
for (i = 0; i < mixinc; i++) {
mixins[i] = GetClassInOuterContext(interp, mixinv[i],
"may only mix in classes");
if (mixins[i] == NULL) {
@@ -2061,7 +2081,7 @@ ClassSuperSet(
Tcl_Obj **superv;
Class **superclasses, *superPtr;
if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) {
Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
"superclassList");
return TCL_ERROR;
@@ -2108,14 +2128,14 @@ ClassSuperSet(
superc = 1;
AddRef(superclasses[0]->thisPtr);
} else {
for (i=0 ; i<superc ; i++) {
for (i = 0; i < superc; i++) {
superclasses[i] = GetClassInOuterContext(interp, superv[i],
"only a class can be a superclass");
if (superclasses[i] == NULL) {
i--;
goto failedAfterAlloc;
}
for (j=0 ; j<i ; j++) {
for (j = 0; j < i; j++) {
if (superclasses[j] == superclasses[i]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"class should only be a direct superclass once",
@@ -2135,8 +2155,12 @@ ClassSuperSet(
ckfree(superclasses);
return TCL_ERROR;
}
/* Corresponding TclOODecrRefCount() is near the end of this
* function */
/*
* Corresponding TclOODecrRefCount() is near the end of this
* function.
*/
AddRef(superclasses[i]->thisPtr);
}
}
@@ -2222,7 +2246,7 @@ ClassVarsSet(
Tcl_Obj **varv, *variableObj;
int i;
if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) {
Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
"filterList");
return TCL_ERROR;
@@ -2241,7 +2265,7 @@ ClassVarsSet(
return TCL_ERROR;
}
for (i=0 ; i<varc ; i++) {
for (i = 0; i < varc; i++) {
const char *varName = Tcl_GetString(varv[i]);
if (strstr(varName, "::") != NULL) {
@@ -2260,7 +2284,7 @@ ClassVarsSet(
}
}
for (i=0 ; i<varc ; i++) {
for (i = 0; i < varc; i++) {
Tcl_IncrRefCount(varv[i]);
}
FOREACH(variableObj, oPtr->classPtr->variables) {
@@ -2285,7 +2309,7 @@ ClassVarsSet(
Tcl_HashTable uniqueTable;
Tcl_InitObjHashTable(&uniqueTable);
for (i=n=0 ; i<varc ; i++) {
for (i = n = 0; i < varc; i++) {
Tcl_CreateHashEntry(&uniqueTable, varv[i], &created);
if (created) {
oPtr->classPtr->variables.list[n++] = varv[i];
@@ -2357,7 +2381,7 @@ ObjFilterSet(
int filterc;
Tcl_Obj **filterv;
if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) {
Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
"filterList");
return TCL_ERROR;
@@ -2430,7 +2454,7 @@ ObjMixinSet(
Class **mixins;
int i;
if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) {
Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
"mixinList");
return TCL_ERROR;
@@ -2445,7 +2469,7 @@ ObjMixinSet(
mixins = TclStackAlloc(interp, sizeof(Class *) * mixinc);
for (i=0 ; i<mixinc ; i++) {
for (i = 0; i < mixinc; i++) {
mixins[i] = GetClassInOuterContext(interp, mixinv[i],
"may only mix in classes");
if (mixins[i] == NULL) {
@@ -2509,7 +2533,7 @@ ObjVarsSet(
int varc, i;
Tcl_Obj **varv, *variableObj;
if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
if (Tcl_ObjectContextSkippedArgs(context) + 1 != objc) {
Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
"variableList");
return TCL_ERROR;
@@ -2522,7 +2546,7 @@ ObjVarsSet(
return TCL_ERROR;
}
for (i=0 ; i<varc ; i++) {
for (i = 0; i < varc; i++) {
const char *varName = Tcl_GetString(varv[i]);
if (strstr(varName, "::") != NULL) {
@@ -2540,7 +2564,7 @@ ObjVarsSet(
return TCL_ERROR;
}
}
for (i=0 ; i<varc ; i++) {
for (i = 0; i < varc; i++) {
Tcl_IncrRefCount(varv[i]);
}
@@ -2565,7 +2589,7 @@ ObjVarsSet(
Tcl_HashTable uniqueTable;
Tcl_InitObjHashTable(&uniqueTable);
for (i=n=0 ; i<varc ; i++) {
for (i = n = 0; i < varc; i++) {
Tcl_CreateHashEntry(&uniqueTable, varv[i], &created);
if (created) {
oPtr->variables.list[n++] = varv[i];
+1 -1
View File
@@ -563,7 +563,7 @@ MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr);
#define FOREACH(var,ary) \
for(i=0 ; i<(ary).num; i++) if ((ary).list[i] == NULL) { \
continue; \
} else if (var = (ary).list[i], 1)
} else if (var = (ary).list[i], 1)
/*
* Convenience macros for iterating through hash tables. FOREACH_HASH_DECLS
+6 -6
View File
@@ -2476,7 +2476,7 @@ Tcl_SetIntObj(
* Success.
*
* TCL_ERROR
*
*
* An error occurred during conversion or the integral value can not
* be represented as an integer (it might be too large). An error
* message is left in the interpreter's result if 'interp' is not
@@ -2804,8 +2804,8 @@ Tcl_GetLongFromObj(
mp_int big;
UNPACK_BIGNUM(objPtr, big);
if ((size_t) big.used <= (CHAR_BIT * sizeof(long) + DIGIT_BIT - 1)
/ DIGIT_BIT) {
if ((size_t) big.used <= (CHAR_BIT * sizeof(long) + MP_DIGIT_BIT - 1)
/ MP_DIGIT_BIT) {
unsigned long value = 0, numBytes = sizeof(long);
long scratch;
unsigned char *bytes = (unsigned char *) &scratch;
@@ -3104,7 +3104,7 @@ Tcl_GetWideIntFromObj(
UNPACK_BIGNUM(objPtr, big);
if ((size_t) big.used <= (CHAR_BIT * sizeof(Tcl_WideInt)
+ DIGIT_BIT - 1) / DIGIT_BIT) {
+ MP_DIGIT_BIT - 1) / MP_DIGIT_BIT) {
Tcl_WideUInt value = 0;
unsigned long numBytes = sizeof(Tcl_WideInt);
Tcl_WideInt scratch;
@@ -3523,7 +3523,7 @@ Tcl_SetBignumObj(
Tcl_Panic("%s called with shared object", "Tcl_SetBignumObj");
}
if ((size_t) bignumValue->used
<= (CHAR_BIT * sizeof(long) + DIGIT_BIT - 1) / DIGIT_BIT) {
<= (CHAR_BIT * sizeof(long) + MP_DIGIT_BIT - 1) / MP_DIGIT_BIT) {
unsigned long value = 0, numBytes = sizeof(long);
long scratch;
unsigned char *bytes = (unsigned char *) &scratch;
@@ -3548,7 +3548,7 @@ Tcl_SetBignumObj(
tooLargeForLong:
#ifndef TCL_WIDE_INT_IS_LONG
if ((size_t) bignumValue->used
<= (CHAR_BIT * sizeof(Tcl_WideInt) + DIGIT_BIT - 1) / DIGIT_BIT) {
<= (CHAR_BIT * sizeof(Tcl_WideInt) + MP_DIGIT_BIT - 1) / MP_DIGIT_BIT) {
Tcl_WideUInt value = 0;
unsigned long numBytes = sizeof(Tcl_WideInt);
Tcl_WideInt scratch;
+1 -1
View File
@@ -510,7 +510,7 @@ SelectPackage(ClientData data[], Tcl_Interp *interp, int result) {
PkgAvail *availPtr, *bestPtr, *bestStablePtr;
char *availVersion, *bestVersion, *bestStableVersion;
/* Internal rep. of versions */
int availStable, satisfies;
int availStable, satisfies;
Require *reqPtr = data[0];
int reqc = PTR2INT(data[1]);
Tcl_Obj **const reqv = data[2];
+20 -20
View File
@@ -1855,15 +1855,15 @@ RefineApproximation(
*/
msb = binExponent + M2; /* 1008 */
nDigits = msb / DIGIT_BIT + 1;
nDigits = msb / MP_DIGIT_BIT + 1;
mp_init_size(&twoMv, nDigits);
i = (msb % DIGIT_BIT + 1);
i = (msb % MP_DIGIT_BIT + 1);
twoMv.used = nDigits;
significand *= SafeLdExp(1.0, i);
while (--nDigits >= 0) {
twoMv.dp[nDigits] = (mp_digit) significand;
significand -= (mp_digit) significand;
significand = SafeLdExp(significand, DIGIT_BIT);
significand = SafeLdExp(significand, MP_DIGIT_BIT);
}
for (i = 0; i <= 8; ++i) {
if (M5 & (1 << i)) {
@@ -3162,7 +3162,7 @@ ShouldBankerRoundUpPowD(
int isodd) /* 1 if the digit is odd, 0 if even. */
{
int i;
static const mp_digit topbit = ((mp_digit)1) << (DIGIT_BIT - 1);
static const mp_digit topbit = ((mp_digit)1) << (MP_DIGIT_BIT - 1);
if (b->used < sd || (b->dp[sd-1] & topbit) == 0) {
return 0;
@@ -3294,7 +3294,7 @@ ShorteningBignumConversionPowD(
*/
TclBNInitBignumFromWideUInt(&b, bw);
mp_init_set_int(&mminus, 1);
mp_init_set(&mminus, 1);
MulPow5(&b, b5, &b);
mp_mul_2d(&b, b2, &b);
@@ -3690,7 +3690,7 @@ ShorteningBignumConversion(
TclBNInitBignumFromWideUInt(&b, bw);
mp_mul_2d(&b, b2, &b);
mp_init_set_int(&S, 1);
mp_init_set(&S, 1);
MulPow5(&S, s5, &S); mp_mul_2d(&S, s2, &S);
/*
@@ -3708,7 +3708,7 @@ ShorteningBignumConversion(
* mminus = 2**m2minus * 5**m5
*/
mp_init_set_int(&mminus, minit);
mp_init_set(&mminus, minit);
mp_mul_2d(&mminus, m2minus, &mminus);
if (m2plus > m2minus) {
mp_init_copy(&mplus, &mminus);
@@ -3903,7 +3903,7 @@ StrictBignumConversion(
mp_init_multi(&temp, &dig, NULL);
TclBNInitBignumFromWideUInt(&b, bw);
mp_mul_2d(&b, b2, &b);
mp_init_set_int(&S, 1);
mp_init_set(&S, 1);
MulPow5(&S, s5, &S); mp_mul_2d(&S, s2, &S);
/*
@@ -4268,8 +4268,8 @@ TclDoubleDigits(
* in the denominator' case.
*/
if (s2 % DIGIT_BIT != 0) {
int delta = DIGIT_BIT - (s2 % DIGIT_BIT);
if (s2 % MP_DIGIT_BIT != 0) {
int delta = MP_DIGIT_BIT - (s2 % MP_DIGIT_BIT);
b2 += delta;
m2plus += delta;
@@ -4277,7 +4277,7 @@ TclDoubleDigits(
s2 += delta;
}
return ShorteningBignumConversionPowD(&d, convType, bw, b2, b5,
m2plus, m2minus, m5, s2/DIGIT_BIT, k, len, ilim, ilim1,
m2plus, m2minus, m5, s2/MP_DIGIT_BIT, k, len, ilim, ilim1,
decpt, endPtr);
} else {
/*
@@ -4324,14 +4324,14 @@ TclDoubleDigits(
* in the denominator' case.
*/
if (s2 % DIGIT_BIT != 0) {
int delta = DIGIT_BIT - (s2 % DIGIT_BIT);
if (s2 % MP_DIGIT_BIT != 0) {
int delta = MP_DIGIT_BIT - (s2 % MP_DIGIT_BIT);
b2 += delta;
s2 += delta;
}
return StrictBignumConversionPowD(&d, convType, bw, b2, b5,
s2/DIGIT_BIT, k, len, ilim, ilim1, decpt, endPtr);
s2/MP_DIGIT_BIT, k, len, ilim, ilim1, decpt, endPtr);
} else {
/*
* There are no helpful special cases, but at least we know in
@@ -4456,7 +4456,7 @@ TclInitDoubleConversion(void)
+ 0.5 * log(10.)) / log(10.));
minDigits = (int) floor((DBL_MIN_EXP - DBL_MANT_DIG)
* log((double) FLT_RADIX) / log(10.));
log10_DIGIT_MAX = (int) floor(DIGIT_BIT * log(2.) / log(10.));
log10_DIGIT_MAX = (int) floor(MP_DIGIT_BIT * log(2.) / log(10.));
/*
* Nokia 770's software-emulated floating point is "middle endian": the
@@ -4631,7 +4631,7 @@ TclBignumToDouble(
*/
mp_div_2d(a, -shift, &b, NULL);
if (mp_get_bit(&b, 0)) {
if (mp_isodd(&b)) {
if (b.sign == MP_ZPOS) {
mp_add_d(&b, 1, &b);
} else {
@@ -4660,7 +4660,7 @@ TclBignumToDouble(
r = 0.0;
for (i=b.used-1 ; i>=0 ; --i) {
r = ldexp(r, DIGIT_BIT) + b.dp[i];
r = ldexp(r, MP_DIGIT_BIT) + b.dp[i];
}
mp_clear(&b);
@@ -4729,7 +4729,7 @@ TclCeil(
mp_add_d(&b, 1, &b);
}
for (i=b.used-1 ; i>=0 ; --i) {
r = ldexp(r, DIGIT_BIT) + b.dp[i];
r = ldexp(r, MP_DIGIT_BIT) + b.dp[i];
}
r = ldexp(r, bits - mantBits);
}
@@ -4779,7 +4779,7 @@ TclFloor(
mp_copy(a, &b);
}
for (i=b.used-1 ; i>=0 ; --i) {
r = ldexp(r, DIGIT_BIT) + b.dp[i];
r = ldexp(r, MP_DIGIT_BIT) + b.dp[i];
}
r = ldexp(r, bits - mantBits);
}
@@ -4841,7 +4841,7 @@ BignumToBiasedFrExp(
r = 0.0;
for (i=b.used-1; i>=0; --i) {
r = ldexp(r, DIGIT_BIT) + b.dp[i];
r = ldexp(r, MP_DIGIT_BIT) + b.dp[i];
}
mp_clear(&b);
+8 -8
View File
@@ -503,7 +503,7 @@ TclCheckEmptyString (
Tcl_DictObjSize(NULL, objPtr, &length);
return length == 0;
}
if (objPtr->bytes == NULL) {
return TCL_EMPTYSTRING_UNKNOWN;
}
@@ -2044,7 +2044,7 @@ Tcl_AppendFormatToObj(
if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) {
goto error;
}
mp_mod_2d(&big, (int) CHAR_BIT*sizeof(Tcl_WideInt), &big);
mp_mod_2d(&big, CHAR_BIT*sizeof(Tcl_WideInt), &big);
objPtr = Tcl_NewBignumObj(&big);
Tcl_IncrRefCount(objPtr);
Tcl_GetWideIntFromObj(NULL, objPtr, &w);
@@ -2059,7 +2059,7 @@ Tcl_AppendFormatToObj(
if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) {
goto error;
}
mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big);
mp_mod_2d(&big, CHAR_BIT * sizeof(long), &big);
objPtr = Tcl_NewBignumObj(&big);
Tcl_IncrRefCount(objPtr);
TclGetLongFromObj(NULL, objPtr, &l);
@@ -2218,11 +2218,11 @@ Tcl_AppendFormatToObj(
}
#endif
} else if (useBig && big.used) {
int leftover = (big.used * DIGIT_BIT) % numBits;
mp_digit mask = (~(mp_digit)0) << (DIGIT_BIT-leftover);
int leftover = (big.used * MP_DIGIT_BIT) % numBits;
mp_digit mask = (~(mp_digit)0) << (MP_DIGIT_BIT-leftover);
numDigits = 1 +
(((Tcl_WideInt) big.used * DIGIT_BIT) / numBits);
(((Tcl_WideInt) big.used * MP_DIGIT_BIT) / numBits);
while ((mask & big.dp[big.used-1]) == 0) {
numDigits--;
mask >>= numBits;
@@ -2258,9 +2258,9 @@ Tcl_AppendFormatToObj(
if (useBig && big.used) {
if (index < big.used && (size_t) shift <
CHAR_BIT*sizeof(Tcl_WideUInt) - DIGIT_BIT) {
CHAR_BIT*sizeof(Tcl_WideUInt) - MP_DIGIT_BIT) {
bits |= ((Tcl_WideUInt) big.dp[index++]) << shift;
shift += DIGIT_BIT;
shift += MP_DIGIT_BIT;
}
shift -= numBits;
}
+7 -1
View File
@@ -51,6 +51,12 @@
#undef TclWinGetServByName
#undef TclWinGetSockOpt
#undef TclWinSetSockOpt
#undef TclBN_mp_tc_and
#undef TclBN_mp_tc_or
#undef TclBN_mp_tc_xor
#define TclBN_mp_tc_and TclBN_mp_and
#define TclBN_mp_tc_or TclBN_mp_or
#define TclBN_mp_tc_xor TclBN_mp_xor
/* See bug 510001: TclSockMinimumBuffers needs plat imp */
#ifdef _WIN64
@@ -862,7 +868,7 @@ const TclTomMathStubs tclTomMathStubs = {
TclBN_mp_tc_and, /* 73 */
TclBN_mp_tc_or, /* 74 */
TclBN_mp_tc_xor, /* 75 */
TclBN_mp_tc_div_2d, /* 76 */
TclBN_mp_signed_rsh, /* 76 */
TclBN_mp_get_bit, /* 77 */
};
+6 -4
View File
@@ -952,8 +952,10 @@ AsyncHandlerProc(
Tcl_MutexLock(&asyncTestMutex);
for (asyncPtr = firstHandler; asyncPtr != NULL;
asyncPtr = asyncPtr->nextPtr) {
if (asyncPtr->id == id) break;
asyncPtr = asyncPtr->nextPtr) {
if (asyncPtr->id == id) {
break;
}
}
Tcl_MutexUnlock(&asyncTestMutex);
@@ -4347,7 +4349,7 @@ TesttranslatefilenameCmd(
*
* TestupvarCmd --
*
* This procedure implements the "testupvar2" command. It is used
* This procedure implements the "testupvar" command. It is used
* to test Tcl_UpVar and Tcl_UpVar2.
*
* Results:
@@ -4969,7 +4971,7 @@ NoopObjCmd(
* without type and with internal representation containing NULL's.
*
* If no argument supplied it returns empty object with tclEmptyStringRep,
* otherwise it returns this as pure bytes object with bytes value equal
* otherwise it returns this as pure bytes object with bytes value equal
* string.
*
* Results:
+2 -2
View File
@@ -290,9 +290,9 @@ TestbignumobjCmd(
return TCL_ERROR;
}
if (!Tcl_IsShared(varPtr[varIndex])) {
Tcl_SetIntObj(varPtr[varIndex], !mp_get_bit(&bignumValue, 0));
Tcl_SetIntObj(varPtr[varIndex], !mp_isodd(&bignumValue));
} else {
SetVarToObj(varPtr, varIndex, Tcl_NewIntObj(!mp_get_bit(&bignumValue, 0)));
SetVarToObj(varPtr, varIndex, Tcl_NewIntObj(!mp_isodd(&bignumValue)));
}
mp_clear(&bignumValue);
break;
+13 -7
View File
@@ -310,8 +310,8 @@ TclCreateAbsoluteTimerHandler(
timerHandlerPtr->token = (Tcl_TimerToken) INT2PTR(tsdPtr->lastTimerId);
/*
* Add the event to the queue in the correct position
* (ordered by event firing time).
* Add the event to the queue in the correct position (ordered by event
* firing time).
*/
for (tPtr2 = tsdPtr->firstTimerHandlerPtr, prevPtr = NULL; tPtr2 != NULL;
@@ -1019,8 +1019,8 @@ AfterDelay(
Tcl_GetTime(&now);
endTime = now;
endTime.sec += (long)(ms/1000);
endTime.usec += ((int)(ms%1000))*1000;
endTime.sec += (long)(ms / 1000);
endTime.usec += ((int)(ms % 1000)) * 1000;
if (endTime.usec >= 1000000) {
endTime.sec++;
endTime.usec -= 1000000;
@@ -1053,11 +1053,17 @@ AfterDelay(
if (diff > TCL_TIME_MAXIMUM_SLICE) {
diff = TCL_TIME_MAXIMUM_SLICE;
}
if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) diff = 1;
if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) {
diff = 1;
}
if (diff > 0) {
Tcl_Sleep((long) diff);
if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) break;
} else break;
if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) {
break;
}
} else {
break;
}
} else {
diff = TCL_TIME_DIFF_MS(iPtr->limit.time, now);
#ifndef TCL_WIDE_INT_IS_LONG
+1 -1
View File
@@ -252,7 +252,7 @@ declare 75 {
int TclBN_mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c)
}
declare 76 {
int TclBN_mp_tc_div_2d(const mp_int *a, int b, mp_int *c)
int TclBN_mp_signed_rsh(const mp_int *a, int b, mp_int *c)
}
declare 77 {
+69 -48
View File
@@ -1,14 +1,6 @@
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#ifndef BN_H_
#define BN_H_
@@ -92,7 +84,11 @@ typedef unsigned int mp_digit;
#define MP_DIGIT_DECLARED
#endif
#ifndef MP_WORD_DECLARED
#ifdef _WIN32
typedef unsigned __int64 mp_word;
#else
typedef unsigned long long mp_word;
#endif
#define MP_WORD_DECLARED
#endif
@@ -115,29 +111,30 @@ typedef unsigned long long mp_word;
#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
#define MP_DIGIT_MAX MP_MASK
/* equalities */
typedef int mp_sign;
#define MP_ZPOS 0 /* positive integer */
#define MP_NEG 1 /* negative */
typedef int mp_ord;
#define MP_LT -1 /* less than */
#define MP_EQ 0 /* equal to */
#define MP_GT 1 /* greater than */
#define MP_ZPOS 0 /* positive integer */
#define MP_NEG 1 /* negative */
typedef int mp_bool;
#define MP_YES 1 /* yes response */
#define MP_NO 0 /* no response */
typedef int mp_err;
#define MP_OKAY 0 /* ok result */
#define MP_ERR -1 /* unknown error */
#define MP_MEM -2 /* out of mem */
#define MP_VAL -3 /* invalid input */
#define MP_RANGE MP_VAL
#define MP_ITER -4 /* Max. iterations reached */
#define MP_YES 1 /* yes response */
#define MP_NO 0 /* no response */
/* Primality generation flags */
#define LTM_PRIME_BBS 0x0001 /* BBS style prime */
#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */
#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */
typedef int mp_err;
/* tunable cutoffs */
/* define this to use lower memory usage routines (exptmods mostly) */
/* #define MP_LOW_MEM */
@@ -146,6 +143,8 @@ typedef int mp_err;
#ifndef MP_PREC
# ifndef MP_LOW_MEM
# define MP_PREC 32 /* default digits of precision */
# elif defined(MP_8BIT)
# define MP_PREC 16 /* default digits of precision */
# else
# define MP_PREC 8 /* default digits of precision */
# endif
@@ -154,6 +153,45 @@ typedef int mp_err;
/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
#define MP_WARRAY (1u << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1))
/*
* MP_WUR - warn unused result
* ---------------------------
*
* The result of functions annotated with MP_WUR must be
* checked and cannot be ignored.
*
* Most functions in libtommath return an error code.
* This error code must be checked in order to prevent crashes or invalid
* results.
*
* If you still want to avoid the error checks for quick and dirty programs
* without robustness guarantees, you can `#define MP_WUR` before including
* tommath.h, disabling the warnings.
*/
#ifndef MP_WUR
# if defined(__GNUC__) && __GNUC__ >= 4
# define MP_WUR __attribute__((warn_unused_result))
# else
# define MP_WUR
# endif
#endif
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 301)
# define MP_DEPRECATED(x) __attribute__((deprecated("replaced by " #x)))
# define PRIVATE_MP_DEPRECATED_PRAGMA(s) _Pragma(#s)
# define MP_DEPRECATED_PRAGMA(s) PRIVATE_MP_DEPRECATED_PRAGMA(GCC warning s)
#elif defined(_MSC_VER) && _MSC_VER >= 1500
# define MP_DEPRECATED(x) __declspec(deprecated("replaced by " #x))
# define MP_DEPRECATED_PRAGMA(s) __pragma(message(s))
#else
# define MP_DEPRECATED
# define MP_DEPRECATED_PRAGMA(s)
#endif
#define USED(m) ((m)->used)
#define DIGIT(m,k) ((m)->dp[(k)])
#define SIGN(m) ((m)->sign)
/* the infamous mp_int structure */
#ifndef MP_INT_DECLARED
#define MP_INT_DECLARED
@@ -168,17 +206,15 @@ struct mp_int {
typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
#define USED(m) ((m)->used)
#define DIGIT(m, k) ((m)->dp[(k)])
#define SIGN(m) ((m)->sign)
/* error code to char* string */
const char *mp_error_to_string(int code);
/*
const char *mp_error_to_string(mp_err code);
*/
/* ---> init and deinit bignum functions <--- */
/* init a bignum */
/*
int mp_init(mp_int *a);
mp_err mp_init(mp_int *a);
*/
/* free a bignum */
@@ -188,7 +224,7 @@ void mp_clear(mp_int *a);
/* init a null terminated series of arguments */
/*
int mp_init_multi(mp_int *mp, ...);
mp_err mp_init_multi(mp_int *mp, ...);
*/
/* clear a null terminated series of arguments */
@@ -203,23 +239,23 @@ void mp_exch(mp_int *a, mp_int *b);
/* shrink ram required for a bignum */
/*
int mp_shrink(mp_int *a);
mp_err mp_shrink(mp_int *a);
*/
/* grow an int to a given size */
/*
int mp_grow(mp_int *a, int size);
mp_err mp_grow(mp_int *a, int size);
*/
/* init to a given number of digits */
/*
int mp_init_size(mp_int *a, int size);
mp_err mp_init_size(mp_int *a, int size);
*/
/* ---> Basic Manipulations <--- */
#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
#define mp_iseven(a) (!mp_get_bit((a),0))
#define mp_isodd(a) mp_get_bit((a),0)
#define mp_iseven(a) (((a)->used == 0 || (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
#define mp_isneg(a) (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO)
/* set to zero */
@@ -380,24 +416,9 @@ int mp_or(const mp_int *a, const mp_int *b, mp_int *c);
int mp_and(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = a XOR b (two complement) */
/*
int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = a OR b (two complement) */
/*
int mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* c = a AND b (two complement) */
/*
int mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c);
*/
/* right shift (two complement) */
/*
int mp_tc_div_2d(const mp_int *a, int b, mp_int *c);
int mp_signed_rsh(const mp_int *a, int b, mp_int *c);
*/
/* ---> Basic arithmetic <--- */
+18 -8
View File
@@ -45,8 +45,11 @@
/* Rename the global symbols in libtommath to avoid linkage conflicts */
#define bn_reverse TclBN_reverse
#define s_mp_reverse TclBN_reverse
#define fast_s_mp_mul_digs TclBN_fast_s_mp_mul_digs
#define s_mp_mul_digs_fast TclBN_fast_s_mp_mul_digs
#define fast_s_mp_sqr TclBN_fast_s_mp_sqr
#define s_mp_sqr_fast TclBN_fast_s_mp_sqr
#define mp_add TclBN_mp_add
#define mp_add_d TclBN_mp_add_d
#define mp_and TclBN_mp_and
@@ -68,6 +71,7 @@
#define mp_expt_d TclBN_mp_expt_d
#define mp_expt_d_ex TclBN_mp_expt_d_ex
#define mp_get_bit TclBN_mp_get_bit
#define s_mp_get_bit TclBN_mp_get_bit
#define mp_grow TclBN_mp_grow
#define mp_init TclBN_mp_init
#define mp_init_copy TclBN_mp_init_copy
@@ -76,7 +80,9 @@
#define mp_init_set_int TclBN_mp_init_set_int
#define mp_init_size TclBN_mp_init_size
#define mp_karatsuba_mul TclBN_mp_karatsuba_mul
#define s_mp_karatsuba_mul TclBN_mp_karatsuba_mul
#define mp_karatsuba_sqr TclBN_mp_karatsuba_sqr
#define s_mp_karatsuba_sqr TclBN_mp_karatsuba_sqr
#define mp_lshd TclBN_mp_lshd
#define mp_mod TclBN_mp_mod
#define mp_mod_2d TclBN_mp_mod_2d
@@ -97,14 +103,17 @@
#define mp_sqrt TclBN_mp_sqrt
#define mp_sub TclBN_mp_sub
#define mp_sub_d TclBN_mp_sub_d
#define mp_tc_and TclBN_mp_tc_and
#define mp_tc_div_2d TclBN_mp_tc_div_2d
#define mp_tc_or TclBN_mp_tc_or
#define mp_tc_xor TclBN_mp_tc_xor
#define mp_signed_rsh TclBN_mp_signed_rsh
#define mp_tc_and TclBN_mp_and
#define mp_tc_div_2d TclBN_mp_signed_rsh
#define mp_tc_or TclBN_mp_or
#define mp_tc_xor TclBN_mp_xor
#define mp_to_unsigned_bin TclBN_mp_to_unsigned_bin
#define mp_to_unsigned_bin_n TclBN_mp_to_unsigned_bin_n
#define mp_toom_mul TclBN_mp_toom_mul
#define s_mp_toom_mul TclBN_mp_toom_mul
#define mp_toom_sqr TclBN_mp_toom_sqr
#define s_mp_toom_sqr TclBN_mp_toom_sqr
#define mp_toradix_n TclBN_mp_toradix_n
#define mp_unsigned_bin_size TclBN_mp_unsigned_bin_size
#define mp_xor TclBN_mp_xor
@@ -322,7 +331,8 @@ EXTERN int TclBN_mp_tc_or(const mp_int *a, const mp_int *b,
EXTERN int TclBN_mp_tc_xor(const mp_int *a, const mp_int *b,
mp_int *c);
/* 76 */
EXTERN int TclBN_mp_tc_div_2d(const mp_int *a, int b, mp_int *c);
EXTERN int TclBN_mp_signed_rsh(const mp_int *a, int b,
mp_int *c);
/* 77 */
EXTERN int TclBN_mp_get_bit(const mp_int *a, int b);
@@ -406,7 +416,7 @@ typedef struct TclTomMathStubs {
int (*tclBN_mp_tc_and) (const mp_int *a, const mp_int *b, mp_int *c); /* 73 */
int (*tclBN_mp_tc_or) (const mp_int *a, const mp_int *b, mp_int *c); /* 74 */
int (*tclBN_mp_tc_xor) (const mp_int *a, const mp_int *b, mp_int *c); /* 75 */
int (*tclBN_mp_tc_div_2d) (const mp_int *a, int b, mp_int *c); /* 76 */
int (*tclBN_mp_signed_rsh) (const mp_int *a, int b, mp_int *c); /* 76 */
int (*tclBN_mp_get_bit) (const mp_int *a, int b); /* 77 */
} TclTomMathStubs;
@@ -570,8 +580,8 @@ extern const TclTomMathStubs *tclTomMathStubsPtr;
(tclTomMathStubsPtr->tclBN_mp_tc_or) /* 74 */
#define TclBN_mp_tc_xor \
(tclTomMathStubsPtr->tclBN_mp_tc_xor) /* 75 */
#define TclBN_mp_tc_div_2d \
(tclTomMathStubsPtr->tclBN_mp_tc_div_2d) /* 76 */
#define TclBN_mp_signed_rsh \
(tclTomMathStubsPtr->tclBN_mp_signed_rsh) /* 76 */
#define TclBN_mp_get_bit \
(tclTomMathStubsPtr->tclBN_mp_get_bit) /* 77 */
+2 -2
View File
@@ -143,7 +143,7 @@ TclBNInitBignumFromLong(
p = a->dp;
while (v) {
*p++ = (mp_digit) (v & MP_MASK);
v >>= DIGIT_BIT;
v >>= MP_DIGIT_BIT;
}
a->used = p - a->dp;
}
@@ -219,7 +219,7 @@ TclBNInitBignumFromWideUInt(
p = a->dp;
while (v) {
*p++ = (mp_digit) (v & MP_MASK);
v >>= DIGIT_BIT;
v >>= MP_DIGIT_BIT;
}
a->used = p - a->dp;
}
+10 -10
View File
@@ -1686,7 +1686,7 @@ UtfWellFormedEnd(
if (Tcl_UtfCharComplete(p, l - p)) {
return bytes;
}
/*
/*
* Malformed utf-8 end, be sure we've NTS to safe compare of end-character,
* avoid segfault by access violation out of range.
*/
@@ -3667,21 +3667,21 @@ TclFormatInt(
*
* Value
* TCL_OK
*
*
* The index is stored at the address given by by 'indexPtr'. If
* 'objPtr' has the value "end", the value stored is 'endValue'.
*
*
* TCL_ERROR
*
*
* The value of 'objPtr' does not have one of the expected formats. If
* 'interp' is non-NULL, an error message is left in the interpreter's
* result object.
*
*
* Effect
*
*
* The object referenced by 'objPtr' is converted, as needed, to an
* integer, wide integer, or end-based-index object.
*
*
*----------------------------------------------------------------------
*/
@@ -3839,7 +3839,7 @@ GetEndOffsetFromObj(
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
@@ -4017,12 +4017,12 @@ TclIndexEncode(
/* usual case, the absolute index value encodes itself */
} else if (TCL_OK == GetEndOffsetFromObj(objPtr, 0, &idx)) {
/*
* We parsed an end+offset index value.
* We parsed an end+offset index value.
* idx holds the offset value in the range INT_MIN...INT_MAX.
*/
if (idx > 0) {
/*
* All end+postive or end-negative expressions
* All end+postive or end-negative expressions
* always indicate "after the end".
*/
idx = after;
+1 -1
View File
@@ -40,5 +40,5 @@ namespace eval ::tcl::clock {
::msgcat::mcset ja LOCALE_DATE_FORMAT "%EY\u5e74%m\u6708%d\u65e5"
::msgcat::mcset ja LOCALE_TIME_FORMAT "%H\u6642%M\u5206%S\u79d2"
::msgcat::mcset ja LOCALE_DATE_TIME_FORMAT "%EY\u5e74%m\u6708%d\u65e5 (%a) %H\u6642%M\u5206%S\u79d2 %z"
::msgcat::mcset ja LOCALE_ERAS "\u007b-9223372036854775808 \u897f\u66a6 0\u007d \u007b-3061011600 \u660e\u6cbb 1867\u007d \u007b-1812186000 \u5927\u6b63 1911\u007d \u007b-1357635600 \u662d\u548c 1925\u007d \u007b600220800 \u5e73\u6210 1988\u007d"
::msgcat::mcset ja LOCALE_ERAS "{-9223372036854775808 \u897f\u66a6 0} {-3061011600 \u660e\u6cbb 1867} {-1812186000 \u5927\u6b63 1911} {-1357635600 \u662d\u548c 1925} {600220800 \u5e73\u6210 1988} {1556668800 \u4ee4\u548c 2018}"
}
+102
View File
@@ -97,4 +97,106 @@ set TZData(:Africa/Casablanca) {
{2111018400 3600 0 +01}
{2138234400 0 1 +01}
{2141863200 3600 0 +01}
{2169079200 0 1 +01}
{2172103200 3600 0 +01}
{2199924000 0 1 +01}
{2202948000 3600 0 +01}
{2230164000 0 1 +01}
{2233792800 3600 0 +01}
{2261008800 0 1 +01}
{2264032800 3600 0 +01}
{2291248800 0 1 +01}
{2294877600 3600 0 +01}
{2322093600 0 1 +01}
{2325117600 3600 0 +01}
{2352938400 0 1 +01}
{2355962400 3600 0 +01}
{2383178400 0 1 +01}
{2386807200 3600 0 +01}
{2414023200 0 1 +01}
{2417047200 3600 0 +01}
{2444868000 0 1 +01}
{2447892000 3600 0 +01}
{2475108000 0 1 +01}
{2478736800 3600 0 +01}
{2505952800 0 1 +01}
{2508976800 3600 0 +01}
{2536192800 0 1 +01}
{2539821600 3600 0 +01}
{2567037600 0 1 +01}
{2570061600 3600 0 +01}
{2597882400 0 1 +01}
{2600906400 3600 0 +01}
{2628122400 0 1 +01}
{2631751200 3600 0 +01}
{2658967200 0 1 +01}
{2661991200 3600 0 +01}
{2689812000 0 1 +01}
{2692836000 3600 0 +01}
{2720052000 0 1 +01}
{2723680800 3600 0 +01}
{2750896800 0 1 +01}
{2753920800 3600 0 +01}
{2781136800 0 1 +01}
{2784765600 3600 0 +01}
{2811981600 0 1 +01}
{2815005600 3600 0 +01}
{2842826400 0 1 +01}
{2845850400 3600 0 +01}
{2873066400 0 1 +01}
{2876695200 3600 0 +01}
{2903911200 0 1 +01}
{2906935200 3600 0 +01}
{2934756000 0 1 +01}
{2937780000 3600 0 +01}
{2964996000 0 1 +01}
{2968020000 3600 0 +01}
{2995840800 0 1 +01}
{2998864800 3600 0 +01}
{3026080800 0 1 +01}
{3029709600 3600 0 +01}
{3056925600 0 1 +01}
{3059949600 3600 0 +01}
{3087770400 0 1 +01}
{3090794400 3600 0 +01}
{3118010400 0 1 +01}
{3121639200 3600 0 +01}
{3148855200 0 1 +01}
{3151879200 3600 0 +01}
{3179700000 0 1 +01}
{3182724000 3600 0 +01}
{3209940000 0 1 +01}
{3212964000 3600 0 +01}
{3240784800 0 1 +01}
{3243808800 3600 0 +01}
{3271024800 0 1 +01}
{3274653600 3600 0 +01}
{3301869600 0 1 +01}
{3304893600 3600 0 +01}
{3332714400 0 1 +01}
{3335738400 3600 0 +01}
{3362954400 0 1 +01}
{3366583200 3600 0 +01}
{3393799200 0 1 +01}
{3396823200 3600 0 +01}
{3424644000 0 1 +01}
{3427668000 3600 0 +01}
{3454884000 0 1 +01}
{3457908000 3600 0 +01}
{3485728800 0 1 +01}
{3488752800 3600 0 +01}
{3515968800 0 1 +01}
{3519597600 3600 0 +01}
{3546813600 0 1 +01}
{3549837600 3600 0 +01}
{3577658400 0 1 +01}
{3580682400 3600 0 +01}
{3607898400 0 1 +01}
{3611527200 3600 0 +01}
{3638743200 0 1 +01}
{3641767200 3600 0 +01}
{3669588000 0 1 +01}
{3672612000 3600 0 +01}
{3699828000 0 1 +01}
{3702852000 3600 0 +01}
}
+102
View File
@@ -86,4 +86,106 @@ set TZData(:Africa/El_Aaiun) {
{2111018400 3600 0 +01}
{2138234400 0 1 +01}
{2141863200 3600 0 +01}
{2169079200 0 1 +01}
{2172103200 3600 0 +01}
{2199924000 0 1 +01}
{2202948000 3600 0 +01}
{2230164000 0 1 +01}
{2233792800 3600 0 +01}
{2261008800 0 1 +01}
{2264032800 3600 0 +01}
{2291248800 0 1 +01}
{2294877600 3600 0 +01}
{2322093600 0 1 +01}
{2325117600 3600 0 +01}
{2352938400 0 1 +01}
{2355962400 3600 0 +01}
{2383178400 0 1 +01}
{2386807200 3600 0 +01}
{2414023200 0 1 +01}
{2417047200 3600 0 +01}
{2444868000 0 1 +01}
{2447892000 3600 0 +01}
{2475108000 0 1 +01}
{2478736800 3600 0 +01}
{2505952800 0 1 +01}
{2508976800 3600 0 +01}
{2536192800 0 1 +01}
{2539821600 3600 0 +01}
{2567037600 0 1 +01}
{2570061600 3600 0 +01}
{2597882400 0 1 +01}
{2600906400 3600 0 +01}
{2628122400 0 1 +01}
{2631751200 3600 0 +01}
{2658967200 0 1 +01}
{2661991200 3600 0 +01}
{2689812000 0 1 +01}
{2692836000 3600 0 +01}
{2720052000 0 1 +01}
{2723680800 3600 0 +01}
{2750896800 0 1 +01}
{2753920800 3600 0 +01}
{2781136800 0 1 +01}
{2784765600 3600 0 +01}
{2811981600 0 1 +01}
{2815005600 3600 0 +01}
{2842826400 0 1 +01}
{2845850400 3600 0 +01}
{2873066400 0 1 +01}
{2876695200 3600 0 +01}
{2903911200 0 1 +01}
{2906935200 3600 0 +01}
{2934756000 0 1 +01}
{2937780000 3600 0 +01}
{2964996000 0 1 +01}
{2968020000 3600 0 +01}
{2995840800 0 1 +01}
{2998864800 3600 0 +01}
{3026080800 0 1 +01}
{3029709600 3600 0 +01}
{3056925600 0 1 +01}
{3059949600 3600 0 +01}
{3087770400 0 1 +01}
{3090794400 3600 0 +01}
{3118010400 0 1 +01}
{3121639200 3600 0 +01}
{3148855200 0 1 +01}
{3151879200 3600 0 +01}
{3179700000 0 1 +01}
{3182724000 3600 0 +01}
{3209940000 0 1 +01}
{3212964000 3600 0 +01}
{3240784800 0 1 +01}
{3243808800 3600 0 +01}
{3271024800 0 1 +01}
{3274653600 3600 0 +01}
{3301869600 0 1 +01}
{3304893600 3600 0 +01}
{3332714400 0 1 +01}
{3335738400 3600 0 +01}
{3362954400 0 1 +01}
{3366583200 3600 0 +01}
{3393799200 0 1 +01}
{3396823200 3600 0 +01}
{3424644000 0 1 +01}
{3427668000 3600 0 +01}
{3454884000 0 1 +01}
{3457908000 3600 0 +01}
{3485728800 0 1 +01}
{3488752800 3600 0 +01}
{3515968800 0 1 +01}
{3519597600 3600 0 +01}
{3546813600 0 1 +01}
{3549837600 3600 0 +01}
{3577658400 0 1 +01}
{3580682400 3600 0 +01}
{3607898400 0 1 +01}
{3611527200 3600 0 +01}
{3638743200 0 1 +01}
{3641767200 3600 0 +01}
{3669588000 0 1 +01}
{3672612000 3600 0 +01}
{3699828000 0 1 +01}
{3702852000 3600 0 +01}
}
-161
View File
@@ -93,165 +93,4 @@ set TZData(:America/Campo_Grande) {
{1518922800 -14400 0 -04}
{1541304000 -10800 1 -04}
{1550372400 -14400 0 -04}
{1572753600 -10800 1 -04}
{1581822000 -14400 0 -04}
{1604203200 -10800 1 -04}
{1613876400 -14400 0 -04}
{1636257600 -10800 1 -04}
{1645326000 -14400 0 -04}
{1667707200 -10800 1 -04}
{1677380400 -14400 0 -04}
{1699156800 -10800 1 -04}
{1708225200 -14400 0 -04}
{1730606400 -10800 1 -04}
{1739674800 -14400 0 -04}
{1762056000 -10800 1 -04}
{1771729200 -14400 0 -04}
{1793505600 -10800 1 -04}
{1803178800 -14400 0 -04}
{1825560000 -10800 1 -04}
{1834628400 -14400 0 -04}
{1857009600 -10800 1 -04}
{1866078000 -14400 0 -04}
{1888459200 -10800 1 -04}
{1897527600 -14400 0 -04}
{1919908800 -10800 1 -04}
{1928977200 -14400 0 -04}
{1951358400 -10800 1 -04}
{1960426800 -14400 0 -04}
{1983412800 -10800 1 -04}
{1992481200 -14400 0 -04}
{2014862400 -10800 1 -04}
{2024535600 -14400 0 -04}
{2046312000 -10800 1 -04}
{2055380400 -14400 0 -04}
{2077761600 -10800 1 -04}
{2086830000 -14400 0 -04}
{2109211200 -10800 1 -04}
{2118884400 -14400 0 -04}
{2140660800 -10800 1 -04}
{2150334000 -14400 0 -04}
{2172715200 -10800 1 -04}
{2181783600 -14400 0 -04}
{2204164800 -10800 1 -04}
{2213233200 -14400 0 -04}
{2235614400 -10800 1 -04}
{2244682800 -14400 0 -04}
{2267064000 -10800 1 -04}
{2276132400 -14400 0 -04}
{2298513600 -10800 1 -04}
{2307582000 -14400 0 -04}
{2329963200 -10800 1 -04}
{2339636400 -14400 0 -04}
{2362017600 -10800 1 -04}
{2371086000 -14400 0 -04}
{2393467200 -10800 1 -04}
{2402535600 -14400 0 -04}
{2424916800 -10800 1 -04}
{2433985200 -14400 0 -04}
{2456366400 -10800 1 -04}
{2465434800 -14400 0 -04}
{2487816000 -10800 1 -04}
{2497489200 -14400 0 -04}
{2519870400 -10800 1 -04}
{2528938800 -14400 0 -04}
{2551320000 -10800 1 -04}
{2560388400 -14400 0 -04}
{2582769600 -10800 1 -04}
{2591838000 -14400 0 -04}
{2614219200 -10800 1 -04}
{2623287600 -14400 0 -04}
{2645668800 -10800 1 -04}
{2654737200 -14400 0 -04}
{2677118400 -10800 1 -04}
{2686791600 -14400 0 -04}
{2709172800 -10800 1 -04}
{2718241200 -14400 0 -04}
{2740622400 -10800 1 -04}
{2749690800 -14400 0 -04}
{2772072000 -10800 1 -04}
{2781140400 -14400 0 -04}
{2803521600 -10800 1 -04}
{2812590000 -14400 0 -04}
{2834971200 -10800 1 -04}
{2844039600 -14400 0 -04}
{2867025600 -10800 1 -04}
{2876094000 -14400 0 -04}
{2898475200 -10800 1 -04}
{2907543600 -14400 0 -04}
{2929924800 -10800 1 -04}
{2938993200 -14400 0 -04}
{2961374400 -10800 1 -04}
{2970442800 -14400 0 -04}
{2992824000 -10800 1 -04}
{3001892400 -14400 0 -04}
{3024273600 -10800 1 -04}
{3033946800 -14400 0 -04}
{3056328000 -10800 1 -04}
{3065396400 -14400 0 -04}
{3087777600 -10800 1 -04}
{3096846000 -14400 0 -04}
{3119227200 -10800 1 -04}
{3128295600 -14400 0 -04}
{3150676800 -10800 1 -04}
{3159745200 -14400 0 -04}
{3182126400 -10800 1 -04}
{3191194800 -14400 0 -04}
{3213576000 -10800 1 -04}
{3223249200 -14400 0 -04}
{3245630400 -10800 1 -04}
{3254698800 -14400 0 -04}
{3277080000 -10800 1 -04}
{3286148400 -14400 0 -04}
{3308529600 -10800 1 -04}
{3317598000 -14400 0 -04}
{3339979200 -10800 1 -04}
{3349047600 -14400 0 -04}
{3371428800 -10800 1 -04}
{3381102000 -14400 0 -04}
{3403483200 -10800 1 -04}
{3412551600 -14400 0 -04}
{3434932800 -10800 1 -04}
{3444001200 -14400 0 -04}
{3466382400 -10800 1 -04}
{3475450800 -14400 0 -04}
{3497832000 -10800 1 -04}
{3506900400 -14400 0 -04}
{3529281600 -10800 1 -04}
{3538350000 -14400 0 -04}
{3560731200 -10800 1 -04}
{3570404400 -14400 0 -04}
{3592785600 -10800 1 -04}
{3601854000 -14400 0 -04}
{3624235200 -10800 1 -04}
{3633303600 -14400 0 -04}
{3655684800 -10800 1 -04}
{3664753200 -14400 0 -04}
{3687134400 -10800 1 -04}
{3696202800 -14400 0 -04}
{3718584000 -10800 1 -04}
{3727652400 -14400 0 -04}
{3750638400 -10800 1 -04}
{3759706800 -14400 0 -04}
{3782088000 -10800 1 -04}
{3791156400 -14400 0 -04}
{3813537600 -10800 1 -04}
{3822606000 -14400 0 -04}
{3844987200 -10800 1 -04}
{3854055600 -14400 0 -04}
{3876436800 -10800 1 -04}
{3885505200 -14400 0 -04}
{3907886400 -10800 1 -04}
{3917559600 -14400 0 -04}
{3939940800 -10800 1 -04}
{3949009200 -14400 0 -04}
{3971390400 -10800 1 -04}
{3980458800 -14400 0 -04}
{4002840000 -10800 1 -04}
{4011908400 -14400 0 -04}
{4034289600 -10800 1 -04}
{4043358000 -14400 0 -04}
{4065739200 -10800 1 -04}
{4074807600 -14400 0 -04}
{4097188800 -10800 1 -04}
}
-161
View File
@@ -93,165 +93,4 @@ set TZData(:America/Cuiaba) {
{1518922800 -14400 0 -04}
{1541304000 -10800 1 -04}
{1550372400 -14400 0 -04}
{1572753600 -10800 1 -04}
{1581822000 -14400 0 -04}
{1604203200 -10800 1 -04}
{1613876400 -14400 0 -04}
{1636257600 -10800 1 -04}
{1645326000 -14400 0 -04}
{1667707200 -10800 1 -04}
{1677380400 -14400 0 -04}
{1699156800 -10800 1 -04}
{1708225200 -14400 0 -04}
{1730606400 -10800 1 -04}
{1739674800 -14400 0 -04}
{1762056000 -10800 1 -04}
{1771729200 -14400 0 -04}
{1793505600 -10800 1 -04}
{1803178800 -14400 0 -04}
{1825560000 -10800 1 -04}
{1834628400 -14400 0 -04}
{1857009600 -10800 1 -04}
{1866078000 -14400 0 -04}
{1888459200 -10800 1 -04}
{1897527600 -14400 0 -04}
{1919908800 -10800 1 -04}
{1928977200 -14400 0 -04}
{1951358400 -10800 1 -04}
{1960426800 -14400 0 -04}
{1983412800 -10800 1 -04}
{1992481200 -14400 0 -04}
{2014862400 -10800 1 -04}
{2024535600 -14400 0 -04}
{2046312000 -10800 1 -04}
{2055380400 -14400 0 -04}
{2077761600 -10800 1 -04}
{2086830000 -14400 0 -04}
{2109211200 -10800 1 -04}
{2118884400 -14400 0 -04}
{2140660800 -10800 1 -04}
{2150334000 -14400 0 -04}
{2172715200 -10800 1 -04}
{2181783600 -14400 0 -04}
{2204164800 -10800 1 -04}
{2213233200 -14400 0 -04}
{2235614400 -10800 1 -04}
{2244682800 -14400 0 -04}
{2267064000 -10800 1 -04}
{2276132400 -14400 0 -04}
{2298513600 -10800 1 -04}
{2307582000 -14400 0 -04}
{2329963200 -10800 1 -04}
{2339636400 -14400 0 -04}
{2362017600 -10800 1 -04}
{2371086000 -14400 0 -04}
{2393467200 -10800 1 -04}
{2402535600 -14400 0 -04}
{2424916800 -10800 1 -04}
{2433985200 -14400 0 -04}
{2456366400 -10800 1 -04}
{2465434800 -14400 0 -04}
{2487816000 -10800 1 -04}
{2497489200 -14400 0 -04}
{2519870400 -10800 1 -04}
{2528938800 -14400 0 -04}
{2551320000 -10800 1 -04}
{2560388400 -14400 0 -04}
{2582769600 -10800 1 -04}
{2591838000 -14400 0 -04}
{2614219200 -10800 1 -04}
{2623287600 -14400 0 -04}
{2645668800 -10800 1 -04}
{2654737200 -14400 0 -04}
{2677118400 -10800 1 -04}
{2686791600 -14400 0 -04}
{2709172800 -10800 1 -04}
{2718241200 -14400 0 -04}
{2740622400 -10800 1 -04}
{2749690800 -14400 0 -04}
{2772072000 -10800 1 -04}
{2781140400 -14400 0 -04}
{2803521600 -10800 1 -04}
{2812590000 -14400 0 -04}
{2834971200 -10800 1 -04}
{2844039600 -14400 0 -04}
{2867025600 -10800 1 -04}
{2876094000 -14400 0 -04}
{2898475200 -10800 1 -04}
{2907543600 -14400 0 -04}
{2929924800 -10800 1 -04}
{2938993200 -14400 0 -04}
{2961374400 -10800 1 -04}
{2970442800 -14400 0 -04}
{2992824000 -10800 1 -04}
{3001892400 -14400 0 -04}
{3024273600 -10800 1 -04}
{3033946800 -14400 0 -04}
{3056328000 -10800 1 -04}
{3065396400 -14400 0 -04}
{3087777600 -10800 1 -04}
{3096846000 -14400 0 -04}
{3119227200 -10800 1 -04}
{3128295600 -14400 0 -04}
{3150676800 -10800 1 -04}
{3159745200 -14400 0 -04}
{3182126400 -10800 1 -04}
{3191194800 -14400 0 -04}
{3213576000 -10800 1 -04}
{3223249200 -14400 0 -04}
{3245630400 -10800 1 -04}
{3254698800 -14400 0 -04}
{3277080000 -10800 1 -04}
{3286148400 -14400 0 -04}
{3308529600 -10800 1 -04}
{3317598000 -14400 0 -04}
{3339979200 -10800 1 -04}
{3349047600 -14400 0 -04}
{3371428800 -10800 1 -04}
{3381102000 -14400 0 -04}
{3403483200 -10800 1 -04}
{3412551600 -14400 0 -04}
{3434932800 -10800 1 -04}
{3444001200 -14400 0 -04}
{3466382400 -10800 1 -04}
{3475450800 -14400 0 -04}
{3497832000 -10800 1 -04}
{3506900400 -14400 0 -04}
{3529281600 -10800 1 -04}
{3538350000 -14400 0 -04}
{3560731200 -10800 1 -04}
{3570404400 -14400 0 -04}
{3592785600 -10800 1 -04}
{3601854000 -14400 0 -04}
{3624235200 -10800 1 -04}
{3633303600 -14400 0 -04}
{3655684800 -10800 1 -04}
{3664753200 -14400 0 -04}
{3687134400 -10800 1 -04}
{3696202800 -14400 0 -04}
{3718584000 -10800 1 -04}
{3727652400 -14400 0 -04}
{3750638400 -10800 1 -04}
{3759706800 -14400 0 -04}
{3782088000 -10800 1 -04}
{3791156400 -14400 0 -04}
{3813537600 -10800 1 -04}
{3822606000 -14400 0 -04}
{3844987200 -10800 1 -04}
{3854055600 -14400 0 -04}
{3876436800 -10800 1 -04}
{3885505200 -14400 0 -04}
{3907886400 -10800 1 -04}
{3917559600 -14400 0 -04}
{3939940800 -10800 1 -04}
{3949009200 -14400 0 -04}
{3971390400 -10800 1 -04}
{3980458800 -14400 0 -04}
{4002840000 -10800 1 -04}
{4011908400 -14400 0 -04}
{4034289600 -10800 1 -04}
{4043358000 -14400 0 -04}
{4065739200 -10800 1 -04}
{4074807600 -14400 0 -04}
{4097188800 -10800 1 -04}
}
-161
View File
@@ -94,165 +94,4 @@ set TZData(:America/Sao_Paulo) {
{1518919200 -10800 0 -03}
{1541300400 -7200 1 -03}
{1550368800 -10800 0 -03}
{1572750000 -7200 1 -03}
{1581818400 -10800 0 -03}
{1604199600 -7200 1 -03}
{1613872800 -10800 0 -03}
{1636254000 -7200 1 -03}
{1645322400 -10800 0 -03}
{1667703600 -7200 1 -03}
{1677376800 -10800 0 -03}
{1699153200 -7200 1 -03}
{1708221600 -10800 0 -03}
{1730602800 -7200 1 -03}
{1739671200 -10800 0 -03}
{1762052400 -7200 1 -03}
{1771725600 -10800 0 -03}
{1793502000 -7200 1 -03}
{1803175200 -10800 0 -03}
{1825556400 -7200 1 -03}
{1834624800 -10800 0 -03}
{1857006000 -7200 1 -03}
{1866074400 -10800 0 -03}
{1888455600 -7200 1 -03}
{1897524000 -10800 0 -03}
{1919905200 -7200 1 -03}
{1928973600 -10800 0 -03}
{1951354800 -7200 1 -03}
{1960423200 -10800 0 -03}
{1983409200 -7200 1 -03}
{1992477600 -10800 0 -03}
{2014858800 -7200 1 -03}
{2024532000 -10800 0 -03}
{2046308400 -7200 1 -03}
{2055376800 -10800 0 -03}
{2077758000 -7200 1 -03}
{2086826400 -10800 0 -03}
{2109207600 -7200 1 -03}
{2118880800 -10800 0 -03}
{2140657200 -7200 1 -03}
{2150330400 -10800 0 -03}
{2172711600 -7200 1 -03}
{2181780000 -10800 0 -03}
{2204161200 -7200 1 -03}
{2213229600 -10800 0 -03}
{2235610800 -7200 1 -03}
{2244679200 -10800 0 -03}
{2267060400 -7200 1 -03}
{2276128800 -10800 0 -03}
{2298510000 -7200 1 -03}
{2307578400 -10800 0 -03}
{2329959600 -7200 1 -03}
{2339632800 -10800 0 -03}
{2362014000 -7200 1 -03}
{2371082400 -10800 0 -03}
{2393463600 -7200 1 -03}
{2402532000 -10800 0 -03}
{2424913200 -7200 1 -03}
{2433981600 -10800 0 -03}
{2456362800 -7200 1 -03}
{2465431200 -10800 0 -03}
{2487812400 -7200 1 -03}
{2497485600 -10800 0 -03}
{2519866800 -7200 1 -03}
{2528935200 -10800 0 -03}
{2551316400 -7200 1 -03}
{2560384800 -10800 0 -03}
{2582766000 -7200 1 -03}
{2591834400 -10800 0 -03}
{2614215600 -7200 1 -03}
{2623284000 -10800 0 -03}
{2645665200 -7200 1 -03}
{2654733600 -10800 0 -03}
{2677114800 -7200 1 -03}
{2686788000 -10800 0 -03}
{2709169200 -7200 1 -03}
{2718237600 -10800 0 -03}
{2740618800 -7200 1 -03}
{2749687200 -10800 0 -03}
{2772068400 -7200 1 -03}
{2781136800 -10800 0 -03}
{2803518000 -7200 1 -03}
{2812586400 -10800 0 -03}
{2834967600 -7200 1 -03}
{2844036000 -10800 0 -03}
{2867022000 -7200 1 -03}
{2876090400 -10800 0 -03}
{2898471600 -7200 1 -03}
{2907540000 -10800 0 -03}
{2929921200 -7200 1 -03}
{2938989600 -10800 0 -03}
{2961370800 -7200 1 -03}
{2970439200 -10800 0 -03}
{2992820400 -7200 1 -03}
{3001888800 -10800 0 -03}
{3024270000 -7200 1 -03}
{3033943200 -10800 0 -03}
{3056324400 -7200 1 -03}
{3065392800 -10800 0 -03}
{3087774000 -7200 1 -03}
{3096842400 -10800 0 -03}
{3119223600 -7200 1 -03}
{3128292000 -10800 0 -03}
{3150673200 -7200 1 -03}
{3159741600 -10800 0 -03}
{3182122800 -7200 1 -03}
{3191191200 -10800 0 -03}
{3213572400 -7200 1 -03}
{3223245600 -10800 0 -03}
{3245626800 -7200 1 -03}
{3254695200 -10800 0 -03}
{3277076400 -7200 1 -03}
{3286144800 -10800 0 -03}
{3308526000 -7200 1 -03}
{3317594400 -10800 0 -03}
{3339975600 -7200 1 -03}
{3349044000 -10800 0 -03}
{3371425200 -7200 1 -03}
{3381098400 -10800 0 -03}
{3403479600 -7200 1 -03}
{3412548000 -10800 0 -03}
{3434929200 -7200 1 -03}
{3443997600 -10800 0 -03}
{3466378800 -7200 1 -03}
{3475447200 -10800 0 -03}
{3497828400 -7200 1 -03}
{3506896800 -10800 0 -03}
{3529278000 -7200 1 -03}
{3538346400 -10800 0 -03}
{3560727600 -7200 1 -03}
{3570400800 -10800 0 -03}
{3592782000 -7200 1 -03}
{3601850400 -10800 0 -03}
{3624231600 -7200 1 -03}
{3633300000 -10800 0 -03}
{3655681200 -7200 1 -03}
{3664749600 -10800 0 -03}
{3687130800 -7200 1 -03}
{3696199200 -10800 0 -03}
{3718580400 -7200 1 -03}
{3727648800 -10800 0 -03}
{3750634800 -7200 1 -03}
{3759703200 -10800 0 -03}
{3782084400 -7200 1 -03}
{3791152800 -10800 0 -03}
{3813534000 -7200 1 -03}
{3822602400 -10800 0 -03}
{3844983600 -7200 1 -03}
{3854052000 -10800 0 -03}
{3876433200 -7200 1 -03}
{3885501600 -10800 0 -03}
{3907882800 -7200 1 -03}
{3917556000 -10800 0 -03}
{3939937200 -7200 1 -03}
{3949005600 -10800 0 -03}
{3971386800 -7200 1 -03}
{3980455200 -10800 0 -03}
{4002836400 -7200 1 -03}
{4011904800 -10800 0 -03}
{4034286000 -7200 1 -03}
{4043354400 -10800 0 -03}
{4065735600 -7200 1 -03}
{4074804000 -10800 0 -03}
{4097185200 -7200 1 -03}
}
+81 -81
View File
@@ -117,166 +117,166 @@ set TZData(:Asia/Gaza) {
{1509141600 7200 0 EET}
{1521846000 10800 1 EEST}
{1540591200 7200 0 EET}
{1553900400 10800 1 EEST}
{1553810400 10800 1 EEST}
{1572040800 7200 0 EET}
{1585350000 10800 1 EEST}
{1585260000 10800 1 EEST}
{1604095200 7200 0 EET}
{1616799600 10800 1 EEST}
{1616709600 10800 1 EEST}
{1635544800 7200 0 EET}
{1648249200 10800 1 EEST}
{1648159200 10800 1 EEST}
{1666994400 7200 0 EET}
{1679698800 10800 1 EEST}
{1680213600 10800 1 EEST}
{1698444000 7200 0 EET}
{1711753200 10800 1 EEST}
{1711663200 10800 1 EEST}
{1729893600 7200 0 EET}
{1743202800 10800 1 EEST}
{1743112800 10800 1 EEST}
{1761343200 7200 0 EET}
{1774652400 10800 1 EEST}
{1774562400 10800 1 EEST}
{1793397600 7200 0 EET}
{1806102000 10800 1 EEST}
{1806012000 10800 1 EEST}
{1824847200 7200 0 EET}
{1837551600 10800 1 EEST}
{1838066400 10800 1 EEST}
{1856296800 7200 0 EET}
{1869001200 10800 1 EEST}
{1869516000 10800 1 EEST}
{1887746400 7200 0 EET}
{1901055600 10800 1 EEST}
{1900965600 10800 1 EEST}
{1919196000 7200 0 EET}
{1932505200 10800 1 EEST}
{1932415200 10800 1 EEST}
{1950645600 7200 0 EET}
{1963954800 10800 1 EEST}
{1963864800 10800 1 EEST}
{1982700000 7200 0 EET}
{1995404400 10800 1 EEST}
{1995314400 10800 1 EEST}
{2014149600 7200 0 EET}
{2026854000 10800 1 EEST}
{2027368800 10800 1 EEST}
{2045599200 7200 0 EET}
{2058303600 10800 1 EEST}
{2058818400 10800 1 EEST}
{2077048800 7200 0 EET}
{2090358000 10800 1 EEST}
{2090268000 10800 1 EEST}
{2108498400 7200 0 EET}
{2121807600 10800 1 EEST}
{2121717600 10800 1 EEST}
{2140552800 7200 0 EET}
{2153257200 10800 1 EEST}
{2153167200 10800 1 EEST}
{2172002400 7200 0 EET}
{2184706800 10800 1 EEST}
{2184616800 10800 1 EEST}
{2203452000 7200 0 EET}
{2216156400 10800 1 EEST}
{2216671200 10800 1 EEST}
{2234901600 7200 0 EET}
{2248210800 10800 1 EEST}
{2248120800 10800 1 EEST}
{2266351200 7200 0 EET}
{2279660400 10800 1 EEST}
{2279570400 10800 1 EEST}
{2297800800 7200 0 EET}
{2311110000 10800 1 EEST}
{2311020000 10800 1 EEST}
{2329855200 7200 0 EET}
{2342559600 10800 1 EEST}
{2342469600 10800 1 EEST}
{2361304800 7200 0 EET}
{2374009200 10800 1 EEST}
{2374524000 10800 1 EEST}
{2392754400 7200 0 EET}
{2405458800 10800 1 EEST}
{2405973600 10800 1 EEST}
{2424204000 7200 0 EET}
{2437513200 10800 1 EEST}
{2437423200 10800 1 EEST}
{2455653600 7200 0 EET}
{2468962800 10800 1 EEST}
{2468872800 10800 1 EEST}
{2487708000 7200 0 EET}
{2500412400 10800 1 EEST}
{2500322400 10800 1 EEST}
{2519157600 7200 0 EET}
{2531862000 10800 1 EEST}
{2531772000 10800 1 EEST}
{2550607200 7200 0 EET}
{2563311600 10800 1 EEST}
{2563826400 10800 1 EEST}
{2582056800 7200 0 EET}
{2595366000 10800 1 EEST}
{2595276000 10800 1 EEST}
{2613506400 7200 0 EET}
{2626815600 10800 1 EEST}
{2626725600 10800 1 EEST}
{2644956000 7200 0 EET}
{2658265200 10800 1 EEST}
{2658175200 10800 1 EEST}
{2677010400 7200 0 EET}
{2689714800 10800 1 EEST}
{2689624800 10800 1 EEST}
{2708460000 7200 0 EET}
{2721164400 10800 1 EEST}
{2721679200 10800 1 EEST}
{2739909600 7200 0 EET}
{2752614000 10800 1 EEST}
{2753128800 10800 1 EEST}
{2771359200 7200 0 EET}
{2784668400 10800 1 EEST}
{2784578400 10800 1 EEST}
{2802808800 7200 0 EET}
{2816118000 10800 1 EEST}
{2816028000 10800 1 EEST}
{2834258400 7200 0 EET}
{2847567600 10800 1 EEST}
{2847477600 10800 1 EEST}
{2866312800 7200 0 EET}
{2879017200 10800 1 EEST}
{2878927200 10800 1 EEST}
{2897762400 7200 0 EET}
{2910466800 10800 1 EEST}
{2910981600 10800 1 EEST}
{2929212000 7200 0 EET}
{2941916400 10800 1 EEST}
{2942431200 10800 1 EEST}
{2960661600 7200 0 EET}
{2973970800 10800 1 EEST}
{2973880800 10800 1 EEST}
{2992111200 7200 0 EET}
{3005420400 10800 1 EEST}
{3005330400 10800 1 EEST}
{3024165600 7200 0 EET}
{3036870000 10800 1 EEST}
{3036780000 10800 1 EEST}
{3055615200 7200 0 EET}
{3068319600 10800 1 EEST}
{3068229600 10800 1 EEST}
{3087064800 7200 0 EET}
{3099769200 10800 1 EEST}
{3100284000 10800 1 EEST}
{3118514400 7200 0 EET}
{3131823600 10800 1 EEST}
{3131733600 10800 1 EEST}
{3149964000 7200 0 EET}
{3163273200 10800 1 EEST}
{3163183200 10800 1 EEST}
{3181413600 7200 0 EET}
{3194722800 10800 1 EEST}
{3194632800 10800 1 EEST}
{3213468000 7200 0 EET}
{3226172400 10800 1 EEST}
{3226082400 10800 1 EEST}
{3244917600 7200 0 EET}
{3257622000 10800 1 EEST}
{3258136800 10800 1 EEST}
{3276367200 7200 0 EET}
{3289071600 10800 1 EEST}
{3289586400 10800 1 EEST}
{3307816800 7200 0 EET}
{3321126000 10800 1 EEST}
{3321036000 10800 1 EEST}
{3339266400 7200 0 EET}
{3352575600 10800 1 EEST}
{3352485600 10800 1 EEST}
{3371320800 7200 0 EET}
{3384025200 10800 1 EEST}
{3383935200 10800 1 EEST}
{3402770400 7200 0 EET}
{3415474800 10800 1 EEST}
{3415384800 10800 1 EEST}
{3434220000 7200 0 EET}
{3446924400 10800 1 EEST}
{3447439200 10800 1 EEST}
{3465669600 7200 0 EET}
{3478978800 10800 1 EEST}
{3478888800 10800 1 EEST}
{3497119200 7200 0 EET}
{3510428400 10800 1 EEST}
{3510338400 10800 1 EEST}
{3528568800 7200 0 EET}
{3541878000 10800 1 EEST}
{3541788000 10800 1 EEST}
{3560623200 7200 0 EET}
{3573327600 10800 1 EEST}
{3573237600 10800 1 EEST}
{3592072800 7200 0 EET}
{3604777200 10800 1 EEST}
{3605292000 10800 1 EEST}
{3623522400 7200 0 EET}
{3636226800 10800 1 EEST}
{3636741600 10800 1 EEST}
{3654972000 7200 0 EET}
{3668281200 10800 1 EEST}
{3668191200 10800 1 EEST}
{3686421600 7200 0 EET}
{3699730800 10800 1 EEST}
{3699640800 10800 1 EEST}
{3717871200 7200 0 EET}
{3731180400 10800 1 EEST}
{3731090400 10800 1 EEST}
{3749925600 7200 0 EET}
{3762630000 10800 1 EEST}
{3762540000 10800 1 EEST}
{3781375200 7200 0 EET}
{3794079600 10800 1 EEST}
{3794594400 10800 1 EEST}
{3812824800 7200 0 EET}
{3825529200 10800 1 EEST}
{3826044000 10800 1 EEST}
{3844274400 7200 0 EET}
{3857583600 10800 1 EEST}
{3857493600 10800 1 EEST}
{3875724000 7200 0 EET}
{3889033200 10800 1 EEST}
{3888943200 10800 1 EEST}
{3907778400 7200 0 EET}
{3920482800 10800 1 EEST}
{3920392800 10800 1 EEST}
{3939228000 7200 0 EET}
{3951932400 10800 1 EEST}
{3951842400 10800 1 EEST}
{3970677600 7200 0 EET}
{3983382000 10800 1 EEST}
{3983896800 10800 1 EEST}
{4002127200 7200 0 EET}
{4015436400 10800 1 EEST}
{4015346400 10800 1 EEST}
{4033576800 7200 0 EET}
{4046886000 10800 1 EEST}
{4046796000 10800 1 EEST}
{4065026400 7200 0 EET}
{4078335600 10800 1 EEST}
{4078245600 10800 1 EEST}
{4097080800 7200 0 EET}
}
+81 -81
View File
@@ -116,166 +116,166 @@ set TZData(:Asia/Hebron) {
{1509141600 7200 0 EET}
{1521846000 10800 1 EEST}
{1540591200 7200 0 EET}
{1553900400 10800 1 EEST}
{1553810400 10800 1 EEST}
{1572040800 7200 0 EET}
{1585350000 10800 1 EEST}
{1585260000 10800 1 EEST}
{1604095200 7200 0 EET}
{1616799600 10800 1 EEST}
{1616709600 10800 1 EEST}
{1635544800 7200 0 EET}
{1648249200 10800 1 EEST}
{1648159200 10800 1 EEST}
{1666994400 7200 0 EET}
{1679698800 10800 1 EEST}
{1680213600 10800 1 EEST}
{1698444000 7200 0 EET}
{1711753200 10800 1 EEST}
{1711663200 10800 1 EEST}
{1729893600 7200 0 EET}
{1743202800 10800 1 EEST}
{1743112800 10800 1 EEST}
{1761343200 7200 0 EET}
{1774652400 10800 1 EEST}
{1774562400 10800 1 EEST}
{1793397600 7200 0 EET}
{1806102000 10800 1 EEST}
{1806012000 10800 1 EEST}
{1824847200 7200 0 EET}
{1837551600 10800 1 EEST}
{1838066400 10800 1 EEST}
{1856296800 7200 0 EET}
{1869001200 10800 1 EEST}
{1869516000 10800 1 EEST}
{1887746400 7200 0 EET}
{1901055600 10800 1 EEST}
{1900965600 10800 1 EEST}
{1919196000 7200 0 EET}
{1932505200 10800 1 EEST}
{1932415200 10800 1 EEST}
{1950645600 7200 0 EET}
{1963954800 10800 1 EEST}
{1963864800 10800 1 EEST}
{1982700000 7200 0 EET}
{1995404400 10800 1 EEST}
{1995314400 10800 1 EEST}
{2014149600 7200 0 EET}
{2026854000 10800 1 EEST}
{2027368800 10800 1 EEST}
{2045599200 7200 0 EET}
{2058303600 10800 1 EEST}
{2058818400 10800 1 EEST}
{2077048800 7200 0 EET}
{2090358000 10800 1 EEST}
{2090268000 10800 1 EEST}
{2108498400 7200 0 EET}
{2121807600 10800 1 EEST}
{2121717600 10800 1 EEST}
{2140552800 7200 0 EET}
{2153257200 10800 1 EEST}
{2153167200 10800 1 EEST}
{2172002400 7200 0 EET}
{2184706800 10800 1 EEST}
{2184616800 10800 1 EEST}
{2203452000 7200 0 EET}
{2216156400 10800 1 EEST}
{2216671200 10800 1 EEST}
{2234901600 7200 0 EET}
{2248210800 10800 1 EEST}
{2248120800 10800 1 EEST}
{2266351200 7200 0 EET}
{2279660400 10800 1 EEST}
{2279570400 10800 1 EEST}
{2297800800 7200 0 EET}
{2311110000 10800 1 EEST}
{2311020000 10800 1 EEST}
{2329855200 7200 0 EET}
{2342559600 10800 1 EEST}
{2342469600 10800 1 EEST}
{2361304800 7200 0 EET}
{2374009200 10800 1 EEST}
{2374524000 10800 1 EEST}
{2392754400 7200 0 EET}
{2405458800 10800 1 EEST}
{2405973600 10800 1 EEST}
{2424204000 7200 0 EET}
{2437513200 10800 1 EEST}
{2437423200 10800 1 EEST}
{2455653600 7200 0 EET}
{2468962800 10800 1 EEST}
{2468872800 10800 1 EEST}
{2487708000 7200 0 EET}
{2500412400 10800 1 EEST}
{2500322400 10800 1 EEST}
{2519157600 7200 0 EET}
{2531862000 10800 1 EEST}
{2531772000 10800 1 EEST}
{2550607200 7200 0 EET}
{2563311600 10800 1 EEST}
{2563826400 10800 1 EEST}
{2582056800 7200 0 EET}
{2595366000 10800 1 EEST}
{2595276000 10800 1 EEST}
{2613506400 7200 0 EET}
{2626815600 10800 1 EEST}
{2626725600 10800 1 EEST}
{2644956000 7200 0 EET}
{2658265200 10800 1 EEST}
{2658175200 10800 1 EEST}
{2677010400 7200 0 EET}
{2689714800 10800 1 EEST}
{2689624800 10800 1 EEST}
{2708460000 7200 0 EET}
{2721164400 10800 1 EEST}
{2721679200 10800 1 EEST}
{2739909600 7200 0 EET}
{2752614000 10800 1 EEST}
{2753128800 10800 1 EEST}
{2771359200 7200 0 EET}
{2784668400 10800 1 EEST}
{2784578400 10800 1 EEST}
{2802808800 7200 0 EET}
{2816118000 10800 1 EEST}
{2816028000 10800 1 EEST}
{2834258400 7200 0 EET}
{2847567600 10800 1 EEST}
{2847477600 10800 1 EEST}
{2866312800 7200 0 EET}
{2879017200 10800 1 EEST}
{2878927200 10800 1 EEST}
{2897762400 7200 0 EET}
{2910466800 10800 1 EEST}
{2910981600 10800 1 EEST}
{2929212000 7200 0 EET}
{2941916400 10800 1 EEST}
{2942431200 10800 1 EEST}
{2960661600 7200 0 EET}
{2973970800 10800 1 EEST}
{2973880800 10800 1 EEST}
{2992111200 7200 0 EET}
{3005420400 10800 1 EEST}
{3005330400 10800 1 EEST}
{3024165600 7200 0 EET}
{3036870000 10800 1 EEST}
{3036780000 10800 1 EEST}
{3055615200 7200 0 EET}
{3068319600 10800 1 EEST}
{3068229600 10800 1 EEST}
{3087064800 7200 0 EET}
{3099769200 10800 1 EEST}
{3100284000 10800 1 EEST}
{3118514400 7200 0 EET}
{3131823600 10800 1 EEST}
{3131733600 10800 1 EEST}
{3149964000 7200 0 EET}
{3163273200 10800 1 EEST}
{3163183200 10800 1 EEST}
{3181413600 7200 0 EET}
{3194722800 10800 1 EEST}
{3194632800 10800 1 EEST}
{3213468000 7200 0 EET}
{3226172400 10800 1 EEST}
{3226082400 10800 1 EEST}
{3244917600 7200 0 EET}
{3257622000 10800 1 EEST}
{3258136800 10800 1 EEST}
{3276367200 7200 0 EET}
{3289071600 10800 1 EEST}
{3289586400 10800 1 EEST}
{3307816800 7200 0 EET}
{3321126000 10800 1 EEST}
{3321036000 10800 1 EEST}
{3339266400 7200 0 EET}
{3352575600 10800 1 EEST}
{3352485600 10800 1 EEST}
{3371320800 7200 0 EET}
{3384025200 10800 1 EEST}
{3383935200 10800 1 EEST}
{3402770400 7200 0 EET}
{3415474800 10800 1 EEST}
{3415384800 10800 1 EEST}
{3434220000 7200 0 EET}
{3446924400 10800 1 EEST}
{3447439200 10800 1 EEST}
{3465669600 7200 0 EET}
{3478978800 10800 1 EEST}
{3478888800 10800 1 EEST}
{3497119200 7200 0 EET}
{3510428400 10800 1 EEST}
{3510338400 10800 1 EEST}
{3528568800 7200 0 EET}
{3541878000 10800 1 EEST}
{3541788000 10800 1 EEST}
{3560623200 7200 0 EET}
{3573327600 10800 1 EEST}
{3573237600 10800 1 EEST}
{3592072800 7200 0 EET}
{3604777200 10800 1 EEST}
{3605292000 10800 1 EEST}
{3623522400 7200 0 EET}
{3636226800 10800 1 EEST}
{3636741600 10800 1 EEST}
{3654972000 7200 0 EET}
{3668281200 10800 1 EEST}
{3668191200 10800 1 EEST}
{3686421600 7200 0 EET}
{3699730800 10800 1 EEST}
{3699640800 10800 1 EEST}
{3717871200 7200 0 EET}
{3731180400 10800 1 EEST}
{3731090400 10800 1 EEST}
{3749925600 7200 0 EET}
{3762630000 10800 1 EEST}
{3762540000 10800 1 EEST}
{3781375200 7200 0 EET}
{3794079600 10800 1 EEST}
{3794594400 10800 1 EEST}
{3812824800 7200 0 EET}
{3825529200 10800 1 EEST}
{3826044000 10800 1 EEST}
{3844274400 7200 0 EET}
{3857583600 10800 1 EEST}
{3857493600 10800 1 EEST}
{3875724000 7200 0 EET}
{3889033200 10800 1 EEST}
{3888943200 10800 1 EEST}
{3907778400 7200 0 EET}
{3920482800 10800 1 EEST}
{3920392800 10800 1 EEST}
{3939228000 7200 0 EET}
{3951932400 10800 1 EEST}
{3951842400 10800 1 EEST}
{3970677600 7200 0 EET}
{3983382000 10800 1 EEST}
{3983896800 10800 1 EEST}
{4002127200 7200 0 EET}
{4015436400 10800 1 EEST}
{4015346400 10800 1 EEST}
{4033576800 7200 0 EET}
{4046886000 10800 1 EEST}
{4046796000 10800 1 EEST}
{4065026400 7200 0 EET}
{4078335600 10800 1 EEST}
{4078245600 10800 1 EEST}
{4097080800 7200 0 EET}
}
+10 -10
View File
@@ -3,24 +3,24 @@
set TZData(:Asia/Hong_Kong) {
{-9223372036854775808 27402 0 LMT}
{-2056690800 28800 0 HKT}
{-900909000 32400 1 HKST}
{-900910800 32400 1 HKST}
{-891579600 30600 0 HKT}
{-884248200 32400 0 JST}
{-766659600 28800 0 HKT}
{-747981000 32400 1 HKST}
{-728544600 28800 0 HKT}
{-761209200 28800 0 HKT}
{-747907200 32400 1 HKST}
{-728541000 28800 0 HKT}
{-717049800 32400 1 HKST}
{-694503000 28800 0 HKT}
{-697091400 28800 0 HKT}
{-683785800 32400 1 HKST}
{-668064600 28800 0 HKT}
{-668061000 28800 0 HKT}
{-654755400 32400 1 HKST}
{-636615000 28800 0 HKT}
{-636611400 28800 0 HKT}
{-623305800 32400 1 HKST}
{-605165400 28800 0 HKT}
{-605161800 28800 0 HKT}
{-591856200 32400 1 HKST}
{-573715800 28800 0 HKT}
{-573712200 28800 0 HKT}
{-559801800 32400 1 HKST}
{-541661400 28800 0 HKT}
{-541657800 28800 0 HKT}
{-528352200 32400 1 HKST}
{-510211800 28800 0 HKT}
{-498112200 32400 1 HKST}
+1 -1
View File
@@ -2,7 +2,7 @@
set TZData(:Europe/Rome) {
{-9223372036854775808 2996 0 LMT}
{-3259097396 2996 0 RMT}
{-3252098996 2996 0 RMT}
{-2403565200 3600 0 CET}
{-1690765200 7200 1 CEST}
{-1680487200 3600 0 CET}
+44 -42
View File
@@ -1,54 +1,56 @@
#include "tommath_private.h"
#ifdef BN_MP_AND_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* AND two ints together */
int mp_and(const mp_int *a, const mp_int *b, mp_int *c)
/* two complement and */
mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c)
{
int res, ix, px;
mp_int t;
const mp_int *x;
int used = MAX(a->used, b->used) + 1, i;
mp_err err;
mp_digit ac = 1, bc = 1, cc = 1;
mp_sign csign = ((a->sign == MP_NEG) && (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS;
if (a->used > b->used) {
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
return res;
if (c->alloc < used) {
if ((err = mp_grow(c, used)) != MP_OKAY) {
return err;
}
px = b->used;
x = b;
} else {
if ((res = mp_init_copy(&t, b)) != MP_OKAY) {
return res;
}
for (i = 0; i < used; i++) {
mp_digit x, y;
/* convert to two complement if negative */
if (a->sign == MP_NEG) {
ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK);
x = ac & MP_MASK;
ac >>= MP_DIGIT_BIT;
} else {
x = (i >= a->used) ? 0uL : a->dp[i];
}
/* convert to two complement if negative */
if (b->sign == MP_NEG) {
bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK);
y = bc & MP_MASK;
bc >>= MP_DIGIT_BIT;
} else {
y = (i >= b->used) ? 0uL : b->dp[i];
}
c->dp[i] = x & y;
/* convert to to sign-magnitude if negative */
if (csign == MP_NEG) {
cc += ~c->dp[i] & MP_MASK;
c->dp[i] = cc & MP_MASK;
cc >>= MP_DIGIT_BIT;
}
px = a->used;
x = a;
}
for (ix = 0; ix < px; ix++) {
t.dp[ix] &= x->dp[ix];
}
/* zero digits above the last from the smallest mp_int */
for (; ix < t.used; ix++) {
t.dp[ix] = 0;
}
mp_clamp(&t);
mp_exch(c, &t);
mp_clear(&t);
c->used = used;
c->sign = csign;
mp_clamp(c);
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+3 -16
View File
@@ -1,19 +1,10 @@
#include "tommath_private.h"
#ifdef BN_MP_CMP_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* compare two ints (signed)*/
int mp_cmp(const mp_int *a, const mp_int *b)
mp_ord mp_cmp(const mp_int *a, const mp_int *b)
{
/* compare based on sign */
if (a->sign != b->sign) {
@@ -33,7 +24,3 @@ int mp_cmp(const mp_int *a, const mp_int *b)
}
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+3 -16
View File
@@ -1,19 +1,10 @@
#include "tommath_private.h"
#ifdef BN_MP_CMP_D_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* compare a digit */
int mp_cmp_d(const mp_int *a, mp_digit b)
mp_ord mp_cmp_d(const mp_int *a, mp_digit b)
{
/* compare based on sign */
if (a->sign == MP_NEG) {
@@ -35,7 +26,3 @@ int mp_cmp_d(const mp_int *a, mp_digit b)
}
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+4 -17
View File
@@ -1,22 +1,13 @@
#include "tommath_private.h"
#ifdef BN_MP_CMP_MAG_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* compare maginitude of two ints (unsigned) */
int mp_cmp_mag(const mp_int *a, const mp_int *b)
mp_ord mp_cmp_mag(const mp_int *a, const mp_int *b)
{
int n;
mp_digit *tmpa, *tmpb;
const mp_digit *tmpa, *tmpb;
/* compare based on # of non-zero digits */
if (a->used > b->used) {
@@ -46,7 +37,3 @@ int mp_cmp_mag(const mp_int *a, const mp_int *b)
return MP_EQ;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
-44
View File
@@ -1,44 +0,0 @@
#include "tommath_private.h"
#ifdef BN_MP_GET_BIT_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* Checks the bit at position b and returns MP_YES
if the bit is 1, MP_NO if it is 0 and MP_VAL
in case of error */
int mp_get_bit(const mp_int *a, int b)
{
int limb;
mp_digit bit, isset;
if (b < 0) {
return MP_VAL;
}
limb = b / DIGIT_BIT;
if (limb >= a->used) {
return MP_NO;
}
bit = (mp_digit)(1) << (b % DIGIT_BIT);
isset = a->dp[limb] & bit;
return (isset != 0u) ? MP_YES : MP_NO;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+44 -36
View File
@@ -1,48 +1,56 @@
#include "tommath_private.h"
#ifdef BN_MP_OR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* OR two ints together */
int mp_or(const mp_int *a, const mp_int *b, mp_int *c)
/* two complement or */
mp_err mp_or(const mp_int *a, const mp_int *b, mp_int *c)
{
int res, ix, px;
mp_int t;
const mp_int *x;
int used = MAX(a->used, b->used) + 1, i;
mp_err err;
mp_digit ac = 1, bc = 1, cc = 1;
mp_sign csign = ((a->sign == MP_NEG) || (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS;
if (a->used > b->used) {
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
return res;
if (c->alloc < used) {
if ((err = mp_grow(c, used)) != MP_OKAY) {
return err;
}
px = b->used;
x = b;
} else {
if ((res = mp_init_copy(&t, b)) != MP_OKAY) {
return res;
}
px = a->used;
x = a;
}
for (ix = 0; ix < px; ix++) {
t.dp[ix] |= x->dp[ix];
for (i = 0; i < used; i++) {
mp_digit x, y;
/* convert to two complement if negative */
if (a->sign == MP_NEG) {
ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK);
x = ac & MP_MASK;
ac >>= MP_DIGIT_BIT;
} else {
x = (i >= a->used) ? 0uL : a->dp[i];
}
/* convert to two complement if negative */
if (b->sign == MP_NEG) {
bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK);
y = bc & MP_MASK;
bc >>= MP_DIGIT_BIT;
} else {
y = (i >= b->used) ? 0uL : b->dp[i];
}
c->dp[i] = x | y;
/* convert to to sign-magnitude if negative */
if (csign == MP_NEG) {
cc += ~c->dp[i] & MP_MASK;
c->dp[i] = cc & MP_MASK;
cc >>= MP_DIGIT_BIT;
}
}
mp_clamp(&t);
mp_exch(c, &t);
mp_clear(&t);
c->used = used;
c->sign = csign;
mp_clamp(c);
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+22
View File
@@ -0,0 +1,22 @@
#include "tommath_private.h"
#ifdef BN_MP_SIGNED_RSH_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* shift right by a certain bit count with sign extension */
mp_err mp_signed_rsh(const mp_int *a, int b, mp_int *c)
{
mp_err res;
if (a->sign == MP_ZPOS) {
return mp_div_2d(a, b, c, NULL);
}
res = mp_add_d(a, 1uL, c);
if (res != MP_OKAY) {
return res;
}
res = mp_div_2d(c, b, c, NULL);
return (res == MP_OKAY) ? mp_sub_d(c, 1uL, c) : res;
}
#endif
-90
View File
@@ -1,90 +0,0 @@
#include "tommath_private.h"
#ifdef BN_MP_TC_AND_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* two complement and */
int mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c)
{
int res = MP_OKAY, bits, abits, bbits;
int as = mp_isneg(a), bs = mp_isneg(b);
mp_int *mx = NULL, _mx, acpy, bcpy;
if ((as != MP_NO) || (bs != MP_NO)) {
abits = mp_count_bits(a);
bbits = mp_count_bits(b);
bits = MAX(abits, bbits);
res = mp_init_set_int(&_mx, 1uL);
if (res != MP_OKAY) {
goto end;
}
mx = &_mx;
res = mp_mul_2d(mx, bits + 1, mx);
if (res != MP_OKAY) {
goto end;
}
if (as != MP_NO) {
res = mp_init(&acpy);
if (res != MP_OKAY) {
goto end;
}
res = mp_add(mx, a, &acpy);
if (res != MP_OKAY) {
mp_clear(&acpy);
goto end;
}
a = &acpy;
}
if (bs != MP_NO) {
res = mp_init(&bcpy);
if (res != MP_OKAY) {
goto end;
}
res = mp_add(mx, b, &bcpy);
if (res != MP_OKAY) {
mp_clear(&bcpy);
goto end;
}
b = &bcpy;
}
}
res = mp_and(a, b, c);
if ((as != MP_NO) && (bs != MP_NO) && (res == MP_OKAY)) {
res = mp_sub(c, mx, c);
}
end:
if (a == &acpy) {
mp_clear(&acpy);
}
if (b == &bcpy) {
mp_clear(&bcpy);
}
if (mx == &_mx) {
mp_clear(mx);
}
return res;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
-35
View File
@@ -1,35 +0,0 @@
#include "tommath_private.h"
#ifdef BN_MP_TC_DIV_2D_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* two complement right shift */
int mp_tc_div_2d(const mp_int *a, int b, mp_int *c)
{
int res;
if (mp_isneg(a) == MP_NO) {
return mp_div_2d(a, b, c, NULL);
}
res = mp_add_d(a, 1uL, c);
if (res != MP_OKAY) {
return res;
}
res = mp_div_2d(c, b, c, NULL);
return (res == MP_OKAY) ? mp_sub_d(c, 1uL, c) : res;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
-90
View File
@@ -1,90 +0,0 @@
#include "tommath_private.h"
#ifdef BN_MP_TC_OR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* two complement or */
int mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c)
{
int res = MP_OKAY, bits, abits, bbits;
int as = mp_isneg(a), bs = mp_isneg(b);
mp_int *mx = NULL, _mx, acpy, bcpy;
if ((as != MP_NO) || (bs != MP_NO)) {
abits = mp_count_bits(a);
bbits = mp_count_bits(b);
bits = MAX(abits, bbits);
res = mp_init_set_int(&_mx, 1uL);
if (res != MP_OKAY) {
goto end;
}
mx = &_mx;
res = mp_mul_2d(mx, bits + 1, mx);
if (res != MP_OKAY) {
goto end;
}
if (as != MP_NO) {
res = mp_init(&acpy);
if (res != MP_OKAY) {
goto end;
}
res = mp_add(mx, a, &acpy);
if (res != MP_OKAY) {
mp_clear(&acpy);
goto end;
}
a = &acpy;
}
if (bs != MP_NO) {
res = mp_init(&bcpy);
if (res != MP_OKAY) {
goto end;
}
res = mp_add(mx, b, &bcpy);
if (res != MP_OKAY) {
mp_clear(&bcpy);
goto end;
}
b = &bcpy;
}
}
res = mp_or(a, b, c);
if (((as != MP_NO) || (bs != MP_NO)) && (res == MP_OKAY)) {
res = mp_sub(c, mx, c);
}
end:
if (a == &acpy) {
mp_clear(&acpy);
}
if (b == &bcpy) {
mp_clear(&bcpy);
}
if (mx == &_mx) {
mp_clear(mx);
}
return res;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
-90
View File
@@ -1,90 +0,0 @@
#include "tommath_private.h"
#ifdef BN_MP_TC_XOR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* two complement xor */
int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c)
{
int res = MP_OKAY, bits, abits, bbits;
int as = mp_isneg(a), bs = mp_isneg(b);
mp_int *mx = NULL, _mx, acpy, bcpy;
if ((as != MP_NO) || (bs != MP_NO)) {
abits = mp_count_bits(a);
bbits = mp_count_bits(b);
bits = MAX(abits, bbits);
res = mp_init_set_int(&_mx, 1uL);
if (res != MP_OKAY) {
goto end;
}
mx = &_mx;
res = mp_mul_2d(mx, bits + 1, mx);
if (res != MP_OKAY) {
goto end;
}
if (as != MP_NO) {
res = mp_init(&acpy);
if (res != MP_OKAY) {
goto end;
}
res = mp_add(mx, a, &acpy);
if (res != MP_OKAY) {
mp_clear(&acpy);
goto end;
}
a = &acpy;
}
if (bs != MP_NO) {
res = mp_init(&bcpy);
if (res != MP_OKAY) {
goto end;
}
res = mp_add(mx, b, &bcpy);
if (res != MP_OKAY) {
mp_clear(&bcpy);
goto end;
}
b = &bcpy;
}
}
res = mp_xor(a, b, c);
if ((as != bs) && (res == MP_OKAY)) {
res = mp_sub(c, mx, c);
}
end:
if (a == &acpy) {
mp_clear(&acpy);
}
if (b == &bcpy) {
mp_clear(&bcpy);
}
if (mx == &_mx) {
mp_clear(mx);
}
return res;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+44 -36
View File
@@ -1,48 +1,56 @@
#include "tommath_private.h"
#ifdef BN_MP_XOR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* XOR two ints together */
int mp_xor(const mp_int *a, const mp_int *b, mp_int *c)
/* two complement xor */
mp_err mp_xor(const mp_int *a, const mp_int *b, mp_int *c)
{
int res, ix, px;
mp_int t;
const mp_int *x;
int used = MAX(a->used, b->used) + 1, i;
mp_err err;
mp_digit ac = 1, bc = 1, cc = 1;
mp_sign csign = (a->sign != b->sign) ? MP_NEG : MP_ZPOS;
if (a->used > b->used) {
if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
return res;
if (c->alloc < used) {
if ((err = mp_grow(c, used)) != MP_OKAY) {
return err;
}
px = b->used;
x = b;
} else {
if ((res = mp_init_copy(&t, b)) != MP_OKAY) {
return res;
}
px = a->used;
x = a;
}
for (ix = 0; ix < px; ix++) {
t.dp[ix] ^= x->dp[ix];
for (i = 0; i < used; i++) {
mp_digit x, y;
/* convert to two complement if negative */
if (a->sign == MP_NEG) {
ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK);
x = ac & MP_MASK;
ac >>= MP_DIGIT_BIT;
} else {
x = (i >= a->used) ? 0uL : a->dp[i];
}
/* convert to two complement if negative */
if (b->sign == MP_NEG) {
bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK);
y = bc & MP_MASK;
bc >>= MP_DIGIT_BIT;
} else {
y = (i >= b->used) ? 0uL : b->dp[i];
}
c->dp[i] = x ^ y;
/* convert to to sign-magnitude if negative */
if (csign == MP_NEG) {
cc += ~c->dp[i] & MP_MASK;
c->dp[i] = cc & MP_MASK;
cc >>= MP_DIGIT_BIT;
}
}
mp_clamp(&t);
mp_exch(c, &t);
mp_clear(&t);
c->used = used;
c->sign = csign;
mp_clamp(c);
return MP_OKAY;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+21
View File
@@ -0,0 +1,21 @@
#include "tommath_private.h"
#ifdef BN_S_MP_GET_BIT_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* Get bit at position b and return MP_YES if the bit is 1, MP_NO if it is 0 */
mp_bool s_mp_get_bit(const mp_int *a, int b)
{
mp_digit bit;
int limb = (int)((unsigned)b / MP_DIGIT_BIT);
if (limb >= a->used) {
return MP_NO;
}
bit = (mp_digit)1 << ((unsigned)b % MP_DIGIT_BIT);
return ((a->dp[limb] & bit) != 0u) ? MP_YES : MP_NO;
}
#endif
File diff suppressed because it is too large Load Diff
+9 -17
View File
@@ -1,14 +1,6 @@
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#ifndef BN_H_
#define BN_H_
@@ -157,18 +149,18 @@ void mp_clear_multi(mp_int *mp, ...);
void mp_exch(mp_int *a, mp_int *b);
/* shrink ram required for a bignum */
int mp_shrink(mp_int *a);
mp_err mp_shrink(mp_int *a);
/* grow an int to a given size */
int mp_grow(mp_int *a, int size);
mp_err mp_grow(mp_int *a, int size);
/* init to a given number of digits */
int mp_init_size(mp_int *a, int size);
mp_err mp_init_size(mp_int *a, int size);
/* ---> Basic Manipulations <--- */
#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
#define mp_iseven(a) (!mp_get_bit((a),0))
#define mp_isodd(a) mp_get_bit((a),0)
#define mp_iseven(a) (((a)->used == 0 || (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
#define mp_isneg(a) (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO)
/* set to zero */
@@ -292,7 +284,7 @@ int mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c);
int mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c);
/* right shift (two complement) */
int mp_tc_div_2d(const mp_int *a, int b, mp_int *c);
int mp_signed_rsh(const mp_int *a, int b, mp_int *c);
/* ---> Basic arithmetic <--- */
+6 -6
View File
@@ -59,7 +59,7 @@
# define BN_MP_FREAD_C
# define BN_MP_FWRITE_C
# define BN_MP_GCD_C
# define BN_MP_GET_BIT_C
# define BN_S_MP_GET_BIT_C
# define BN_MP_GET_DOUBLE_C
# define BN_MP_GET_INT_C
# define BN_MP_GET_LONG_C
@@ -135,7 +135,7 @@
# define BN_MP_SUB_D_C
# define BN_MP_SUBMOD_C
# define BN_MP_TC_AND_C
# define BN_MP_TC_DIV_2D_C
# define BN_MP_SIGNED_RSH_C
# define BN_MP_TC_OR_C
# define BN_MP_TC_XOR_C
# define BN_MP_TO_SIGNED_BIN_C
@@ -442,7 +442,7 @@
# define BN_MP_CLEAR_C
#endif
#if defined(BN_MP_GET_BIT_C)
#if defined(BN_S_MP_GET_BIT_C)
# define BN_MP_ISZERO_C
#endif
@@ -715,7 +715,7 @@
# define BN_MP_MUL_C
# define BN_MP_SUB_C
# define BN_MP_MOD_C
# define BN_MP_GET_BIT_C
# define BN_S_MP_GET_BIT_C
# define BN_MP_EXCH_C
# define BN_MP_ISZERO_C
# define BN_MP_CMP_C
@@ -802,7 +802,7 @@
# define BN_MP_MOD_C
# define BN_MP_SQR_C
# define BN_MP_SUB_C
# define BN_MP_GET_BIT_C
# define BN_S_MP_GET_BIT_C
# define BN_MP_ADD_C
# define BN_MP_ISODD_C
# define BN_MP_DIV_2_C
@@ -1034,7 +1034,7 @@
# define BN_MP_SUB_C
#endif
#if defined(BN_MP_TC_DIV_2D_C)
#if defined(BN_MP_SIGNED_RSH_C)
# define BN_MP_ISNEG_C
# define BN_MP_DIV_2D_C
# define BN_MP_ADD_D_C
+7 -7
View File
@@ -2,18 +2,18 @@
# ------------------------------------------------------------------------
#
# test-performance.tcl --
#
#
# This file provides common performance tests for comparison of tcl-speed
# degradation by switching between branches.
# (currently for clock ensemble only)
#
# ------------------------------------------------------------------------
#
#
# Copyright (c) 2014 Serg G. Brester (aka sebres)
#
#
# See the file "license.terms" for information on usage and redistribution
# of this file.
#
#
array set in {-time 500}
if {[info exists ::argv0] && [file tail $::argv0] eq [file tail [info script]]} {
@@ -215,7 +215,7 @@ proc test-freescan {{reptime 1000}} {
{clock scan "next January" -base 0 -gmt 1}
# FreeScan : relative week
{clock scan "next Fri" -base 0 -gmt 1}
# FreeScan : relative weekday and week offset
# FreeScan : relative weekday and week offset
{clock scan "next January + 2 week" -base 0 -gmt 1}
# FreeScan : time only with base
{clock scan "19:18:30" -base 148863600 -gmt 1}
@@ -300,7 +300,7 @@ proc test-convert {{reptime 1000}} {
{clock format [clock scan "19:18:30 EST" -base 148863600] -format "%H:%M:%S %z" -timezone EST}
# Format locale 1x: comparison values
{clock format 0 -gmt 1 -locale en}
{clock format 0 -gmt 1 -locale en}
{clock format 0 -gmt 1 -locale de}
{clock format 0 -gmt 1 -locale fr}
# Format locale 2x: without switching locale (en, en)
@@ -340,7 +340,7 @@ proc test-convert {{reptime 1000}} {
{clock scan "19:18:30 MST" -base 148863600; clock scan "19:18:30 EST" -base 148863600}
# FreeScan TZ 2x (+1 gmt, +1 system-default)
{clock scan "19:18:30 MST" -base 148863600 -gmt 1; clock scan "19:18:30 EST" -base 148863600}
# Scan TZ: comparison included in scan string vs. given
{clock scan "2009-06-30T18:30:00 CEST" -format "%Y-%m-%dT%H:%M:%S %z"}
{clock scan "2009-06-30T18:30:00 CET" -format "%Y-%m-%dT%H:%M:%S %z"}
+73 -27
View File
@@ -1,19 +1,19 @@
# ------------------------------------------------------------------------
#
# test-performance.tcl --
#
#
# This file provides common performance tests for comparison of tcl-speed
# degradation or regression by switching between branches.
#
# To execute test case evaluate direct corresponding file "tests-perf\*.perf.tcl".
#
# ------------------------------------------------------------------------
#
#
# Copyright (c) 2014 Serg G. Brester (aka sebres)
#
#
# See the file "license.terms" for information on usage and redistribution
# of this file.
#
#
namespace eval ::tclTestPerf {
# warm-up interpeter compiler env, calibrate timerate measurement functionality:
@@ -33,7 +33,7 @@ if {[lindex [timerate {} 10] 6] >= (10-1)} {
}
proc {**STOP**} {args} {
return -code error -level 4 "**STOP** in [info level [expr {[info level]-2}]] [join $args { }]"
return -code error -level 4 "**STOP** in [info level [expr {[info level]-2}]] [join $args { }]"
}
proc _test_get_commands {lst} {
@@ -51,13 +51,13 @@ proc _test_out_total {} {
set mintm 0x7fffffff
set maxtm 0
set nett 0
set nettm 0
set wtm 0
set wcnt 0
set i 0
foreach tm $_(itm) {
if {[llength $tm] > 6} {
set nett [expr {$nett + [lindex $tm 6]}]
set nettm [expr {$nettm + [lindex $tm 6]}]
}
set wtm [expr {$wtm + [lindex $tm 0]}]
set wcnt [expr {$wcnt + [lindex $tm 2]}]
@@ -69,15 +69,15 @@ proc _test_out_total {} {
puts [string repeat ** 40]
set s [format "%d cases in %.2f sec." $tcnt [expr {([clock milliseconds] - $_(starttime)) / 1000.0}]]
if {$nett > 0} {
append s [format " (%.2f nett-sec.)" [expr {$nett / 1000.0}]]
if {$nettm > 0} {
append s [format " (%.2f net-sec.)" [expr {$nettm / 1000.0}]]
}
puts "Total $s:"
lset _(m) 0 [format %.6f $wtm]
lset _(m) 2 $wcnt
lset _(m) 4 [format %.3f [expr {$wcnt / (($nett ? $nett : ($tcnt * [lindex $_(reptime) 0])) / 1000.0)}]]
lset _(m) 4 [format %.3f [expr {$wcnt / (($nettm ? $nettm : ($tcnt * [lindex $_(reptime) 0])) / 1000.0)}]]
if {[llength $_(m)] > 6} {
lset _(m) 6 [format %.3f $nett]
lset _(m) 6 [format %.3f $nettm]
}
puts $_(m)
puts "Average:"
@@ -94,51 +94,97 @@ proc _test_out_total {} {
puts [lindex $_(itm) $maxi]
puts [string repeat ** 40]
puts ""
unset -nocomplain _(itm) _(starttime)
}
proc _test_start {reptime} {
upvar _ _
array set _ [list itm {} reptime $reptime starttime [clock milliseconds] -from-run 0]
}
proc _test_iter {args} {
if {[llength $args] > 2} {
return -code error "wrong # args: should be \"[lindex [info level [info level]] 0] ?level? measure-result\""
}
set lvl 1
if {[llength $args] > 1} {
set args [lassign $args lvl]
}
upvar $lvl _ _
puts [set _(m) {*}$args]
lappend _(itm) $_(m)
puts ""
}
proc _adjust_maxcount {reptime maxcount} {
if {[llength $reptime] > 1} {
lreplace $reptime 1 1 [expr {min($maxcount,[lindex $reptime 1])}]
} else {
lappend reptime $maxcount
}
}
proc _test_run {args} {
upvar _ _
# parse args:
set _(out-result) 1
if {[lindex $args 0] eq "-no-result"} {
set _(out-result) 0
array set _ [set _opts {-no-result 0 -uplevel 0}]
while {[llength $args] > 2} {
if {[set o [lindex $args 0]] ni $_opts || $_($o)} {
break
}
set _($o) 1
set args [lrange $args 1 end]
}
unset -nocomplain _opts o
if {[llength $args] < 2 || [llength $args] > 3} {
return -code error "wrong # args: should be \"[lindex [info level [info level]] 0] ?-no-result? reptime lst ?outcmd?\""
}
set outcmd {puts $_(r)}
set _(outcmd) {puts}
set args [lassign $args reptime lst]
if {[llength $args]} {
set outcmd [lindex $args 0]
set _(outcmd) [lindex $args 0]
}
# avoid output if only once:
if {[lindex $reptime 0] <= 1 || ([llength $reptime] > 1 && [lindex $reptime 1] == 1)} {
set _(out-result) 0
set _(-no-result) 1
}
if {![info exists _(itm)]} {
array set _ [list itm {} reptime $reptime starttime [clock milliseconds] -from-run 1]
} else {
array set _ [list reptime $reptime]
}
array set _ [list itm {} reptime $reptime starttime [clock milliseconds]]
# process measurement:
foreach _(c) [_test_get_commands $lst] {
puts "% [regsub -all {\n[ \t]*} $_(c) {; }]"
{*}$_(outcmd) "% [regsub -all {\n[ \t]*} $_(c) {; }]"
if {[regexp {^\s*\#} $_(c)]} continue
if {[regexp {^\s*(?:setup|cleanup)\s+} $_(c)]} {
puts [if 1 [lindex $_(c) 1]]
set _(c) [lindex $_(c) 1]
if {$_(-uplevel)} {
set _(c) [list uplevel 1 $_(c)]
}
{*}$_(outcmd) [if 1 $_(c)]
continue
}
if {$_(-uplevel)} {
set _(c) [list uplevel 1 $_(c)]
}
set _(ittime) $_(reptime)
# if output result (and not once):
if {$_(out-result)} {
if {!$_(-no-result)} {
set _(r) [if 1 $_(c)]
if {$outcmd ne {}} $outcmd
if {[llength $_(reptime)] > 1} { # decrement max-count
lset _(reptime) 1 [expr {[lindex $_(reptime) 1] - 1}]
if {$_(outcmd) ne {}} {{*}$_(outcmd) $_(r)}
if {[llength $_(ittime)] > 1} { # decrement max-count
lset _(ittime) 1 [expr {[lindex $_(ittime) 1] - 1}]
}
}
puts [set _(m) [timerate $_(c) {*}$_(reptime)]]
{*}$_(outcmd) [set _(m) [timerate $_(c) {*}$_(ittime)]]
lappend _(itm) $_(m)
puts ""
{*}$_(outcmd) ""
}
if {$_(-from-run)} {
_test_out_total
}
_test_out_total
}
}; # end of namespace ::tclTestPerf
+8 -8
View File
@@ -3,17 +3,17 @@
# ------------------------------------------------------------------------
#
# timer-event.perf.tcl --
#
#
# This file provides performance tests for comparison of tcl-speed
# of timer events (event-driven tcl-handling).
#
# ------------------------------------------------------------------------
#
#
# Copyright (c) 2014 Serg G. Brester (aka sebres)
#
#
# See the file "license.terms" for information on usage and redistribution
# of this file.
#
#
if {![namespace exists ::tclTestPerf]} {
@@ -40,7 +40,7 @@ proc test-queue {{reptime {1000 10000}}} {
{after idle {set foo bar}}
# update / after idle:
{update; if {![llength [after info]]} break}
# generate up to $howmuch idle-events:
{after idle {set foo bar}}
# update idletasks / after idle:
@@ -50,7 +50,7 @@ proc test-queue {{reptime {1000 10000}}} {
{after 0 {set foo bar}}
# update / after 0:
{update; if {![llength [after info]]} break}
# generate up to $howmuch 1-ms events:
{after 1 {set foo bar}}
setup {after 1}
@@ -83,7 +83,7 @@ proc test-queue {{reptime {1000 10000}}} {
setup {set le $i; incr i; list $le .. 1; # cancel up to $howmuch events}
{after cancel $ev([incr i -1]); if {$i <= 1} break}
cleanup {update; unset -nocomplain ev}
# end $howmuch events.
cleanup {if [llength [after info]] {error "unexpected: [llength [after info]] events are still there."}}
}]
@@ -149,7 +149,7 @@ proc test-long {{reptime 1000}} {
{time {after idle {after 30}} 10; after 1 {set important 1}; vwait important;}
cleanup {foreach i [after info] {after cancel $i}}
# in-between important event (of new generation) by amount of idle events:
{time {after idle {after 30}} 10; after 1 {after 0 {set important 1}}; vwait important;}
{time {after idle {after 30}} 10; after 1 {after 0 {set important 1}}; vwait important;}
cleanup {foreach i [after info] {after cancel $i}}
}
}
+12
View File
@@ -968,6 +968,18 @@ test basic-48.24.$noComp {expansion: empty not canonical list, regression test,
run {list [list {*}{ }] [list {*}[format %c 32]] [list {*}[set a { }]]}
} -result [lrepeat 3 {}] -cleanup {unset -nocomplain a}
test basic-48.25.$noComp {Bug cc191552c: expansion: empty non-canonical list} -setup {
unset -nocomplain ::CRLF
set ::CRLF "\r\n"
} -body {
# Force variant that turned up in Bug 2c154a40be as that's externally
# noticeable in an important downstream project.
run {scan [list {*}$::CRLF]x %c%c%c}
} -cleanup {
unset -nocomplain ::CRLF
} -result {120 {} {}}
} ;# End of noComp loop
test basic-49.1 {Tcl_EvalEx: verify TCL_EVAL_GLOBAL operation} testevalex {
+12 -10
View File
@@ -36707,16 +36707,18 @@ test clock-58.1 {clock l10n - Japanese localisation} {*}{
}
-body {
set trouble {}
foreach {date jdate} [list \
1872-12-31 \u897f\u66a61872\u5e7412\u670831\u65e5 \
1873-01-01 \u660e\u6cbb06\u5e7401\u670801\u65e5 \
1912-07-29 \u660e\u6cbb45\u5e7407\u670829\u65e5 \
1912-07-30 \u5927\u6b6301\u5e7407\u670830\u65e5 \
1926-12-24 \u5927\u6b6315\u5e7412\u670824\u65e5 \
1926-12-25 \u662d\u548c01\u5e7412\u670825\u65e5 \
1989-01-07 \u662d\u548c64\u5e7401\u670807\u65e5 \
1989-01-08 \u5e73\u621001\u5e7401\u670808\u65e5 \
] {
foreach {date jdate} {
1872-12-31 \u897f\u66a61872\u5e7412\u670831\u65e5
1873-01-01 \u660e\u6cbb06\u5e7401\u670801\u65e5
1912-07-29 \u660e\u6cbb45\u5e7407\u670829\u65e5
1912-07-30 \u5927\u6b6301\u5e7407\u670830\u65e5
1926-12-24 \u5927\u6b6315\u5e7412\u670824\u65e5
1926-12-25 \u662d\u548c01\u5e7412\u670825\u65e5
1989-01-07 \u662d\u548c64\u5e7401\u670807\u65e5
1989-01-08 \u5e73\u621001\u5e7401\u670808\u65e5
2019-04-30 \u5e73\u621031\u5e7404\u670830\u65e5
2019-05-01 \u4ee4\u548c01\u5e7405\u670801\u65e5
} {
set status [catch {
set secs [clock scan $date \
-timezone +0900 \
+16 -2
View File
@@ -373,10 +373,10 @@ test cmdMZ-6.4 {Tcl_TimeRateObjCmd: compile of script happens even with negative
list [catch {timerate "foreach a {c d e} \{" -12456} msg] $msg
} {1 {missing close-brace}}
test cmdMZ-6.5a {Tcl_TimeRateObjCmd: result format and one iteration} {
regexp {^\d+(?:\.\d+)? \ws/# 1 # \d+(?:\.\d+)? #/sec \d+(?:\.\d+)? nett-ms$} [timerate {} 0]
regexp {^\d+(?:\.\d+)? \ws/# 1 # \d+(?:\.\d+)? #/sec \d+(?:\.\d+)? net-ms$} [timerate {} 0]
} 1
test cmdMZ-6.5b {Tcl_TimeRateObjCmd: result format without iterations} {
regexp {^0 \ws/# 0 # 0 #/sec 0 nett-ms$} [timerate {} 0 0]
regexp {^0 \ws/# 0 # 0 #/sec 0 net-ms$} [timerate {} 0 0]
} 1
test cmdMZ-6.6 {Tcl_TimeRateObjCmd: slower commands take longer, but it remains almost the same time of measument} {
set m1 [timerate {_nrt_sleep 0} 20]
@@ -407,6 +407,14 @@ test cmdMZ-6.8 {Tcl_TimeRateObjCmd: allow (conditional) break from timerate} {
[expr {[lindex $m1 4] > 1000}] \
[expr {[lindex $m1 6] < 10}]
} {1 1 1 1}
test cmdMZ-6.8.1 {Tcl_TimeRateObjCmd: allow (conditional) continue in timerate} {
set m1 [timerate {continue; return -code error "unexpected"} 1000 10]
list \
[expr {[lindex $m1 0] < 1000}] \
[expr {[lindex $m1 2] == 10}] \
[expr {[lindex $m1 4] > 1000}] \
[expr {[lindex $m1 6] < 100}]
} {1 1 1 1}
test cmdMZ-6.9 {Tcl_TimeRateObjCmd: max count of iterations} {
set m1 [timerate {} 1000 5]; # max-count wins
set m2 [timerate {_nrt_sleep 20} 1 5]; # max-time wins
@@ -420,6 +428,12 @@ test cmdMZ-6.10 {Tcl_TimeRateObjCmd: huge overhead cause 0us result} {
[expr {[lindex $m1 4] == 1000000}] \
[expr {[lindex $m1 6] <= 0.001}]
} {1 1 1 1}
test cmdMZ-6.11 {Tcl_TimeRateObjCmd: done/continue optimization rollback} {
set m1 {set m2 ok}
if 1 $m1
timerate $m1 1000 10
if 1 $m1; # if rollback is missing throws an error: invoked "continue" outside of a loop
} ok
# The tests for Tcl_WhileObjCmd are in while.test
+96 -11
View File
@@ -626,19 +626,31 @@ test coroutine-7.5 {return codes} {
}
set result
} {0 1 2 3 4 5}
test coroutine-7.6 {Early yield crashes} {
proc foo args {}
trace add execution foo enter {catch yield}
coroutine demo foo
rename foo {}
} {}
test coroutine-7.7 {Bug 2486550} -setup {
interp hide {} yield
test coroutine-7.6 {Early yield crashes} -setup {
set i [interp create]
} -body {
coroutine demo interp invokehidden {} yield ok
# Force into a child interpreter [bug 60559fd4a6]
$i eval {
proc foo args {}
trace add execution foo enter {catch yield}
coroutine demo foo
rename foo {}
return ok
}
} -cleanup {
demo
interp expose {} yield
interp delete $i
} -result ok
test coroutine-7.7 {Bug 2486550} -setup {
set i [interp create]
$i hide yield
} -body {
# Force into a child interpreter [bug 60559fd4a6]
$i eval {
coroutine demo interp invokehidden {} yield ok
}
} -cleanup {
$i eval demo
interp delete $i
} -result ok
test coroutine-7.8 {yieldto context nuke: Bug a90d9331bc} -setup {
namespace eval cotest {}
@@ -781,7 +793,80 @@ test coroutine-8.1.2 {coro inject with result, ticket 42202ba1e5ff566e} -body {
set result
} -result {inject-executed}
test coroutine-9.1 {coro type} {
coroutine demo eval {
yield
yield "PHASE 1"
yieldto string cat "PHASE 2"
::tcl::unsupported::corotype [info coroutine]
}
list [demo] [::tcl::unsupported::corotype demo] \
[demo] [::tcl::unsupported::corotype demo] [demo]
} {{PHASE 1} yield {PHASE 2} yieldto active}
test coroutine-9.2 {coro type} -setup {
catch {rename nosuchcommand ""}
} -returnCodes error -body {
::tcl::unsupported::corotype nosuchcommand
} -result {can only get coroutine type of a coroutine}
test coroutine-9.3 {coro type} -returnCodes error -body {
proc notacoroutine {} {}
::tcl::unsupported::corotype notacoroutine
} -returnCodes error -cleanup {
rename notacoroutine {}
} -result {can only get coroutine type of a coroutine}
test coroutine-10.1 {coroutine general introspection} -setup {
set i [interp create]
} -body {
$i eval {
# Make the introspection code
namespace path tcl::unsupported
proc probe {type var} {
upvar 1 $var v
set f [info frame]
incr f -1
set result [list $v [dict get [info frame $f] proc]]
if {$type eq "yield"} {
tailcall yield $result
} else {
tailcall yieldto string cat $result
}
}
proc pokecoro {c var} {
inject $c probe [corotype $c] $var
$c
}
# Coroutine implementations
proc cbody1 {} {
set val [info coroutine]
set accum {}
while {[set val [yield $val]] ne ""} {
lappend accum $val
set val ok
}
return $accum
}
proc cbody2 {} {
set val [info coroutine]
set accum {}
while {[llength [set val [yieldto string cat $val]]]} {
lappend accum {*}$val
set val ok
}
return $accum
}
# Make the coroutines
coroutine c1 cbody1
coroutine c2 cbody2
list [c1 abc] [c2 1 2 3] [pokecoro c1 accum] [pokecoro c2 accum] \
[c1 def] [c2 4 5 6] [pokecoro c1 accum] [pokecoro c2 accum] \
[c1] [c2]
}
} -cleanup {
interp delete $i
} -result {ok ok {abc ::cbody1} {{1 2 3} ::cbody2} ok ok {{abc def} ::cbody1} {{1 2 3 4 5 6} ::cbody2} {abc def} {1 2 3 4 5 6}}
# cleanup
unset lambda
+39
View File
@@ -1066,6 +1066,45 @@ test execute-11.3 {Bug a0ece9d6d4} -setup {
trace remove execution crash enterstep {apply {args {info frame -2}}}
rename crash {}
} -result 1
test execute-12.1 {failing multi-lappend to unshared} -setup {
unset -nocomplain x y
} -body {
set x 1
lappend x 2 3
trace add variable x write {apply {args {error boo}}}
lappend x 4 5
} -cleanup {
unset -nocomplain x y
} -returnCodes error -result {can't set "x": boo}
test execute-12.2 {failing multi-lappend to shared} -setup {
unset -nocomplain x y
} -body {
set x 1
lappend x 2 3
set y $x
trace add variable x write {apply {args {error boo}}}
lappend x 4 5
} -cleanup {
unset -nocomplain x y
} -returnCodes error -result {can't set "x": boo}
test execute-12.3 {failing multi-lappend to unshared: LVT} -body {
apply {{} {
set x 1
lappend x 2 3
trace add variable x write {apply {args {error boo}}}
lappend x 4 5
}}
} -returnCodes error -result {can't set "x": boo}
test execute-12.4 {failing multi-lappend to shared: LVT} -body {
apply {{} {
set x 1
lappend x 2 3
set y $x
trace add variable x write {apply {args {error boo}}}
lappend x 4 5
}}
} -returnCodes error -result {can't set "x": boo}
# cleanup
if {[info commands testobj] != {}} {
+20 -20
View File
@@ -768,26 +768,26 @@ test info-22.8 {info frame, basic trace} -match glob -body {
* {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
test info-23.0.1 {eval'd info frame} -constraints {singleTestInterp} -match glob -body {
eval {info frame}
} -result {1[12]} ;# SingleTestInterp results changes depending on running the whole suite, or info.test alone.
test info-23.1.0 {eval'd info frame, semi-dynamic} {!singleTestInterp} {
eval info frame
} 8
test info-23.1.1 {eval'd info frame, semi-dynamic} -constraints {singleTestInterp} -match glob -body {
eval info frame
} -result {1[12]}
test info-23.2.0 {eval'd info frame, dynamic} -constraints {!singleTestInterp} -body {
set script {info frame}
eval $script
} -cleanup {unset script} -result 8
test info-23.2.1 {eval'd info frame, dynamic} -constraints {singleTestInterp} -match glob -body {
set script {info frame}
eval $script
} -cleanup {unset script} -result {1[12]}
## The line 1967 is off by 5 from the true value of 1972. This is a knownBug, see testcase 30.0
test info-23.0 {eval'd info frame} -constraints {!singleTestInterp} -body {
list [i eval {info frame}] [i eval {eval {info frame}}]
} -setup {interp create i} -cleanup {interp delete i} -result {1 2}
test info-23.1 {eval'd info frame, semi-dynamic} -constraints {!singleTestInterp} -body {
i eval {eval info frame}
} -setup {interp create i} -cleanup {interp delete i} -result 2
test info-23.2 {eval'd info frame, dynamic} -constraints {!singleTestInterp} -body {
i eval { set script {info frame}
eval $script}
} -setup {interp create i} -cleanup {interp delete i} -result 2
test info-23.3 {eval'd info frame, literal} -match glob -body {
eval {
info frame 0
+10
View File
@@ -25,6 +25,16 @@ foreach i {int real bool string} {
unset -nocomplain $i
}
test link-0.1 {leak test} {testlink} {
interp create i
load {} Tcltest i
i eval {
testlink create 1 0 0 0 0 0 0 0 0 0 0 0 0 0
namespace delete ::
}
interp delete i
} {}
test link-1.1 {reading C variables from Tcl} -constraints {testlink} -setup {
testlink delete
} -body {
+17 -4
View File
@@ -1797,7 +1797,7 @@ test namespace-42.7 {ensembles: nested} -body {
list [ns x0 z] [ns x1] [ns x2] [ns x3]
} -cleanup {
namespace delete ns
} -result {{1 z} 1 2 3}
} -result {{1 ::ns::x0::z} 1 2 3}
test namespace-42.8 {
ensembles: [Bug 1670091], panic due to pointer to a deallocated List
struct.
@@ -2128,7 +2128,7 @@ test namespace-47.1 {ensemble: unknown handler} {
lappend result [catch {ns c d e} msg] $msg
lappend result [catch {ns Magic foo bar spong wibble} msg] $msg
list $result [lsort [info commands ::ns::*]] $log [namespace delete ns]
} {{0 2 0 2 0 2 0 2 1 {unknown or protected subcommand "Magic"}} {::ns::Magic ::ns::a ::ns::b ::ns::c} {{making a} {running a b c} {running a b c} {making b} {running b c d} {making c} {running c d e} {unknown Magic - args = foo bar spong wibble}} {}}
} {{0 2 0 2 0 2 0 2 1 {unknown or protected subcommand "Magic"}} {::ns::Magic ::ns::a ::ns::b ::ns::c} {{making a} {running ::ns::a b c} {running ::ns::a b c} {making b} {running ::ns::b c d} {making c} {running ::ns::c d e} {unknown Magic - args = foo bar spong wibble}} {}}
test namespace-47.2 {ensemble: unknown handler} {
namespace eval ns {
namespace export {[a-z]*}
@@ -3227,7 +3227,7 @@ test namespace-53.10 {ensembles: nested rewrite} -setup {
1 {wrong # args: should be "ns z1 x a1"}\
1 {wrong # args: should be "ns z2 x a1 a2"}\
1 {wrong # args: should be "ns z2 x a1 a2"}\
1 {wrong # args: should be "z0"}\
1 {wrong # args: should be "::ns::x::z0"}\
0 {1 v}\
1 {wrong # args: should be "ns v x z2 a2"}\
0 {2 v v2}}
@@ -3312,7 +3312,7 @@ test namespace-56.3 {bug f97d4ee020: mutually-entangled deletion} {
}
} {::testing::abc::def ::testing::abc::ghi}
test namespace-56.4 {bug 16fe1b5807: names starting with ":"} {
test namespace-56.4 {bug 16fe1b5807: names starting with ":"} knownBug {
namespace eval : {
namespace ensemble create
namespace export *
@@ -3323,6 +3323,19 @@ namespace eval : {
: p1
} 16fe1b5807
test namespace-56.5 {Bug 8b9854c3d8} -setup {
namespace eval namespace-56.5 {
proc cmd {} {string match ::* [lindex [[string cat info] level 0] 0]}
namespace export *
namespace ensemble create
}
} -body {
namespace-56.5 cmd
} -cleanup {
namespace delete namespace-56.5
} -result 1
# cleanup
catch {rename cmd1 {}}
+4
View File
@@ -356,6 +356,10 @@ test upvar-8.11 {upvar will not create a variable that looks like an array} -set
test upvar-9.1 {Tcl_UpVar2 procedure} testupvar {
list [catch {testupvar xyz a {} x global} msg] $msg
} {1 {bad level "xyz"}}
test upvar-9.1.1 {TclGetFrame, via Tcl_UpVar2} testupvar {
apply {{} {testupvar xyz a {} x local; set x foo}}
set a
} foo
test upvar-9.2 {Tcl_UpVar2 procedure} testupvar {
catch {unset a}
catch {unset x}
+24 -19
View File
@@ -97,8 +97,13 @@ if {[testConstraint testvolumetype]} {
# NB: filename is chosen to be short but unlikely to clash with other apps
if {[file exists c:/] && [file exists d:/]} {
catch {file delete d:/TclTmpF.1}
if {[catch {createfile d:/TclTmpF.1 {}}] == 0} {
file delete d:/TclTmpF.1
catch {file delete d:/TclTmpD.1}
catch {file delete c:/TclTmpC.1}
if {![catch {createfile d:/TclTmpF.1 {}}] && [file isfile d:/TclTmpF.1]
&& ![catch {file mkdir d:/TclTmpD.1}] && [file isdirectory d:/TclTmpD.1]
&& ![catch {file mkdir c:/TclTmpC.1}] && [file isdirectory c:/TclTmpC.1]
} {
file delete d:/TclTmpF.1 d:/TclTmpD.1 c:/TclTmpC.1
testConstraint exdev 1
}
}
@@ -178,12 +183,12 @@ test winFCmd-1.9 {TclpRenameFile: errno: ENOTDIR} -setup {
testfile mv td1 tf1
} -returnCodes error -result ENOTDIR
test winFCmd-1.10 {TclpRenameFile: errno: EXDEV} -setup {
file delete -force d:/tf1
file delete -force d:/TclTmpD.1
} -constraints {win exdev testfile} -body {
file mkdir c:/tf1
testfile mv c:/tf1 d:/tf1
file mkdir c:/TclTmpC.1
testfile mv c:/TclTmpC.1 d:/TclTmpD.1
} -cleanup {
file delete -force c:/tf1
file delete -force c:/TclTmpC.1
} -returnCodes error -result EXDEV
test winFCmd-1.11 {TclpRenameFile: errno: EACCES} -setup {
cleanup
@@ -333,15 +338,15 @@ test winFCmd-1.32 {TclpRenameFile: TclpRemoveDirectory succeeds} -setup {
} -result {0 1 1}
test winFCmd-1.33 {TclpRenameFile: After removing dst dir, MoveFile fails} \
-constraints {win exdev testfile testchmod} -body {
file mkdir d:/td1
testchmod 0 d:/td1
file mkdir c:/tf1
catch {testfile mv c:/tf1 d:/td1} msg
list $msg [file writable d:/td1]
file mkdir d:/TclTmpD.1
testchmod 0 d:/TclTmpD.1
file mkdir c:/TclTmpC.1
catch {testfile mv c:/TclTmpC.1 d:/TclTmpD.1} msg
list $msg [file writable d:/TclTmpD.1]
} -cleanup {
catch {testchmod 0o666 d:/td1}
file delete d:/td1
file delete -force c:/tf1
catch {testchmod 0o666 d:/TclTmpD.1}
file delete d:/TclTmpD.1
file delete -force c:/TclTmpC.1
} -result {EXDEV 0}
test winFCmd-1.34 {TclpRenameFile: src is dir, dst is not} -setup {
cleanup
@@ -1070,13 +1075,13 @@ test winFCmd-12.5 {ConvertFileNameFormat: absolute path} -body {
list [file attributes / -longname] [file attributes \\ -longname]
} -constraints {win} -result {/ /}
test winFCmd-12.6 {ConvertFileNameFormat: absolute path with drive} -setup {
catch {file delete -force -- c:/td1}
catch {file delete -force -- c:/TclTmpC.1}
} -constraints {win win2000orXP} -body {
createfile c:/td1 {}
string tolower [file attributes c:/td1 -longname]
createfile c:/TclTmpC.1 {}
string tolower [file attributes c:/TclTmpC.1 -longname]
} -cleanup {
file delete -force -- c:/td1
} -result {c:/td1}
file delete -force -- c:/TclTmpC.1
} -result [string tolower {c:/TclTmpC.1}]
test winFCmd-12.6.2 {ConvertFileNameFormat: absolute path with drive (in temp folder)} -setup {
catch {file delete -force -- $::env(TEMP)/td1}
} -constraints {win} -body {
+2 -2
View File
@@ -523,7 +523,7 @@ proc genStubs::makeDecl {name decl index} {
}
append line ", ...)"
if {[lindex $args end] eq "{const char *} format"} {
append line " TCL_FORMAT_PRINTF(" [expr [llength $args] - 1] ", " [llength $args] ")"
append line " TCL_FORMAT_PRINTF(" [expr {[llength $args] - 1}] ", " [llength $args] ")"
}
}
default {
@@ -631,7 +631,7 @@ proc genStubs::makeSlot {name decl index} {
}
append text ", ...)"
if {[lindex $args end] eq "{const char *} format"} {
append text " TCL_FORMAT_PRINTF(" [expr [llength $args] - 1] ", " [llength $args] ")"
append text " TCL_FORMAT_PRINTF(" [expr {[llength $args] - 1}] ", " [llength $args] ")"
}
}
default {
+1 -1
View File
@@ -827,7 +827,7 @@ proc IPmacro {argList} {
set text "\u00b7"
}
set tab [expr $indent * 0.1]i
set tab [expr {$indent * 0.1}]i
newPara $tab -$tab
set state(sb) 80
setTabs $tab
+11 -11
View File
@@ -114,9 +114,9 @@ proc text string {
set pos [string first "\t" $string]
if {$pos >= 0} {
text [string range $string 0 [expr $pos-1]]
text [string range $string 0 [expr {$pos-1}]]
tab
text [string range $string [expr $pos+1] end]
text [string range $string [expr {$pos+1}] end]
return
}
if {$inTable} {
@@ -471,27 +471,27 @@ proc formattedText text {
text $text
return
}
text [string range $text 0 [expr $index-1]]
set c [string index $text [expr $index+1]]
text [string range $text 0 [expr {$index-1}]]
set c [string index $text [expr {$index+1}]]
switch -- $c {
f {
font [string index $text [expr $index+2]]
set text [string range $text [expr $index+3] end]
font [string index $text [expr {$index+2}]]
set text [string range $text [expr {$index+3}] end]
}
e {
text \\
set text [string range $text [expr $index+2] end]
set text [string range $text [expr {$index+2}] end]
}
- {
dash
set text [string range $text [expr $index+2] end]
set text [string range $text [expr {$index+2}] end]
}
| {
set text [string range $text [expr $index+2] end]
set text [string range $text [expr {$index+2}] end]
}
default {
puts stderr "Unknown sequence: \\$c"
set text [string range $text [expr $index+2] end]
set text [string range $text [expr {$index+2}] end]
}
}
}
@@ -527,7 +527,7 @@ proc tab {} {
global inPRE charCnt tabString file
# ? charCnt
if {$inPRE == 1} {
set pos [expr $charCnt % [string length $tabString] ]
set pos [expr {$charCnt % [string length $tabString]}]
set spaces [string first "1" [string range $tabString $pos end] ]
text [format "%*s" [incr spaces] " "]
} else {
+3 -3
View File
@@ -17,13 +17,13 @@ proc readInputFile {} {
set len [string length $line]
if {($len > 0) && ([string index $line [expr $len - 1]] == "\\")} {
if {($len > 0) && ([string index $line [expr {$len - 1}]] == "\\")} {
if {[info exists lineArray(c$i)] == 0} {
set lineArray(c$i) 1
} else {
incr lineArray(c$i)
}
set line [string range $line 0 [expr $len - 2]]
set line [string range $line 0 [expr {$len - 2}]]
append lineArray($i) $line
continue
}
@@ -204,7 +204,7 @@ proc convertTestLine {currentLine len lineNum srcLineNum} {
# find the test result
set numVars [expr $len - 3]
set numVars [expr {$len - 3}]
set vars {}
set vals {}
set result 0
+1 -1
View File
@@ -39,7 +39,7 @@ static char data\[\]=\"[translate $r]\";"
static const char * const data\[\]= {"
set n 1
for {set i 0} {$i<$lg} {incr i $MAX} {
set part [string range $r $i [expr $i+$MAX-1]]
set part [string range $r $i [expr {$i+$MAX-1}]]
set len [string length $part];
puts "\t/* Start of part $n ($len characters) */"
puts "\t\"[translate $part]\","
+9 -21
View File
@@ -322,7 +322,7 @@ TOMMATH_OBJS = bn_reverse.o bn_fast_s_mp_mul_digs.o \
bn_mp_cnt_lsb.o bn_mp_copy.o \
bn_mp_count_bits.o bn_mp_div.o bn_mp_div_d.o bn_mp_div_2.o \
bn_mp_div_2d.o bn_mp_div_3.o bn_mp_exch.o bn_mp_expt_d.o \
bn_mp_expt_d_ex.o bn_mp_get_bit.o bn_mp_grow.o bn_mp_init.o \
bn_mp_expt_d_ex.o bn_s_mp_get_bit.o bn_mp_grow.o bn_mp_init.o \
bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o \
bn_mp_init_set_int.o bn_mp_init_size.o bn_mp_karatsuba_mul.o \
bn_mp_karatsuba_sqr.o \
@@ -332,7 +332,7 @@ TOMMATH_OBJS = bn_reverse.o bn_fast_s_mp_mul_digs.o \
bn_mp_read_radix.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_int.o \
bn_mp_set_long.o bn_mp_shrink.o \
bn_mp_sqr.o bn_mp_sqrt.o bn_mp_sub.o bn_mp_sub_d.o \
bn_mp_tc_and.o bn_mp_tc_div_2d.o bn_mp_tc_or.o bn_mp_tc_xor.o \
bn_mp_signed_rsh.o \
bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o \
bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix_n.o \
bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o bn_s_mp_add.o \
@@ -506,7 +506,7 @@ TOMMATH_SRCS = \
$(TOMMATH_DIR)/bn_mp_exch.c \
$(TOMMATH_DIR)/bn_mp_expt_d.c \
$(TOMMATH_DIR)/bn_mp_expt_d_ex.c \
$(TOMMATH_DIR)/bn_mp_get_bit.c \
$(TOMMATH_DIR)/bn_s_mp_get_bit.c \
$(TOMMATH_DIR)/bn_mp_grow.c \
$(TOMMATH_DIR)/bn_mp_init.c \
$(TOMMATH_DIR)/bn_mp_init_copy.c \
@@ -537,10 +537,7 @@ TOMMATH_SRCS = \
$(TOMMATH_DIR)/bn_mp_sqrt.c \
$(TOMMATH_DIR)/bn_mp_sub.c \
$(TOMMATH_DIR)/bn_mp_sub_d.c \
$(TOMMATH_DIR)/bn_mp_tc_and.c \
$(TOMMATH_DIR)/bn_mp_tc_div_2d.c \
$(TOMMATH_DIR)/bn_mp_tc_or.c \
$(TOMMATH_DIR)/bn_mp_tc_xor.c \
$(TOMMATH_DIR)/bn_mp_signed_rsh.c \
$(TOMMATH_DIR)/bn_mp_to_unsigned_bin.c \
$(TOMMATH_DIR)/bn_mp_to_unsigned_bin_n.c \
$(TOMMATH_DIR)/bn_mp_toom_mul.c \
@@ -1429,8 +1426,8 @@ bn_mp_expt_d.o: $(TOMMATH_DIR)/bn_mp_expt_d.c $(MATHHDRS)
bn_mp_expt_d_ex.o: $(TOMMATH_DIR)/bn_mp_expt_d_ex.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_expt_d_ex.c
bn_mp_get_bit.o: $(TOMMATH_DIR)/bn_mp_get_bit.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_get_bit.c
bn_s_mp_get_bit.o: $(TOMMATH_DIR)/bn_s_mp_get_bit.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_s_mp_get_bit.c
bn_mp_grow.o: $(TOMMATH_DIR)/bn_mp_grow.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_grow.c
@@ -1522,17 +1519,8 @@ bn_mp_sub.o: $(TOMMATH_DIR)/bn_mp_sub.c $(MATHHDRS)
bn_mp_sub_d.o: $(TOMMATH_DIR)/bn_mp_sub_d.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_sub_d.c
bn_mp_tc_and.o: $(TOMMATH_DIR)/bn_mp_tc_and.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_tc_and.c
bn_mp_tc_div_2d.o: $(TOMMATH_DIR)/bn_mp_tc_div_2d.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_tc_div_2d.c
bn_mp_tc_or.o: $(TOMMATH_DIR)/bn_mp_tc_or.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_tc_or.c
bn_mp_tc_xor.o: $(TOMMATH_DIR)/bn_mp_tc_xor.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_tc_xor.c
bn_mp_signed_rsh.o: $(TOMMATH_DIR)/bn_mp_signed_rsh.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_signed_rsh.c
bn_mp_to_unsigned_bin.o: $(TOMMATH_DIR)/bn_mp_to_unsigned_bin.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bn_mp_to_unsigned_bin.c
@@ -1993,7 +1981,7 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M
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 \
cp -p $(TOP_DIR)/changes $(TOP_DIR)/ChangeLog $(TOP_DIR)/README.md \
$(TOP_DIR)/ChangeLog.[12]??? $(TOP_DIR)/license.terms \
$(DISTDIR)
@mkdir $(DISTDIR)/library
+3 -5
View File
@@ -174,6 +174,7 @@ TCL_EXE = @TCL_EXE@
# look into these paths when resolving .c to .obj dependencies.
VPATH = $(GENERIC_DIR):$(TOMMATH_DIR):$(WIN_DIR):$(COMPAT_DIR):$(ZLIB_DIR)
$(info NB: $$VPATH is [$(VPATH)])
AR = @AR@
RANLIB = @RANLIB@
@@ -334,7 +335,7 @@ TOMMATH_OBJS = \
bn_mp_exch.${OBJEXT} \
bn_mp_expt_d.${OBJEXT} \
bn_mp_expt_d_ex.${OBJEXT} \
bn_mp_get_bit.${OBJEXT} \
bn_s_mp_get_bit.${OBJEXT} \
bn_mp_grow.${OBJEXT} \
bn_mp_init.${OBJEXT} \
bn_mp_init_copy.${OBJEXT} \
@@ -365,10 +366,7 @@ TOMMATH_OBJS = \
bn_mp_sqrt.${OBJEXT} \
bn_mp_sub.${OBJEXT} \
bn_mp_sub_d.${OBJEXT} \
bn_mp_tc_and.${OBJEXT} \
bn_mp_tc_div_2d.${OBJEXT} \
bn_mp_tc_or.${OBJEXT} \
bn_mp_tc_xor.${OBJEXT} \
bn_mp_signed_rsh.${OBJEXT} \
bn_mp_to_unsigned_bin.${OBJEXT} \
bn_mp_to_unsigned_bin_n.${OBJEXT} \
bn_mp_toom_mul.${OBJEXT} \
+3293 -3126
View File
File diff suppressed because it is too large Load Diff
+3 -6
View File
@@ -55,7 +55,7 @@
# c:\tcl_src\win\>nmake -f makefile.vc release
# c:\tcl_src\win\>nmake -f makefile.vc test
# c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
# c:\tcl_src\win\>nmake -f makefile.vc release OPTS=pdbs
# c:\tcl_src\win\>nmake -f makefile.vc release OPTS=pdbs
# c:\tcl_src\win\>nmake -f makefile.vc release OPTS=symbols
#
@@ -274,7 +274,7 @@ TOMMATHOBJS = \
$(TMP_DIR)\bn_mp_exch.obj \
$(TMP_DIR)\bn_mp_expt_d.obj \
$(TMP_DIR)\bn_mp_expt_d_ex.obj \
$(TMP_DIR)\bn_mp_get_bit.obj \
$(TMP_DIR)\bn_s_mp_get_bit.obj \
$(TMP_DIR)\bn_mp_grow.obj \
$(TMP_DIR)\bn_mp_init.obj \
$(TMP_DIR)\bn_mp_init_copy.obj \
@@ -305,10 +305,7 @@ TOMMATHOBJS = \
$(TMP_DIR)\bn_mp_sqrt.obj \
$(TMP_DIR)\bn_mp_sub.obj \
$(TMP_DIR)\bn_mp_sub_d.obj \
$(TMP_DIR)\bn_mp_tc_and.obj \
$(TMP_DIR)\bn_mp_tc_div_2d.obj \
$(TMP_DIR)\bn_mp_tc_or.obj \
$(TMP_DIR)\bn_mp_tc_xor.obj \
$(TMP_DIR)\bn_mp_signed_rsh.obj \
$(TMP_DIR)\bn_mp_to_unsigned_bin.obj \
$(TMP_DIR)\bn_mp_to_unsigned_bin_n.obj \
$(TMP_DIR)\bn_mp_toom_mul.obj \
+9 -9
View File
@@ -394,7 +394,7 @@ MSG = ^
# If INSTALLDIR set to Tcl installation root dir then reset to the
# lib dir for installing extensions
# lib dir for installing extensions
!if exist("$(_INSTALLDIR)\include\tcl.h")
_INSTALLDIR=$(_INSTALLDIR)\lib
!endif
@@ -561,7 +561,7 @@ NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
# The following macros are set:
# OPTIMIZATIONS - the compiler flags to be used for optimized builds
# DEBUGFLAGS - the compiler flags to be used for debug builds
# LINKERFLAGS - Flags passed to the linker
# LINKERFLAGS - Flags passed to the linker
#
# Note that these are the compiler settings *available*, not those
# that will be *used*. The latter depends on the OPTS macro settings
@@ -1343,7 +1343,7 @@ USE_WIDECHAR_API = 0
!endif
!if $(USE_WIDECHAR_API)
COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
!endif
# Like the TEA system only set this non empty for non-Tk extensions
@@ -1353,7 +1353,7 @@ COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
-DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
-DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
-DMODULE_SCOPE=extern
-DMODULE_SCOPE=extern
!endif
# crt picks the C run time based on selected OPTS
@@ -1446,7 +1446,7 @@ pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
# compiled with another VC version. Check for this and fix accordingly.
stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
# Link flags
# Link flags
!if $(DEBUG)
ldebug = -debug -debugtype:cv
@@ -1462,7 +1462,7 @@ ldebug = $(ldebug) -debug -debugtype:cv
ldebug= $(ldebug) -profile
!endif
### Declarations common to all linker versions
### Declarations common to all linker versions
lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
@@ -1527,7 +1527,7 @@ RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
-DVERSION=\"$(VERSION)\" \
-DSUFX=\"$(SUFX)\" \
-DPROJECT=\"$(PROJECT)\" \
-DPRJLIBNAME=\"$(PRJLIBNAME)\"
-DPRJLIBNAME=\"$(PRJLIBNAME)\"
!ifndef DEFAULT_BUILD_TARGET
DEFAULT_BUILD_TARGET = $(PROJECT)
@@ -1646,7 +1646,7 @@ default-shell: default-setup $(PROJECT)
@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
$(DEBUGGER) $(TCLSH)
# Generation of Windows version resource
# Generation of Windows version resource
!ifdef RCFILE
# Note: don't use $** in below rule because there may be other dependencies
@@ -1685,7 +1685,7 @@ BEGIN
VALUE "OriginalFilename", PRJLIBNAME
VALUE "FileVersion", DOTVERSION
VALUE "ProductName", "Package " PROJECT " for Tcl"
VALUE "ProductVersion", DOTVERSION
VALUE "ProductVersion", DOTVERSION
END
END
BLOCK "VarFileInfo"
Executable → Regular
+201 -108
View File
@@ -682,7 +682,8 @@ NativeReadReparse(
HANDLE hFile;
DWORD returnedLength;
hFile = CreateFile(linkDirPath, desiredAccess, FILE_SHARE_READ, NULL, OPEN_EXISTING,
hFile = CreateFile(linkDirPath, desiredAccess, FILE_SHARE_READ, NULL,
OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
@@ -844,7 +845,7 @@ tclWinDebugPanic(
#endif
abort();
}
/*
*---------------------------------------------------------------------------
*
@@ -1461,11 +1462,16 @@ TclpGetUserHome(
if (domain == NULL) {
const char *ptr;
/* no domain - firstly check it's the current user */
if ( (ptr = TclpGetUserName(&ds)) != NULL
&& strcasecmp(name, ptr) == 0
) {
/* try safest and fastest way to get current user home */
/*
* No domain. Firstly check it's the current user
*/
ptr = TclpGetUserName(&ds);
if (ptr != NULL && strcasecmp(name, ptr) == 0) {
/*
* Try safest and fastest way to get current user home
*/
ptr = TclGetEnv("HOME", &ds);
if (ptr != NULL) {
Tcl_JoinPath(1, &ptr, bufferPtr);
@@ -1486,18 +1492,28 @@ TclpGetUserHome(
wName = Tcl_UtfToUniCharDString(name, nameLen, &ds);
while (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) &uiPtr) != 0) {
/*
* user does not exists - if domain was not specified,
* try again using current domain.
* User does not exist; if domain was not specified, try again
* using current domain.
*/
rc = 1;
if (domain != NULL) break;
/* get current domain */
if (domain != NULL) {
break;
}
/*
* Get current domain
*/
rc = NetGetDCName(NULL, NULL, (LPBYTE *) &wDomain);
if (rc != 0) break;
if (rc != 0) {
break;
}
domain = INT2PTR(-1); /* repeat once */
}
if (rc == 0) {
DWORD i, size = MAX_PATH;
wHomeDir = uiPtr->usri1_home_dir;
if ((wHomeDir != NULL) && (wHomeDir[0] != L'\0')) {
size = lstrlenW(wHomeDir);
@@ -1507,15 +1523,22 @@ TclpGetUserHome(
* User exists but has no home dir. Return
* "{GetProfilesDirectory}/<user>".
*/
GetProfilesDirectoryW(buf, &size);
Tcl_UniCharToUtfDString(buf, size-1, bufferPtr);
Tcl_DStringAppend(bufferPtr, "/", 1);
Tcl_DStringAppend(bufferPtr, name, nameLen);
}
result = Tcl_DStringValue(bufferPtr);
/* be sure we returns normalized path */
for (i = 0; i < size; ++i){
if (result[i] == '\\') result[i] = '/';
/*
* Be sure we returns normalized path
*/
for (i = 0; i < size; ++i) {
if (result[i] == '\\') {
result[i] = '/';
}
}
NetApiBufferFree((void *) uiPtr);
}
@@ -1603,48 +1626,72 @@ NativeAccess(
/*
* If it's not a directory (assume file), do several fast checks:
*/
if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
/*
* If the attributes say this is not writable at all. The file is a
* regular file (i.e., not a directory), then the file is not
* writable, full stop. For directories, the read-only bit is
* writable, full stop. For directories, the read-only bit is
* (mostly) ignored by Windows, so we can't ascertain anything about
* directory access from the attrib data. However, if we have the
* advanced 'getFileSecurityProc', then more robust ACL checks
* will be done below.
* advanced 'getFileSecurityProc', then more robust ACL checks will be
* done below.
*/
if ((mode & W_OK) && (attr & FILE_ATTRIBUTE_READONLY)) {
Tcl_SetErrno(EACCES);
return -1;
}
/* If doesn't have the correct extension, it can't be executable */
/*
* If doesn't have the correct extension, it can't be executable
*/
if ((mode & X_OK) && !NativeIsExec(nativePath)) {
Tcl_SetErrno(EACCES);
return -1;
}
/* Special case for read/write/executable check on file */
/*
* Special case for read/write/executable check on file
*/
if ((mode & (R_OK|W_OK|X_OK)) && !(mode & ~(R_OK|W_OK|X_OK))) {
DWORD mask = 0;
HANDLE hFile;
if (mode & R_OK) { mask |= GENERIC_READ; }
if (mode & W_OK) { mask |= GENERIC_WRITE; }
if (mode & X_OK) { mask |= GENERIC_EXECUTE; }
if (mode & R_OK) {
mask |= GENERIC_READ;
}
if (mode & W_OK) {
mask |= GENERIC_WRITE;
}
if (mode & X_OK) {
mask |= GENERIC_EXECUTE;
}
hFile = CreateFile(nativePath, mask,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
CloseHandle(hFile);
return 0;
}
/* fast exit if access was denied */
/*
* Fast exit if access was denied
*/
if (GetLastError() == ERROR_ACCESS_DENIED) {
Tcl_SetErrno(EACCES);
return -1;
}
}
/* We cannnot verify the access fast, check it below using security info. */
/*
* We cannnot verify the access fast, check it below using security
* info.
*/
}
/*
@@ -2021,13 +2068,12 @@ NativeStat(
* 'getFileAttributesExProc', and if that isn't available, then on even
* simpler routines.
*
* Special consideration must be given to Windows hardcoded names
* like CON, NULL, COM1, LPT1 etc. For these, we still need to
* do the CreateFile as some may not exist (e.g. there is no CON
* in wish by default). However the subsequent GetFileInformationByHandle
* will fail. We do a WinIsReserved to see if it is one of the special
* names, and if successful, mock up a BY_HANDLE_FILE_INFORMATION
* structure.
* Special consideration must be given to Windows hardcoded names like
* CON, NULL, COM1, LPT1 etc. For these, we still need to do the
* CreateFile as some may not exist (e.g. there is no CON in wish by
* default). However the subsequent GetFileInformationByHandle will
* fail. We do a WinIsReserved to see if it is one of the special names,
* and if successful, mock up a BY_HANDLE_FILE_INFORMATION structure.
*/
fileHandle = CreateFile(nativePath, GENERIC_READ,
@@ -2045,7 +2091,11 @@ NativeStat(
Tcl_SetErrno(ENOENT);
return -1;
}
/* Mock up the expected structure */
/*
* Mock up the expected structure
*/
memset(&data, 0, sizeof(data));
statPtr->st_atime = 0;
statPtr->st_mtime = 0;
@@ -2328,7 +2378,7 @@ TclpGetNativeCwd(
}
if (clientData != NULL) {
if (_tcscmp((const TCHAR*)clientData, buffer) == 0) {
if (_tcscmp((const TCHAR *) clientData, buffer) == 0) {
return clientData;
}
}
@@ -2556,10 +2606,12 @@ TclpObjNormalizePath(
(int)(sizeof(WCHAR) * len));
lastValidPathEnd = currentPathEndPosition;
} else if (nextCheckpoint == 0) {
/* Path starts with a drive designation
* that's not actually on the system.
* We still must normalize up past the
* first separator. [Bug 3603434] */
/*
* Path starts with a drive designation that's not
* actually on the system. We still must normalize up
* past the first separator. [Bug 3603434]
*/
currentPathEndPosition++;
}
}
@@ -2574,11 +2626,10 @@ TclpObjNormalizePath(
*/
/*
* Check for symlinks, except at last component of path (we
* don't follow final symlinks). Also a drive (C:/) for
* example, may sometimes have the reparse flag set for some
* reason I don't understand. We therefore don't perform this
* check for drives.
* Check for symlinks, except at last component of path (we don't
* follow final symlinks). Also a drive (C:/) for example, may
* sometimes have the reparse flag set for some reason I don't
* understand. We therefore don't perform this check for drives.
*/
if (cur != 0 && !isDrive &&
@@ -2587,8 +2638,8 @@ TclpObjNormalizePath(
if (to != NULL) {
/*
* Read the reparse point ok. Now, reparse points need
* not be normalized, otherwise we could use:
* Read the reparse point ok. Now, reparse points need not
* be normalized, otherwise we could use:
*
* Tcl_GetStringFromObj(to, &pathLen);
* nextCheckpoint = pathLen;
@@ -2628,9 +2679,9 @@ TclpObjNormalizePath(
#ifndef TclNORM_LONG_PATH
/*
* Now we convert the tail of the current path to its 'long
* form', and append it to 'dsNorm' which holds the current
* normalized path
* Now we convert the tail of the current path to its 'long form',
* and append it to 'dsNorm' which holds the current normalized
* path
*/
if (isDrive) {
@@ -2659,10 +2710,10 @@ TclpObjNormalizePath(
int dotLen = currentPathEndPosition-lastValidPathEnd;
/*
* Path is just dots. We shouldn't really ever see a
* path like that. However, to be nice we at least
* don't mangle the path - we just add the dots as a
* path segment and continue.
* Path is just dots. We shouldn't really ever see a path
* like that. However, to be nice we at least don't mangle
* the path - we just add the dots as a path segment and
* continue.
*/
Tcl_DStringAppend(&dsNorm, ((const char *)nativePath)
@@ -2680,8 +2731,7 @@ TclpObjNormalizePath(
handle = FindFirstFileW((WCHAR *) nativePath, &fData);
if (handle == INVALID_HANDLE_VALUE) {
/*
* This is usually the '/' in 'c:/' at end of
* string.
* This is usually the '/' in 'c:/' at end of string.
*/
Tcl_DStringAppend(&dsNorm, (const char *) L"/",
@@ -2711,8 +2761,8 @@ TclpObjNormalizePath(
}
/*
* If we get here, we've got past one directory delimiter, so
* we know it is no longer a drive.
* If we get here, we've got past one directory delimiter, so we
* know it is no longer a drive.
*/
isDrive = 0;
@@ -3007,7 +3057,11 @@ TclNativeCreateNativeRep(
if (validPathPtr == NULL) {
return NULL;
}
/* refCount of validPathPtr was already incremented in Tcl_FSGetTranslatedPath */
/*
* refCount of validPathPtr was already incremented in
* Tcl_FSGetTranslatedPath
*/
} else {
/*
* Make sure the normalized path is set.
@@ -3017,73 +3071,101 @@ TclNativeCreateNativeRep(
if (validPathPtr == NULL) {
return NULL;
}
/* validPathPtr returned from Tcl_FSGetNormalizedPath is owned by Tcl, so incr refCount here */
/*
* validPathPtr returned from Tcl_FSGetNormalizedPath is owned by Tcl,
* so incr refCount here
*/
Tcl_IncrRefCount(validPathPtr);
}
str = Tcl_GetString(validPathPtr);
len = validPathPtr->length;
if (strlen(str)!=(unsigned int)len) {
/* String contains NUL-bytes. This is invalid. */
if (strlen(str) != (unsigned int) len) {
/*
* String contains NUL-bytes. This is invalid.
*/
goto done;
}
/* For a reserved device, strip a possible postfix ':' */
/*
* For a reserved device, strip a possible postfix ':'
*/
len = WinIsReserved(str);
if (len == 0) {
/* Let MultiByteToWideChar check for other invalid sequences, like
* 0xC0 0x80 (== overlong NUL). See bug [3118489]: NUL in filenames */
/*
* Let MultiByteToWideChar check for other invalid sequences, like
* 0xC0 0x80 (== overlong NUL). See bug [3118489]: NUL in filenames
*/
len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, 0, 0);
if (len==0) {
goto done;
}
}
/* Overallocate 6 chars, making some room for extended paths */
wp = nativePathPtr = ckalloc( (len+6) * sizeof(WCHAR) );
/*
* Overallocate 6 chars, making some room for extended paths
*/
wp = nativePathPtr = ckalloc((len + 6) * sizeof(WCHAR));
if (nativePathPtr==0) {
goto done;
}
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, nativePathPtr, len+1);
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, nativePathPtr,
len + 1);
/*
** If path starts with "//?/" or "\\?\" (extended path), translate
** any slashes to backslashes but leave the '?' intact
*/
if ((str[0]=='\\' || str[0]=='/') && (str[1]=='\\' || str[1]=='/')
&& str[2]=='?' && (str[3]=='\\' || str[3]=='/')) {
* If path starts with "//?/" or "\\?\" (extended path), translate any
* slashes to backslashes but leave the '?' intact
*/
if ((str[0] == '\\' || str[0] == '/') && (str[1] == '\\' || str[1] == '/')
&& str[2] == '?' && (str[3] == '\\' || str[3] == '/')) {
wp[0] = wp[1] = wp[3] = '\\';
str += 4;
wp += 4;
}
/*
** If there is no "\\?\" prefix but there is a drive or UNC
** path prefix and the path is larger than MAX_PATH chars,
** no Win32 API function can handle that unless it is
** prefixed with the extended path prefix. See:
** <http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath>
**/
if (((str[0]>='A'&&str[0]<='Z') || (str[0]>='a'&&str[0]<='z'))
&& str[1]==':') {
if (wp==nativePathPtr && len>MAX_PATH && (str[2]=='\\' || str[2]=='/')) {
memmove(wp+4, wp, len*sizeof(WCHAR));
memcpy(wp, L"\\\\?\\", 4*sizeof(WCHAR));
* If there is no "\\?\" prefix but there is a drive or UNC path prefix
* and the path is larger than MAX_PATH chars, no Win32 API function can
* handle that unless it is prefixed with the extended path prefix. See:
* <http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath>
*/
if (((str[0] >= 'A' && str[0] <= 'Z') || (str[0] >= 'a' && str[0] <= 'z'))
&& str[1] == ':') {
if (wp == nativePathPtr && len > MAX_PATH
&& (str[2] == '\\' || str[2] == '/')) {
memmove(wp + 4, wp, len * sizeof(WCHAR));
memcpy(wp, L"\\\\?\\", 4 * sizeof(WCHAR));
wp += 4;
}
/*
** If (remainder of) path starts with "<drive>:",
** leave the ':' intact.
* If (remainder of) path starts with "<drive>:", leave the ':'
* intact.
*/
wp += 2;
} else if (wp==nativePathPtr && len>MAX_PATH
&& (str[0]=='\\' || str[0]=='/')
&& (str[1]=='\\' || str[1]=='/') && str[2]!='?') {
memmove(wp+6, wp, len*sizeof(WCHAR));
memcpy(wp, L"\\\\?\\UNC", 7*sizeof(WCHAR));
} else if (wp == nativePathPtr && len > MAX_PATH
&& (str[0] == '\\' || str[0] == '/')
&& (str[1] == '\\' || str[1] == '/') && str[2] != '?') {
memmove(wp + 6, wp, len * sizeof(WCHAR));
memcpy(wp, L"\\\\?\\UNC", 7 * sizeof(WCHAR));
wp += 7;
}
/*
** In the remainder of the path, translate invalid characters to
** characters in the Unicode private use area.
*/
* In the remainder of the path, translate invalid characters to
* characters in the Unicode private use area.
*/
while (*wp != '\0') {
if ((*wp < ' ') || wcschr(L"\"*:<>?|", *wp)) {
*wp |= 0xF000;
@@ -3094,7 +3176,6 @@ TclNativeCreateNativeRep(
}
done:
TclDecrRefCount(validPathPtr);
return nativePathPtr;
}
@@ -3220,21 +3301,28 @@ TclWinFileOwned(
native = Tcl_FSGetNativePath(pathPtr);
if (GetNamedSecurityInfo((LPTSTR) native, SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION, &ownerSid,
NULL, NULL, NULL, &secd) != ERROR_SUCCESS) {
/* Either not a file, or we do not have access to it in which
case we are in all likelihood not the owner */
OWNER_SECURITY_INFORMATION, &ownerSid, NULL, NULL, NULL,
&secd) != ERROR_SUCCESS) {
/*
* Either not a file, or we do not have access to it in which case we
* are in all likelihood not the owner.
*/
return 0;
}
/*
* Getting the current process SID is a multi-step process.
* We make the assumption that if a call fails, this process is
* so underprivileged it could not possibly own anything. Normally
* a process can *always* look up its own token.
* Getting the current process SID is a multi-step process. We make the
* assumption that if a call fails, this process is so underprivileged it
* could not possibly own anything. Normally a process can *always* look
* up its own token.
*/
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
/* Find out how big the buffer needs to be */
/*
* Find out how big the buffer needs to be.
*/
bufsz = 0;
GetTokenInformation(token, TokenUser, NULL, 0, &bufsz);
if (bufsz) {
@@ -3246,15 +3334,20 @@ TclWinFileOwned(
CloseHandle(token);
}
/* Free allocations and be done */
if (secd)
/*
* Free allocations and be done.
*/
if (secd) {
LocalFree(secd); /* Also frees ownerSid */
if (buf)
}
if (buf) {
ckfree(buf);
}
return (owned != 0); /* Convert non-0 to 1 */
}
/*
* Local Variables:
* mode: c
+301 -160
View File
@@ -124,8 +124,7 @@ typedef struct PipeInfo {
* write. Set to 0 if no error has been
* detected. This word is shared with the
* writer thread so access must be
* synchronized with the writable object.
*/
* synchronized with the writable object. */
char *writeBuf; /* Current background output buffer. Access is
* synchronized with the writable object. */
int writeBufLen; /* Size of write buffer. Access is
@@ -218,7 +217,7 @@ static const Tcl_ChannelType pipeChannelType = {
NULL, /* handler proc. */
NULL, /* wide seek proc */
PipeThreadActionProc, /* thread action proc */
NULL /* truncate */
NULL /* truncate */
};
/*
@@ -1445,9 +1444,12 @@ ApplicationType(
static const char *
BuildCmdLineBypassBS(
const char *current,
const char **bspos
) {
/* mark first backslash possition */
const char **bspos)
{
/*
* Mark first backslash position.
*/
if (!*bspos) {
*bspos = current;
}
@@ -1462,14 +1464,14 @@ QuoteCmdLineBackslash(
Tcl_DString *dsPtr,
const char *start,
const char *current,
const char *bspos
) {
const char *bspos)
{
if (!bspos) {
if (current > start) { /* part before current (special) */
if (current > start) { /* part before current (special) */
Tcl_DStringAppend(dsPtr, start, (int) (current - start));
}
} else {
if (bspos > start) { /* part before first backslash */
if (bspos > start) { /* part before first backslash */
Tcl_DStringAppend(dsPtr, start, (int) (bspos - start));
}
while (bspos++ < current) { /* each backslash twice */
@@ -1484,38 +1486,59 @@ QuoteCmdLinePart(
const char *start,
const char *special,
const char *specMetaChars,
const char **bspos
) {
const char **bspos)
{
if (!*bspos) {
/* rest before special (before quote) */
/*
* Rest before special (before quote).
*/
QuoteCmdLineBackslash(dsPtr, start, special, NULL);
start = special;
} else {
/* rest before first backslash and backslashes into new quoted block */
/*
* Rest before first backslash and backslashes into new quoted block.
*/
QuoteCmdLineBackslash(dsPtr, start, *bspos, NULL);
start = *bspos;
}
/*
* escape all special chars enclosed in quotes like `"..."`, note that here we
* don't must escape `\` (with `\`), because it's outside of the main quotes,
* so `\` remains `\`, but important - not at end of part, because results as
* before the quote, so `%\%\` should be escaped as `"%\%"\\`).
* escape all special chars enclosed in quotes like `"..."`, note that
* here we don't must escape `\` (with `\`), because it's outside of the
* main quotes, so `\` remains `\`, but important - not at end of part,
* because results as before the quote, so `%\%\` should be escaped as
* `"%\%"\\`).
*/
TclDStringAppendLiteral(dsPtr, "\""); /* opening escape quote-char */
do {
*bspos = NULL;
special++;
if (*special == '\\') {
/* bypass backslashes (and mark first backslash possition)*/
/*
* Bypass backslashes (and mark first backslash position).
*/
special = BuildCmdLineBypassBS(special, bspos);
if (*special == '\0') break;
if (*special == '\0') {
break;
}
}
} while (*special && strchr(specMetaChars, *special));
if (!*bspos) {
/* unescaped rest before quote */
/*
* Unescaped rest before quote.
*/
QuoteCmdLineBackslash(dsPtr, start, special, NULL);
} else {
/* unescaped rest before first backslash (rather belongs to the main block) */
/*
* Unescaped rest before first backslash (rather belongs to the main
* block).
*/
QuoteCmdLineBackslash(dsPtr, start, *bspos, NULL);
}
TclDStringAppendLiteral(dsPtr, "\""); /* closing escape quote-char */
@@ -1534,13 +1557,14 @@ BuildCommandLine(
const char *arg, *start, *special, *bspos;
int quote = 0, i;
Tcl_DString ds;
/* characters to enclose in quotes if unpaired quote flag set */
static const char specMetaChars[] = "&|^<>!()%";
/* character to enclose in quotes in any case (regardless unpaired-flag) */
/* Characters to enclose in quotes if unpaired
* quote flag set. */
static const char specMetaChars2[] = "%";
/* Quote flags:
/* Character to enclose in quotes in any case
* (regardless of unpaired-flag). */
/*
* Quote flags:
* CL_ESCAPE - escape argument;
* CL_QUOTE - enclose in quotes;
* CL_UNPAIRED - previous arguments chain contains unpaired quote-char;
@@ -1572,30 +1596,31 @@ BuildCommandLine(
quote = CL_QUOTE;
} else {
for (start = arg;
*start != '\0' &&
(quote & (CL_ESCAPE|CL_QUOTE)) != (CL_ESCAPE|CL_QUOTE);
start++
) {
if (*start & 0x80) continue;
*start != '\0' &&
(quote & (CL_ESCAPE|CL_QUOTE)) != (CL_ESCAPE|CL_QUOTE);
start++) {
if (*start & 0x80) {
continue;
}
if (TclIsSpaceProc(*start)) {
quote |= CL_QUOTE; /* quote only */
if (bspos) { /* if backslash found - escape & quote */
quote |= CL_QUOTE; /* quote only */
if (bspos) { /* if backslash found, escape & quote */
quote |= CL_ESCAPE;
break;
}
continue;
}
if (strchr(specMetaChars, *start)) {
quote |= (CL_ESCAPE|CL_QUOTE); /*escape & quote */
quote |= (CL_ESCAPE|CL_QUOTE); /* escape & quote */
break;
}
if (*start == '"') {
quote |= CL_ESCAPE; /* escape only */
quote |= CL_ESCAPE; /* escape only */
continue;
}
if (*start == '\\') {
bspos = start;
if (quote & CL_QUOTE) { /* if quote - escape & quote */
if (quote & CL_QUOTE) { /* if quote, escape & quote */
quote |= CL_ESCAPE;
break;
}
@@ -1605,56 +1630,116 @@ BuildCommandLine(
bspos = NULL;
}
if (quote & CL_QUOTE) {
/* start of argument (main opening quote-char) */
/*
* Start of argument (main opening quote-char).
*/
TclDStringAppendLiteral(&ds, "\"");
}
if (!(quote & CL_ESCAPE)) {
/* nothing to escape */
/*
* Nothing to escape.
*/
Tcl_DStringAppend(&ds, arg, -1);
} else {
start = arg;
for (special = arg; *special != '\0'; ) {
/* position of `\` is important before quote or at end (equal `\"` because quoted) */
/*
* Position of `\` is important before quote or at end (equal
* `\"` because quoted).
*/
if (*special == '\\') {
/* bypass backslashes (and mark first backslash possition)*/
/*
* Bypass backslashes (and mark first backslash position)
*/
special = BuildCmdLineBypassBS(special, &bspos);
if (*special == '\0') break;
if (*special == '\0') {
break;
}
}
/* ["] */
if (*special == '"') {
quote ^= CL_UNPAIRED; /* invert unpaired flag - observe unpaired quotes */
/* add part before (and escape backslashes before quote) */
/*
* Invert the unpaired flag - observe unpaired quotes
*/
quote ^= CL_UNPAIRED;
/*
* Add part before (and escape backslashes before quote).
*/
QuoteCmdLineBackslash(&ds, start, special, bspos);
bspos = NULL;
/* escape using backslash */
/*
* Escape using backslash
*/
TclDStringAppendLiteral(&ds, "\\\"");
start = ++special;
continue;
}
/* unpaired (escaped) quote causes special handling on meta-chars */
/*
* Unpaired (escaped) quote causes special handling on
* meta-chars
*/
if ((quote & CL_UNPAIRED) && strchr(specMetaChars, *special)) {
special = QuoteCmdLinePart(&ds, start, special, specMetaChars, &bspos);
/* start to current or first backslash */
special = QuoteCmdLinePart(&ds, start, special,
specMetaChars, &bspos);
/*
* Start to current or first backslash
*/
start = !bspos ? special : bspos;
continue;
}
/* special case for % - should be enclosed always (paired also) */
/*
* Special case for % - should be enclosed always (paired
* also)
*/
if (strchr(specMetaChars2, *special)) {
special = QuoteCmdLinePart(&ds, start, special, specMetaChars2, &bspos);
/* start to current or first backslash */
special = QuoteCmdLinePart(&ds, start, special,
specMetaChars2, &bspos);
/*
* Start to current or first backslash.
*/
start = !bspos ? special : bspos;
continue;
}
/* other not special (and not meta) character */
bspos = NULL; /* reset last backslash possition (not interesting) */
/*
* Other not special (and not meta) character
*/
bspos = NULL; /* reset last backslash position (not
* interesting) */
special++;
}
/* rest of argument (and escape backslashes before closing main quote) */
/*
* Rest of argument (and escape backslashes before closing main
* quote)
*/
QuoteCmdLineBackslash(&ds, start, special,
(quote & CL_QUOTE) ? bspos : NULL);
(quote & CL_QUOTE) ? bspos : NULL);
}
if (quote & CL_QUOTE) {
/* end of argument (main closing quote-char) */
/*
* End of argument (main closing quote-char)
*/
TclDStringAppendLiteral(&ds, "\"");
}
}
@@ -2192,8 +2277,9 @@ PipeOutputProc(
*errorCode = 0;
/* avoid blocking if pipe-thread exited */
timeout = ((infoPtr->flags & PIPE_ASYNC) || !TclPipeThreadIsAlive(&infoPtr->writeTI)
|| TclInExit() || TclInThreadExit()) ? 0 : INFINITE;
timeout = ((infoPtr->flags & PIPE_ASYNC)
|| !TclPipeThreadIsAlive(&infoPtr->writeTI)
|| TclInExit() || TclInThreadExit()) ? 0 : INFINITE;
if (WaitForSingleObject(infoPtr->writable, timeout) == WAIT_TIMEOUT) {
/*
* The writer thread is blocked waiting for a write to complete and
@@ -2379,6 +2465,7 @@ PipeWatchProc(
infoPtr->watchMask = mask & infoPtr->validMask;
if (infoPtr->watchMask) {
Tcl_Time blockTime = { 0, 0 };
if (!oldMask) {
infoPtr->nextPtr = tsdPtr->firstPipePtr;
tsdPtr->firstPipePtr = infoPtr;
@@ -2848,7 +2935,7 @@ static DWORD WINAPI
PipeReaderThread(
LPVOID arg)
{
TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg;
TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *) arg;
PipeInfo *infoPtr = NULL; /* access info only after success init/wait */
HANDLE handle = NULL;
DWORD count, err;
@@ -2859,13 +2946,14 @@ PipeReaderThread(
* Wait for the main thread to signal before attempting to wait on the
* pipe becoming readable.
*/
if (!TclPipeThreadWaitForSignal(&pipeTI)) {
/* exit */
break;
}
if (!infoPtr) {
infoPtr = (PipeInfo *)pipeTI->clientData;
infoPtr = (PipeInfo *) pipeTI->clientData;
handle = ((WinFile *) infoPtr->readFile)->handle;
}
@@ -3211,7 +3299,7 @@ TclPipeThreadCreateTI(
pipeTI = malloc(sizeof(TclPipeThreadInfo));
#else
pipeTI = ckalloc(sizeof(TclPipeThreadInfo));
#endif
#endif /* !_PTI_USE_CKALLOC */
pipeTI->evControl = CreateEvent(NULL, FALSE, FALSE, NULL);
pipeTI->state = PTI_STATE_IDLE;
pipeTI->clientData = clientData;
@@ -3250,40 +3338,64 @@ TclPipeThreadWaitForSignal(
}
wakeEvent = pipeTI->evWakeUp;
/*
* Wait for the main thread to signal before attempting to do the work.
*/
/* reset work state of thread (idle/waiting) */
if ((state = InterlockedCompareExchange(&pipeTI->state,
PTI_STATE_IDLE, PTI_STATE_WORK)) & (PTI_STATE_STOP|PTI_STATE_END)) {
/* end of work, check the owner of structure */
/*
* Reset work state of thread (idle/waiting)
*/
state = InterlockedCompareExchange(&pipeTI->state, PTI_STATE_IDLE,
PTI_STATE_WORK);
if (state & (PTI_STATE_STOP|PTI_STATE_END)) {
/*
* End of work, check the owner of structure.
*/
goto end;
}
/* entering wait */
/*
* Entering wait
*/
waitResult = WaitForSingleObject(pipeTI->evControl, INFINITE);
if (waitResult != WAIT_OBJECT_0) {
/*
* The control event was not signaled, so end of work (unexpected
* behaviour, main thread can be dead?).
*/
goto end;
}
/* try to set work state of thread */
if ((state = InterlockedCompareExchange(&pipeTI->state,
PTI_STATE_WORK, PTI_STATE_IDLE)) & (PTI_STATE_STOP|PTI_STATE_END)) {
/* end of work */
/*
* Try to set work state of thread
*/
state = InterlockedCompareExchange(&pipeTI->state, PTI_STATE_WORK,
PTI_STATE_IDLE);
if (state & (PTI_STATE_STOP|PTI_STATE_END)) {
/*
* End of work
*/
goto end;
}
/* signaled to work */
/*
* Signaled to work.
*/
return 1;
end:
/* end of work, check the owner of the TI structure */
end:
/*
* End of work, check the owner of the TI structure.
*/
if (state != PTI_STATE_STOP) {
*pipeTIPtr = NULL;
} else {
@@ -3313,7 +3425,8 @@ end:
int
TclPipeThreadStopSignal(
TclPipeThreadInfo **pipeTIPtr, HANDLE wakeEvent)
TclPipeThreadInfo **pipeTIPtr,
HANDLE wakeEvent)
{
TclPipeThreadInfo *pipeTI = *pipeTIPtr;
HANDLE evControl;
@@ -3324,28 +3437,27 @@ TclPipeThreadStopSignal(
}
evControl = pipeTI->evControl;
pipeTI->evWakeUp = wakeEvent;
switch (
(state = InterlockedCompareExchange(&pipeTI->state,
PTI_STATE_STOP, PTI_STATE_IDLE))
) {
case PTI_STATE_IDLE:
/* Thread was idle/waiting, notify it goes teardown */
SetEvent(evControl);
*pipeTIPtr = NULL;
case PTI_STATE_DOWN:
state = InterlockedCompareExchange(&pipeTI->state, PTI_STATE_STOP,
PTI_STATE_IDLE);
switch (state) {
case PTI_STATE_IDLE:
/*
* Thread was idle/waiting, notify it goes teardown
*/
SetEvent(evControl);
*pipeTIPtr = NULL;
case PTI_STATE_DOWN:
return 1;
default:
/*
* Thread works currently, we should try to end it, own the TI structure
* (because of possible sharing the joint structures with thread)
*/
InterlockedExchange(&pipeTI->state, PTI_STATE_END);
default:
/*
* Thread works currently, we should try to end it, own the TI
* structure (because of possible sharing the joint structures with
* thread)
*/
InterlockedExchange(&pipeTI->state, PTI_STATE_END);
break;
}
@@ -3388,46 +3500,63 @@ TclPipeThreadStop(
pipeTI = *pipeTIPtr;
evControl = pipeTI->evControl;
pipeTI->evWakeUp = NULL;
/*
* Try to sane stop the pipe worker, corresponding its current state
*/
switch (
(state = InterlockedCompareExchange(&pipeTI->state,
PTI_STATE_STOP, PTI_STATE_IDLE))
) {
case PTI_STATE_IDLE:
state = InterlockedCompareExchange(&pipeTI->state, PTI_STATE_STOP,
PTI_STATE_IDLE);
switch (state) {
case PTI_STATE_IDLE:
/*
* Thread was idle/waiting, notify it goes teardown
*/
/* Thread was idle/waiting, notify it goes teardown */
SetEvent(evControl);
SetEvent(evControl);
/* we don't need to wait for it at all, thread frees himself (owns the TI structure) */
pipeTI = NULL;
/*
* We don't need to wait for it at all, thread frees himself (owns the
* TI structure)
*/
pipeTI = NULL;
break;
case PTI_STATE_STOP:
/* already stopped, thread frees himself (owns the TI structure) */
pipeTI = NULL;
break;
case PTI_STATE_DOWN:
/* Thread already down (?), do nothing */
case PTI_STATE_STOP:
/*
* Already stopped, thread frees himself (owns the TI structure)
*/
/* we don't need to wait for it, but we should free pipeTI */
hThread = NULL;
pipeTI = NULL;
break;
case PTI_STATE_DOWN:
/*
* Thread already down (?), do nothing
*/
/*
* We don't need to wait for it, but we should free pipeTI
*/
hThread = NULL;
break;
/* case PTI_STATE_WORK: */
default:
default:
/*
* Thread works currently, we should try to end it, own the TI
* structure (because of possible sharing the joint structures with
* thread)
*/
state = InterlockedCompareExchange(&pipeTI->state, PTI_STATE_END,
PTI_STATE_WORK);
if (state == PTI_STATE_DOWN) {
/*
* Thread works currently, we should try to end it, own the TI structure
* (because of possible sharing the joint structures with thread)
* We don't need to wait for it, but we should free pipeTI
*/
if ((state = InterlockedCompareExchange(&pipeTI->state,
PTI_STATE_END, PTI_STATE_WORK)) == PTI_STATE_DOWN
) {
/* we don't need to wait for it, but we should free pipeTI */
hThread = NULL;
};
hThread = NULL;
}
break;
}
@@ -3442,8 +3571,8 @@ TclPipeThreadStop(
GetExitCodeThread(hThread, &exitCode);
if (exitCode == STILL_ACTIVE) {
int inExit = (TclInExit() || TclInThreadExit());
/*
* Set the stop event so that if the pipe thread is blocked
* somewhere, it may hereafter sane exit cleanly.
@@ -3454,59 +3583,69 @@ TclPipeThreadStop(
/*
* Cancel all sync-IO of this thread (may be blocked there).
*/
if (tclWinProcs.cancelSynchronousIo) {
tclWinProcs.cancelSynchronousIo(hThread);
}
/*
* Wait at most 20 milliseconds for the reader thread to
* close (regarding TIP#398-fast-exit).
* Wait at most 20 milliseconds for the reader thread to close
* (regarding TIP#398-fast-exit).
*/
/* if we want TIP#398-fast-exit. */
if (WaitForSingleObject(hThread, inExit ? 0 : 20) == WAIT_TIMEOUT) {
/*
* If we want TIP#398-fast-exit.
*/
if (WaitForSingleObject(hThread, inExit ? 0 : 20) == WAIT_TIMEOUT) {
/*
* The thread must be blocked waiting for the pipe to
* become readable in ReadFile(). There isn't a clean way
* to exit the thread from this condition. We should
* terminate the child process instead to get the reader
* thread to fall out of ReadFile with a FALSE. (below) is
* not the correct way to do this, but will stay here
* until a better solution is found.
* The thread must be blocked waiting for the pipe to become
* readable in ReadFile(). There isn't a clean way to exit the
* thread from this condition. We should terminate the child
* process instead to get the reader thread to fall out of
* ReadFile with a FALSE. (below) is not the correct way to do
* this, but will stay here until a better solution is found.
*
* Note that we need to guard against terminating the
* thread while it is in the middle of Tcl_ThreadAlert
* because it won't be able to release the notifier lock.
* Note that we need to guard against terminating the thread
* while it is in the middle of Tcl_ThreadAlert because it
* won't be able to release the notifier lock.
*
* Also note that terminating threads during their initialization or teardown phase
* may result in ntdll.dll's LoaderLock to remain locked indefinitely.
* This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock.
* LdrpInitializeThread() is executed within new threads to perform
* initialization and to execute DllMain() of all loaded dlls.
* As a result, all new threads are deadlocked in their initialization phase and never execute,
* even though CreateThread() reports successful thread creation.
* This results in a very weird process-wide behavior, which is extremely hard to debug.
* Also note that terminating threads during their
* initialization or teardown phase may result in ntdll.dll's
* LoaderLock to remain locked indefinitely. This causes
* ntdll.dll's LdrpInitializeThread() to deadlock trying to
* acquire LoaderLock. LdrpInitializeThread() is executed
* within new threads to perform initialization and to execute
* DllMain() of all loaded dlls. As a result, all new threads
* are deadlocked in their initialization phase and never
* execute, even though CreateThread() reports successful
* thread creation. This results in a very weird process-wide
* behavior, which is extremely hard to debug.
*
* THREADS SHOULD NEVER BE TERMINATED. Period.
*
* But for now, check if thread is exiting, and if so, let it die peacefully.
* But for now, check if thread is exiting, and if so, let it
* die peacefully.
*
* Also don't terminate if in exit (otherwise deadlocked in ntdll.dll's).
* Also don't terminate if in exit (otherwise deadlocked in
* ntdll.dll's).
*/
if ( pipeTI->state != PTI_STATE_DOWN
&& WaitForSingleObject(hThread,
inExit ? 50 : 5000) != WAIT_OBJECT_0
) {
if (pipeTI->state != PTI_STATE_DOWN
&& WaitForSingleObject(hThread,
inExit ? 50 : 5000) != WAIT_OBJECT_0) {
/* BUG: this leaks memory */
if (inExit || !TerminateThread(hThread, 0)) {
/* in exit or terminate fails, just give thread a chance to exit */
/*
* in exit or terminate fails, just give thread a
* chance to exit
*/
if (InterlockedExchange(&pipeTI->state,
PTI_STATE_STOP) != PTI_STATE_DOWN) {
pipeTI = NULL;
}
};
}
}
}
}
@@ -3518,11 +3657,11 @@ TclPipeThreadStop(
SetEvent(pipeTI->evWakeUp);
}
CloseHandle(pipeTI->evControl);
#ifndef _PTI_USE_CKALLOC
#ifndef _PTI_USE_CKALLOC
free(pipeTI);
#else
#else
ckfree(pipeTI);
#endif
#endif /* !_PTI_USE_CKALLOC */
}
}
@@ -3551,28 +3690,30 @@ TclPipeThreadExit(
{
LONG state;
TclPipeThreadInfo *pipeTI = *pipeTIPtr;
/*
* If state of thread was set to stop (exactly), we can sane free its info
* structure, otherwise it is shared with main thread, so main thread will
* own it.
*/
if (!pipeTI) {
return;
}
*pipeTIPtr = NULL;
if ((state = InterlockedExchange(&pipeTI->state,
PTI_STATE_DOWN)) == PTI_STATE_STOP) {
state = InterlockedExchange(&pipeTI->state, PTI_STATE_DOWN);
if (state == PTI_STATE_STOP) {
CloseHandle(pipeTI->evControl);
if (pipeTI->evWakeUp) {
SetEvent(pipeTI->evWakeUp);
}
#ifndef _PTI_USE_CKALLOC
#ifndef _PTI_USE_CKALLOC
free(pipeTI);
#else
#else
ckfree(pipeTI);
/* be sure all subsystems used are finalized */
Tcl_FinalizeThread();
#endif
#endif /* !_PTI_USE_CKALLOC */
}
}
+5 -3
View File
@@ -480,10 +480,12 @@ typedef DWORD_PTR * PDWORD_PTR;
* including the *printf family and others. Tell it to shut up.
* (_MSC_VER is 1200 for VC6, 1300 or 1310 for vc7.net, 1400 for 8.0)
*/
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
#if defined(_MSC_VER)
# pragma warning(disable:4244)
# pragma warning(disable:4267)
# pragma warning(disable:4996)
# if _MSC_VER >= 1400
# pragma warning(disable:4267)
# pragma warning(disable:4996)
# endif
#endif
/*