Compare commits
106
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4654f8568 | ||
|
|
332f3e88d2 | ||
|
|
49935f618a | ||
|
|
12b79cb977 | ||
|
|
3a5183b88e | ||
|
|
d129d1a6e9 | ||
|
|
b032f6d67b | ||
|
|
777a642667 | ||
|
|
eaaa675e99 | ||
|
|
5d106cabda | ||
|
|
4b7f867f90 | ||
|
|
a4c8e24f4c | ||
|
|
309510e33e | ||
|
|
58c45c0f97 | ||
|
|
fdf2dd144f | ||
|
|
97bf1ced2b | ||
|
|
28f17c0d70 | ||
|
|
9d0dfc6f26 | ||
|
|
4d25168772 | ||
|
|
912f1a8816 | ||
|
|
24829b80ac | ||
|
|
12c3fbcb0c | ||
|
|
a33b0950be | ||
|
|
9740bc1662 | ||
|
|
8751d32304 | ||
|
|
b0ffd31845 | ||
|
|
ac198c7f44 | ||
|
|
150fb8061f | ||
|
|
d17af2c703 | ||
|
|
41be9233e9 | ||
|
|
574c3c0027 | ||
|
|
d25a0dae48 | ||
|
|
c4459402a9 | ||
|
|
7c0afa7cd6 | ||
|
|
595cb86379 | ||
|
|
5ef1c629df | ||
|
|
9392d9001a | ||
|
|
e113eb82e5 | ||
|
|
334b8029ed | ||
|
|
be26adf83b | ||
|
|
9489b8b506 | ||
|
|
8ab0ae062e | ||
|
|
2f8cb2ab85 | ||
|
|
a9083528ab | ||
|
|
96f1d4ec34 | ||
|
|
c1ee80eccf | ||
|
|
526c432322 | ||
|
|
1ebe878444 | ||
|
|
1cd98b93bd | ||
|
|
5645bb01ff | ||
|
|
e69d76af16 | ||
|
|
6420ec98e8 | ||
|
|
44d4c7f793 | ||
|
|
1cab268c94 | ||
|
|
39fba10b45 | ||
|
|
5f72a5554c | ||
|
|
3fe6dfccc1 | ||
|
|
774c2050f1 | ||
|
|
ab3a73bf75 | ||
|
|
d23bb9578a | ||
|
|
be861c2430 | ||
|
|
984c717026 | ||
|
|
7a1b66b00d | ||
|
|
6c6bec6689 | ||
|
|
372248583f | ||
|
|
4ff1524f2a | ||
|
|
4e994192a1 | ||
|
|
c70641a878 | ||
|
|
b15a6a700f | ||
|
|
ffdd95d4a3 | ||
|
|
d249b0629d | ||
|
|
cb9018a721 | ||
|
|
e298c2595d | ||
|
|
3ab1f672a4 | ||
|
|
7db84b0155 | ||
|
|
e2f5de73e3 | ||
|
|
57c23073f7 | ||
|
|
245ed0c3c3 | ||
|
|
543703d4ee | ||
|
|
1f5c7c693b | ||
|
|
2865a8da13 | ||
|
|
8af3fb7317 | ||
|
|
ccc592df50 | ||
|
|
de4f571baa | ||
|
|
8094d33e43 | ||
|
|
9ca29b09ae | ||
|
|
95d2a7f7c0 | ||
|
|
d232a6d28e | ||
|
|
5419f8e0ba | ||
|
|
f218c1f1eb | ||
|
|
84f4682378 | ||
|
|
06124df7de | ||
|
|
4909a5cc24 | ||
|
|
55b6550aaa | ||
|
|
cd6fdc6976 | ||
|
|
48891ff56a | ||
|
|
5ee08fdf00 | ||
|
|
e42fbc68b9 | ||
|
|
ba3eca6d7e | ||
|
|
eaf90743ee | ||
|
|
1e9a4512c7 | ||
|
|
407ebf2899 | ||
|
|
0cced28f38 | ||
|
|
05509bdd77 | ||
|
|
68c28bd274 | ||
|
|
f720f4cad5 |
+113
-53
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -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/).
|
||||
|
||||
[](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
@@ -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
@@ -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
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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),
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1071,6 +1071,13 @@ Tcl_DeleteNamespace(
|
||||
}
|
||||
TclNsDecrRefCount(nsPtr);
|
||||
}
|
||||
|
||||
int
|
||||
TclNamespaceDeleted(
|
||||
Namespace *nsPtr)
|
||||
{
|
||||
return (nsPtr->flags & NS_DYING) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
|
||||
+110
-57
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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 <--- */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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}"
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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
@@ -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
@@ -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$ */
|
||||
|
||||
@@ -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$ */
|
||||
|
||||
@@ -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$ */
|
||||
|
||||
@@ -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
@@ -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$ */
|
||||
|
||||
@@ -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
|
||||
@@ -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$ */
|
||||
@@ -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$ */
|
||||
@@ -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$ */
|
||||
@@ -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
@@ -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$ */
|
||||
|
||||
@@ -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
@@ -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 <--- */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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 {}}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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} \
|
||||
|
||||
Vendored
+3293
-3126
File diff suppressed because it is too large
Load Diff
+3
-6
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user