Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Merge trunk |
|---|---|
| Timelines: | family | ancestors | descendants | both | apn-channel-perftools |
| Files: | files | file ages | folders |
| SHA3-256: |
490b048ff3d8d570fc5ec1f10da6d625 |
| User & Date: | apnadkarni 2025-01-15 02:58:47.061 |
Context
|
2025-01-16
| ||
| 02:03 | Better off as extension and not in the core. Closed-Leaf check-in: a8da039f50 user: apnadkarni tags: apn-channel-perftools | |
|
2025-01-15
| ||
| 02:58 | Merge trunk check-in: 490b048ff3 user: apnadkarni tags: apn-channel-perftools | |
|
2025-01-12
| ||
| 18:10 | Fix [70f3b23cad]. Doc fix only check-in: 5d7aa913b0 user: jan.nijtmans tags: trunk, main | |
|
2024-12-02
| ||
| 09:42 | Start on channel performance measurement tools check-in: f21e8a892a user: apnadkarni tags: apn-channel-perftools | |
Changes
Changes to .fossil-settings/crlf-glob.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | compat/zlib/win32/*.txt compat/zlib/win64/*.txt compat/zlib/zlib.map libtommath/*.dsp libtommath/*.sln libtommath/*.vcproj tools/tcl.wse.in | > | < < < < | 8 9 10 11 12 13 14 15 16 17 18 19 | compat/zlib/win32/*.txt compat/zlib/win64/*.txt compat/zlib/zlib.map libtommath/*.dsp libtommath/*.sln libtommath/*.vcproj tools/tcl.wse.in win/*.bat win/*.vc win/coffbase.txt win/tcl.dsp win/tcl.dsw |
Changes to .gitattributes.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 | *.ts text *.tcl text *.test text # Declare files that will always have CRLF line endings on checkout. *.bat eol=crlf *.cs eol=crlf *.sln eol=crlf *.vc eol=crlf # Denote all files that are truly binary and should not be modified. *.a binary *.bmp binary *.dll binary | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | *.ts text *.tcl text *.test text # Declare files that will always have CRLF line endings on checkout. *.bat eol=crlf *.cs eol=crlf *.dsp eol=crlf *.dsw eol=crlf *.sln eol=crlf *.vc eol=crlf # Denote all files that are truly binary and should not be modified. *.a binary *.bmp binary *.dll binary |
| ︙ | ︙ |
Changes to .github/workflows/onefiledist.yml.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
ulimit -a || echo 'get limit failed'
echo 'puts exe:\t[info nameofexecutable]\nver:\t[info patchlevel]\t[if {![catch tcl::build-info ret]} {set ret}]\nlib:\t[info library]\nplat:\t[lsort -dictionary -stride 2 [array get tcl_platform]]' | make runtest || echo 'get info failed'
- name: Upload
uses: actions/upload-artifact@v4
with:
name: Tclsh ${{ env.TCL_PATCHLEVEL }} Linux single-file build (snapshot)
path: 1dist/*.tar
macos:
name: macOS
runs-on: macos-13
defaults:
run:
shell: bash
timeout-minutes: 10
| > > > | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
ulimit -a || echo 'get limit failed'
echo 'puts exe:\t[info nameofexecutable]\nver:\t[info patchlevel]\t[if {![catch tcl::build-info ret]} {set ret}]\nlib:\t[info library]\nplat:\t[lsort -dictionary -stride 2 [array get tcl_platform]]' | make runtest || echo 'get info failed'
- name: Upload
uses: actions/upload-artifact@v4
with:
name: Tclsh ${{ env.TCL_PATCHLEVEL }} Linux single-file build (snapshot)
path: 1dist/*.tar
id: upload
outputs:
url: ${{ steps.upload.outputs.artifact-url }}
macos:
name: macOS
runs-on: macos-13
defaults:
run:
shell: bash
timeout-minutes: 10
|
| ︙ | ︙ | |||
112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
ulimit -a || echo 'get limit failed'
echo 'puts exe:\t[info nameofexecutable]\nver:\t[info patchlevel]\t[if {![catch tcl::build-info ret]} {set ret}]\nlib:\t[info library]\nplat:\t[lsort -dictionary -stride 2 [array get tcl_platform]]' | make runtest || echo 'get info failed'
- name: Upload
uses: actions/upload-artifact@v4
with:
name: Tclsh ${{ env.TCL_PATCHLEVEL }} macOS single-file build (snapshot)
path: 1dist/*.dmg
win:
name: Windows
runs-on: windows-2019
defaults:
run:
shell: msys2 {0}
timeout-minutes: 10
| > > > | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
ulimit -a || echo 'get limit failed'
echo 'puts exe:\t[info nameofexecutable]\nver:\t[info patchlevel]\t[if {![catch tcl::build-info ret]} {set ret}]\nlib:\t[info library]\nplat:\t[lsort -dictionary -stride 2 [array get tcl_platform]]' | make runtest || echo 'get info failed'
- name: Upload
uses: actions/upload-artifact@v4
with:
name: Tclsh ${{ env.TCL_PATCHLEVEL }} macOS single-file build (snapshot)
path: 1dist/*.dmg
id: upload
outputs:
url: ${{ steps.upload.outputs.artifact-url }}
win:
name: Windows
runs-on: windows-2019
defaults:
run:
shell: msys2 {0}
timeout-minutes: 10
|
| ︙ | ︙ | |||
161 162 163 164 165 166 167 |
ulimit -a || echo 'get limit failed'
echo 'puts exe:\t[info nameofexecutable]\nver:\t[info patchlevel]\t[if {![catch tcl::build-info ret]} {set ret}]\nlib:\t[info library]\nplat:\t[lsort -dictionary -stride 2 [array get tcl_platform]]' | make runtest || echo 'get info failed'
- name: Upload
uses: actions/upload-artifact@v4
with:
name: Tclsh ${{ env.TCL_PATCHLEVEL }} Windows single-file build (snapshot)
path: '1dist/*_snapshot.exe'
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
ulimit -a || echo 'get limit failed'
echo 'puts exe:\t[info nameofexecutable]\nver:\t[info patchlevel]\t[if {![catch tcl::build-info ret]} {set ret}]\nlib:\t[info library]\nplat:\t[lsort -dictionary -stride 2 [array get tcl_platform]]' | make runtest || echo 'get info failed'
- name: Upload
uses: actions/upload-artifact@v4
with:
name: Tclsh ${{ env.TCL_PATCHLEVEL }} Windows single-file build (snapshot)
path: '1dist/*_snapshot.exe'
id: upload
outputs:
url: ${{ steps.upload.outputs.artifact-url }}
combine:
needs:
- linux
- macos
- win
name: Combine Artifacts (prototype)
runs-on: ubuntu-latest
defaults:
run:
shell: bash
timeout-minutes: 10
env:
# See also
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables
REMOTE_PATH: ${{ vars.PUBLISH_DROP_PATH }}/data-${{ github.sha }}
steps:
- name: Make directory
run: |
mkdir data
- name: Get Linux build
uses: actions/download-artifact@v4
with:
path: data
# Can't download by artifact ID; stupid missing feature!
merge-multiple: true
- name: Check data downloaded
run: |
ls -AlR
working-directory: data
- name: Transfer built files
# https://github.com/marketplace/actions/rsync-deployments-action
uses: burnett01/rsync-deployments@7.0.1
id: rsync
if: false # Disabled... for now
with:
# I don't know what the right switches are here, BTW
switches: -avzr
path: data/
remote_path: ${{ env.REMOTE_PATH }}
remote_host: ${{ vars.PUBLISH_HOST }}
remote_user: ${{ vars.PUBLISH_USER }}
remote_key: ${{ secrets.DEPLOY_HOST_KEY }}
# MUST be a literal passwordless key
- name: Publish files
# https://github.com/marketplace/actions/ssh-remote-commands
uses: appleboy/ssh-action@v1.2.0
id: ssh
if: steps.rsync.outcome == 'success'
with:
host: ${{ vars.PUBLISH_HOST }}
username: ${{ vars.PUBLISH_USER }}
key: ${{ secrets.DEPLOY_HOST_KEY }}
script: |
${{ vars.PUBLISHER_SCRIPT }} ${{ env.REMOTE_PATH }} ${{ github.ref_type }} ${{ github.ref_name }}
- name: Report what would be done
if: steps.rsync.outcome == 'skipped'
env:
SWITCHES: -av
LOCAL_PATH: data/
REMOTE_HOST: ${{ vars.PUBLISH_HOST }}
REMOTE_USER: ${{ vars.PUBLISH_USER }}
REMOTE_SCRIPT: |
${{ vars.PUBLISHER_SCRIPT }} ${{ env.REMOTE_PATH }} ${{ github.ref_type }} ${{ github.ref_name }}
run: |
echo "would run: rsync $SWITCHES $LOCAL_PATH $REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH"
echo "would run: ssh $REMOTE_USER@$REMOTE_HOST $REMOTE_SCRIPT"
# Consider https://github.com/marketplace/actions/slack-notify maybe?
|
Changes to README.md.
1 2 | # README: Tcl | | | 1 2 3 4 5 6 7 8 9 10 | # README: Tcl This is the **Tcl 9.0.2** source distribution. You can get any source release of Tcl from [our distribution site](https://sourceforge.net/projects/tcl/files/Tcl/). 9.0 (production release, daily build) [](https://github.com/tcltk/tcl/actions/workflows/linux-build.yml?query=branch%3Amain) [](https://github.com/tcltk/tcl/actions/workflows/win-build.yml?query=branch%3Amain) |
| ︙ | ︙ |
Changes to changes.md.
1 2 3 4 5 6 7 8 | The source code for Tcl is managed by fossil. Tcl developers coordinate all changes to the Tcl source code at > [Tcl Source Code](https://core.tcl-lang.org/tcl/timeline) Release Tcl 9.0.1 arises from the check-in with tag `core-9-0-1`. | > > > > > > > > > > > > > > > > > > | > > > > | > | | | > > > | | > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | The source code for Tcl is managed by fossil. Tcl developers coordinate all changes to the Tcl source code at > [Tcl Source Code](https://core.tcl-lang.org/tcl/timeline) Release Tcl 9.0.2 arises from the check-in with tag `core-9-0-2`. Tcl patch releases have the primary purpose of delivering bug fixes to the userbase. # Bug fixes - Better error-message than "interpreter uses an incompatible stubs mechanism"](https://core.tcl-lang.org/tcl/tktview/fc3509) # Incompatibilities - No known incompatibilities with the Tcl 9.0.0 public interface. # Updated bundled packages, libraries, standards, data - sqlite3 3.48.0 Release Tcl 9.0.1 arises from the check-in with tag `core-9-0-1`. Tcl patch releases have the primary purpose of delivering bug fixes to the userbase. As the first patch release in the Tcl 9.0.\* series, Tcl 9.0.1 also includes a small number of interface changes that complete some incomplete features first delivered in Tcl 9.0.0. # Completed 9.0 Features and Interfaces - [TIP 701 - Tcl_FSTildeExpand C API](https://core.tcl-lang.org/tips/doc/trunk/tip/701.md) - [TIP 707 - ptrAndSize internal rep in Tcl_Obj](https://core.tcl-lang.org/tips/doc/trunk/tip/707.md) - [Size modifiers j, q, z, t not implemented]( https://core.tcl-lang.org/tcl/info/c4f365) # Bug fixes - [regression in tzdata, %z instead of offset TZ-name](https://core.tcl-lang.org/tcl/tktview/2c237b) - [Tcl will not start properly if there is an init.tcl file in the current dir](https://core.tcl-lang.org/tcl/tktview/43c94f) - [clock scan "24:00", ISO-8601 compatibility](https://core.tcl-lang.org/tcl/tktview/aee9f2) - [Temporary folder with file "tcl9registry13.dll" remains after "exit"](https://core.tcl-lang.org/tcl/tktview/6ce3c0) - [Wrong result by "lsearch -stride -subindices -inline -all"](https://core.tcl-lang.org/tcl/info/5a1aaa) - [TIP 609 - required Tcl_ThreadAlert() skipped with nested event loop](https://core.tcl-lang.org/tcl/info/c7e4c4) - [buffer overwrite for non-BMP characters in utf-16](https://core.tcl-lang.org/tcl/tktview/66da4d) - [zipfs info on mountpoint of executable returns zero offset in field 4"](https://core.tcl-lang.org/tcl/info/aaa84f) - [zlib-8.8, zlib-8.16 fail on Fedora 40, gcc 14.1.1](https://core.tcl-lang.org/tcl/tktview/73d5cb) - [install registry and dde in $INSTALL_DIR\lib always](https://core.tcl-lang.org/tcl/tktview/364bd9) - [cannot build .chm help file (Windows)](https://core.tcl-lang.org/tcl/tktview/bb110c) # Incompatibilities - No known incompatibilities with the Tcl 9.0.0 public interface. # Updated bundled packages, libraries, standards, data - Itcl 4.3.2 - sqlite3 3.47.2 - Thread 3.0.1 - TDBC\* 1.1.10 - tcltest 2.5.9 - tzdata 2024b, corrected Release Tcl 9.0.0 arises from the check-in with tag `core-9-0-0`. Highlighted differences between Tcl 9.0 and Tcl 8.6 are summarized below, with focus on changes important to programmers using the Tcl library and writing Tcl scripts. |
| ︙ | ︙ | |||
152 153 154 155 156 157 158 | - configurable properties - `method -export`, `method -unexport` # Known bugs - [changed behaviour wrt command names, namespaces and resolution](https://core.tcl-lang.org/tcl/tktview/f14b33) - [windows dos device paths inconsistencies and missing functionality](https://core.tcl-lang.org/tcl/tktview/d8f121) - [load library (dll) from zipfs-library causes a leak in temporary folder](https://core.tcl-lang.org/tcl/tktview/a8e4f7) | < | 188 189 190 191 192 193 194 195 196 197 | - configurable properties - `method -export`, `method -unexport` # Known bugs - [changed behaviour wrt command names, namespaces and resolution](https://core.tcl-lang.org/tcl/tktview/f14b33) - [windows dos device paths inconsistencies and missing functionality](https://core.tcl-lang.org/tcl/tktview/d8f121) - [load library (dll) from zipfs-library causes a leak in temporary folder](https://core.tcl-lang.org/tcl/tktview/a8e4f7) - [lsearch -sorted -inline -subindices incorrect result](https://core.tcl-lang.org/tcl/tktview/bc4ac0) - ["No error" when load fails due to a missing secondary DLL](https://core.tcl-lang.org/tcl/tktview/bc4ac0) |
Changes to doc/InitStubs.3.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 | \fBTcl_InitStubs\fR(\fIinterp, version, exact\fR) .fi .SH ARGUMENTS .AS Tcl_Interp *interp .AP Tcl_Interp *interp in Tcl interpreter handle. .AP "const char" *version in | | | | > > | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | \fBTcl_InitStubs\fR(\fIinterp, version, exact\fR) .fi .SH ARGUMENTS .AS Tcl_Interp *interp .AP Tcl_Interp *interp in Tcl interpreter handle. .AP "const char" *version in A version string, indicating which minimal version of Tcl is accepted. Normally just \fB"9.0"\fR. Or \fB"8.6-"\fR if both 8.6 and 9.0 are accepted. .AP int exact in 1 means that only the particular version specified by \fIversion\fR is accepted. 0 means that versions newer than \fIversion\fR are also accepted. If the\fIversion\fR ends with \fB-\fR, higher major versions are accepted as well, otherwise the major version must be the same as in \fIversion\fR. Other bits have no effect. .BE .SH INTRODUCTION .PP The Tcl stubs mechanism defines a way to dynamically bind extensions to a particular Tcl implementation at run time. This provides two significant benefits to Tcl users: .IP 1) 5 Extensions that use the stubs mechanism can be loaded into multiple versions of Tcl without being recompiled or relinked, as long as the major Tcl version is the same. .IP 2) 5 Extensions that use the stubs mechanism can be dynamically loaded into statically-linked Tcl applications. .PP The stubs mechanism accomplishes this by exporting function tables that define an interface to the Tcl API. The extension then accesses the Tcl API through offsets into the function table, so there are no |
| ︙ | ︙ | |||
73 74 75 76 77 78 79 | with the Tk stubs libraries. See the \fBTk_InitStubs\fR page for more information. .SH DESCRIPTION \fBTcl_InitStubs\fR attempts to initialize the stub table pointers and ensure that the correct version of Tcl is loaded. In addition to an interpreter handle, it accepts as arguments a version number and a Boolean flag indicating whether the extension requires | | > | | | > > > > | > | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | with the Tk stubs libraries. See the \fBTk_InitStubs\fR page for more information. .SH DESCRIPTION \fBTcl_InitStubs\fR attempts to initialize the stub table pointers and ensure that the correct version of Tcl is loaded. In addition to an interpreter handle, it accepts as arguments a version number and a Boolean flag indicating whether the extension requires an exact version match or not. If \fIexact\fR is 0, then versions newer than \fIversion\fR are also accepted. If the\fIversion\fR ends with \fB-\fR, higher major versions are accepted as well, otherwise the major version must be the same as in \fIversion\fR. 1 means that only the specified \fIversion\fR is accepted. \fIversion\fR can be any construct as described for \fBpackage require\fR (\fBPACKAGE\fR manual page in the section \fBREQUIREMENT\fR). Multiple requirement strings like with \fBpackage require\fR are not supported. \fBTcl_InitStubs\fR returns a string containing the actual version of Tcl satisfying the request, or NULL if the Tcl version is not accepted, does not support stubs, or any other error condition occurred. .SH "SEE ALSO" Tk_InitStubs package .SH KEYWORDS stubs |
Changes to doc/IntObj.3.
1 2 3 4 5 6 7 8 9 10 | '\" '\" Copyright (c) 1996-1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" .TH Tcl_IntObj 3 8.5 Tcl "Tcl Library Procedures" .so man.macros .BS .SH NAME | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | '\" '\" Copyright (c) 1996-1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" .TH Tcl_IntObj 3 8.5 Tcl "Tcl Library Procedures" .so man.macros .BS .SH NAME Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_NewWideUIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_SetWideUIntObj, Tcl_GetIntFromObj, Tcl_GetIntForIndex, Tcl_GetLongFromObj, Tcl_GetSizeIntFromObj, Tcl_GetWideIntFromObj, Tcl_GetWideUIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl values as integers .SH SYNOPSIS .nf \fB#include <tcl.h>\fR .sp Tcl_Obj * \fBTcl_NewIntObj\fR(\fIintValue\fR) .sp |
| ︙ | ︙ | |||
120 121 122 123 124 125 126 127 128 129 130 131 132 133 | provides value exchange routines are \fBint\fR, \fBlong int\fR, \fBTcl_WideInt\fR, and \fBmp_int\fR. The \fBint\fR and \fBlong int\fR types are provided by the C language standard. The \fBTcl_WideInt\fR type is a typedef defined to be whatever signed integral type covers at least the 64-bit integer range (-9223372036854775808 to 9223372036854775807). Depending on the platform and the C compiler, the actual type might be \fBlong long int\fR, or something else. The \fBmp_int\fR type is a multiple-precision integer type defined by the LibTomMath multiple-precision integer library. .PP The \fBTcl_NewIntObj\fR, \fBTcl_NewLongObj\fR, \fBTcl_NewWideIntObj\fR, \fBTcl_NewWideUIntObj\fR, and \fBTcl_NewBignumObj\fR routines each create and return a new Tcl value initialized to the integral value of the argument. The returned Tcl value is unshared. | > > > > > | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | provides value exchange routines are \fBint\fR, \fBlong int\fR, \fBTcl_WideInt\fR, and \fBmp_int\fR. The \fBint\fR and \fBlong int\fR types are provided by the C language standard. The \fBTcl_WideInt\fR type is a typedef defined to be whatever signed integral type covers at least the 64-bit integer range (-9223372036854775808 to 9223372036854775807). Depending on the platform and the C compiler, the actual type might be \fBlong long int\fR, or something else. The \fBTcl_Size\fR typedef is a signed integer type capable of holding the maximum permitted lengths of Tcl values like strings and lists. Correspondingly, the preprocessor constant \fBTCL_SIZE_MAX\fR defines the maximum value that can be stored in a variable of this type. The \fBmp_int\fR type is a multiple-precision integer type defined by the LibTomMath multiple-precision integer library. .PP The \fBTcl_NewIntObj\fR, \fBTcl_NewLongObj\fR, \fBTcl_NewWideIntObj\fR, \fBTcl_NewWideUIntObj\fR, and \fBTcl_NewBignumObj\fR routines each create and return a new Tcl value initialized to the integral value of the argument. The returned Tcl value is unshared. |
| ︙ | ︙ | |||
189 190 191 192 193 194 195 | \fBTcl_NewObj\fR. .PP \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR, and \fBTcl_SetBignumObj\fR do not modify the reference count of their \fIobjPtr\fR arguments, but do require that the object be unshared. .PP \fBTcl_GetIntFromObj\fR, \fBTcl_GetIntForIndex\fR, \fBTcl_GetLongFromObj\fR, | | > | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | \fBTcl_NewObj\fR. .PP \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR, and \fBTcl_SetBignumObj\fR do not modify the reference count of their \fIobjPtr\fR arguments, but do require that the object be unshared. .PP \fBTcl_GetIntFromObj\fR, \fBTcl_GetIntForIndex\fR, \fBTcl_GetLongFromObj\fR, \fBTcl_GetWideIntFromObj\fR, \fBTcl_GetSizeIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and \fBTcl_TakeBignumFromObj\fR do not modify the reference count of their \fIobjPtr\fR arguments; they only read. Note however that this function may set the interpreter result; if that is the only place that is holding a reference to the object, it will be deleted. Also note that if \fBTcl_TakeBignumFromObj\fR is given an unshared value, the value of that object may be modified; it is intended to be used when the value is .QW consumed |
| ︙ | ︙ |
Changes to doc/Method.3.
1 2 3 4 5 6 7 8 9 10 11 | '\" '\" Copyright (c) 2007 Donal K. Fellows '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" .TH Tcl_Method 3 0.1 TclOO "TclOO Library Functions" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME | | > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
'\"
'\" Copyright (c) 2007 Donal K. Fellows
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tcl_Method 3 0.1 TclOO "TclOO Library Functions"
.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_ClassSetConstructor, Tcl_ClassSetDestructor, Tcl_MethodDeclarerClass, Tcl_MethodDeclarerObject, Tcl_MethodIsPublic, Tcl_MethodIsPrivate, Tcl_MethodIsType, Tcl_MethodIsType2, Tcl_MethodName, Tcl_NewInstanceMethod, Tcl_NewInstanceMethod2, Tcl_NewMethod, Tcl_NewMethod2, Tcl_ObjectContextInvokeNext, Tcl_ObjectContextIsFiltering, Tcl_ObjectContextMethod, Tcl_ObjectContextObject, Tcl_ObjectContextSkippedArgs \- manipulate methods and method-call contexts
.SH SYNOPSIS
.nf
\fB#include <tclOO.h>\fR
.sp
Tcl_Method
\fBTcl_NewMethod\fR(\fIinterp, class, nameObj, flags, methodTypePtr,
clientData\fR)
.sp
Tcl_Method
\fBTcl_NewMethod2\fR(\fIinterp, class, nameObj, flags, methodType2Ptr,
clientData\fR)
.sp
Tcl_Method
\fBTcl_NewInstanceMethod\fR(\fIinterp, object, nameObj, flags, methodTypePtr,
clientData\fR)
.sp
Tcl_Method
\fBTcl_NewInstanceMethod2\fR(\fIinterp, object, nameObj, flags, methodType2Ptr,
clientData\fR)
.sp
\fBTcl_ClassSetConstructor\fR(\fIinterp, class, method\fR)
.sp
\fBTcl_ClassSetDestructor\fR(\fIinterp, class, method\fR)
.sp
Tcl_Class
\fBTcl_MethodDeclarerClass\fR(\fImethod\fR)
.sp
|
| ︙ | ︙ | |||
42 43 44 45 46 47 48 49 50 51 52 53 54 55 | .sp int \fBTcl_MethodIsPrivate\fR(\fImethod\fR) .sp int \fBTcl_MethodIsType\fR(\fImethod, methodTypePtr, clientDataPtr\fR) .sp int \fBTcl_ObjectContextInvokeNext\fR(\fIinterp, context, objc, objv, skip\fR) .sp int \fBTcl_ObjectContextIsFiltering\fR(\fIcontext\fR) .sp Tcl_Method | > > > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | .sp int \fBTcl_MethodIsPrivate\fR(\fImethod\fR) .sp int \fBTcl_MethodIsType\fR(\fImethod, methodTypePtr, clientDataPtr\fR) .sp int \fBTcl_MethodIsType2\fR(\fImethod, methodType2Ptr, clientDataPtr\fR) .sp int \fBTcl_ObjectContextInvokeNext\fR(\fIinterp, context, objc, objv, skip\fR) .sp int \fBTcl_ObjectContextIsFiltering\fR(\fIcontext\fR) .sp Tcl_Method |
| ︙ | ︙ | |||
80 81 82 83 84 85 86 87 88 89 90 91 92 93 | compatibility) for a non-exported method, .VS TIP500 and \fBTCL_OO_METHOD_PRIVATE\fR for a private method. .VE TIP500 .AP Tcl_MethodType *methodTypePtr in A description of the type of the method to create, or the type of method to compare against. .AP void *clientData in A piece of data that is passed to the implementation of the method without interpretation. .AP void **clientDataPtr out A pointer to a variable in which to write the \fIclientData\fR value supplied when the method was created. If NULL, the \fIclientData\fR value will not be retrieved. | > > > | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | compatibility) for a non-exported method, .VS TIP500 and \fBTCL_OO_METHOD_PRIVATE\fR for a private method. .VE TIP500 .AP Tcl_MethodType *methodTypePtr in A description of the type of the method to create, or the type of method to compare against. .AP Tcl_MethodType2 *methodType2Ptr in A description of the type of the method to create, or the type of method to compare against. .AP void *clientData in A piece of data that is passed to the implementation of the method without interpretation. .AP void **clientDataPtr out A pointer to a variable in which to write the \fIclientData\fR value supplied when the method was created. If NULL, the \fIclientData\fR value will not be retrieved. |
| ︙ | ︙ | |||
122 123 124 125 126 127 128 129 130 131 | and whether the method is private is retrieved with \fBTcl_MethodIsPrivate\fR. .VE TIP500 The type of the method can also be introspected upon to a limited degree; the function \fBTcl_MethodIsType\fR returns whether a method is of a particular type, assigning the per-method \fIclientData\fR to the variable pointed to by \fIclientDataPtr\fR if (that is non-NULL) if the type is matched. .SS "METHOD CREATION" .PP Methods are created by \fBTcl_NewMethod\fR and \fBTcl_NewInstanceMethod\fR, | > | > | | | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | and whether the method is private is retrieved with \fBTcl_MethodIsPrivate\fR. .VE TIP500 The type of the method can also be introspected upon to a limited degree; the function \fBTcl_MethodIsType\fR returns whether a method is of a particular type, assigning the per-method \fIclientData\fR to the variable pointed to by \fIclientDataPtr\fR if (that is non-NULL) if the type is matched. \fBTcl_MethodIsType2\fR does the same for TCL_OO_METHOD_VERSION_2. .SS "METHOD CREATION" .PP Methods are created by \fBTcl_NewMethod\fR and \fBTcl_NewInstanceMethod\fR, or by \fBTcl_NewMethod2\fR and \fBTcl_NewInstanceMethod2\fR which create a method attached to a class or an object respectively. In both cases, the \fInameObj\fR argument gives the name of the method to create, the \fIflags\fR argument states whether the method should be exported initially .VS TIP500 or be marked as a private method, .VE TIP500 the \fImethodTypePtr\fR or \fImethodType2Ptr\fR (for TCL_OO_METHOD_VERSION_2) argument describes the implementation of the method (see the \fBMETHOD TYPES\fR section below) and the \fIclientData\fR argument gives some implementation-specific data that is passed on to the implementation of the method when it is called. .PP When the \fInameObj\fR argument to \fBTcl_NewMethod\fR or \fBTcl_NewMethod2\fR is NULL, an unnamed method is created, which is used for constructors and destructors. Constructors should be installed into their class using the \fBTcl_ClassSetConstructor\fR function, and destructors (which must not require any arguments) should be installed into their class using the \fBTcl_ClassSetDestructor\fR function. Unnamed methods should not be used for any other purpose, and named methods should not be used as either constructors or destructors. Also note that a NULL \fImethodTypePtr\fR or \fImethodType2Ptr\fR is used to provide internal signaling, and should not be used in client code. .SS "METHOD CALL CONTEXTS" .PP When a method is called, a method-call context reference is passed in as one of the arguments to the implementation function. This context can be inspected to provide information about the caller, but should not be retained beyond the moment when the method call terminates. |
| ︙ | ︙ | |||
174 175 176 177 178 179 180 | implementation has pushed one or more extra frames on the stack as part of its implementation, it is also responsible for temporarily popping those frames from the stack while the \fBTcl_ObjectContextInvokeNext\fR function is executing. Note also that the method-call context is \fInever\fR deleted during the execution of this function. .SH "METHOD TYPES" .PP | | | > > > > > > > > < | > | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
implementation has pushed one or more extra frames on the stack as part of its
implementation, it is also responsible for temporarily popping those frames
from the stack while the \fBTcl_ObjectContextInvokeNext\fR function is
executing. Note also that the method-call context is \fInever\fR deleted
during the execution of this function.
.SH "METHOD TYPES"
.PP
The types of methods are described by a pointer to a Tcl_MethodType or
Tcl_MethodType2 (for TCL_OO_METHOD_VERSION_2) structure, which are defined as:
.PP
.CS
typedef struct {
int \fIversion\fR;
const char *\fIname\fR;
Tcl_MethodCallProc *\fIcallProc\fR;
Tcl_MethodDeleteProc *\fIdeleteProc\fR;
Tcl_CloneProc *\fIcloneProc\fR;
} \fBTcl_MethodType\fR;
typedef struct {
int \fIversion\fR;
const char *\fIname\fR;
Tcl_MethodCallProc2 *\fIcallProc\fR;
Tcl_MethodDeleteProc *\fIdeleteProc\fR;
Tcl_CloneProc *\fIcloneProc\fR;
} \fBTcl_MethodType2\fR;
.CE
.PP
The \fIversion\fR field should always be declared equal to TCL_OO_METHOD_VERSION_CURRENT,
TCL_OO_METHOD_VERSION_1 or TCL_OO_METHOD_VERSION_2. The
\fIname\fR field provides a human-readable name for the type, and is the value
that is exposed via the \fBinfo class methodtype\fR and
\fBinfo object methodtype\fR Tcl commands.
.PP
The \fIcallProc\fR field gives a function that is called when the method is
invoked; it must never be NULL.
.PP
|
| ︙ | ︙ | |||
215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
.CS
typedef int \fBTcl_MethodCallProc\fR(
void *\fIclientData\fR,
Tcl_Interp *\fIinterp\fR,
Tcl_ObjectContext \fIobjectContext\fR,
int \fIobjc\fR,
Tcl_Obj *const *\fIobjv\fR);
.CE
.PP
The \fIclientData\fR argument to a Tcl_MethodCallProc is the value that was
given when the method was created, the \fIinterp\fR is a place in which to
execute scripts and access variables as well as being where to put the result
of the method, and the \fIobjc\fR and \fIobjv\fR fields give the parameter
objects to the method. The calling context of the method can be discovered
| > > > > > > > | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
.CS
typedef int \fBTcl_MethodCallProc\fR(
void *\fIclientData\fR,
Tcl_Interp *\fIinterp\fR,
Tcl_ObjectContext \fIobjectContext\fR,
int \fIobjc\fR,
Tcl_Obj *const *\fIobjv\fR);
typedef int \fBTcl_MethodCallProc2\fR(
void *\fIclientData\fR,
Tcl_Interp *\fIinterp\fR,
Tcl_ObjectContext \fIobjectContext\fR,
Tcl_Size \fIobjc\fR,
Tcl_Obj *const *\fIobjv\fR);
.CE
.PP
The \fIclientData\fR argument to a Tcl_MethodCallProc is the value that was
given when the method was created, the \fIinterp\fR is a place in which to
execute scripts and access variables as well as being where to put the result
of the method, and the \fIobjc\fR and \fIobjv\fR fields give the parameter
objects to the method. The calling context of the method can be discovered
|
| ︙ | ︙ |
Changes to doc/Object.3.
| ︙ | ︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
void *\fIptr1\fR;
void *\fIptr2\fR;
} \fItwoPtrValue\fR;
struct {
void *\fIptr\fR;
unsigned long \fIvalue\fR;
} \fIptrAndLongRep\fR;
} \fIinternalRep\fR;
} \fBTcl_Obj\fR;
.CE
.PP
The \fIbytes\fR and the \fIlength\fR members together hold
a value's UTF-8 string representation,
which is a \fIcounted string\fR not containing null bytes (UTF-8 null
| > > > > | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
void *\fIptr1\fR;
void *\fIptr2\fR;
} \fItwoPtrValue\fR;
struct {
void *\fIptr\fR;
unsigned long \fIvalue\fR;
} \fIptrAndLongRep\fR;
struct {
void *\fIptr\fR;
Tcl_Size \fIsize\fR;
} \fIptrAndSize\fR;
} \fIinternalRep\fR;
} \fBTcl_Obj\fR;
.CE
.PP
The \fIbytes\fR and the \fIlength\fR members together hold
a value's UTF-8 string representation,
which is a \fIcounted string\fR not containing null bytes (UTF-8 null
|
| ︙ | ︙ | |||
156 157 158 159 160 161 162 | If \fItypePtr\fR is NULL, the internal representation is invalid. .PP The \fIinternalRep\fR union member holds a value's internal representation. This is either a (long) integer, a double-precision floating-point number, a pointer to a value containing additional information | | | | > | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | If \fItypePtr\fR is NULL, the internal representation is invalid. .PP The \fIinternalRep\fR union member holds a value's internal representation. This is either a (long) integer, a double-precision floating-point number, a pointer to a value containing additional information needed by the value's type to represent the value, a \fBTcl_WideInt\fR integer, two arbitrary pointers, a pair made up of a pointer and an unsigned long integer, or a pair made up of a pointer and \fBTcl_Size\fR which is a signed integer type capable of holding the maximum lengths permitted in Tcl. .PP The \fIrefCount\fR member is used to tell when it is safe to free a value's storage. It holds the count of active references to the value. Maintaining the correct reference count is a key responsibility of extension writers. Reference counting is discussed below |
| ︙ | ︙ |
Changes to doc/StringObj.3.
| ︙ | ︙ | |||
210 211 212 213 214 215 216 | it returns -1; .PP \fBTcl_GetRange\fR returns a newly created value comprised of the characters between \fIfirst\fR and \fIlast\fR (inclusive) in the value's Unicode representation. If the value's Unicode representation is invalid, the Unicode representation is regenerated from the value's string representation. If \fIfirst\fR is negative, then the returned | | | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | it returns -1; .PP \fBTcl_GetRange\fR returns a newly created value comprised of the characters between \fIfirst\fR and \fIlast\fR (inclusive) in the value's Unicode representation. If the value's Unicode representation is invalid, the Unicode representation is regenerated from the value's string representation. If \fIfirst\fR is negative, then the returned string starts at the beginning of the value. If \fIlast\fR is negative, then the returned string ends at the end of the value. .PP \fBTcl_GetCharLength\fR returns the number of characters (as opposed to bytes) in the string value. .PP \fBTcl_AppendToObj\fR appends the data given by \fIbytes\fR and \fIlength\fR to the string representation of the value specified by |
| ︙ | ︙ | |||
347 348 349 350 351 352 353 354 355 356 357 358 359 360 | Tcl_Obj *newPtr = \fBTcl_ObjPrintf\fR(format, ...); \fBTcl_AppendObjToObj\fR(objPtr, newPtr); \fBTcl_DecrRefCount\fR(newPtr); .CE .PP but with greater convenience and efficiency when the appending functionality is needed. .PP The \fBTcl_SetObjLength\fR procedure changes the length of the string value of its \fIobjPtr\fR argument. If the \fInewLength\fR argument is greater than the space allocated for the value's string, then the string space is reallocated and the old value is copied to the new space; the bytes between the old length of the string and the new length may have arbitrary values. | > > > > > > > > > > > > > > > > | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 |
Tcl_Obj *newPtr = \fBTcl_ObjPrintf\fR(format, ...);
\fBTcl_AppendObjToObj\fR(objPtr, newPtr);
\fBTcl_DecrRefCount\fR(newPtr);
.CE
.PP
but with greater convenience and efficiency when the appending
functionality is needed.
.PP
When printing integer types defined by Tcl, such as \fBTcl_Size\fR
or \fBTcl_WideInt\fR, a format size specifier is needed as the
integer width of those types is dependent on the Tcl version,
platform and compiler. To accomodate these differences, Tcl defines
C preprocessor symbols \fBTCL_LL_MODIFER\fR and
\fBTCL_SIZE_MODIFER\fR for use when formatting values of type
\fBTcl_WideInt\fR and \fBTcl_Size\fR respectively. Their usage
is illustrated by
.PP
.CS
Tcl_WideInt wide;
Tcl_Size len;
Tcl_Obj *wideObj = Tcl_ObjPrintf("wide = %" \fBTCL_LL_MODIFIER\fR "d", wide);
Tcl_Obj *lenObj = Tcl_ObjPrintf("len = %" \fBTCL_SIZE_MODIFIER\fR "d", len);
.CE
.PP
The \fBTcl_SetObjLength\fR procedure changes the length of the
string value of its \fIobjPtr\fR argument. If the \fInewLength\fR
argument is greater than the space allocated for the value's
string, then the string space is reallocated and the old value
is copied to the new space; the bytes between the old length of
the string and the new length may have arbitrary values.
|
| ︙ | ︙ |
Changes to doc/cookiejar.n.
| ︙ | ︙ | |||
185 186 187 188 189 190 191 | the start of the application. .PP .CS package require http \fBpackage require cookiejar\fR set cookiedb [file join [file home] cookiejar] | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | the start of the application. .PP .CS package require http \fBpackage require cookiejar\fR set cookiedb [file join [file home] cookiejar] http::config -cookiejar [\fBhttp::cookiejar new\fR $cookiedb] # No further explicit steps are required to use cookies set tok [http::geturl http://core.tcl-lang.org/] .CE .PP To only allow a particular domain to use cookies, perhaps because you only want to enable a particular host to create and manipulate sessions, create a |
| ︙ | ︙ |
Changes to doc/package.n.
| ︙ | ︙ | |||
119 120 121 122 123 124 125 | indicate which package is wanted, and the command ensures that a suitable version of the package is loaded into the interpreter. If the command succeeds, it returns the version number that is loaded; otherwise it generates an error. .RS .PP A suitable version of the package is any version which satisfies at | | | | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | indicate which package is wanted, and the command ensures that a suitable version of the package is loaded into the interpreter. If the command succeeds, it returns the version number that is loaded; otherwise it generates an error. .RS .PP A suitable version of the package is any version which satisfies at least one of the requirements as defined in the section \fBREQUIREMENT\fR below. If multiple versions are suitable the implementation with the highest version is chosen. This last part is additionally influenced by the selection mode set with \fBpackage prefer\fR. .PP In the .QW stable selection mode the command will select the highest stable version satisfying the requirements, if any. If no stable |
| ︙ | ︙ | |||
201 202 203 204 205 206 207 | for which information has been provided by \fBpackage ifneeded\fR commands. .\" METHOD: vsatisfies .TP \fBpackage vsatisfies \fIversion requirement...\fR . Returns 1 if the \fIversion\fR satisfies at least one of the given | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | for which information has been provided by \fBpackage ifneeded\fR commands. .\" METHOD: vsatisfies .TP \fBpackage vsatisfies \fIversion requirement...\fR . Returns 1 if the \fIversion\fR satisfies at least one of the given requirements, and 0 otherwise. \fIrequirements\fR are defined in the \fBREQUIREMENT\fR section below. .\" METHOD: prefer .TP \fBpackage prefer \fR?\fBlatest\fR|\fBstable\fR? . With no arguments, the commands returns either .QW latest or |
| ︙ | ︙ | |||
346 347 348 349 350 351 352 353 354 355 356 357 358 359 | .PP The recommended way to use packages in Tcl is to invoke \fBpackage require\fR and \fBpackage provide\fR commands in scripts, and use the procedure \fBpkg_mkIndex\fR to create package index files. Once you have done this, packages will be loaded automatically in response to \fBpackage require\fR commands. See the documentation for \fBpkg_mkIndex\fR for details. .SH EXAMPLES .PP To state that a Tcl script requires the Tk and http packages, put this at the top of the script: .PP .CS \fBpackage require\fR Tk | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 | .PP The recommended way to use packages in Tcl is to invoke \fBpackage require\fR and \fBpackage provide\fR commands in scripts, and use the procedure \fBpkg_mkIndex\fR to create package index files. Once you have done this, packages will be loaded automatically in response to \fBpackage require\fR commands. See the documentation for \fBpkg_mkIndex\fR for details. .SH "REQUIREMENT" .PP A \fIrequirement\fR string checks, if a compatible version number of a package is present. Most commands accept a list of requirement strings where the highest suitable version is matched. .PP Each \fIrequirement\fR is allowed to have any of the forms: .RS .IP \fImin\fR This form is called .QW min-bounded . .IP \fImin\fB\-\fR This form is called .QW min-unbound . .IP \fImin\fB\-\fImax\fR This form is called .QW bounded . .PP where .QW \fImin\fR and .QW \fImax\fR are valid version numbers. The legacy syntax is a special case of the extended syntax, keeping backward compatibility. Regarding satisfaction the rules are: .IP [1] The \fIversion\fR has to pass at least one of the listed \fIrequirement\fRs to be satisfactory. .IP [2] A version satisfies a .QW bounded requirement when .RS .IP [a] For \fImin\fR equal to the \fImax\fR if, and only if the \fIversion\fR is equal to the \fImin\fR. .IP [b] Otherwise if, and only if the \fIversion\fR is greater than or equal to the \fImin\fR, and less than the \fImax\fR, where both \fImin\fR and \fImax\fR have been padded internally with .QW a0 . Note that while the comparison to \fImin\fR is inclusive, the comparison to \fImax\fR is exclusive. .RE .IP [3] A .QW min-bounded requirement is a .QW bounded requirement in disguise, with the \fImax\fR part implicitly specified as the next higher major version number of the \fImin\fR part. A version satisfies it per the rules above. .IP [4] A \fIversion\fR satisfies a .QW min-unbound requirement if, and only if it is greater than or equal to the \fImin\fR, where the \fImin\fR has been padded internally with .QW a0 . There is no constraint to a maximum. .RE .SH EXAMPLES .PP To state that a Tcl script requires the Tk and http packages, put this at the top of the script: .PP .CS \fBpackage require\fR Tk |
| ︙ | ︙ |
Changes to generic/tcl.h.
| ︙ | ︙ | |||
48 49 50 51 52 53 54 | #if !defined(TCL_MAJOR_VERSION) # define TCL_MAJOR_VERSION 9 #endif #if TCL_MAJOR_VERSION == 9 # define TCL_MINOR_VERSION 0 # define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE | | | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #if !defined(TCL_MAJOR_VERSION) # define TCL_MAJOR_VERSION 9 #endif #if TCL_MAJOR_VERSION == 9 # define TCL_MINOR_VERSION 0 # define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE # define TCL_RELEASE_SERIAL 2 # define TCL_VERSION "9.0" # define TCL_PATCH_LEVEL "9.0.2" #endif /* TCL_MAJOR_VERSION */ #if defined(RC_INVOKED) /* * Utility macros: STRINGIFY takes an argument and wraps it in "" (double * quotation marks), JOIN joins two arguments. */ |
| ︙ | ︙ | |||
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
#define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val)))
#define Tcl_LongAsWide(val) ((Tcl_WideInt)((long)(val)))
#define Tcl_WideAsDouble(val) ((double)((Tcl_WideInt)(val)))
#define Tcl_DoubleAsWide(val) ((Tcl_WideInt)((double)(val)))
#if TCL_MAJOR_VERSION < 9
typedef int Tcl_Size;
# define TCL_SIZE_MAX ((int)(((unsigned int)-1)>>1))
# define TCL_SIZE_MODIFIER ""
#else
typedef ptrdiff_t Tcl_Size;
# define TCL_SIZE_MAX ((Tcl_Size)(((size_t)-1)>>1))
# define TCL_SIZE_MODIFIER TCL_T_MODIFIER
#endif /* TCL_MAJOR_VERSION */
#ifdef _WIN32
| > > > > > > | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
#define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val)))
#define Tcl_LongAsWide(val) ((Tcl_WideInt)((long)(val)))
#define Tcl_WideAsDouble(val) ((double)((Tcl_WideInt)(val)))
#define Tcl_DoubleAsWide(val) ((Tcl_WideInt)((double)(val)))
#if TCL_MAJOR_VERSION < 9
# ifndef Tcl_Size
typedef int Tcl_Size;
# endif
# ifndef TCL_SIZE_MAX
# define TCL_SIZE_MAX ((int)(((unsigned int)-1)>>1))
# endif
# ifndef TCL_SIZE_MODIFIER
# define TCL_SIZE_MODIFIER ""
#endif
#else
typedef ptrdiff_t Tcl_Size;
# define TCL_SIZE_MAX ((Tcl_Size)(((size_t)-1)>>1))
# define TCL_SIZE_MODIFIER TCL_T_MODIFIER
#endif /* TCL_MAJOR_VERSION */
#ifdef _WIN32
|
| ︙ | ︙ | |||
724 725 726 727 728 729 730 731 732 733 734 735 736 737 |
void *ptr1;
void *ptr2;
} twoPtrValue;
struct { /* - internal rep as a pointer and a long, */
void *ptr; /* not used internally any more. */
unsigned long value;
} ptrAndLongRep;
} Tcl_ObjInternalRep;
/*
* One of the following structures exists for each object in the Tcl system.
* An object stores a value as either a string, some internal representation,
* or both.
*/
| > > > > | 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 |
void *ptr1;
void *ptr2;
} twoPtrValue;
struct { /* - internal rep as a pointer and a long, */
void *ptr; /* not used internally any more. */
unsigned long value;
} ptrAndLongRep;
struct { /* - use for pointer and length reps */
void *ptr;
Tcl_Size size;
} ptrAndSize;
} Tcl_ObjInternalRep;
/*
* One of the following structures exists for each object in the Tcl system.
* An object stores a value as either a string, some internal representation,
* or both.
*/
|
| ︙ | ︙ | |||
2079 2080 2081 2082 2083 2084 2085 | * Unicode character in UTF-8. The valid values are 3 and 4. If > 3, * then Tcl_UniChar must be 4-bytes in size (UCS-4) (the default). If == 3, * then Tcl_UniChar must be 2-bytes in size (UTF-16). Since Tcl 9.0, UCS-4 * mode is the default and recommended mode. */ #ifndef TCL_UTF_MAX | | | 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 | * Unicode character in UTF-8. The valid values are 3 and 4. If > 3, * then Tcl_UniChar must be 4-bytes in size (UCS-4) (the default). If == 3, * then Tcl_UniChar must be 2-bytes in size (UTF-16). Since Tcl 9.0, UCS-4 * mode is the default and recommended mode. */ #ifndef TCL_UTF_MAX # if defined(BUILD_tcl) || TCL_MAJOR_VERSION > 8 # define TCL_UTF_MAX 4 # else # define TCL_UTF_MAX 3 # endif #endif /* |
| ︙ | ︙ | |||
2313 2314 2315 2316 2317 2318 2319 | const char * Tcl_InitStubs(Tcl_Interp *interp, const char *version, int exact, int magic); const char * TclTomMathInitializeStubs(Tcl_Interp *interp, const char *version, int epoch, int revision); const char * TclInitStubTable(const char *version); void * TclStubCall(void *arg); #if defined(_WIN32) | | | 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 |
const char * Tcl_InitStubs(Tcl_Interp *interp, const char *version,
int exact, int magic);
const char * TclTomMathInitializeStubs(Tcl_Interp *interp,
const char *version, int epoch, int revision);
const char * TclInitStubTable(const char *version);
void * TclStubCall(void *arg);
#if defined(_WIN32)
TCL_NORETURN void Tcl_ConsolePanic(const char *format, ...);
#else
# define Tcl_ConsolePanic ((Tcl_PanicProc *)NULL)
#endif
#ifdef USE_TCL_STUBS
#if TCL_MAJOR_VERSION < 9
# if TCL_UTF_MAX < 4
|
| ︙ | ︙ | |||
2363 2364 2365 2366 2367 2368 2369 | #endif /* * Public functions that are not accessible via the stubs table. * Tcl_GetMemoryInfo is needed for AOLserver. [Bug 1868171] */ | | < | | 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 | #endif /* * Public functions that are not accessible via the stubs table. * Tcl_GetMemoryInfo is needed for AOLserver. [Bug 1868171] */ #define Tcl_Main(argc, argv, proc) Tcl_MainEx(argc, argv, proc, \ ((Tcl_SetPanicProc(Tcl_ConsolePanic), Tcl_CreateInterp()))) EXTERN TCL_NORETURN void Tcl_MainEx(Tcl_Size argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); EXTERN const char * Tcl_PkgInitStubsCheck(Tcl_Interp *interp, const char *version, int exact); EXTERN const char * Tcl_InitSubsystems(void); EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); EXTERN const char * Tcl_FindExecutable(const char *argv0); EXTERN const char * Tcl_SetPreInitScript(const char *string); EXTERN const char * Tcl_SetPanicProc( Tcl_PanicProc *panicProc); EXTERN void Tcl_StaticLibrary(Tcl_Interp *interp, const char *prefix, Tcl_LibraryInitProc *initProc, Tcl_LibraryInitProc *safeInitProc); #ifndef TCL_NO_DEPRECATED # define Tcl_StaticPackage Tcl_StaticLibrary #endif EXTERN Tcl_ExitProc * Tcl_SetExitProc(Tcl_ExitProc *proc); #ifdef _WIN32 EXTERN const char *TclZipfs_AppHook(int *argc, wchar_t ***argv); #else EXTERN const char *TclZipfs_AppHook(int *argc, char ***argv); #endif #if defined(_WIN32) && defined(UNICODE) #ifndef USE_TCL_STUBS # define Tcl_FindExecutable(arg) ((Tcl_FindExecutable)((const char *)(arg))) #endif |
| ︙ | ︙ |
Changes to generic/tclArithSeries.c.
| ︙ | ︙ | |||
47 48 49 50 51 52 53 54 55 56 57 58 |
* but it's faster to cache it inside the internal representation.
*/
typedef struct {
Tcl_Size len;
Tcl_Obj **elements;
int isDouble;
} ArithSeries;
typedef struct {
ArithSeries base;
Tcl_WideInt start;
| > < < | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
* but it's faster to cache it inside the internal representation.
*/
typedef struct {
Tcl_Size len;
Tcl_Obj **elements;
int isDouble;
Tcl_Size refCount;
} ArithSeries;
typedef struct {
ArithSeries base;
Tcl_WideInt start;
Tcl_WideInt step;
} ArithSeriesInt;
typedef struct {
ArithSeries base;
double start;
double step;
unsigned precision; /* Number of decimal places to render. */
} ArithSeriesDbl;
/* Forward declarations. */
static int TclArithSeriesObjIndex(TCL_UNUSED(Tcl_Interp *),
|
| ︙ | ︙ | |||
87 88 89 90 91 92 93 | static void FreeArithSeriesInternalRep(Tcl_Obj *arithSeriesObjPtr); static void UpdateStringOfArithSeries(Tcl_Obj *arithSeriesObjPtr); static int SetArithSeriesFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static int ArithSeriesInOperation(Tcl_Interp *interp, Tcl_Obj *valueObj, Tcl_Obj *arithSeriesObj, int *boolResult); | < < | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
static void FreeArithSeriesInternalRep(Tcl_Obj *arithSeriesObjPtr);
static void UpdateStringOfArithSeries(Tcl_Obj *arithSeriesObjPtr);
static int SetArithSeriesFromAny(Tcl_Interp *interp,
Tcl_Obj *objPtr);
static int ArithSeriesInOperation(Tcl_Interp *interp,
Tcl_Obj *valueObj, Tcl_Obj *arithSeriesObj,
int *boolResult);
/* ------------------------ ArithSeries object type -------------------------- */
static const Tcl_ObjType arithSeriesType = {
"arithseries", /* name */
FreeArithSeriesInternalRep, /* freeIntRepProc */
DupArithSeriesInternalRep, /* dupIntRepProc */
|
| ︙ | ︙ | |||
128 129 130 131 132 133 134 135 |
* in the arithSeries
*/
static inline double
power10(
unsigned n)
{
static const double powers[] = {
| > | | > > > | > > > > > | > > > > > > > > > > > > > > > > > > > > > > < | > | > > | < < < < | > < < < < | > | < | | > > | > > > | > | | > | > > > > > | | | | | | > | | > > > | > > > | > | > > | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
* in the arithSeries
*/
static inline double
power10(
unsigned n)
{
/* few "precomputed" powers (note, max double is mostly 1.7e+308) */
static const double powers[] = {
1, 10, 100, 1000, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10,
1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20,
1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30,
1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39, 1e40,
1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49, 1e50
};
if (n < sizeof(powers) / sizeof(*powers)) {
return powers[n];
} else {
// Not an expected case. Doesn't need to be so fast
return pow(10, n);
}
}
static inline double
ArithRound(
double d,
unsigned n)
{
double scaleFactor;
if (!n) {
return d;
}
scaleFactor = power10(n);
return round(d * scaleFactor) / scaleFactor;
}
static inline double
ArithSeriesEndDbl(
ArithSeriesDbl *dblRepPtr)
{
double d;
if (!dblRepPtr->base.len) {
return dblRepPtr->start;
}
d = dblRepPtr->start + ((dblRepPtr->base.len-1) * dblRepPtr->step);
return ArithRound(d, dblRepPtr->precision);
}
static inline Tcl_WideInt
ArithSeriesEndInt(
ArithSeriesInt *intRepPtr)
{
if (!intRepPtr->base.len) {
return intRepPtr->start;
}
return intRepPtr->start + ((intRepPtr->base.len-1) * intRepPtr->step);
}
static inline double
ArithSeriesIndexDbl(
ArithSeries *arithSeriesRepPtr,
Tcl_WideInt index)
{
ArithSeriesDbl *dblRepPtr = (ArithSeriesDbl *)arithSeriesRepPtr;
assert(arithSeriesRepPtr->isDouble);
double d = dblRepPtr->start;
if (index) {
d += (index * dblRepPtr->step);
}
return ArithRound(d, dblRepPtr->precision);
}
static inline Tcl_WideInt
ArithSeriesIndexInt(
ArithSeries *arithSeriesRepPtr,
Tcl_WideInt index)
{
ArithSeriesInt *intRepPtr = (ArithSeriesInt *)arithSeriesRepPtr;
assert(!arithSeriesRepPtr->isDouble);
return intRepPtr->start + (index * intRepPtr->step);
}
static inline ArithSeries *
ArithSeriesGetInternalRep(
Tcl_Obj *objPtr)
{
const Tcl_ObjInternalRep *irPtr = TclFetchInternalRep(objPtr,
&arithSeriesType);
return irPtr ? (ArithSeries *) irPtr->twoPtrValue.ptr1 : NULL;
}
/*
* Compute number of significant fractional digits
*/
static inline unsigned
ObjPrecision(
Tcl_Obj *numObj)
{
void *ptr;
int type;
if (TclHasInternalRep(numObj, &tclDoubleType) || (
Tcl_GetNumberFromObj(NULL, numObj, &ptr, &type) == TCL_OK &&
type == TCL_NUMBER_DOUBLE
)
) { /* TCL_NUMBER_DOUBLE */
const char *str = TclGetString(numObj);
if (strchr(str, 'e') == NULL && strchr(str, 'E') == NULL) {
str = strchr(str, '.');
return (str ? strlen(str + 1) : 0);
}
/* don't calculate precision for e-notation */
}
/* no fraction for TCL_NUMBER_NAN, TCL_NUMBER_INT, TCL_NUMBER_BIG */
return 0;
}
/*
* Find longest number of digits after the decimal point.
*/
static inline unsigned
maxObjPrecision(
Tcl_Obj *start,
Tcl_Obj *end,
Tcl_Obj *step)
{
unsigned i, dp = 0;
if (step) {
dp = ObjPrecision(step);
}
if (start) {
i = ObjPrecision(start);
if (i > dp) {
dp = i;
}
}
if (end) {
i = ObjPrecision(end);
if (i > dp) {
dp = i;
}
}
return dp;
}
/*
*----------------------------------------------------------------------
*
* ArithSeriesLen --
|
| ︙ | ︙ | |||
254 255 256 257 258 259 260 |
Tcl_WideInt step)
{
Tcl_WideInt len;
if (step == 0) {
return 0;
}
| | > | > > | > > > > | | > > > > > > > > > > > > > > > | > > > > > > > > | > > > > | > > | 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
Tcl_WideInt step)
{
Tcl_WideInt len;
if (step == 0) {
return 0;
}
len = (end - start) / step + 1;
if (len < 0) {
return 0;
}
return len;
}
static Tcl_WideInt
ArithSeriesLenDbl(
double start,
double end,
double step,
unsigned precision)
{
double scaleFactor;
volatile double len; /* use volatile for more deterministic cross-platform
* FP arithmetics, (e. g. to avoid wrong optimization
* and divergent results by different compilers/platforms
* with and w/o FPU_INLINE_ASM, _CONTROLFP, etc) */
if (step == 0) {
return 0;
}
if (precision) {
scaleFactor = power10(precision);
start *= scaleFactor;
end *= scaleFactor;
step *= scaleFactor;
}
/* distance */
end -= start;
/*
* To improve numerical stability use wide arithmetic instead of IEEE-754
* when distance and step do not exceed wide-integers.
*/
if (
((double)WIDE_MIN <= end && end <= (double)WIDE_MAX) &&
((double)WIDE_MIN <= step && step <= (double)WIDE_MAX)
) {
Tcl_WideInt iend = end < 0 ? end - 0.5 : end + 0.5;
Tcl_WideInt istep = step < 0 ? step - 0.5 : step + 0.5;
if (istep) { /* avoid div by zero, steps like 0.1, precision 0 */
return (iend / istep) + 1;
}
}
/*
* Too large, so use double (note the result may be instable due
* to IEEE-754, so to be as precise as possible we'll use volatile len)
*/
len = (end / step) + 1;
if (len >= (double)TCL_SIZE_MAX) {
return TCL_SIZE_MAX;
}
if (len < 0) {
return 0;
}
return (Tcl_WideInt)len;
}
/*
*----------------------------------------------------------------------
*
* DupArithSeriesInternalRep --
*
|
| ︙ | ︙ | |||
304 305 306 307 308 309 310 |
DupArithSeriesInternalRep(
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
{
ArithSeries *srcRepPtr = (ArithSeries *)
srcPtr->internalRep.twoPtrValue.ptr1;
| | < < < < < < | < < < < < < < < < | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
DupArithSeriesInternalRep(
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
{
ArithSeries *srcRepPtr = (ArithSeries *)
srcPtr->internalRep.twoPtrValue.ptr1;
srcRepPtr->refCount++;
copyPtr->internalRep.twoPtrValue.ptr1 = srcRepPtr;
copyPtr->internalRep.twoPtrValue.ptr2 = NULL;
copyPtr->typePtr = &arithSeriesType;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
350 351 352 353 354 355 356 |
{
if (arithSeriesRepPtr->elements) {
Tcl_WideInt i, len = arithSeriesRepPtr->len;
for (i=0; i<len; i++) {
Tcl_DecrRefCount(arithSeriesRepPtr->elements[i]);
}
| | | | | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 |
{
if (arithSeriesRepPtr->elements) {
Tcl_WideInt i, len = arithSeriesRepPtr->len;
for (i=0; i<len; i++) {
Tcl_DecrRefCount(arithSeriesRepPtr->elements[i]);
}
Tcl_Free((void *)arithSeriesRepPtr->elements);
arithSeriesRepPtr->elements = NULL;
}
}
static void
FreeArithSeriesInternalRep(
Tcl_Obj *arithSeriesObjPtr)
{
ArithSeries *arithSeriesRepPtr = (ArithSeries *)
arithSeriesObjPtr->internalRep.twoPtrValue.ptr1;
if (arithSeriesRepPtr && arithSeriesRepPtr->refCount-- <= 1) {
FreeElements(arithSeriesRepPtr);
Tcl_Free((void *)arithSeriesRepPtr);
}
}
/*
*----------------------------------------------------------------------
*
* NewArithSeriesInt --
|
| ︙ | ︙ | |||
388 389 390 391 392 393 394 |
* None.
*
*----------------------------------------------------------------------
*/
static Tcl_Obj *
NewArithSeriesInt(
Tcl_WideInt start,
| < | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 |
* None.
*
*----------------------------------------------------------------------
*/
static Tcl_Obj *
NewArithSeriesInt(
Tcl_WideInt start,
Tcl_WideInt step,
Tcl_WideInt len)
{
Tcl_WideInt length;
Tcl_Obj *arithSeriesObj;
ArithSeriesInt *arithSeriesRepPtr;
|
| ︙ | ︙ | |||
411 412 413 414 415 416 417 |
return arithSeriesObj;
}
arithSeriesRepPtr = (ArithSeriesInt *) Tcl_Alloc(sizeof(ArithSeriesInt));
arithSeriesRepPtr->base.len = length;
arithSeriesRepPtr->base.elements = NULL;
arithSeriesRepPtr->base.isDouble = 0;
| | | | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
return arithSeriesObj;
}
arithSeriesRepPtr = (ArithSeriesInt *) Tcl_Alloc(sizeof(ArithSeriesInt));
arithSeriesRepPtr->base.len = length;
arithSeriesRepPtr->base.elements = NULL;
arithSeriesRepPtr->base.isDouble = 0;
arithSeriesRepPtr->base.refCount = 1;
arithSeriesRepPtr->start = start;
arithSeriesRepPtr->step = step;
arithSeriesObj->internalRep.twoPtrValue.ptr1 = arithSeriesRepPtr;
arithSeriesObj->internalRep.twoPtrValue.ptr2 = NULL;
arithSeriesObj->typePtr = &arithSeriesType;
if (length > 0) {
Tcl_InvalidateStringRep(arithSeriesObj);
}
|
| ︙ | ︙ | |||
443 444 445 446 447 448 449 |
* Side Effects:
* None.
*----------------------------------------------------------------------
*/
static Tcl_Obj *
NewArithSeriesDbl(
double start,
| < | > | | | | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 |
* Side Effects:
* None.
*----------------------------------------------------------------------
*/
static Tcl_Obj *
NewArithSeriesDbl(
double start,
double step,
Tcl_WideInt len,
unsigned precision)
{
Tcl_WideInt length;
Tcl_Obj *arithSeriesObj;
ArithSeriesDbl *arithSeriesRepPtr;
length = len>=0 ? len : -1;
if (length < 0) {
length = -1;
}
TclNewObj(arithSeriesObj);
if (length <= 0) {
return arithSeriesObj;
}
arithSeriesRepPtr = (ArithSeriesDbl *) Tcl_Alloc(sizeof(ArithSeriesDbl));
arithSeriesRepPtr->base.len = length;
arithSeriesRepPtr->base.elements = NULL;
arithSeriesRepPtr->base.isDouble = 1;
arithSeriesRepPtr->base.refCount = 1;
arithSeriesRepPtr->start = start;
arithSeriesRepPtr->step = step;
arithSeriesRepPtr->precision = precision;
arithSeriesObj->internalRep.twoPtrValue.ptr1 = arithSeriesRepPtr;
arithSeriesObj->internalRep.twoPtrValue.ptr2 = NULL;
arithSeriesObj->typePtr = &arithSeriesType;
if (length > 0) {
Tcl_InvalidateStringRep(arithSeriesObj);
}
|
| ︙ | ︙ | |||
505 506 507 508 509 510 511 |
assignNumber(
Tcl_Interp *interp,
int useDoubles,
Tcl_WideInt *intNumberPtr,
double *dblNumberPtr,
Tcl_Obj *numberObj)
{
| | | | < | | > > | > > | | > | > > | > | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 |
assignNumber(
Tcl_Interp *interp,
int useDoubles,
Tcl_WideInt *intNumberPtr,
double *dblNumberPtr,
Tcl_Obj *numberObj)
{
void *ptr;
int type;
if (Tcl_GetNumberFromObj(interp, numberObj, &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
if (type == TCL_NUMBER_BIG) {
/* bignum is not supported yet. */
Tcl_WideInt w;
(void)Tcl_GetWideIntFromObj(interp, numberObj, &w);
return TCL_ERROR;
}
if (useDoubles) {
if (type != TCL_NUMBER_INT) {
double value = *(double *)ptr;
*intNumberPtr = (Tcl_WideInt)value;
*dblNumberPtr = value;
} else {
Tcl_WideInt value = *(Tcl_WideInt *)ptr;
*intNumberPtr = value;
*dblNumberPtr = (double)value;
}
} else {
if (type == TCL_NUMBER_INT) {
Tcl_WideInt value = *(Tcl_WideInt *)ptr;
*intNumberPtr = value;
*dblNumberPtr = (double)value;
} else {
double value = *(double *)ptr;
*intNumberPtr = (Tcl_WideInt)value;
*dblNumberPtr = value;
}
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
561 562 563 564 565 566 567 |
int useDoubles, /* Flag indicates values start,
** end, step, are treated as doubles */
Tcl_Obj *startObj, /* Starting value */
Tcl_Obj *endObj, /* Ending limit */
Tcl_Obj *stepObj, /* increment value */
Tcl_Obj *lenObj) /* Number of elements */
{
| | | > | | < < < < < | | > | | > > | | > > > > > > > | > > > > > > > > > > < | < | > > > > > > | > > > > > > > > > > > > > > | > | > > | 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 |
int useDoubles, /* Flag indicates values start,
** end, step, are treated as doubles */
Tcl_Obj *startObj, /* Starting value */
Tcl_Obj *endObj, /* Ending limit */
Tcl_Obj *stepObj, /* increment value */
Tcl_Obj *lenObj) /* Number of elements */
{
double dstart, dend, dstep = 1.0;
Tcl_WideInt start, end, step = 1;
Tcl_WideInt len = -1;
Tcl_Obj *objPtr;
unsigned precision = (unsigned)-1; /* unknown precision */
if (startObj) {
if (assignNumber(interp, useDoubles, &start, &dstart, startObj) != TCL_OK) {
return NULL;
}
} else {
start = 0;
dstart = 0.0;
}
if (stepObj) {
if (assignNumber(interp, useDoubles, &step, &dstep, stepObj) != TCL_OK) {
return NULL;
}
if (!useDoubles ? !step : !dstep) {
TclNewObj(objPtr);
return objPtr;
}
}
if (endObj) {
if (assignNumber(interp, useDoubles, &end, &dend, endObj) != TCL_OK) {
return NULL;
}
}
if (lenObj) {
if (Tcl_GetWideIntFromObj(interp, lenObj, &len) != TCL_OK) {
return NULL;
}
}
if (endObj) {
if (!stepObj) {
if (useDoubles) {
if (dstart > dend) {
dstep = -1.0;
step = -1;
}
} else {
if (start > end) {
step = -1;
dstep = -1.0;
}
}
}
assert(dstep!=0);
if (!lenObj) {
if (useDoubles) {
if (isinf(dstart) || isinf(dend)) {
goto exceeded;
}
if (isnan(dstart) || isnan(dend)) {
const char *description = "non-numeric floating-point value";
char tmp[TCL_DOUBLE_SPACE + 2];
tmp[0] = '\0';
Tcl_PrintDouble(NULL, isnan(dstart)?dstart:dend, tmp);
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"cannot use %s \"%s\" to estimate length of arith-series",
description, tmp));
Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", description,
(char *)NULL);
return NULL;
}
precision = maxObjPrecision(startObj, endObj, stepObj);
len = ArithSeriesLenDbl(dstart, dend, dstep, precision);
} else {
len = ArithSeriesLenInt(start, end, step);
}
}
} else {
if (useDoubles) {
// Compute precision based on given command argument values
precision = maxObjPrecision(startObj, NULL, stepObj);
dend = dstart + (dstep * (len-1));
// Make computed end value match argument(s) precision
dend = ArithRound(dend, precision);
end = dend;
} else {
end = start + (step * (len - 1));
dend = end;
}
}
/*
* todo: check whether the boundary must be rather LIST_MAX, to be more
* similar to plain lists, otherwise it'd generare an error or panic later
* (0x0ffffffffffffffa instead of 0x7fffffffffffffff by 64bit)
*/
if (len > TCL_SIZE_MAX) {
exceeded:
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"max length of a Tcl list exceeded", TCL_AUTO_LENGTH));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", (char *)NULL);
return NULL;
}
if (useDoubles) {
/* ensure we'll not get NaN somewhere in the arith-series,
* so simply check the end of it and behave like [expr {Inf - Inf}] */
double d = dstart + (len - 1) * dstep;
if (isnan(d)) {
const char *s = "domain error: argument not in valid range";
Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1));
Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", s, (char *)NULL);
return NULL;
}
if (precision == (unsigned)-1) {
precision = maxObjPrecision(startObj, endObj, stepObj);
}
objPtr = NewArithSeriesDbl(dstart, dstep, len, precision);
} else {
objPtr = NewArithSeriesInt(start, step, len);
}
return objPtr;
}
/*
*----------------------------------------------------------------------
*
* TclArithSeriesObjIndex --
|
| ︙ | ︙ | |||
716 717 718 719 720 721 722 |
{
ArithSeries *arithSeriesRepPtr = (ArithSeries *)
arithSeriesObj->internalRep.twoPtrValue.ptr1;
return arithSeriesRepPtr->len;
}
/*
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 825 826 827 828 829 830 831 832 833 834 835 836 837 838 |
{
ArithSeries *arithSeriesRepPtr = (ArithSeries *)
arithSeriesObj->internalRep.twoPtrValue.ptr1;
return arithSeriesRepPtr->len;
}
/*
* SetArithSeriesFromAny --
*
* The Arithmetic Series object is just an way to optimize
* Lists space complexity, so no one should try to convert
* a string to an Arithmetic Series object.
*
* This function is here just to populate the Type structure.
|
| ︙ | ︙ | |||
804 805 806 807 808 809 810 |
Tcl_Interp *interp, /* For error message(s) */
Tcl_Obj *arithSeriesObj, /* List object to take a range from. */
Tcl_Size fromIdx, /* Index of first element to include. */
Tcl_Size toIdx, /* Index of last element to include. */
Tcl_Obj **newObjPtr) /* return value */
{
ArithSeries *arithSeriesRepPtr;
| | | 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 |
Tcl_Interp *interp, /* For error message(s) */
Tcl_Obj *arithSeriesObj, /* List object to take a range from. */
Tcl_Size fromIdx, /* Index of first element to include. */
Tcl_Size toIdx, /* Index of last element to include. */
Tcl_Obj **newObjPtr) /* return value */
{
ArithSeries *arithSeriesRepPtr;
Tcl_WideInt len;
(void)interp; /* silence compiler */
arithSeriesRepPtr = ArithSeriesGetInternalRep(arithSeriesObj);
if (fromIdx == TCL_INDEX_NONE) {
fromIdx = 0;
|
| ︙ | ︙ | |||
829 830 831 832 833 834 835 |
if (fromIdx < 0) {
fromIdx = 0;
}
if (toIdx < 0) {
toIdx = 0;
}
| < < | > | < | < | < | < < > | < < < | < | < | < | | | | | < | < < < < < < < | > | < < | < < > | | | > > > > > > > > > | | > | < | < | | < < < < | 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 |
if (fromIdx < 0) {
fromIdx = 0;
}
if (toIdx < 0) {
toIdx = 0;
}
len = toIdx - fromIdx + 1;
if (arithSeriesRepPtr->isDouble) {
ArithSeriesDbl *dblRepPtr = (ArithSeriesDbl *)arithSeriesRepPtr;
double dstart = ArithSeriesIndexDbl(arithSeriesRepPtr, fromIdx);
if (Tcl_IsShared(arithSeriesObj) || ((arithSeriesRepPtr->refCount > 1))) {
/* as new object */
*newObjPtr = NewArithSeriesDbl(dstart, dblRepPtr->step, len,
dblRepPtr->precision);
} else {
/* in-place is possible */
*newObjPtr = arithSeriesObj;
/*
* Even if nothing below causes any changes, we still want the
* string-canonizing effect of [lrange 0 end].
*/
TclInvalidateStringRep(arithSeriesObj);
dblRepPtr->start = dstart;
/* step and precision remain the same */
dblRepPtr->base.len = len;
FreeElements(arithSeriesRepPtr);
}
} else {
ArithSeriesInt *intRepPtr = (ArithSeriesInt *) arithSeriesRepPtr;
Tcl_WideInt start = ArithSeriesIndexInt(arithSeriesRepPtr, fromIdx);
if (Tcl_IsShared(arithSeriesObj) || ((arithSeriesRepPtr->refCount > 1))) {
/* as new object */
*newObjPtr = NewArithSeriesInt(start, intRepPtr->step, len);
} else {
/* in-place is possible. */
*newObjPtr = arithSeriesObj;
/*
* Even if nothing below causes any changes, we still want the
* string-canonizing effect of [lrange 0 end].
*/
TclInvalidateStringRep(arithSeriesObj);
intRepPtr->start = start;
/* step remains the same */
intRepPtr->base.len = len;
FreeElements(arithSeriesRepPtr);
}
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TclArithSeriesGetElements --
|
| ︙ | ︙ | |||
1009 1010 1011 1012 1013 1014 1015 |
int
TclArithSeriesObjReverse(
Tcl_Interp *interp, /* For error message(s) */
Tcl_Obj *arithSeriesObj, /* List object to reverse. */
Tcl_Obj **newObjPtr)
{
ArithSeries *arithSeriesRepPtr;
| < < < < | < | < | | | < < < < | < | < < < < < < | < < < < < < | | | | < < < < | | | < | > | | | | < < < < | 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 |
int
TclArithSeriesObjReverse(
Tcl_Interp *interp, /* For error message(s) */
Tcl_Obj *arithSeriesObj, /* List object to reverse. */
Tcl_Obj **newObjPtr)
{
ArithSeries *arithSeriesRepPtr;
Tcl_Obj *resultObj;
(void)interp;
assert(newObjPtr != NULL);
arithSeriesRepPtr = ArithSeriesGetInternalRep(arithSeriesObj);
if (Tcl_IsShared(arithSeriesObj) || (arithSeriesRepPtr->refCount > 1)) {
if (arithSeriesRepPtr->isDouble) {
ArithSeriesDbl *dblRepPtr = (ArithSeriesDbl *)arithSeriesRepPtr;
resultObj = NewArithSeriesDbl(ArithSeriesEndDbl(dblRepPtr),
-dblRepPtr->step, arithSeriesRepPtr->len, dblRepPtr->precision);
} else {
ArithSeriesInt *intRepPtr = (ArithSeriesInt *)arithSeriesRepPtr;
resultObj = NewArithSeriesInt(ArithSeriesEndInt(intRepPtr),
-intRepPtr->step, arithSeriesRepPtr->len);
}
} else {
/*
* In-place is possible.
*/
TclInvalidateStringRep(arithSeriesObj);
if (arithSeriesRepPtr->isDouble) {
ArithSeriesDbl *dblRepPtr = (ArithSeriesDbl *)arithSeriesRepPtr;
dblRepPtr->start = ArithSeriesEndDbl(dblRepPtr);
dblRepPtr->step = -dblRepPtr->step;
/* precision remains the same */
} else {
ArithSeriesInt *intRepPtr = (ArithSeriesInt *)arithSeriesRepPtr;
intRepPtr->start = ArithSeriesEndInt(intRepPtr);
intRepPtr->step = -intRepPtr->step;
}
FreeElements(arithSeriesRepPtr);
resultObj = arithSeriesObj;
}
*newObjPtr = resultObj;
return resultObj ? TCL_OK : TCL_ERROR;
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
1120 1121 1122 1123 1124 1125 1126 |
static void
UpdateStringOfArithSeries(
Tcl_Obj *arithSeriesObjPtr)
{
ArithSeries *arithSeriesRepPtr = (ArithSeries *)
arithSeriesObjPtr->internalRep.twoPtrValue.ptr1;
char *p;
| < > > > > > | | > < | > | | > > < > | | | | > | > > > | | > | < < > > | < < > | | 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 |
static void
UpdateStringOfArithSeries(
Tcl_Obj *arithSeriesObjPtr)
{
ArithSeries *arithSeriesRepPtr = (ArithSeries *)
arithSeriesObjPtr->internalRep.twoPtrValue.ptr1;
char *p;
Tcl_Size i, bytlen = 0;
if (!arithSeriesRepPtr->len) {
TclInitEmptyStringRep(arithSeriesObjPtr);
return;
}
/*
* Pass 1: estimate space.
*/
if (!arithSeriesRepPtr->isDouble) {
for (i = 0; i < arithSeriesRepPtr->len; i++) {
double d = (double)ArithSeriesIndexInt(arithSeriesRepPtr, i);
Tcl_Size slen = d>0 ? log10(d)+1 : d<0 ? log10(-d)+2 : 1;
bytlen += slen;
}
} else {
char tmp[TCL_DOUBLE_SPACE + 2];
for (i = 0; i < arithSeriesRepPtr->len; i++) {
double d = ArithSeriesIndexDbl(arithSeriesRepPtr, i);
tmp[0] = '\0';
Tcl_PrintDouble(NULL,d,tmp);
bytlen += strlen(tmp);
if (bytlen > TCL_SIZE_MAX) {
/* overflow, todo: check we could use some representation instead of the panic
* to signal it is too large for string representation, because too heavy */
Tcl_Panic("UpdateStringOfArithSeries: too large to represent");
}
}
}
bytlen += arithSeriesRepPtr->len; // Space for each separator
/*
* Pass 2: generate the string repr.
*/
p = Tcl_InitStringRep(arithSeriesObjPtr, NULL, bytlen);
if (!arithSeriesRepPtr->isDouble) {
for (i = 0; i < arithSeriesRepPtr->len; i++) {
Tcl_WideInt d = ArithSeriesIndexInt(arithSeriesRepPtr, i);
p += TclFormatInt(p, d);
assert(p - arithSeriesObjPtr->bytes <= bytlen);
*p++ = ' ';
}
} else {
for (i = 0; i < arithSeriesRepPtr->len; i++) {
double d = ArithSeriesIndexDbl(arithSeriesRepPtr, i);
*p = '\0';
Tcl_PrintDouble(NULL,d,p);
p += strlen(p);
assert(p - arithSeriesObjPtr->bytes <= bytlen);
*p++ = ' ';
}
}
*(--p) = '\0';
arithSeriesObjPtr->length = p - arithSeriesObjPtr->bytes;
}
/*
*----------------------------------------------------------------------
*
* ArithSeriesInOperator --
*
|
| ︙ | ︙ |
Changes to generic/tclBasic.c.
| ︙ | ︙ | |||
64 65 66 67 68 69 70 | #endif /* !TCL_FPCLASSIFY_MODE */ /* * Bug 7371b6270b: to check C call stack depth, prefer an approach which is * compatible with AddressSanitizer (ASan) use-after-return detection. */ | | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
#endif /* !TCL_FPCLASSIFY_MODE */
/*
* Bug 7371b6270b: to check C call stack depth, prefer an approach which is
* compatible with AddressSanitizer (ASan) use-after-return detection.
*/
#if defined(_MSC_VER)
#include <intrin.h> /* for _AddressOfReturnAddress() */
#endif
/*
* As suggested by
* https://clang.llvm.org/docs/LanguageExtensions.html#has-builtin
*/
#ifndef __has_builtin
#define __has_builtin(x) 0 /* for non-clang compilers */
#endif
void *
TclGetCStackPtr(void)
{
#if defined( __GNUC__ ) || __has_builtin(__builtin_frame_address)
return __builtin_frame_address(0);
#elif defined(_MSC_VER)
return _AddressOfReturnAddress();
#else
ptrdiff_t unused = 0;
/*
* LLVM recommends using volatile:
* https://github.com/llvm/llvm-project/blob/llvmorg-10.0.0-rc1/clang/lib/Basic/Stack.cpp#L31
*/
|
| ︙ | ︙ | |||
8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 |
return FP_NAN;
}
#else /* TCL_FPCLASSIFY_MODE not in (0..3) */
#error "unknown or unexpected TCL_FPCLASSIFY_MODE"
#endif /* TCL_FPCLASSIFY_MODE */
#endif /* !fpclassify */
}
static int
ExprIsFiniteFunc(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* The interpreter in which to execute the
* function. */
int objc, /* Actual parameter count */
Tcl_Obj *const *objv) /* Actual parameter list */
{
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < | < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < | < < < | < < < < < | | > < < < < < | | | | 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 |
return FP_NAN;
}
#else /* TCL_FPCLASSIFY_MODE not in (0..3) */
#error "unknown or unexpected TCL_FPCLASSIFY_MODE"
#endif /* TCL_FPCLASSIFY_MODE */
#endif /* !fpclassify */
}
static inline int
DoubleObjClass(
Tcl_Interp *interp,
Tcl_Obj *objPtr, /* Object with double to get its class. */
int *fpClsPtr) /* FP class retrieved for double in object. */
{
double d;
void *ptr;
int type;
if (Tcl_GetNumberFromObj(interp, objPtr, &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
switch (type) {
case TCL_NUMBER_NAN:
*fpClsPtr = FP_NAN;
return TCL_OK;
case TCL_NUMBER_DOUBLE:
d = *((const double *) ptr);
break;
case TCL_NUMBER_INT:
d = (double)*((const Tcl_WideInt *) ptr);
break;
default:
if (Tcl_GetDoubleFromObj(interp, objPtr, &d) != TCL_OK) {
return TCL_ERROR;
}
break;
}
*fpClsPtr = ClassifyDouble(d);
return TCL_OK;
}
static inline int
DoubleObjIsClass(
Tcl_Interp *interp,
int objc, /* Actual parameter count */
Tcl_Obj *const *objv, /* Actual parameter list */
int cmpCls, /* FP class to compare. */
int positive) /* 1 if compare positive, 0 - otherwise */
{
int dCls;
if (objc != 2) {
MathFuncWrongNumArgs(interp, 2, objc, objv);
return TCL_ERROR;
}
if (DoubleObjClass(interp, objv[1], &dCls) != TCL_OK) {
return TCL_ERROR;
}
dCls = (
positive
? (dCls == cmpCls)
: (dCls != cmpCls && dCls != FP_NAN)
) ? 1 : 0;
Tcl_SetObjResult(interp, ((Interp *)interp)->execEnvPtr->constants[dCls]);
return TCL_OK;
}
static int
ExprIsFiniteFunc(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* The interpreter in which to execute the
* function. */
int objc, /* Actual parameter count */
Tcl_Obj *const *objv) /* Actual parameter list */
{
return DoubleObjIsClass(interp, objc, objv, FP_INFINITE, 0);
}
static int
ExprIsInfinityFunc(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* The interpreter in which to execute the
* function. */
int objc, /* Actual parameter count */
Tcl_Obj *const *objv) /* Actual parameter list */
{
return DoubleObjIsClass(interp, objc, objv, FP_INFINITE, 1);
}
static int
ExprIsNaNFunc(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* The interpreter in which to execute the
* function. */
int objc, /* Actual parameter count */
Tcl_Obj *const *objv) /* Actual parameter list */
{
return DoubleObjIsClass(interp, objc, objv, FP_NAN, 1);
}
static int
ExprIsNormalFunc(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* The interpreter in which to execute the
* function. */
int objc, /* Actual parameter count */
Tcl_Obj *const *objv) /* Actual parameter list */
{
return DoubleObjIsClass(interp, objc, objv, FP_NORMAL, 1);
}
static int
ExprIsSubnormalFunc(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* The interpreter in which to execute the
* function. */
int objc, /* Actual parameter count */
Tcl_Obj *const *objv) /* Actual parameter list */
{
return DoubleObjIsClass(interp, objc, objv, FP_SUBNORMAL, 1);
}
static int
ExprIsUnorderedFunc(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* The interpreter in which to execute the
* function. */
int objc, /* Actual parameter count */
Tcl_Obj *const *objv) /* Actual parameter list */
{
int dCls, dCls2;
if (objc != 3) {
MathFuncWrongNumArgs(interp, 3, objc, objv);
return TCL_ERROR;
}
if (
DoubleObjClass(interp, objv[1], &dCls) != TCL_OK ||
DoubleObjClass(interp, objv[2], &dCls2) != TCL_OK
) {
return TCL_ERROR;
}
dCls = ((dCls == FP_NAN) || (dCls2 == FP_NAN)) ? 1 : 0;
Tcl_SetObjResult(interp, ((Interp *)interp)->execEnvPtr->constants[dCls]);
return TCL_OK;
}
static int
FloatClassifyObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* The interpreter in which to execute the
|
| ︙ | ︙ |
Changes to generic/tclCmdIL.c.
| ︙ | ︙ | |||
3923 3924 3925 3926 3927 3928 3929 |
if (returnSubindices && (sortInfo.indexc != 0)) {
Tcl_BounceRefCount(itemPtr);
itemPtr = SelectObjFromSublist(listv[i+groupOffset],
&sortInfo);
Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
} else if (returnSubindices && (sortInfo.indexc == 0) && (groupSize > 1)) {
| | | 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 |
if (returnSubindices && (sortInfo.indexc != 0)) {
Tcl_BounceRefCount(itemPtr);
itemPtr = SelectObjFromSublist(listv[i+groupOffset],
&sortInfo);
Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
} else if (returnSubindices && (sortInfo.indexc == 0) && (groupSize > 1)) {
Tcl_BounceRefCount(itemPtr);
itemPtr = listv[i + groupOffset];
Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
} else if (groupSize > 1) {
Tcl_ListObjReplace(interp, listPtr, LIST_MAX, 0,
groupSize, &listv[i]);
} else {
Tcl_BounceRefCount(itemPtr);
|
| ︙ | ︙ | |||
4185 4186 4187 4188 4189 4190 4191 |
allowedArgs = RangeKeywordArg;
/* if last number but 2 arguments remain, next is not numeric */
if ((remNums != 1) || ((objc-1-i) != 2)) {
allowedArgs |= NumericArg;
}
numValues[value_i] = numberObj;
values[value_i] = keyword; /* TCL_NUMBER_* */
| | > > | 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 |
allowedArgs = RangeKeywordArg;
/* if last number but 2 arguments remain, next is not numeric */
if ((remNums != 1) || ((objc-1-i) != 2)) {
allowedArgs |= NumericArg;
}
numValues[value_i] = numberObj;
values[value_i] = keyword; /* TCL_NUMBER_* */
if ((keyword == TCL_NUMBER_DOUBLE || keyword == TCL_NUMBER_NAN)) {
useDoubles++;
}
value_i++;
break;
case RangeKeywordArg:
arg_key += RangeKeywordArg;
allowedArgs = NumericArg; /* after keyword always numeric only */
values[value_i] = keyword; /* SequenceOperators */
|
| ︙ | ︙ | |||
4214 4215 4216 4217 4218 4219 4220 |
/* lseq n */
case 1:
start = zero;
elementCount = numValues[0];
end = NULL;
step = one;
| | | | | | 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 |
/* lseq n */
case 1:
start = zero;
elementCount = numValues[0];
end = NULL;
step = one;
useDoubles = 0; /* Can only have Integer value. If a fractional value
* is given, this will fail later. In other words,
* "3.0" is allowed and used as Integer, but "3.1"
* will be flagged as an error. (bug f4a4bd7f1070) */
break;
/* lseq n n */
case 11:
start = numValues[0];
end = numValues[1];
break;
|
| ︙ | ︙ | |||
4255 4256 4257 4258 4259 4260 4261 | break; case LSEQ_COUNT: start = numValues[0]; elementCount = numValues[2]; step = one; break; default: | | | 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 |
break;
case LSEQ_COUNT:
start = numValues[0];
elementCount = numValues[2];
step = one;
break;
default:
goto syntax;
}
break;
/* lseq n 'to' n n */
/* lseq n 'count' n n */
case 1211:
opmode = (SequenceOperators)values[1];
|
| ︙ | ︙ | |||
4277 4278 4279 4280 4281 4282 4283 | case LSEQ_COUNT: start = numValues[0]; elementCount = numValues[2]; step = numValues[3]; break; case LSEQ_BY: /* Error case */ | | | | | | | | < | | 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 |
case LSEQ_COUNT:
start = numValues[0];
elementCount = numValues[2];
step = numValues[3];
break;
case LSEQ_BY:
/* Error case */
goto syntax;
break;
default:
goto syntax;
break;
}
break;
/* lseq n n 'by' n */
case 1121:
start = numValues[0];
end = numValues[1];
opmode = (SequenceOperators)values[2];
switch (opmode) {
case LSEQ_BY:
step = numValues[3];
break;
case LSEQ_DOTS:
case LSEQ_TO:
case LSEQ_COUNT:
default:
goto syntax;
break;
}
break;
/* lseq n 'to' n 'by' n */
/* lseq n 'count' n 'by' n */
case 12121:
start = numValues[0];
opmode = (SequenceOperators)values[3];
switch (opmode) {
case LSEQ_BY:
step = numValues[4];
break;
default:
goto syntax;
break;
}
opmode = (SequenceOperators)values[1];
switch (opmode) {
case LSEQ_DOTS:
case LSEQ_TO:
start = numValues[0];
end = numValues[2];
break;
case LSEQ_COUNT:
start = numValues[0];
elementCount = numValues[2];
break;
default:
goto syntax;
break;
}
break;
/* All other argument errors */
default:
syntax:
Tcl_WrongNumArgs(interp, 1, objv, "n ??op? n ??by? n??");
goto done;
break;
}
/* Count needs to be integer, so try to convert if possible */
if (elementCount && TclHasInternalRep(elementCount, &tclDoubleType)) {
double d = elementCount->internalRep.doubleValue;
/* Don't consider Count type to indicate using double values in seqence */
useDoubles -= (useDoubles > 0) ? 1 : 0;
if (!isinf(d) && !isnan(d) && floor(d) == d) {
if ((d >= (double)WIDE_MAX) || (d <= (double)WIDE_MIN)) {
mp_int big;
if (Tcl_InitBignumFromDouble(NULL, d, &big) == TCL_OK) {
elementCount = Tcl_NewBignumObj(&big);
keyword = TCL_NUMBER_INT;
}
|
| ︙ | ︙ |
Changes to generic/tclDTrace.d.
| ︙ | ︙ | |||
205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
void *ptr1;
void *ptr2;
} twoPtrValue;
struct {
void *ptr;
unsigned long value;
} ptrAndLongRep;
} internalRep;
};
enum return_codes {
TCL_OK = 0,
TCL_ERROR,
TCL_RETURN,
| > > > > | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
void *ptr1;
void *ptr2;
} twoPtrValue;
struct {
void *ptr;
unsigned long value;
} ptrAndLongRep;
struct {
void *ptr;
Tcl_Size size;
} ptrAndSize;
} internalRep;
};
enum return_codes {
TCL_OK = 0,
TCL_ERROR,
TCL_RETURN,
|
| ︙ | ︙ |
Changes to generic/tclDate.c.
| ︙ | ︙ | |||
86 87 88 89 90 91 92 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "tclInt.h" /* | | | > > | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "tclInt.h" /* * Bison generates several labels that happen to be unused. Several compilers * don't like that, and complain. Simply disable the warning to silence them. */ #ifdef _MSC_VER #pragma warning( disable : 4102 ) #elif defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) #pragma GCC diagnostic ignored "-Wunused-but-set-variable" #endif #if 0 #define YYDEBUG 1 #endif /* * yyparse will accept a 'struct DateInfo' as its parameter; that's where the |
| ︙ | ︙ |
Changes to generic/tclDecls.h.
| ︙ | ︙ | |||
3968 3969 3970 3971 3972 3973 3974 |
#define Tcl_SetResult(interp, result, freeProc) \
do { \
const char *__result = result; \
Tcl_FreeProc *__freeProc = freeProc; \
Tcl_SetObjResult(interp, Tcl_NewStringObj(__result, -1)); \
if (__result != NULL && __freeProc != NULL && __freeProc != TCL_VOLATILE) { \
if (__freeProc == TCL_DYNAMIC) { \
| | | | 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 |
#define Tcl_SetResult(interp, result, freeProc) \
do { \
const char *__result = result; \
Tcl_FreeProc *__freeProc = freeProc; \
Tcl_SetObjResult(interp, Tcl_NewStringObj(__result, -1)); \
if (__result != NULL && __freeProc != NULL && __freeProc != TCL_VOLATILE) { \
if (__freeProc == TCL_DYNAMIC) { \
Tcl_Free((void *)__result); \
} else { \
(*__freeProc)((void *)__result); \
} \
} \
} while(0)
#if defined(USE_TCL_STUBS)
# if defined(_WIN32) && defined(_WIN64) && TCL_MAJOR_VERSION < 9
# undef Tcl_GetTime
|
| ︙ | ︙ |
Changes to generic/tclEncoding.c.
| ︙ | ︙ | |||
123 124 125 126 127 128 129 | /* Information about each EscapeSubTable used * by this encoding type. The actual size is * as large as necessary to hold all * EscapeSubTables. */ } EscapeEncodingData; /* | | | | | | | > > | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
/* Information about each EscapeSubTable used
* by this encoding type. The actual size is
* as large as necessary to hold all
* EscapeSubTables. */
} EscapeEncodingData;
/*
* Values used when loading an encoding file to identify the type of the
* file.
*/
enum EncodingTypes {
ENCODING_SINGLEBYTE = 0, /* Encoding is single byte per character. */
ENCODING_DOUBLEBYTE = 1, /* Encoding is two bytes per character. */
ENCODING_MULTIBYTE = 2, /* Encoding is variable bytes per character. */
ENCODING_ESCAPE = 3 /* Encoding has modes with escapes to move
* between them. */
};
/*
* A list of directories in which Tcl should look for *.enc files. This list
* is shared by all threads. Access is governed by a mutex lock.
*/
static TclInitProcessGlobalValueProc InitializeEncodingSearchPath;
|
| ︙ | ︙ |
Changes to generic/tclExecute.c.
| ︙ | ︙ | |||
4425 4426 4427 4428 4429 4430 4431 |
if (framePtr == NULL ||
!(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
TRACE(("=> ERROR: no TclOO call context\n"));
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"self may only be called from inside a method",
-1));
DECACHE_STACK_INFO();
| | | 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 |
if (framePtr == NULL ||
!(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
TRACE(("=> ERROR: no TclOO call context\n"));
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"self may only be called from inside a method",
-1));
DECACHE_STACK_INFO();
OO_ERROR(interp, CONTEXT_REQUIRED);
CACHE_STACK_INFO();
goto gotError;
}
contextPtr = (CallContext *)framePtr->clientData;
/*
* Call out to get the name; it's expensive to compute but cached.
|
| ︙ | ︙ | |||
4453 4454 4455 4456 4457 4458 4459 |
if (framePtr == NULL ||
!(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
TRACE_APPEND(("ERROR: no TclOO call context\n"));
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"nextto may only be called from inside a method",
-1));
DECACHE_STACK_INFO();
| | | | 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 |
if (framePtr == NULL ||
!(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
TRACE_APPEND(("ERROR: no TclOO call context\n"));
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"nextto may only be called from inside a method",
-1));
DECACHE_STACK_INFO();
OO_ERROR(interp, CONTEXT_REQUIRED);
CACHE_STACK_INFO();
goto gotError;
}
contextPtr = (CallContext *)framePtr->clientData;
oPtr = (Object *) Tcl_GetObjectFromObj(interp, valuePtr);
if (oPtr == NULL) {
TRACE_APPEND(("ERROR: \"%.30s\" not object\n", O2S(valuePtr)));
goto gotError;
} else {
Class *classPtr = oPtr->classPtr;
struct MInvoke *miPtr;
Tcl_Size i;
const char *methodType;
if (classPtr == NULL) {
TRACE_APPEND(("ERROR: \"%.30s\" not class\n", O2S(valuePtr)));
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"\"%s\" is not a class", TclGetString(valuePtr)));
DECACHE_STACK_INFO();
OO_ERROR(interp, CLASS_REQUIRED);
CACHE_STACK_INFO();
goto gotError;
}
for (i=contextPtr->index+1 ; i<contextPtr->callPtr->numChain ; i++) {
miPtr = contextPtr->callPtr->chain + i;
if (!miPtr->isFilter &&
|
| ︙ | ︙ | |||
4525 4526 4527 4528 4529 4530 4531 |
|| miPtr->mPtr->declaringClassPtr != classPtr) {
continue;
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s implementation by \"%s\" not reachable from here",
methodType, TclGetString(valuePtr)));
DECACHE_STACK_INFO();
| | < | | | 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 |
|| miPtr->mPtr->declaringClassPtr != classPtr) {
continue;
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s implementation by \"%s\" not reachable from here",
methodType, TclGetString(valuePtr)));
DECACHE_STACK_INFO();
OO_ERROR(interp, CLASS_NOT_REACHABLE);
CACHE_STACK_INFO();
goto gotError;
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s has no non-filter implementation by \"%s\"",
methodType, TclGetString(valuePtr)));
DECACHE_STACK_INFO();
OO_ERROR(interp, CLASS_NOT_THERE);
CACHE_STACK_INFO();
goto gotError;
}
case INST_TCLOO_NEXT:
opnd = TclGetUInt1AtPtr(pc+1);
objv = &OBJ_AT_DEPTH(opnd - 1);
framePtr = iPtr->varFramePtr;
skip = 1;
TRACE(("%d => ", opnd));
if (framePtr == NULL ||
!(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
TRACE_APPEND(("ERROR: no TclOO call context\n"));
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"next may only be called from inside a method",
-1));
DECACHE_STACK_INFO();
OO_ERROR(interp, CONTEXT_REQUIRED);
CACHE_STACK_INFO();
goto gotError;
}
contextPtr = (CallContext *)framePtr->clientData;
newDepth = contextPtr->index + 1;
if (newDepth >= contextPtr->callPtr->numChain) {
|
| ︙ | ︙ | |||
4581 4582 4583 4584 4585 4586 4587 |
methodType = "method";
}
TRACE_APPEND(("ERROR: no TclOO next impl\n"));
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"no next %s implementation", methodType));
DECACHE_STACK_INFO();
| | | 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 |
methodType = "method";
}
TRACE_APPEND(("ERROR: no TclOO next impl\n"));
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"no next %s implementation", methodType));
DECACHE_STACK_INFO();
OO_ERROR(interp, NOTHING_NEXT);
CACHE_STACK_INFO();
goto gotError;
#ifdef TCL_COMPILE_DEBUG
} else if (tclTraceExec >= 2) {
int i;
if (traceInstructions) {
|
| ︙ | ︙ |
Changes to generic/tclGetDate.y.
| ︙ | ︙ | |||
35 36 37 38 39 40 41 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "tclInt.h" /* | | | > > | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "tclInt.h" /* * Bison generates several labels that happen to be unused. Several compilers * don't like that, and complain. Simply disable the warning to silence them. */ #ifdef _MSC_VER #pragma warning( disable : 4102 ) #elif defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) #pragma GCC diagnostic ignored "-Wunused-but-set-variable" #endif #if 0 #define YYDEBUG 1 #endif /* * yyparse will accept a 'struct DateInfo' as its parameter; that's where the |
| ︙ | ︙ |
Changes to generic/tclIOUtil.c.
| ︙ | ︙ | |||
448 449 450 451 452 453 454 |
int
TclFSCwdIsNative(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
/* if not yet initialized - ensure we'll once obtain cwd */
if (!tsdPtr->cwdPathEpoch) {
| | > | 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 |
int
TclFSCwdIsNative(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
/* if not yet initialized - ensure we'll once obtain cwd */
if (!tsdPtr->cwdPathEpoch) {
Tcl_Obj *temp = Tcl_FSGetCwd(NULL);
if (temp) { Tcl_DecrRefCount(temp); }
}
if (tsdPtr->cwdClientData != NULL) {
return 1;
} else {
return 0;
}
|
| ︙ | ︙ | |||
3251 3252 3253 3254 3255 3256 3257 |
buffer = TclpLoadMemoryGetBuffer(size);
if (!buffer) {
Tcl_CloseEx(interp, data, 0);
goto mustCopyToTempAnyway;
}
ret = Tcl_Read(data, (char *)buffer, size);
Tcl_CloseEx(interp, data, 0);
| | | 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 |
buffer = TclpLoadMemoryGetBuffer(size);
if (!buffer) {
Tcl_CloseEx(interp, data, 0);
goto mustCopyToTempAnyway;
}
ret = Tcl_Read(data, (char *)buffer, size);
Tcl_CloseEx(interp, data, 0);
ret = TclpLoadMemory(buffer, size, ret, TclGetString(pathPtr), handlePtr,
&unloadProcPtr, flags);
if (ret == TCL_OK && *handlePtr != NULL) {
goto resolveSymbols;
}
}
mustCopyToTempAnyway:
|
| ︙ | ︙ |
Changes to generic/tclInt.h.
| ︙ | ︙ | |||
3665 3666 3667 3668 3669 3670 3671 | MODULE_SCOPE Tcl_Obj * TclpFilesystemPathType(Tcl_Obj *pathPtr); MODULE_SCOPE int TclpDlopen(Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); MODULE_SCOPE int TclpUtime(Tcl_Obj *pathPtr, struct utimbuf *tval); #ifdef TCL_LOAD_FROM_MEMORY MODULE_SCOPE void * TclpLoadMemoryGetBuffer(size_t size); | | | | 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 | MODULE_SCOPE Tcl_Obj * TclpFilesystemPathType(Tcl_Obj *pathPtr); MODULE_SCOPE int TclpDlopen(Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); MODULE_SCOPE int TclpUtime(Tcl_Obj *pathPtr, struct utimbuf *tval); #ifdef TCL_LOAD_FROM_MEMORY MODULE_SCOPE void * TclpLoadMemoryGetBuffer(size_t size); MODULE_SCOPE int TclpLoadMemory(void *buffer, size_t size, Tcl_Size codeSize, const char *path, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); #endif MODULE_SCOPE void TclInitThreadStorage(void); MODULE_SCOPE void TclFinalizeThreadDataThread(void); MODULE_SCOPE void TclFinalizeThreadStorage(void); #ifdef TCL_WIDE_CLICKS |
| ︙ | ︙ | |||
4501 4502 4503 4504 4505 4506 4507 |
*/
#define TclInvalidateStringRep(objPtr) \
do { \
Tcl_Obj *_isobjPtr = (Tcl_Obj *)(objPtr); \
if (_isobjPtr->bytes != NULL) { \
if (_isobjPtr->bytes != &tclEmptyString) { \
| | | 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 |
*/
#define TclInvalidateStringRep(objPtr) \
do { \
Tcl_Obj *_isobjPtr = (Tcl_Obj *)(objPtr); \
if (_isobjPtr->bytes != NULL) { \
if (_isobjPtr->bytes != &tclEmptyString) { \
Tcl_Free((void *)_isobjPtr->bytes); \
} \
_isobjPtr->bytes = NULL; \
} \
} while (0)
/*
* These form part of the native filesystem support. They are needed here
|
| ︙ | ︙ |
Changes to generic/tclLoad.c.
| ︙ | ︙ | |||
478 479 480 481 482 483 484 |
* from the target interpreter to the originating one.
*/
if (code != TCL_OK) {
Interp *iPtr = (Interp *) target;
if (iPtr->legacyResult && *(iPtr->legacyResult) && !iPtr->legacyFreeProc) {
/*
| | | < | | 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
* from the target interpreter to the originating one.
*/
if (code != TCL_OK) {
Interp *iPtr = (Interp *) target;
if (iPtr->legacyResult && *(iPtr->legacyResult) && !iPtr->legacyFreeProc) {
/*
* A call to Tcl_InitStubs() determined the caller extension
* Stubs were introduced in Tcl 8.1, so there's only one possible reason.
*/
Tcl_SetObjResult(target, Tcl_NewStringObj("this extension is compiled for Tcl 8.x", -1));
iPtr->legacyResult = NULL;
iPtr->legacyFreeProc = (void (*) (void))-1;
}
Tcl_TransferResult(target, code, interp);
goto done;
}
|
| ︙ | ︙ |
Changes to generic/tclLoadNone.c.
| ︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
}
MODULE_SCOPE int
TclpLoadMemory(
TCL_UNUSED(void *),
TCL_UNUSED(size_t),
TCL_UNUSED(Tcl_Size),
TCL_UNUSED(Tcl_LoadHandle *),
TCL_UNUSED(Tcl_FSUnloadFileProc **),
TCL_UNUSED(int))
{
return TCL_ERROR;
}
| > | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
}
MODULE_SCOPE int
TclpLoadMemory(
TCL_UNUSED(void *),
TCL_UNUSED(size_t),
TCL_UNUSED(Tcl_Size),
TCL_UNUSED(const char *),
TCL_UNUSED(Tcl_LoadHandle *),
TCL_UNUSED(Tcl_FSUnloadFileProc **),
TCL_UNUSED(int))
{
return TCL_ERROR;
}
|
| ︙ | ︙ |
Changes to generic/tclNamesp.c.
| ︙ | ︙ | |||
3188 3189 3190 3191 3192 3193 3194 |
listPtr = Tcl_NewListObj(0, NULL);
if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
size_t length = strlen(nsPtr->fullName);
if (strncmp(pattern, nsPtr->fullName, length) != 0) {
goto searchDone;
}
| > > > | | 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 |
listPtr = Tcl_NewListObj(0, NULL);
if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
size_t length = strlen(nsPtr->fullName);
if (strncmp(pattern, nsPtr->fullName, length) != 0) {
goto searchDone;
}
/*
* Global namespace members are prefixed with "::", others not. Ticket [63449c0514]
*/
if (FindChildEntry(nsPtr, (nsPtr != globalNsPtr ? 2 : 0) + pattern+length) != NULL) {
Tcl_ListObjAppendElement(NULL, listPtr,
Tcl_NewStringObj(pattern, -1));
}
goto searchDone;
}
entryPtr = FirstChildEntry(nsPtr, &search);
while (entryPtr != NULL) {
|
| ︙ | ︙ |
Changes to generic/tclNotify.c.
| ︙ | ︙ | |||
53 54 55 56 57 58 59 60 |
*/
typedef struct ThreadSpecificData {
Tcl_Event *firstEventPtr; /* First pending event, or NULL if none. */
Tcl_Event *lastEventPtr; /* Last pending event, or NULL if none. */
Tcl_Event *markerEventPtr; /* Last high-priority event in queue, or NULL
* if none. */
Tcl_Mutex queueMutex; /* Mutex to protect access to the previous
| > > | > < | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
*/
typedef struct ThreadSpecificData {
Tcl_Event *firstEventPtr; /* First pending event, or NULL if none. */
Tcl_Event *lastEventPtr; /* Last pending event, or NULL if none. */
Tcl_Event *markerEventPtr; /* Last high-priority event in queue, or NULL
* if none. */
Tcl_Size eventCount; /* Number of entries, but refer to comments in
* Tcl_ServiceEvent(). */
Tcl_Mutex queueMutex; /* Mutex to protect access to the previous
* four fields. */
int serviceMode; /* One of TCL_SERVICE_NONE or
* TCL_SERVICE_ALL. */
int blockTimeSet; /* 0 means there is no maximum block time:
* block forever. */
Tcl_Time blockTime; /* If blockTimeSet is 1, gives the maximum
* elapsed time for the next block. */
int inTraversal; /* 1 if Tcl_SetMaxBlockTime is being called
* during an event source traversal. */
int initialized; /* 1 if notifier has been initialized. */
EventSource *firstEventSourcePtr;
/* Pointer to first event source in list of
* event sources for this thread. */
Tcl_ThreadId threadId; /* Thread that owns this notifier instance. */
void *clientData; /* Opaque handle for platform specific
* notifier. */
struct ThreadSpecificData *nextPtr;
/* Next notifier in global list of notifiers.
* Access is controlled by the listLock global
* mutex. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
|
| ︙ | ︙ | |||
182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
for (evPtr = tsdPtr->firstEventPtr; evPtr != NULL; ) {
hold = evPtr;
evPtr = evPtr->nextPtr;
Tcl_Free(hold);
}
tsdPtr->firstEventPtr = NULL;
tsdPtr->lastEventPtr = NULL;
Tcl_MutexUnlock(&(tsdPtr->queueMutex));
Tcl_MutexLock(&listLock);
Tcl_FinalizeNotifier(tsdPtr->clientData);
Tcl_MutexFinalize(&(tsdPtr->queueMutex));
for (prevPtrPtr = &firstNotifierPtr; *prevPtrPtr != NULL;
| > | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
for (evPtr = tsdPtr->firstEventPtr; evPtr != NULL; ) {
hold = evPtr;
evPtr = evPtr->nextPtr;
Tcl_Free(hold);
}
tsdPtr->firstEventPtr = NULL;
tsdPtr->lastEventPtr = NULL;
tsdPtr->eventCount = 0;
Tcl_MutexUnlock(&(tsdPtr->queueMutex));
Tcl_MutexLock(&listLock);
Tcl_FinalizeNotifier(tsdPtr->clientData);
Tcl_MutexFinalize(&(tsdPtr->queueMutex));
for (prevPtrPtr = &firstNotifierPtr; *prevPtrPtr != NULL;
|
| ︙ | ︙ | |||
482 483 484 485 486 487 488 |
* must have been allocated the caller with
* malloc (Tcl_Alloc), and it becomes the
* property of the event queue. It will be
* freed after the event has been handled. */
int position) /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK,
* possibly combined with TCL_QUEUE_ALERT_IF_EMPTY */
{
| | < < | > | 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 |
* must have been allocated the caller with
* malloc (Tcl_Alloc), and it becomes the
* property of the event queue. It will be
* freed after the event has been handled. */
int position) /* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK,
* possibly combined with TCL_QUEUE_ALERT_IF_EMPTY */
{
int wasEmpty = 0;
Tcl_MutexLock(&(tsdPtr->queueMutex));
if ((position & 3) == TCL_QUEUE_TAIL) {
/*
* Append the event on the end of the queue.
*/
evPtr->nextPtr = NULL;
if (tsdPtr->firstEventPtr == NULL) {
|
| ︙ | ︙ | |||
526 527 528 529 530 531 532 533 |
tsdPtr->markerEventPtr->nextPtr = evPtr;
}
tsdPtr->markerEventPtr = evPtr;
if (evPtr->nextPtr == NULL) {
tsdPtr->lastEventPtr = evPtr;
}
}
Tcl_MutexUnlock(&(tsdPtr->queueMutex));
| > > > > | | 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 |
tsdPtr->markerEventPtr->nextPtr = evPtr;
}
tsdPtr->markerEventPtr = evPtr;
if (evPtr->nextPtr == NULL) {
tsdPtr->lastEventPtr = evPtr;
}
}
if (position & TCL_QUEUE_ALERT_IF_EMPTY) {
wasEmpty = (tsdPtr->eventCount <= 0);
}
tsdPtr->eventCount++;
Tcl_MutexUnlock(&(tsdPtr->queueMutex));
return wasEmpty;
}
/*
*----------------------------------------------------------------------
*
* Tcl_DeleteEvents --
*
|
| ︙ | ︙ | |||
600 601 602 603 604 605 606 607 608 609 610 611 612 613 |
/*
* Delete the event data structure.
*/
hold = evPtr;
evPtr = evPtr->nextPtr;
Tcl_Free(hold);
} else {
/*
* Event is to be retained.
*/
prevPtr = evPtr;
evPtr = evPtr->nextPtr;
| > | 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 |
/*
* Delete the event data structure.
*/
hold = evPtr;
evPtr = evPtr->nextPtr;
Tcl_Free(hold);
tsdPtr->eventCount--;
} else {
/*
* Event is to be retained.
*/
prevPtr = evPtr;
evPtr = evPtr->nextPtr;
|
| ︙ | ︙ | |||
643 644 645 646 647 648 649 |
* TCL_FILE_EVENTS, TCL_TIMER_EVENTS, or other
* flags defined elsewhere. Events not
* matching this will be skipped for
* processing later. */
{
Tcl_Event *evPtr, *prevPtr;
Tcl_EventProc *proc;
| | > | 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 |
* TCL_FILE_EVENTS, TCL_TIMER_EVENTS, or other
* flags defined elsewhere. Events not
* matching this will be skipped for
* processing later. */
{
Tcl_Event *evPtr, *prevPtr;
Tcl_EventProc *proc;
Tcl_Size eventCount;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
int result;
/*
* Asynchronous event handlers are considered to be the highest priority
* events, and so must be invoked before we process events on the event
* queue.
*/
|
| ︙ | ︙ | |||
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 |
evPtr->proc = NULL;
/*
* Release the lock before calling the event function. This allows
* other threads to post events if we enter a recursive event loop in
* this thread. Note that we are making the assumption that if the
* proc returns 0, the event is still in the list.
*/
Tcl_MutexUnlock(&(tsdPtr->queueMutex));
result = proc(evPtr, flags);
Tcl_MutexLock(&(tsdPtr->queueMutex));
if (result) {
/*
* The event was processed, so remove it from the queue.
*/
if (tsdPtr->firstEventPtr == evPtr) {
| > > > > > > > > | 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 |
evPtr->proc = NULL;
/*
* Release the lock before calling the event function. This allows
* other threads to post events if we enter a recursive event loop in
* this thread. Note that we are making the assumption that if the
* proc returns 0, the event is still in the list.
*
* The eventCount is remembered and set to zero that the next
* level of Tcl_ServiceEvent() gets an empty condition for the
* Tcl_ThreadQueueEvent() to perform optional wakeups.
* On exit of the next level, the eventCount is readjusted.
*/
eventCount = tsdPtr->eventCount;
tsdPtr->eventCount = 0;
Tcl_MutexUnlock(&(tsdPtr->queueMutex));
result = proc(evPtr, flags);
Tcl_MutexLock(&(tsdPtr->queueMutex));
tsdPtr->eventCount += eventCount;
if (result) {
/*
* The event was processed, so remove it from the queue.
*/
if (tsdPtr->firstEventPtr == evPtr) {
|
| ︙ | ︙ | |||
739 740 741 742 743 744 745 746 747 748 749 750 751 752 |
}
} else {
evPtr = NULL;
}
}
if (evPtr) {
Tcl_Free(evPtr);
}
Tcl_MutexUnlock(&(tsdPtr->queueMutex));
return 1;
} else {
/*
* The event wasn't actually handled, so we have to restore the
* proc field to allow the event to be attempted again.
| > | 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 |
}
} else {
evPtr = NULL;
}
}
if (evPtr) {
Tcl_Free(evPtr);
tsdPtr->eventCount--;
}
Tcl_MutexUnlock(&(tsdPtr->queueMutex));
return 1;
} else {
/*
* The event wasn't actually handled, so we have to restore the
* proc field to allow the event to be attempted again.
|
| ︙ | ︙ |
Changes to generic/tclOO.c.
| ︙ | ︙ | |||
1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 |
}
Tcl_Free(clsPtr->superclasses.list);
clsPtr->superclasses.num = 0;
clsPtr->superclasses.list = NULL;
}
FOREACH_HASH_VALUE(mPtr, &clsPtr->classMethods) {
TclOODelMethodRef(mPtr);
}
Tcl_DeleteHashTable(&clsPtr->classMethods);
TclOODelMethodRef(clsPtr->constructorPtr);
TclOODelMethodRef(clsPtr->destructorPtr);
FOREACH(variableObj, clsPtr->variables) {
| > > > > | 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 |
}
Tcl_Free(clsPtr->superclasses.list);
clsPtr->superclasses.num = 0;
clsPtr->superclasses.list = NULL;
}
FOREACH_HASH_VALUE(mPtr, &clsPtr->classMethods) {
/* instance gets deleted, so if method remains, reset it there */
if (mPtr->refCount > 1 && mPtr->declaringClassPtr == clsPtr) {
mPtr->declaringClassPtr = NULL;
}
TclOODelMethodRef(mPtr);
}
Tcl_DeleteHashTable(&clsPtr->classMethods);
TclOODelMethodRef(clsPtr->constructorPtr);
TclOODelMethodRef(clsPtr->destructorPtr);
FOREACH(variableObj, clsPtr->variables) {
|
| ︙ | ︙ | |||
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 |
}
if (i) {
Tcl_Free(oPtr->filters.list);
}
if (oPtr->methodsPtr) {
FOREACH_HASH_VALUE(mPtr, oPtr->methodsPtr) {
TclOODelMethodRef(mPtr);
}
Tcl_DeleteHashTable(oPtr->methodsPtr);
Tcl_Free(oPtr->methodsPtr);
}
FOREACH(variableObj, oPtr->variables) {
| > > > > | 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 |
}
if (i) {
Tcl_Free(oPtr->filters.list);
}
if (oPtr->methodsPtr) {
FOREACH_HASH_VALUE(mPtr, oPtr->methodsPtr) {
/* instance gets deleted, so if method remains, reset it there */
if (mPtr->refCount > 1 && mPtr->declaringObjectPtr == oPtr) {
mPtr->declaringObjectPtr = NULL;
}
TclOODelMethodRef(mPtr);
}
Tcl_DeleteHashTable(oPtr->methodsPtr);
Tcl_Free(oPtr->methodsPtr);
}
FOREACH(variableObj, oPtr->variables) {
|
| ︙ | ︙ | |||
1880 1881 1882 1883 1884 1885 1886 |
*/
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));
| | | 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 |
*/
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));
OO_ERROR(interp, OVERWRITE_OBJECT);
return NULL;
}
}
/*
* Create the object.
*/
|
| ︙ | ︙ | |||
1937 1938 1939 1940 1941 1942 1943 |
* Ensure an error if the object was deleted in the constructor. Don't
* want to lose errors by accident. [Bug 2903011]
*/
if (result != TCL_ERROR && Destructing(oPtr)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"object deleted in constructor", TCL_AUTO_LENGTH));
| | | 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 |
* Ensure an error if the object was deleted in the constructor. Don't
* want to lose errors by accident. [Bug 2903011]
*/
if (result != TCL_ERROR && Destructing(oPtr)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"object deleted in constructor", TCL_AUTO_LENGTH));
OO_ERROR(interp, STILLBORN);
result = TCL_ERROR;
}
if (result != TCL_OK) {
Tcl_DiscardInterpState(state);
/*
* Take care to not delete a deleted object; that would be bad. [Bug
|
| ︙ | ︙ | |||
2008 2009 2010 2011 2012 2013 2014 |
/*
* Sanity check.
*/
if (IsRootClass(oPtr)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"may not clone the class of classes", TCL_AUTO_LENGTH));
| | | 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 |
/*
* Sanity check.
*/
if (IsRootClass(oPtr)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"may not clone the class of classes", TCL_AUTO_LENGTH));
OO_ERROR(interp, CLONING_CLASS);
return NULL;
}
/*
* Build the instance. Note that this does not run any constructors.
*/
|
| ︙ | ︙ | |||
2899 2900 2901 2902 2903 2904 2905 |
methodType = "destructor";
} else {
methodType = "method";
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"no next %s implementation", methodType));
| | | 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 |
methodType = "destructor";
} else {
methodType = "method";
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"no next %s implementation", methodType));
OO_ERROR(interp, NOTHING_NEXT);
return TCL_ERROR;
}
/*
* Advance to the next method implementation in the chain in the method
* call context while we process the body. However, need to adjust the
* argument-skip control because we're guaranteed to have a single prefix
|
| ︙ | ︙ | |||
2968 2969 2970 2971 2972 2973 2974 |
methodType = "destructor";
} else {
methodType = "method";
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"no next %s implementation", methodType));
| | | 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 |
methodType = "destructor";
} else {
methodType = "method";
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"no next %s implementation", methodType));
OO_ERROR(interp, NOTHING_NEXT);
return TCL_ERROR;
}
/*
* Advance to the next method implementation in the chain in the method
* call context while we process the body. However, need to adjust the
* argument-skip control because we're guaranteed to have a single prefix
|
| ︙ | ︙ |
Changes to generic/tclOO.decls.
| ︙ | ︙ | |||
229 230 231 232 233 234 235 236 237 238 239 240 241 |
void TclOOObjectSetMixins(Object *oPtr, Tcl_Size numMixins,
Class *const *mixins)
}
declare 15 {
void TclOOClassSetMixins(Tcl_Interp *interp, Class *classPtr,
Tcl_Size numMixins, Class *const *mixins)
}
return
# Local Variables:
# mode: tcl
# End:
| > > > > > > > > > > > > | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
void TclOOObjectSetMixins(Object *oPtr, Tcl_Size numMixins,
Class *const *mixins)
}
declare 15 {
void TclOOClassSetMixins(Tcl_Interp *interp, Class *classPtr,
Tcl_Size numMixins, Class *const *mixins)
}
declare 16 {
Tcl_Method TclOOMakeProcInstanceMethod2(Tcl_Interp *interp, Object *oPtr,
int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
const Tcl_MethodType2 *typePtr, void *clientData,
Proc **procPtrPtr)
}
declare 17 {
Tcl_Method TclOOMakeProcMethod2(Tcl_Interp *interp, Class *clsPtr,
int flags, Tcl_Obj *nameObj, const char *namePtr,
Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType2 *typePtr,
void *clientData, Proc **procPtrPtr)
}
return
# Local Variables:
# mode: tcl
# End:
|
Changes to generic/tclOOBasic.c.
| ︙ | ︙ | |||
202 203 204 205 206 207 208 |
*/
if (oPtr->classPtr == NULL) {
Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"object \"%s\" is not a class", TclGetString(cmdnameObj)));
| | | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
*/
if (oPtr->classPtr == NULL) {
Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"object \"%s\" is not a class", TclGetString(cmdnameObj)));
OO_ERROR(interp, INSTANTIATE_NONCLASS);
return TCL_ERROR;
}
/*
* Check we have the right number of (sensible) arguments.
*/
if (objc < 1 + Tcl_ObjectContextSkippedArgs(context)) {
Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
"objectName ?arg ...?");
return TCL_ERROR;
}
objName = Tcl_GetStringFromObj(
objv[Tcl_ObjectContextSkippedArgs(context)], &len);
if (len == 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"object name must not be empty", TCL_AUTO_LENGTH));
OO_ERROR(interp, EMPTY_NAME);
return TCL_ERROR;
}
/*
* Make the object and return its name.
*/
|
| ︙ | ︙ | |||
267 268 269 270 271 272 273 |
*/
if (oPtr->classPtr == NULL) {
Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"object \"%s\" is not a class", TclGetString(cmdnameObj)));
| | | | | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
*/
if (oPtr->classPtr == NULL) {
Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"object \"%s\" is not a class", TclGetString(cmdnameObj)));
OO_ERROR(interp, INSTANTIATE_NONCLASS);
return TCL_ERROR;
}
/*
* Check we have the right number of (sensible) arguments.
*/
if (objc + 1 < Tcl_ObjectContextSkippedArgs(context) + 3) {
Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
"objectName namespaceName ?arg ...?");
return TCL_ERROR;
}
objName = Tcl_GetStringFromObj(
objv[Tcl_ObjectContextSkippedArgs(context)], &len);
if (len == 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"object name must not be empty", TCL_AUTO_LENGTH));
OO_ERROR(interp, EMPTY_NAME);
return TCL_ERROR;
}
nsName = Tcl_GetStringFromObj(
objv[Tcl_ObjectContextSkippedArgs(context) + 1], &len);
if (len == 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"namespace name must not be empty", TCL_AUTO_LENGTH));
OO_ERROR(interp, EMPTY_NAME);
return TCL_ERROR;
}
/*
* Make the object and return its name.
*/
|
| ︙ | ︙ | |||
338 339 340 341 342 343 344 |
*/
if (oPtr->classPtr == NULL) {
Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"object \"%s\" is not a class", TclGetString(cmdnameObj)));
| | | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
*/
if (oPtr->classPtr == NULL) {
Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"object \"%s\" is not a class", TclGetString(cmdnameObj)));
OO_ERROR(interp, INSTANTIATE_NONCLASS);
return TCL_ERROR;
}
/*
* Make the object and return its name.
*/
|
| ︙ | ︙ | |||
614 615 616 617 618 619 620 |
}
Tcl_AppendToObj(errorMsg, methodNames[i], TCL_AUTO_LENGTH);
}
if (i) {
Tcl_AppendToObj(errorMsg, " or ", TCL_AUTO_LENGTH);
}
Tcl_AppendToObj(errorMsg, methodNames[i], TCL_AUTO_LENGTH);
| | | 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 |
}
Tcl_AppendToObj(errorMsg, methodNames[i], TCL_AUTO_LENGTH);
}
if (i) {
Tcl_AppendToObj(errorMsg, " or ", TCL_AUTO_LENGTH);
}
Tcl_AppendToObj(errorMsg, methodNames[i], TCL_AUTO_LENGTH);
Tcl_Free((void *)methodNames);
Tcl_SetObjResult(interp, errorMsg);
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
TclGetString(objv[skip]), (char *)NULL);
return TCL_ERROR;
}
/*
|
| ︙ | ︙ | |||
930 931 932 933 934 935 936 |
* retrieve the handle to the object call context.
*/
if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s may only be called from inside a method",
TclGetString(objv[0])));
| | | 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 |
* retrieve the handle to the object call context.
*/
if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s may only be called from inside a method",
TclGetString(objv[0])));
OO_ERROR(interp, CONTEXT_REQUIRED);
return TCL_ERROR;
}
context = (Tcl_ObjectContext) framePtr->clientData;
/*
* Invoke the (advanced) method call context in the caller context. Note
* that this is like [uplevel 1] and not [eval].
|
| ︙ | ︙ | |||
970 971 972 973 974 975 976 |
* retrieve the handle to the object call context.
*/
if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s may only be called from inside a method",
TclGetString(objv[0])));
| | | | 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 |
* retrieve the handle to the object call context.
*/
if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s may only be called from inside a method",
TclGetString(objv[0])));
OO_ERROR(interp, CONTEXT_REQUIRED);
return TCL_ERROR;
}
contextPtr = (CallContext *) framePtr->clientData;
/*
* Sanity check the arguments; we need the first one to refer to a class.
*/
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "class ?arg...?");
return TCL_ERROR;
}
object = Tcl_GetObjectFromObj(interp, objv[1]);
if (object == NULL) {
return TCL_ERROR;
}
classPtr = ((Object *) object)->classPtr;
if (classPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"\"%s\" is not a class", TclGetString(objv[1])));
OO_ERROR(interp, CLASS_REQUIRED);
return TCL_ERROR;
}
/*
* Search for an implementation of a method associated with the current
* call on the call chain past the point where we currently are. Do not
* allow jumping backwards!
|
| ︙ | ︙ | |||
1039 1040 1041 1042 1043 1044 1045 |
for (i=contextPtr->index ; i != TCL_INDEX_NONE ; i--) {
MInvoke *miPtr = &contextPtr->callPtr->chain[i];
if (!miPtr->isFilter && miPtr->mPtr->declaringClassPtr == classPtr) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s implementation by \"%s\" not reachable from here",
methodType, TclGetString(objv[1])));
| | < | | 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 |
for (i=contextPtr->index ; i != TCL_INDEX_NONE ; i--) {
MInvoke *miPtr = &contextPtr->callPtr->chain[i];
if (!miPtr->isFilter && miPtr->mPtr->declaringClassPtr == classPtr) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s implementation by \"%s\" not reachable from here",
methodType, TclGetString(objv[1])));
OO_ERROR(interp, CLASS_NOT_REACHABLE);
return TCL_ERROR;
}
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s has no non-filter implementation by \"%s\"",
methodType, TclGetString(objv[1])));
OO_ERROR(interp, CLASS_NOT_THERE);
return TCL_ERROR;
}
static int
NextRestoreFrame(
void *data[],
Tcl_Interp *interp,
|
| ︙ | ︙ | |||
1109 1110 1111 1112 1113 1114 1115 |
* Start with sanity checks on the calling context and the method context.
*/
if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s may only be called from inside a method",
TclGetString(objv[0])));
| | | 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 |
* Start with sanity checks on the calling context and the method context.
*/
if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s may only be called from inside a method",
TclGetString(objv[0])));
OO_ERROR(interp, CONTEXT_REQUIRED);
return TCL_ERROR;
}
contextPtr = (CallContext *) framePtr->clientData;
/*
* Now we do "conventional" argument parsing for a while. Note that no
|
| ︙ | ︙ | |||
1144 1145 1146 1147 1148 1149 1150 |
return TCL_OK;
case SELF_CLASS: {
Class *clsPtr = CurrentlyInvoked(contextPtr).mPtr->declaringClassPtr;
if (clsPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"method not defined by a class", TCL_AUTO_LENGTH));
| | | | 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 |
return TCL_OK;
case SELF_CLASS: {
Class *clsPtr = CurrentlyInvoked(contextPtr).mPtr->declaringClassPtr;
if (clsPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"method not defined by a class", TCL_AUTO_LENGTH));
OO_ERROR(interp, UNMATCHED_CONTEXT);
return TCL_ERROR;
}
Tcl_SetObjResult(interp, TclOOObjectName(interp, clsPtr->thisPtr));
return TCL_OK;
}
case SELF_METHOD:
if (contextPtr->callPtr->flags & CONSTRUCTOR) {
Tcl_SetObjResult(interp, contextPtr->oPtr->fPtr->constructorName);
} else if (contextPtr->callPtr->flags & DESTRUCTOR) {
Tcl_SetObjResult(interp, contextPtr->oPtr->fPtr->destructorName);
} else {
Tcl_SetObjResult(interp,
CurrentlyInvoked(contextPtr).mPtr->namePtr);
}
return TCL_OK;
case SELF_FILTER:
if (!CurrentlyInvoked(contextPtr).isFilter) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"not inside a filtering context", TCL_AUTO_LENGTH));
OO_ERROR(interp, UNMATCHED_CONTEXT);
return TCL_ERROR;
} else {
MInvoke *miPtr = &CurrentlyInvoked(contextPtr);
Object *oPtr;
const char *type;
if (miPtr->filterDeclarer != NULL) {
|
| ︙ | ︙ | |||
1191 1192 1193 1194 1195 1196 1197 |
return TCL_OK;
}
case SELF_CALLER:
if ((framePtr->callerVarPtr == NULL) ||
!(framePtr->callerVarPtr->isProcCallFrame & FRAME_IS_METHOD)){
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"caller is not an object", TCL_AUTO_LENGTH));
| | | 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 |
return TCL_OK;
}
case SELF_CALLER:
if ((framePtr->callerVarPtr == NULL) ||
!(framePtr->callerVarPtr->isProcCallFrame & FRAME_IS_METHOD)){
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"caller is not an object", TCL_AUTO_LENGTH));
OO_ERROR(interp, CONTEXT_REQUIRED);
return TCL_ERROR;
} else {
CallContext *callerPtr = (CallContext *)
framePtr->callerVarPtr->clientData;
Method *mPtr = callerPtr->callPtr->chain[callerPtr->index].mPtr;
Object *declarerPtr;
|
| ︙ | ︙ | |||
1260 1261 1262 1263 1264 1265 1266 |
Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
}
return TCL_OK;
case SELF_TARGET:
if (!CurrentlyInvoked(contextPtr).isFilter) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"not inside a filtering context", TCL_AUTO_LENGTH));
| | | 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 |
Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
}
return TCL_OK;
case SELF_TARGET:
if (!CurrentlyInvoked(contextPtr).isFilter) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"not inside a filtering context", TCL_AUTO_LENGTH));
OO_ERROR(interp, UNMATCHED_CONTEXT);
return TCL_ERROR;
} else {
Method *mPtr;
Object *declarerPtr;
Tcl_Size i;
for (i=contextPtr->index ; i<contextPtr->callPtr->numChain ; i++) {
|
| ︙ | ︙ |
Changes to generic/tclOOCall.c.
| ︙ | ︙ | |||
640 641 642 643 644 645 646 |
if (i > 0) {
if (i > 1) {
qsort((void *) strings, i, sizeof(char *), CmpStr);
}
*stringsPtr = strings;
} else {
| | | 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 |
if (i > 0) {
if (i > 1) {
qsort((void *) strings, i, sizeof(char *), CmpStr);
}
*stringsPtr = strings;
} else {
Tcl_Free((void *)strings);
*stringsPtr = NULL;
}
return i;
}
/*
* Comparator for SortMethodNames
|
| ︙ | ︙ |
Changes to generic/tclOODefineCmds.c.
| ︙ | ︙ | |||
715 716 717 718 719 720 721 |
if (toPtr) {
newHPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, toPtr,
&isNew);
if (hPtr == newHPtr) {
renameToSelf:
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"cannot rename method to itself", TCL_AUTO_LENGTH));
| | | | 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 |
if (toPtr) {
newHPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, toPtr,
&isNew);
if (hPtr == newHPtr) {
renameToSelf:
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"cannot rename method to itself", TCL_AUTO_LENGTH));
OO_ERROR(interp, RENAME_TO_SELF);
return TCL_ERROR;
} else if (!isNew) {
renameToExisting:
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"method called %s already exists",
TclGetString(toPtr)));
OO_ERROR(interp, RENAME_OVER);
return TCL_ERROR;
}
}
} else {
hPtr = Tcl_FindHashEntry(&oPtr->classPtr->classMethods, fromPtr);
if (hPtr == NULL) {
goto noSuchMethod;
|
| ︙ | ︙ | |||
790 791 792 793 794 795 796 |
FOREACH_HASH_DECLS;
Tcl_Size soughtLen;
const char *soughtStr, *nameStr, *matchedStr = NULL;
if (objc < 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"bad call of unknown handler", TCL_AUTO_LENGTH));
| | | 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 |
FOREACH_HASH_DECLS;
Tcl_Size soughtLen;
const char *soughtStr, *nameStr, *matchedStr = NULL;
if (objc < 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"bad call of unknown handler", TCL_AUTO_LENGTH));
OO_ERROR(interp, BAD_UNKNOWN);
return TCL_ERROR;
}
if (TclOOGetDefineCmdContext(interp) == NULL) {
return TCL_ERROR;
}
soughtStr = TclGetStringFromObj(objv[1], &soughtLen);
|
| ︙ | ︙ | |||
923 924 925 926 927 928 929 |
Tcl_Obj *const objv[])
{
CallFrame *framePtr, **framePtrPtr = &framePtr;
if (namespacePtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"no definition namespace available", TCL_AUTO_LENGTH));
| | | 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 |
Tcl_Obj *const objv[])
{
CallFrame *framePtr, **framePtrPtr = &framePtr;
if (namespacePtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"no definition namespace available", TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
/*
* framePtrPtr is needed to satisfy GCC 3.3's strict aliasing rules.
*/
|
| ︙ | ︙ | |||
965 966 967 968 969 970 971 |
if ((iPtr->varFramePtr == NULL)
|| (iPtr->varFramePtr->isProcCallFrame != FRAME_IS_OO_DEFINE
&& iPtr->varFramePtr->isProcCallFrame != PRIVATE_FRAME)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"this command may only be called from within the context of"
" an ::oo::define or ::oo::objdefine command",
TCL_AUTO_LENGTH));
| | | | | 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 |
if ((iPtr->varFramePtr == NULL)
|| (iPtr->varFramePtr->isProcCallFrame != FRAME_IS_OO_DEFINE
&& iPtr->varFramePtr->isProcCallFrame != PRIVATE_FRAME)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"this command may only be called from within the context of"
" an ::oo::define or ::oo::objdefine command",
TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return NULL;
}
object = (Tcl_Object) iPtr->varFramePtr->clientData;
if (Tcl_ObjectDeleted(object)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"this command cannot be called when the object has been"
" deleted", TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return NULL;
}
return object;
}
Class *
TclOOGetClassDefineCmdContext(
Tcl_Interp *interp)
{
Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
if (oPtr == NULL) {
return NULL;
}
if (!oPtr->classPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return NULL;
}
return oPtr->classPtr;
}
/*
* ----------------------------------------------------------------------
|
| ︙ | ︙ | |||
1533 1534 1535 1536 1537 1538 1539 |
if (oPtr == NULL) {
return TCL_ERROR;
}
if (oPtr->flags & ROOT_OBJECT) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"may not modify the class of the root object class",
TCL_AUTO_LENGTH));
| | | | | 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 |
if (oPtr == NULL) {
return TCL_ERROR;
}
if (oPtr->flags & ROOT_OBJECT) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"may not modify the class of the root object class",
TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
if (oPtr->flags & ROOT_CLASS) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"may not modify the class of the class of classes",
TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
/*
* Parse the argument to get the class to set the object's class to.
*/
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "className");
return TCL_ERROR;
}
clsPtr = GetClassInOuterContext(interp, objv[1],
"the class of an object must be a class");
if (clsPtr == NULL) {
return TCL_ERROR;
}
if (oPtr == clsPtr->thisPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"may not change classes into an instance of themselves",
TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
/*
* Set the object's class.
*/
|
| ︙ | ︙ | |||
1703 1704 1705 1706 1707 1708 1709 |
if (clsPtr == NULL) {
return TCL_ERROR;
} else if (clsPtr->thisPtr->flags & (ROOT_OBJECT | ROOT_CLASS)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"may not modify the definition namespace of the root classes",
TCL_AUTO_LENGTH));
| | | 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 |
if (clsPtr == NULL) {
return TCL_ERROR;
} else if (clsPtr->thisPtr->flags & (ROOT_OBJECT | ROOT_CLASS)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"may not modify the definition namespace of the root classes",
TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
/*
* Parse the arguments and work out what the user wants to do.
*/
|
| ︙ | ︙ | |||
1780 1781 1782 1783 1784 1785 1786 |
oPtr = (Object *) TclOOGetDefineCmdContext(interp);
if (oPtr == NULL) {
return TCL_ERROR;
}
if (!isInstanceDeleteMethod && !oPtr->classPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
| | | 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 |
oPtr = (Object *) TclOOGetDefineCmdContext(interp);
if (oPtr == NULL) {
return TCL_ERROR;
}
if (!isInstanceDeleteMethod && !oPtr->classPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
for (i = 1; i < objc; i++) {
/*
* Delete the method structure from the appropriate hash table.
*/
|
| ︙ | ︙ | |||
1902 1903 1904 1905 1906 1907 1908 |
if (oPtr == NULL) {
return TCL_ERROR;
}
clsPtr = oPtr->classPtr;
if (!isInstanceExport && !clsPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
| | | 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 |
if (oPtr == NULL) {
return TCL_ERROR;
}
clsPtr = oPtr->classPtr;
if (!isInstanceExport && !clsPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
for (i = 1; i < objc; i++) {
/*
* Exporting is done by adding the PUBLIC_METHOD flag to the method
* record. If there is no such method in this object or class (i.e.
|
| ︙ | ︙ | |||
1997 1998 1999 2000 2001 2002 2003 |
oPtr = (Object *) TclOOGetDefineCmdContext(interp);
if (oPtr == NULL) {
return TCL_ERROR;
}
if (!isInstanceForward && !oPtr->classPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
| | | 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 |
oPtr = (Object *) TclOOGetDefineCmdContext(interp);
if (oPtr == NULL) {
return TCL_ERROR;
}
if (!isInstanceForward && !oPtr->classPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
isPublic = Tcl_StringMatch(TclGetString(objv[1]), PUBLIC_PATTERN)
? PUBLIC_METHOD : 0;
if (IsPrivateDefine(interp)) {
isPublic = TRUE_PRIVATE_METHOD;
}
|
| ︙ | ︙ | |||
2075 2076 2077 2078 2079 2080 2081 |
oPtr = (Object *) TclOOGetDefineCmdContext(interp);
if (oPtr == NULL) {
return TCL_ERROR;
}
if (!isInstanceMethod && !oPtr->classPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
| | | 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 |
oPtr = (Object *) TclOOGetDefineCmdContext(interp);
if (oPtr == NULL) {
return TCL_ERROR;
}
if (!isInstanceMethod && !oPtr->classPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
if (objc == 5) {
if (Tcl_GetIndexFromObj(interp, objv[2], exportModes, "export flag",
0, &exportMode) != TCL_OK) {
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
2154 2155 2156 2157 2158 2159 2160 |
oPtr = (Object *) TclOOGetDefineCmdContext(interp);
if (oPtr == NULL) {
return TCL_ERROR;
}
if (!isInstanceRenameMethod && !oPtr->classPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
| | | 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 |
oPtr = (Object *) TclOOGetDefineCmdContext(interp);
if (oPtr == NULL) {
return TCL_ERROR;
}
if (!isInstanceRenameMethod && !oPtr->classPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
/*
* Delete the method entry from the appropriate hash table, and transfer
* the thing it points to to its new entry. To do this, we first need to
* get the entries from the appropriate hash tables (this can generate a
|
| ︙ | ︙ | |||
2216 2217 2218 2219 2220 2221 2222 |
if (oPtr == NULL) {
return TCL_ERROR;
}
clsPtr = oPtr->classPtr;
if (!isInstanceUnexport && !clsPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
| | | 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 |
if (oPtr == NULL) {
return TCL_ERROR;
}
clsPtr = oPtr->classPtr;
if (!isInstanceUnexport && !clsPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
for (i = 1; i < objc; i++) {
/*
* Unexporting is done by removing the PUBLIC_METHOD flag from the
* method record. If there is no such method in this object or class
|
| ︙ | ︙ | |||
2542 2543 2544 2545 2546 2547 2548 |
goto freeAndError;
}
(void) Tcl_CreateHashEntry(&uniqueCheck, (void *) mixins[i], &isNew);
if (!isNew) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"class should only be a direct mixin once",
TCL_AUTO_LENGTH));
| | | | 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 |
goto freeAndError;
}
(void) Tcl_CreateHashEntry(&uniqueCheck, (void *) mixins[i], &isNew);
if (!isNew) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"class should only be a direct mixin once",
TCL_AUTO_LENGTH));
OO_ERROR(interp, REPETITIOUS);
goto freeAndError;
}
if (TclOOIsReachable(clsPtr, mixins[i])) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"may not mix a class into itself", TCL_AUTO_LENGTH));
OO_ERROR(interp, SELF_MIXIN);
goto freeAndError;
}
}
TclOOClassSetMixins(interp, clsPtr, mixinc, mixins);
Tcl_DeleteHashTable(&uniqueCheck);
TclStackFree(interp, mixins);
|
| ︙ | ︙ | |||
2633 2634 2635 2636 2637 2638 2639 |
objv += Tcl_ObjectContextSkippedArgs(context);
Foundation *fPtr = clsPtr->thisPtr->fPtr;
if (clsPtr == fPtr->objectCls) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"may not modify the superclass of the root object",
TCL_AUTO_LENGTH));
| | | 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 |
objv += Tcl_ObjectContextSkippedArgs(context);
Foundation *fPtr = clsPtr->thisPtr->fPtr;
if (clsPtr == fPtr->objectCls) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"may not modify the superclass of the root object",
TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
} else if (TclListObjGetElements(interp, objv[0], &superc,
&superv) != TCL_OK) {
return TCL_ERROR;
}
/*
|
| ︙ | ︙ | |||
2674 2675 2676 2677 2678 2679 2680 |
goto failedAfterAlloc;
}
for (j = 0; j < i; j++) {
if (superclasses[j] == superclasses[i]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"class should only be a direct superclass once",
TCL_AUTO_LENGTH));
| | | | 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 |
goto failedAfterAlloc;
}
for (j = 0; j < i; j++) {
if (superclasses[j] == superclasses[i]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"class should only be a direct superclass once",
TCL_AUTO_LENGTH));
OO_ERROR(interp, REPETITIOUS);
goto failedAfterAlloc;
}
}
if (TclOOIsReachable(clsPtr, superclasses[i])) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to form circular dependency graph",
TCL_AUTO_LENGTH));
OO_ERROR(interp, CIRCULARITY);
failedAfterAlloc:
for (; i-- > 0 ;) {
TclOODecrRefCount(superclasses[i]->thisPtr);
}
Tcl_Free(superclasses);
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
2806 2807 2808 2809 2810 2811 2812 |
for (i = 0; i < varc; i++) {
const char *varName = TclGetString(varv[i]);
if (strstr(varName, "::") != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid declared variable name \"%s\": must not %s",
varName, "contain namespace separators"));
| | | | 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 |
for (i = 0; i < varc; i++) {
const char *varName = TclGetString(varv[i]);
if (strstr(varName, "::") != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid declared variable name \"%s\": must not %s",
varName, "contain namespace separators"));
OO_ERROR(interp, BAD_DECLVAR);
return TCL_ERROR;
}
if (Tcl_StringMatch(varName, "*(*)")) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid declared variable name \"%s\": must not %s",
varName, "refer to an array element"));
OO_ERROR(interp, BAD_DECLVAR);
return TCL_ERROR;
}
}
if (IsPrivateDefine(interp)) {
InstallPrivateVariableMapping(&clsPtr->privateVariables,
varc, varv, clsPtr->thisPtr->creationEpoch);
|
| ︙ | ︙ | |||
2981 2982 2983 2984 2985 2986 2987 |
goto freeAndError;
}
(void) Tcl_CreateHashEntry(&uniqueCheck, (void *) mixins[i], &isNew);
if (!isNew) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"class should only be a direct mixin once",
TCL_AUTO_LENGTH));
| | | 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 |
goto freeAndError;
}
(void) Tcl_CreateHashEntry(&uniqueCheck, (void *) mixins[i], &isNew);
if (!isNew) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"class should only be a direct mixin once",
TCL_AUTO_LENGTH));
OO_ERROR(interp, REPETITIOUS);
goto freeAndError;
}
}
TclOOObjectSetMixins(oPtr, mixinc, mixins);
TclStackFree(interp, mixins);
Tcl_DeleteHashTable(&uniqueCheck);
|
| ︙ | ︙ | |||
3077 3078 3079 3080 3081 3082 3083 |
for (i = 0; i < varc; i++) {
const char *varName = TclGetString(varv[i]);
if (strstr(varName, "::") != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid declared variable name \"%s\": must not %s",
varName, "contain namespace separators"));
| | | | 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 |
for (i = 0; i < varc; i++) {
const char *varName = TclGetString(varv[i]);
if (strstr(varName, "::") != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid declared variable name \"%s\": must not %s",
varName, "contain namespace separators"));
OO_ERROR(interp, BAD_DECLVAR);
return TCL_ERROR;
}
if (Tcl_StringMatch(varName, "*(*)")) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid declared variable name \"%s\": must not %s",
varName, "refer to an array element"));
OO_ERROR(interp, BAD_DECLVAR);
return TCL_ERROR;
}
}
if (IsPrivateDefine(interp)) {
InstallPrivateVariableMapping(&oPtr->privateVariables, varc, varv,
oPtr->creationEpoch);
|
| ︙ | ︙ |
Changes to generic/tclOOInfo.c.
| ︙ | ︙ | |||
660 661 662 663 664 665 666 |
&names);
for (i=0 ; i<numNames ; i++) {
Tcl_ListObjAppendElement(NULL, resultObj,
Tcl_NewStringObj(names[i], TCL_AUTO_LENGTH));
}
if (numNames > 0) {
| | | 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 |
&names);
for (i=0 ; i<numNames ; i++) {
Tcl_ListObjAppendElement(NULL, resultObj,
Tcl_NewStringObj(names[i], TCL_AUTO_LENGTH));
}
if (numNames > 0) {
Tcl_Free((void *)names);
}
} else if (oPtr->methodsPtr) {
if (scope == SCOPE_DEFAULT) {
/*
* Handle legacy-mode matching. [Bug 36e5517a6850]
*/
int scopeFilter = flag | TRUE_PRIVATE_METHOD;
|
| ︙ | ︙ | |||
884 885 886 887 888 889 890 |
return TCL_ERROR;
}
if (objc == 3) {
if (strcmp("-private", TclGetString(objv[2])) != 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"option \"%s\" is not exactly \"-private\"",
TclGetString(objv[2])));
| | | 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 |
return TCL_ERROR;
}
if (objc == 3) {
if (strcmp("-private", TclGetString(objv[2])) != 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"option \"%s\" is not exactly \"-private\"",
TclGetString(objv[2])));
OO_ERROR(interp, BAD_ARG);
return TCL_ERROR;
}
isPrivate = 1;
}
oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
if (oPtr == NULL) {
return TCL_ERROR;
|
| ︙ | ︙ | |||
1011 1012 1013 1014 1015 1016 1017 |
return TCL_OK;
}
procPtr = TclOOGetProcFromMethod(clsPtr->constructorPtr);
if (procPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"definition not available for this kind of method",
TCL_AUTO_LENGTH));
| | | 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 |
return TCL_OK;
}
procPtr = TclOOGetProcFromMethod(clsPtr->constructorPtr);
if (procPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"definition not available for this kind of method",
TCL_AUTO_LENGTH));
OO_ERROR(interp, METHOD_TYPE);
return TCL_ERROR;
}
TclNewObj(resultObjs[0]);
for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL;
localPtr=localPtr->nextPtr) {
if (TclIsVarArgument(localPtr)) {
|
| ︙ | ︙ | |||
1189 1190 1191 1192 1193 1194 1195 |
return TCL_OK;
}
procPtr = TclOOGetProcFromMethod(clsPtr->destructorPtr);
if (procPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"definition not available for this kind of method",
TCL_AUTO_LENGTH));
| | | 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 |
return TCL_OK;
}
procPtr = TclOOGetProcFromMethod(clsPtr->destructorPtr);
if (procPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"definition not available for this kind of method",
TCL_AUTO_LENGTH));
OO_ERROR(interp, METHOD_TYPE);
return TCL_ERROR;
}
Tcl_SetObjResult(interp, TclOOGetMethodBody(clsPtr->destructorPtr));
return TCL_OK;
}
|
| ︙ | ︙ | |||
1436 1437 1438 1439 1440 1441 1442 |
Tcl_Size i, numNames = TclOOGetSortedClassMethodList(clsPtr, flag, &names);
for (i=0 ; i<numNames ; i++) {
Tcl_ListObjAppendElement(NULL, resultObj,
Tcl_NewStringObj(names[i], TCL_AUTO_LENGTH));
}
if (numNames > 0) {
| | | 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 |
Tcl_Size i, numNames = TclOOGetSortedClassMethodList(clsPtr, flag, &names);
for (i=0 ; i<numNames ; i++) {
Tcl_ListObjAppendElement(NULL, resultObj,
Tcl_NewStringObj(names[i], TCL_AUTO_LENGTH));
}
if (numNames > 0) {
Tcl_Free((void *)names);
}
} else {
FOREACH_HASH_DECLS;
if (scope == SCOPE_DEFAULT) {
/*
* Handle legacy-mode matching. [Bug 36e5517a6850]
|
| ︙ | ︙ | |||
1686 1687 1688 1689 1690 1691 1692 |
return TCL_ERROR;
}
if (objc == 3) {
if (strcmp("-private", TclGetString(objv[2])) != 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"option \"%s\" is not exactly \"-private\"",
TclGetString(objv[2])));
| | | 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 |
return TCL_ERROR;
}
if (objc == 3) {
if (strcmp("-private", TclGetString(objv[2])) != 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"option \"%s\" is not exactly \"-private\"",
TclGetString(objv[2])));
OO_ERROR(interp, BAD_ARG);
return TCL_ERROR;
}
isPrivate = 1;
}
clsPtr = TclOOGetClassFromObj(interp, objv[1]);
if (clsPtr == NULL) {
return TCL_ERROR;
|
| ︙ | ︙ | |||
1752 1753 1754 1755 1756 1757 1758 |
*/
contextPtr = TclOOGetCallContext(oPtr, objv[2], PUBLIC_METHOD, NULL, NULL,
NULL);
if (contextPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"cannot construct any call chain", TCL_AUTO_LENGTH));
| | | 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 |
*/
contextPtr = TclOOGetCallContext(oPtr, objv[2], PUBLIC_METHOD, NULL, NULL,
NULL);
if (contextPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"cannot construct any call chain", TCL_AUTO_LENGTH));
OO_ERROR(interp, BAD_CALL_CHAIN);
return TCL_ERROR;
}
Tcl_SetObjResult(interp,
TclOORenderCallChain(interp, contextPtr->callPtr));
TclOODeleteContext(contextPtr);
return TCL_OK;
}
|
| ︙ | ︙ | |||
1798 1799 1800 1801 1802 1803 1804 |
* Get an render the stereotypical call chain.
*/
callPtr = TclOOGetStereotypeCallChain(clsPtr, objv[2], PUBLIC_METHOD);
if (callPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"cannot construct any call chain", TCL_AUTO_LENGTH));
| | | 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 |
* Get an render the stereotypical call chain.
*/
callPtr = TclOOGetStereotypeCallChain(clsPtr, objv[2], PUBLIC_METHOD);
if (callPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"cannot construct any call chain", TCL_AUTO_LENGTH));
OO_ERROR(interp, BAD_CALL_CHAIN);
return TCL_ERROR;
}
Tcl_SetObjResult(interp, TclOORenderCallChain(interp, callPtr));
TclOODeleteChain(callPtr);
return TCL_OK;
}
|
| ︙ | ︙ |
Changes to generic/tclOOInt.h.
| ︙ | ︙ | |||
706 707 708 709 710 711 712 713 714 715 716 717 718 719 |
if (len != 0) { \
memcpy(((target).list=(type*)Tcl_Alloc(len)), (source).list, len); \
} else { \
(target).list = NULL; \
} \
} while(0)
#endif /* TCL_OO_INTERNAL_H */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
| > > > > > > | 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 |
if (len != 0) { \
memcpy(((target).list=(type*)Tcl_Alloc(len)), (source).list, len); \
} else { \
(target).list = NULL; \
} \
} while(0)
/*
* Convenience macro for generating error codes.
*/
#define OO_ERROR(interp, code) \
Tcl_SetErrorCode((interp), "TCL", "OO", #code, (char *)NULL)
#endif /* TCL_OO_INTERNAL_H */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
|
| ︙ | ︙ |
Changes to generic/tclOOIntDecls.h.
| ︙ | ︙ | |||
87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
/* 14 */
TCLAPI void TclOOObjectSetMixins(Object *oPtr,
Tcl_Size numMixins, Class *const *mixins);
/* 15 */
TCLAPI void TclOOClassSetMixins(Tcl_Interp *interp,
Class *classPtr, Tcl_Size numMixins,
Class *const *mixins);
typedef struct TclOOIntStubs {
int magic;
void *hooks;
Tcl_Object (*tclOOGetDefineCmdContext) (Tcl_Interp *interp); /* 0 */
Tcl_Method (*tclOOMakeProcInstanceMethod) (Tcl_Interp *interp, Object *oPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType *typePtr, void *clientData, Proc **procPtrPtr); /* 1 */
| > > > > > > > > > > > > > | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
/* 14 */
TCLAPI void TclOOObjectSetMixins(Object *oPtr,
Tcl_Size numMixins, Class *const *mixins);
/* 15 */
TCLAPI void TclOOClassSetMixins(Tcl_Interp *interp,
Class *classPtr, Tcl_Size numMixins,
Class *const *mixins);
/* 16 */
TCLAPI Tcl_Method TclOOMakeProcInstanceMethod2(Tcl_Interp *interp,
Object *oPtr, int flags, Tcl_Obj *nameObj,
Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
const Tcl_MethodType2 *typePtr,
void *clientData, Proc **procPtrPtr);
/* 17 */
TCLAPI Tcl_Method TclOOMakeProcMethod2(Tcl_Interp *interp,
Class *clsPtr, int flags, Tcl_Obj *nameObj,
const char *namePtr, Tcl_Obj *argsObj,
Tcl_Obj *bodyObj,
const Tcl_MethodType2 *typePtr,
void *clientData, Proc **procPtrPtr);
typedef struct TclOOIntStubs {
int magic;
void *hooks;
Tcl_Object (*tclOOGetDefineCmdContext) (Tcl_Interp *interp); /* 0 */
Tcl_Method (*tclOOMakeProcInstanceMethod) (Tcl_Interp *interp, Object *oPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType *typePtr, void *clientData, Proc **procPtrPtr); /* 1 */
|
| ︙ | ︙ | |||
108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
Tcl_Method (*tclOONewProcInstanceMethodEx) (Tcl_Interp *interp, Tcl_Object oPtr, TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, void *clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 9 */
Tcl_Method (*tclOONewProcMethodEx) (Tcl_Interp *interp, Tcl_Class clsPtr, TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, void *clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 10 */
int (*tclOOInvokeObject) (Tcl_Interp *interp, Tcl_Object object, Tcl_Class startCls, int publicPrivate, Tcl_Size objc, Tcl_Obj *const *objv); /* 11 */
void (*tclOOObjectSetFilters) (Object *oPtr, Tcl_Size numFilters, Tcl_Obj *const *filters); /* 12 */
void (*tclOOClassSetFilters) (Tcl_Interp *interp, Class *classPtr, Tcl_Size numFilters, Tcl_Obj *const *filters); /* 13 */
void (*tclOOObjectSetMixins) (Object *oPtr, Tcl_Size numMixins, Class *const *mixins); /* 14 */
void (*tclOOClassSetMixins) (Tcl_Interp *interp, Class *classPtr, Tcl_Size numMixins, Class *const *mixins); /* 15 */
} TclOOIntStubs;
extern const TclOOIntStubs *tclOOIntStubsPtr;
#ifdef __cplusplus
}
#endif
| > > | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
Tcl_Method (*tclOONewProcInstanceMethodEx) (Tcl_Interp *interp, Tcl_Object oPtr, TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, void *clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 9 */
Tcl_Method (*tclOONewProcMethodEx) (Tcl_Interp *interp, Tcl_Class clsPtr, TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, void *clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 10 */
int (*tclOOInvokeObject) (Tcl_Interp *interp, Tcl_Object object, Tcl_Class startCls, int publicPrivate, Tcl_Size objc, Tcl_Obj *const *objv); /* 11 */
void (*tclOOObjectSetFilters) (Object *oPtr, Tcl_Size numFilters, Tcl_Obj *const *filters); /* 12 */
void (*tclOOClassSetFilters) (Tcl_Interp *interp, Class *classPtr, Tcl_Size numFilters, Tcl_Obj *const *filters); /* 13 */
void (*tclOOObjectSetMixins) (Object *oPtr, Tcl_Size numMixins, Class *const *mixins); /* 14 */
void (*tclOOClassSetMixins) (Tcl_Interp *interp, Class *classPtr, Tcl_Size numMixins, Class *const *mixins); /* 15 */
Tcl_Method (*tclOOMakeProcInstanceMethod2) (Tcl_Interp *interp, Object *oPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType2 *typePtr, void *clientData, Proc **procPtrPtr); /* 16 */
Tcl_Method (*tclOOMakeProcMethod2) (Tcl_Interp *interp, Class *clsPtr, int flags, Tcl_Obj *nameObj, const char *namePtr, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType2 *typePtr, void *clientData, Proc **procPtrPtr); /* 17 */
} TclOOIntStubs;
extern const TclOOIntStubs *tclOOIntStubsPtr;
#ifdef __cplusplus
}
#endif
|
| ︙ | ︙ | |||
154 155 156 157 158 159 160 161 162 163 164 165 166 | (tclOOIntStubsPtr->tclOOObjectSetFilters) /* 12 */ #define TclOOClassSetFilters \ (tclOOIntStubsPtr->tclOOClassSetFilters) /* 13 */ #define TclOOObjectSetMixins \ (tclOOIntStubsPtr->tclOOObjectSetMixins) /* 14 */ #define TclOOClassSetMixins \ (tclOOIntStubsPtr->tclOOClassSetMixins) /* 15 */ #endif /* defined(USE_TCLOO_STUBS) */ /* !END!: Do not edit above this line. */ #endif /* _TCLOOINTDECLS */ | > > > > | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | (tclOOIntStubsPtr->tclOOObjectSetFilters) /* 12 */ #define TclOOClassSetFilters \ (tclOOIntStubsPtr->tclOOClassSetFilters) /* 13 */ #define TclOOObjectSetMixins \ (tclOOIntStubsPtr->tclOOObjectSetMixins) /* 14 */ #define TclOOClassSetMixins \ (tclOOIntStubsPtr->tclOOClassSetMixins) /* 15 */ #define TclOOMakeProcInstanceMethod2 \ (tclOOIntStubsPtr->tclOOMakeProcInstanceMethod2) /* 16 */ #define TclOOMakeProcMethod2 \ (tclOOIntStubsPtr->tclOOMakeProcMethod2) /* 17 */ #endif /* defined(USE_TCLOO_STUBS) */ /* !END!: Do not edit above this line. */ #endif /* _TCLOOINTDECLS */ |
Changes to generic/tclOOMethod.c.
| ︙ | ︙ | |||
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 |
* the procedure record reference. Presumably
* inside the structure indicated by the
* pointer in clientData. */
{
Interp *iPtr = (Interp *) interp;
Proc *procPtr;
if (TclCreateProc(interp, NULL, TclGetString(nameObj), argsObj, bodyObj,
procPtrPtr) != TCL_OK) {
return NULL;
}
procPtr = *procPtrPtr;
procPtr->cmdPtr = NULL;
InitCmdFrame(iPtr, procPtr);
return TclNewInstanceMethod(interp, (Tcl_Object) oPtr, nameObj, flags,
typePtr, clientData);
}
/*
* ----------------------------------------------------------------------
*
* TclOOMakeProcMethod --
*
* The guts of the code to make a procedure-like method for a class.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 |
* the procedure record reference. Presumably
* inside the structure indicated by the
* pointer in clientData. */
{
Interp *iPtr = (Interp *) interp;
Proc *procPtr;
if (typePtr->version > TCL_OO_METHOD_VERSION_1) {
Tcl_Panic("%s: Wrong version in typePtr->version, should be %s",
"TclOOMakeProcInstanceMethod", "TCL_OO_METHOD_VERSION_1");
}
if (TclCreateProc(interp, NULL, TclGetString(nameObj), argsObj, bodyObj,
procPtrPtr) != TCL_OK) {
return NULL;
}
procPtr = *procPtrPtr;
procPtr->cmdPtr = NULL;
InitCmdFrame(iPtr, procPtr);
return TclNewInstanceMethod(interp, (Tcl_Object) oPtr, nameObj, flags,
typePtr, clientData);
}
Tcl_Method
TclOOMakeProcInstanceMethod2(
Tcl_Interp *interp, /* The interpreter containing the object. */
Object *oPtr, /* The object to modify. */
int flags, /* Whether this is a public method. */
Tcl_Obj *nameObj, /* The name of the method, which _must not_ be
* NULL. */
Tcl_Obj *argsObj, /* The formal argument list for the method,
* which _must not_ be NULL. */
Tcl_Obj *bodyObj, /* The body of the method, which _must not_ be
* NULL. */
const Tcl_MethodType2 *typePtr,
/* The type of the method to create. */
void *clientData, /* The per-method type-specific data. */
Proc **procPtrPtr) /* A pointer to the variable in which to write
* the procedure record reference. Presumably
* inside the structure indicated by the
* pointer in clientData. */
{
Interp *iPtr = (Interp *) interp;
Proc *procPtr;
if (typePtr->version < TCL_OO_METHOD_VERSION_2) {
Tcl_Panic("%s: Wrong version in typePtr->version, should be %s",
"TclOOMakeProcInstanceMethod2", "TCL_OO_METHOD_VERSION_2");
}
if (TclCreateProc(interp, NULL, TclGetString(nameObj), argsObj, bodyObj,
procPtrPtr) != TCL_OK) {
return NULL;
}
procPtr = *procPtrPtr;
procPtr->cmdPtr = NULL;
InitCmdFrame(iPtr, procPtr);
return TclNewInstanceMethod(interp, (Tcl_Object) oPtr, nameObj, flags,
(const Tcl_MethodType *)typePtr, clientData);
}
/*
* ----------------------------------------------------------------------
*
* TclOOMakeProcMethod --
*
* The guts of the code to make a procedure-like method for a class.
|
| ︙ | ︙ | |||
671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 |
* the procedure record reference. Presumably
* inside the structure indicated by the
* pointer in clientData. */
{
Interp *iPtr = (Interp *) interp;
Proc *procPtr;
if (TclCreateProc(interp, NULL, namePtr, argsObj, bodyObj,
procPtrPtr) != TCL_OK) {
return NULL;
}
procPtr = *procPtrPtr;
procPtr->cmdPtr = NULL;
InitCmdFrame(iPtr, procPtr);
return TclNewMethod(
(Tcl_Class) clsPtr, nameObj, flags, typePtr, clientData);
}
/*
* ----------------------------------------------------------------------
*
* InvokeProcedureMethod, PushMethodCallFrame --
*
* How to invoke a procedure-like method.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 |
* the procedure record reference. Presumably
* inside the structure indicated by the
* pointer in clientData. */
{
Interp *iPtr = (Interp *) interp;
Proc *procPtr;
if (typePtr->version > TCL_OO_METHOD_VERSION_1) {
Tcl_Panic("%s: Wrong version in typePtr->version, should be %s",
"TclOOMakeProcMethod", "TCL_OO_METHOD_VERSION_1");
}
if (TclCreateProc(interp, NULL, namePtr, argsObj, bodyObj,
procPtrPtr) != TCL_OK) {
return NULL;
}
procPtr = *procPtrPtr;
procPtr->cmdPtr = NULL;
InitCmdFrame(iPtr, procPtr);
return TclNewMethod(
(Tcl_Class) clsPtr, nameObj, flags, typePtr, clientData);
}
Tcl_Method
TclOOMakeProcMethod2(
Tcl_Interp *interp, /* The interpreter containing the class. */
Class *clsPtr, /* The class to modify. */
int flags, /* Whether this is a public method. */
Tcl_Obj *nameObj, /* The name of the method, which may be NULL;
* if so, up to caller to manage storage
* (e.g., because it is a constructor or
* destructor). */
const char *namePtr, /* The name of the method as a string, which
* _must not_ be NULL. */
Tcl_Obj *argsObj, /* The formal argument list for the method,
* which _must not_ be NULL. */
Tcl_Obj *bodyObj, /* The body of the method, which _must not_ be
* NULL. */
const Tcl_MethodType2 *typePtr,
/* The type of the method to create. */
void *clientData, /* The per-method type-specific data. */
Proc **procPtrPtr) /* A pointer to the variable in which to write
* the procedure record reference. Presumably
* inside the structure indicated by the
* pointer in clientData. */
{
Interp *iPtr = (Interp *) interp;
Proc *procPtr;
if (typePtr->version < TCL_OO_METHOD_VERSION_2) {
Tcl_Panic("%s: Wrong version in typePtr->version, should be %s",
"TclOOMakeProcMethod2", "TCL_OO_METHOD_VERSION_2");
}
if (TclCreateProc(interp, NULL, namePtr, argsObj, bodyObj,
procPtrPtr) != TCL_OK) {
return NULL;
}
procPtr = *procPtrPtr;
procPtr->cmdPtr = NULL;
InitCmdFrame(iPtr, procPtr);
return TclNewMethod(
(Tcl_Class) clsPtr, nameObj, flags, (const Tcl_MethodType *)typePtr, clientData);
}
/*
* ----------------------------------------------------------------------
*
* InvokeProcedureMethod, PushMethodCallFrame --
*
* How to invoke a procedure-like method.
|
| ︙ | ︙ | |||
1201 1202 1203 1204 1205 1206 1207 | * ---------------------------------------------------------------------- */ // TODO: Check whether Tcl_AppendLimitedToObj() can work here. #define LIMIT 60 #define ELLIPSIFY(str,len) \ | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < < | < < < < < < < < < < | < < < < < < < < < < < < < | < < < < < < < < < < | < < < < < < < < < < < < | < < < < < < < < < < | < < < < < | 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 |
* ----------------------------------------------------------------------
*/
// TODO: Check whether Tcl_AppendLimitedToObj() can work here.
#define LIMIT 60
#define ELLIPSIFY(str,len) \
((len) > LIMIT ? LIMIT : (int)(len)), (str), ((len) > LIMIT ? "..." : "")
static void
CommonMethErrorHandler(
Tcl_Interp *interp,
const char *special)
{
Tcl_Size objectNameLen;
CallContext *contextPtr = (CallContext *)((Interp *)
interp)->varFramePtr->clientData;
Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr;
const char *objectName, *kindName = "instance";
Object *declarerPtr = NULL;
if (mPtr->declaringObjectPtr != NULL) {
declarerPtr = mPtr->declaringObjectPtr;
kindName = "object";
} else if (mPtr->declaringClassPtr != NULL) {
declarerPtr = mPtr->declaringClassPtr->thisPtr;
kindName = "class";
}
if (declarerPtr) {
objectName = TclGetStringFromObj(TclOOObjectName(interp, declarerPtr),
&objectNameLen);
} else {
objectName = "unknown or deleted";
objectNameLen = 18;
}
if (!special) {
Tcl_Size nameLen;
const char *methodName = TclGetStringFromObj(mPtr->namePtr, &nameLen);
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
"\n (%s \"%.*s%s\" method \"%.*s%s\" line %d)",
kindName, ELLIPSIFY(objectName, objectNameLen),
ELLIPSIFY(methodName, nameLen), Tcl_GetErrorLine(interp)));
} else {
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
"\n (%s \"%.*s%s\" %s line %d)",
kindName, ELLIPSIFY(objectName, objectNameLen), special,
Tcl_GetErrorLine(interp)));
}
}
static void
MethodErrorHandler(
Tcl_Interp *interp,
TCL_UNUSED(Tcl_Obj *) /*methodNameObj*/)
{
/* We pull the method name out of context instead of from argument. */
CommonMethErrorHandler(interp, NULL);
}
static void
ConstructorErrorHandler(
Tcl_Interp *interp,
TCL_UNUSED(Tcl_Obj *) /*methodNameObj*/)
{
/* We know this is for the constructor. */
CommonMethErrorHandler(interp, "constructor");
}
static void
DestructorErrorHandler(
Tcl_Interp *interp,
TCL_UNUSED(Tcl_Obj *) /*methodNameObj*/)
{
/* We know this is for the destructor. */
CommonMethErrorHandler(interp, "destructor");
}
/*
* ----------------------------------------------------------------------
*
* DeleteProcedureMethod, CloneProcedureMethod --
*
|
| ︙ | ︙ | |||
1427 1428 1429 1430 1431 1432 1433 |
if (TclListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) {
return NULL;
}
if (prefixLen < 1) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"method forward prefix must be non-empty", TCL_AUTO_LENGTH));
| | | 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 |
if (TclListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) {
return NULL;
}
if (prefixLen < 1) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"method forward prefix must be non-empty", TCL_AUTO_LENGTH));
OO_ERROR(interp, BAD_FORWARD);
return NULL;
}
fmPtr = (ForwardMethod *) Tcl_Alloc(sizeof(ForwardMethod));
fmPtr->prefixObj = prefixObj;
Tcl_IncrRefCount(prefixObj);
return (Method *) TclNewInstanceMethod(interp, (Tcl_Object) oPtr,
|
| ︙ | ︙ | |||
1466 1467 1468 1469 1470 1471 1472 |
if (TclListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) {
return NULL;
}
if (prefixLen < 1) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"method forward prefix must be non-empty", TCL_AUTO_LENGTH));
| | | 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 |
if (TclListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) {
return NULL;
}
if (prefixLen < 1) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"method forward prefix must be non-empty", TCL_AUTO_LENGTH));
OO_ERROR(interp, BAD_FORWARD);
return NULL;
}
fmPtr = (ForwardMethod *) Tcl_Alloc(sizeof(ForwardMethod));
fmPtr->prefixObj = prefixObj;
Tcl_IncrRefCount(prefixObj);
return (Method *) TclNewMethod((Tcl_Class) clsPtr, nameObj,
|
| ︙ | ︙ |
Changes to generic/tclOOProp.c.
| ︙ | ︙ | |||
1005 1006 1007 1008 1009 1010 1011 |
ImplementClassProperty(cls, propName, readable, writable);
}
return TCL_OK;
badProp:
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad property name \"%s\": %s", name, reason));
| | | 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 |
ImplementClassProperty(cls, propName, readable, writable);
}
return TCL_OK;
badProp:
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad property name \"%s\": %s", name, reason));
OO_ERROR(interp, PROPERTY_FORMAT);
return TCL_ERROR;
}
/*
* ----------------------------------------------------------------------
*
* TclOODefinePropertyCmd --
|
| ︙ | ︙ | |||
1048 1049 1050 1051 1052 1053 1054 |
if (oPtr == NULL) {
return TCL_ERROR;
}
if (!useInstance && !oPtr->classPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
| | | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 |
if (oPtr == NULL) {
return TCL_ERROR;
}
if (!useInstance && !oPtr->classPtr) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"attempt to misuse API", TCL_AUTO_LENGTH));
OO_ERROR(interp, MONKEY_BUSINESS);
return TCL_ERROR;
}
for (i = 1; i < objc; i++) {
Tcl_Obj *propObj = objv[i], *nextObj, *argObj, *hyphenated;
Tcl_Obj *getterScript = NULL, *setterScript = NULL;
|
| ︙ | ︙ |
Changes to generic/tclOOStubInit.c.
| ︙ | ︙ | |||
31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
TclOONewProcInstanceMethodEx, /* 9 */
TclOONewProcMethodEx, /* 10 */
TclOOInvokeObject, /* 11 */
TclOOObjectSetFilters, /* 12 */
TclOOClassSetFilters, /* 13 */
TclOOObjectSetMixins, /* 14 */
TclOOClassSetMixins, /* 15 */
};
static const TclOOStubHooks tclOOStubHooks = {
&tclOOIntStubs
};
const TclOOStubs tclOOStubs = {
| > > | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
TclOONewProcInstanceMethodEx, /* 9 */
TclOONewProcMethodEx, /* 10 */
TclOOInvokeObject, /* 11 */
TclOOObjectSetFilters, /* 12 */
TclOOClassSetFilters, /* 13 */
TclOOObjectSetMixins, /* 14 */
TclOOClassSetMixins, /* 15 */
TclOOMakeProcInstanceMethod2, /* 16 */
TclOOMakeProcMethod2, /* 17 */
};
static const TclOOStubHooks tclOOStubHooks = {
&tclOOIntStubs
};
const TclOOStubs tclOOStubs = {
|
| ︙ | ︙ |
Changes to generic/tclProc.c.
| ︙ | ︙ | |||
2620 2621 2622 2623 2624 2625 2626 |
Tcl_Obj **nsObjPtrPtr)
{
Proc *procPtr;
Tcl_Obj *nsObjPtr;
LambdaGetInternalRep(objPtr, procPtr, nsObjPtr);
| | | 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 |
Tcl_Obj **nsObjPtrPtr)
{
Proc *procPtr;
Tcl_Obj *nsObjPtr;
LambdaGetInternalRep(objPtr, procPtr, nsObjPtr);
if (!procPtr || (procPtr->iPtr != (Interp *)interp)) {
if (SetLambdaFromAny(interp, objPtr) != TCL_OK) {
return NULL;
}
LambdaGetInternalRep(objPtr, procPtr, nsObjPtr);
}
assert(procPtr != NULL);
|
| ︙ | ︙ |
Changes to generic/tclScan.c.
| ︙ | ︙ | |||
704 705 706 707 708 709 710 |
} else if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */
char *formatEnd;
/* Note currently XPG3 range limited to INT_MAX to match type of objc */
value = strtoul(format-1, &formatEnd, 10);/* INTL: "C" locale. */
if (*formatEnd == '$') {
format = formatEnd+1;
format += TclUtfToUniChar(format, &ch);
| | | > > > > > > > > > > > | > | 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 |
} else if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */
char *formatEnd;
/* Note currently XPG3 range limited to INT_MAX to match type of objc */
value = strtoul(format-1, &formatEnd, 10);/* INTL: "C" locale. */
if (*formatEnd == '$') {
format = formatEnd+1;
format += TclUtfToUniChar(format, &ch);
objIndex = (int)value - 1;
}
}
/*
* Parse any width specifier.
*/
if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */
unsigned long long ull;
ull = strtoull(format-1, (char **)&format, 10); /* INTL: "C" locale. */
assert(ull <= TCL_SIZE_MAX); /* Else ValidateFormat should've error'ed */
width = (Tcl_Size)ull;
format += TclUtfToUniChar(format, &ch);
} else {
width = 0;
}
/*
* Handle any size specifier.
*/
switch (ch) {
case 'z':
case 't':
if (sizeof(void *) > sizeof(int)) {
flags |= SCAN_LONGER;
}
format += TclUtfToUniChar(format, &ch);
break;
case 'L':
flags |= SCAN_BIG;
format += TclUtfToUniChar(format, &ch);
break;
case 'l':
if (*format == 'l') {
flags |= SCAN_BIG;
format += 1;
format += TclUtfToUniChar(format, &ch);
break;
}
/* FALLTHRU */
case 'j':
case 'q':
flags |= SCAN_LONGER;
/* FALLTHRU */
case 'h':
format += TclUtfToUniChar(format, &ch);
}
/*
|
| ︙ | ︙ |
Changes to generic/tclStubLib.c.
| ︙ | ︙ | |||
56 57 58 59 60 61 62 |
int exact,
int magic)
{
Interp *iPtr = (Interp *)interp;
const char *actualVersion = NULL;
void *pkgData = NULL;
const TclStubs *stubsPtr = iPtr->stubTable;
| | > | < > > | > > > > > > > > > > > > > > > > > > > | | > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
int exact,
int magic)
{
Interp *iPtr = (Interp *)interp;
const char *actualVersion = NULL;
void *pkgData = NULL;
const TclStubs *stubsPtr = iPtr->stubTable;
const char *tclName = "tcl";
if ((exact&0xFF00) < 0x900) {
magic = (int)0xFCA3BACF; /* TCL_STUB_MAGIC from Tcl 8.x */
tclName = "Tcl";
}
/*
* We can't optimize this check by caching tclStubsPtr because that
* prevents apps from being able to load/unload Tcl dynamically multiple
* times. [Bug 615304]
*/
if (!stubsPtr || (stubsPtr->magic != magic)) {
exact &= 0xFFFF00; /* Filter out minor/major Tcl version */
if (!exact) {
exact = 0x060800;
}
if (stubsPtr && (stubsPtr->magic == TCL_STUB_MAGIC)
&& ((exact|0x010000) == 0x070800)) {
/* We are running in Tcl 9.x, but extension is compiled with 8.6 or 8.7 */
stubsPtr->tcl_SetObjResult(interp, stubsPtr->tcl_ObjPrintf(
"this extension is compiled for Tcl %d.%d",
(exact & 0x0FF00)>>8, (exact & 0x0FF0000)>>16));
} else if (stubsPtr && (stubsPtr->magic == (int)0xFCA3BACF)
&& ((exact & 0x0FF00) >= 0x0900)) {
/* We are running in Tcl 8.x, but extension is compiled with 9.0+ */
char major[4], minor[4];
snprintf(major, sizeof(major), "%d", (exact & 0xFF00)>>8);
snprintf(minor, sizeof(minor), "%d", (exact & 0xFF0000)>>16);
stubsPtr->tcl_AppendResult(interp,
"this extension is compiled for Tcl ", major, ".", minor, (char *)NULL);
} else {
iPtr->legacyResult = "interpreter uses an incompatible stubs mechanism";
iPtr->legacyFreeProc = 0; /* TCL_STATIC */
}
return NULL;
}
actualVersion = stubsPtr->tcl_PkgRequireEx(interp, tclName, version, 0, &pkgData);
if (actualVersion == NULL) {
return NULL;
}
|
| ︙ | ︙ |
Changes to generic/tclUtf.c.
| ︙ | ︙ | |||
14 15 16 17 18 19 20 | /* * Include the static character classification tables and macros. */ #include "tclUniData.c" /* | | | | | > | | | | | | | | | | | | | | | > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
/*
* Include the static character classification tables and macros.
*/
#include "tclUniData.c"
/*
* The following masks are used for fast character category tests. The x_BITS
* values are shifted right by the category value to determine whether the
* given category is included in the set.
*/
enum UnicodeCharacterCategoryMasks {
ALPHA_BITS = (1 << UPPERCASE_LETTER) | (1 << LOWERCASE_LETTER) |
(1 << TITLECASE_LETTER) | (1 << MODIFIER_LETTER) |
(1 << OTHER_LETTER),
CONTROL_BITS = (1 << CONTROL) | (1 << FORMAT),
DIGIT_BITS = (1 << DECIMAL_DIGIT_NUMBER),
SPACE_BITS = (1 << SPACE_SEPARATOR) | (1 << LINE_SEPARATOR) |
(1 << PARAGRAPH_SEPARATOR),
WORD_BITS = ALPHA_BITS | DIGIT_BITS | (1 << CONNECTOR_PUNCTUATION),
PUNCT_BITS = (1 << CONNECTOR_PUNCTUATION) |
(1 << DASH_PUNCTUATION) | (1 << OPEN_PUNCTUATION) |
(1 << CLOSE_PUNCTUATION) | (1 << INITIAL_QUOTE_PUNCTUATION) |
(1 << FINAL_QUOTE_PUNCTUATION) | (1 << OTHER_PUNCTUATION),
GRAPH_BITS = WORD_BITS | PUNCT_BITS |
(1 << NON_SPACING_MARK) | (1 << ENCLOSING_MARK) |
(1 << COMBINING_SPACING_MARK) | (1 << LETTER_NUMBER) |
(1 << OTHER_NUMBER) |
(1 << MATH_SYMBOL) | (1 << CURRENCY_SYMBOL) |
(1 << MODIFIER_SYMBOL) | (1 << OTHER_SYMBOL)
};
/*
* Unicode characters less than this value are represented by themselves in
* UTF-8 strings.
*/
#define UNICODE_SELF 0x80
|
| ︙ | ︙ |
Changes to generic/tclUtil.c.
| ︙ | ︙ | |||
53 54 55 56 57 58 59 | * are for internal use only. Make sure they do not overlap with the public * values above. * * The Tcl*Scan*Element() routines make a determination which of 4 modes of * conversion is most appropriate for Tcl*Convert*Element() to perform, and * sets two bits of the flags value to indicate the mode selected. * | < < < < < < < < < < < < < < < < < < < < < < < < < < < | | > > > > > | > | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > | > | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
* are for internal use only. Make sure they do not overlap with the public
* values above.
*
* The Tcl*Scan*Element() routines make a determination which of 4 modes of
* conversion is most appropriate for Tcl*Convert*Element() to perform, and
* sets two bits of the flags value to indicate the mode selected.
*
* For more details, see the comments on the Tcl*Scan*Element and
* Tcl*Convert*Element routines.
*/
enum ConvertFlags {
CONVERT_NONE = 0, /* The element needs no quoting. Its literal
* string is suitable as is. */
DONT_USE_BRACES = TCL_DONT_USE_BRACES,
/* The caller is insisting that brace quoting
* not be used when converting the list
* element. */
CONVERT_BRACE = 2, /* The conversion should be enclosing the
* literal string in braces. */
CONVERT_ESCAPE = 4, /* The conversion should be using backslashes
* to escape any characters in the string that
* require it. */
DONT_QUOTE_HASH = TCL_DONT_QUOTE_HASH,
/* The caller insists that a leading hash
* character ('#') should *not* be quoted. This
* is appropriate when the caller can guarantee
* the element is not the first element of a
* list, so [eval] cannot mis-parse the element
* as a comment.*/
CONVERT_MASK = CONVERT_BRACE | CONVERT_ESCAPE,
/* A mask value used to extract the conversion
* mode from the flags argument.
*
* Also indicates a strange conversion mode
* where all special characters are escaped
* with backslashes *except for braces*. This
* is a strange and unnecessary case, but it's
* part of the historical way in which lists
* have been formatted in Tcl. To experiment
* with removing this case, define the value of
* COMPAT to be 0. */
CONVERT_ANY = 16 /* The caller of TclScanElement() declares it
* can make no promise about what public flags
* will be passed to the matching call of
* TclConvertElement(). As such,
* TclScanElement() has to determine the worst
* case destination buffer length over all
* possibilities, and in other cases this means
* an overestimate of the required size.
*
* Used only by callers of TclScanElement().
* The flag value produced by a call to
* Tcl*Scan*Element() will never leave this
* bit set. */
};
#ifndef COMPAT
#define COMPAT 1
#endif
/*
* Prototypes for functions defined later in this file.
*/
static void ClearHash(Tcl_HashTable *tablePtr);
static void FreeProcessGlobalValue(void *clientData);
|
| ︙ | ︙ | |||
1061 1062 1063 1064 1065 1066 1067 |
* the element #{a"b} like this:
* {#{a"b}}
* and not like this:
* \#{a\"b}
* This is inconsistent with [list x{a"b}], but we will not change that now.
* Set that preference here so that we compute a tight size requirement.
*/
| | | 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 |
* the element #{a"b} like this:
* {#{a"b}}
* and not like this:
* \#{a\"b}
* This is inconsistent with [list x{a"b}], but we will not change that now.
* Set that preference here so that we compute a tight size requirement.
*/
if ((*src == '#') && !(*flagPtr & DONT_QUOTE_HASH)) {
preferBrace = 1;
}
#endif
if ((*p == '{') || (*p == '"')) {
/*
* Must escape or protect so leading character of value is not
|
| ︙ | ︙ | |||
1200 1201 1202 1203 1204 1205 1206 | bytesNeeded += extra; /* * Make room to escape leading #, if needed. */ | | | | | | | | | 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 |
bytesNeeded += extra;
/*
* Make room to escape leading #, if needed.
*/
if ((*src == '#') && !(*flagPtr & DONT_QUOTE_HASH)) {
bytesNeeded++;
}
*flagPtr = CONVERT_ESCAPE;
return bytesNeeded;
}
if (*flagPtr & CONVERT_ANY) {
/*
* The caller has not let us know what flags it will pass to
* TclConvertElement() so compute the max size we might need for any
* possible choice. Normally the formatting using escape sequences is
* the longer one, and a minimum "extra" value of 2 makes sure we
* don't request too small a buffer in those edge cases where that's
* not true.
*/
if (extra < 2) {
extra = 2;
}
*flagPtr &= ~CONVERT_ANY;
*flagPtr |= DONT_USE_BRACES;
}
if (forbidNone) {
/*
* We must request some form of quoting of escaping...
*/
#if COMPAT
if (preferEscape && !preferBrace) {
/*
* If we are quoting solely due to ] or internal " characters use
* the CONVERT_MASK mode where we escape all special characters
* except for braces. "extra" counted space needed to escape
* braces too, so subtract "braceCount" to get our actual needs.
*/
bytesNeeded += (extra - braceCount);
/* Make room to escape leading #, if needed. */
if ((*src == '#') && !(*flagPtr & DONT_QUOTE_HASH)) {
bytesNeeded++;
}
/*
* If the caller reports it will direct TclConvertElement() to
* use full escapes on the element, add back the bytes needed to
* escape the braces.
*/
if (*flagPtr & DONT_USE_BRACES) {
bytesNeeded += braceCount;
}
*flagPtr = CONVERT_MASK;
return bytesNeeded;
}
#endif /* COMPAT */
if (*flagPtr & DONT_USE_BRACES) {
/*
* If the caller reports it will direct TclConvertElement() to
* use escapes, add the extra bytes needed to have room for them.
*/
bytesNeeded += extra;
/*
* Make room to escape leading #, if needed.
*/
if ((*src == '#') && !(*flagPtr & DONT_QUOTE_HASH)) {
bytesNeeded++;
}
} else {
/*
* Add 2 bytes for room for the enclosing braces.
*/
bytesNeeded += 2;
}
*flagPtr = CONVERT_BRACE;
return bytesNeeded;
}
/*
* So far, no need to quote or escape anything.
*/
if ((*src == '#') && !(*flagPtr & DONT_QUOTE_HASH)) {
/*
* If we need to quote a leading #, make room to enclose in braces.
*/
bytesNeeded += 2;
}
*flagPtr = CONVERT_NONE;
|
| ︙ | ︙ | |||
1394 1395 1396 1397 1398 1399 1400 |
int conversion = flags & CONVERT_MASK;
char *p = dst;
/*
* Let the caller demand we use escape sequences rather than braces.
*/
| | | | 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 |
int conversion = flags & CONVERT_MASK;
char *p = dst;
/*
* Let the caller demand we use escape sequences rather than braces.
*/
if ((flags & DONT_USE_BRACES) && (conversion & CONVERT_BRACE)) {
conversion = CONVERT_ESCAPE;
}
/*
* No matter what the caller demands, empty string must be braced!
*/
if ((src == NULL) || (length == 0) || (*src == '\0' && length == TCL_INDEX_NONE)) {
p[0] = '{';
p[1] = '}';
return 2;
}
/*
* Escape leading hash as needed and requested.
*/
if ((*src == '#') && !(flags & DONT_QUOTE_HASH)) {
if (conversion == CONVERT_ESCAPE) {
p[0] = '\\';
p[1] = '#';
p += 2;
src++;
length -= (length > 0);
} else {
|
| ︙ | ︙ | |||
1596 1597 1598 1599 1600 1601 1602 |
if (argc <= LOCAL_SIZE) {
flagPtr = localFlags;
} else {
flagPtr = (char *)Tcl_Alloc(argc);
}
for (i = 0; i < argc; i++) {
| | | | 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 |
if (argc <= LOCAL_SIZE) {
flagPtr = localFlags;
} else {
flagPtr = (char *)Tcl_Alloc(argc);
}
for (i = 0; i < argc; i++) {
flagPtr[i] = ( i ? DONT_QUOTE_HASH : 0 );
bytesNeeded += TclScanElement(argv[i], TCL_INDEX_NONE, &flagPtr[i]);
}
bytesNeeded += argc;
/*
* Pass two: copy into the result area.
*/
result = (char *)Tcl_Alloc(bytesNeeded);
dst = result;
for (i = 0; i < argc; i++) {
flagPtr[i] |= ( i ? DONT_QUOTE_HASH : 0 );
dst += TclConvertElement(argv[i], TCL_INDEX_NONE, dst, flagPtr[i]);
*dst = ' ';
dst++;
}
dst[-1] = 0;
if (flagPtr != localFlags) {
|
| ︙ | ︙ | |||
2730 2731 2732 2733 2734 2735 2736 |
while ((--dst >= dsPtr->string) && TclIsSpaceProcM(*dst)) {
}
/* Call again without whitespace to confound things. */
quoteHash = !TclNeedSpace(dsPtr->string, dst+1);
}
if (!quoteHash) {
| | | | 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 |
while ((--dst >= dsPtr->string) && TclIsSpaceProcM(*dst)) {
}
/* Call again without whitespace to confound things. */
quoteHash = !TclNeedSpace(dsPtr->string, dst+1);
}
if (!quoteHash) {
flags |= DONT_QUOTE_HASH;
}
newSize = dsPtr->length + needSpace + TclScanElement(element, TCL_INDEX_NONE, &flags);
if (!quoteHash) {
flags |= DONT_QUOTE_HASH;
}
/*
* Allocate a larger buffer for the string if the current one isn't large
* enough. Allocate extra space in the new buffer so that there will be
* room to grow before we have to allocate again. SPECIAL NOTE: must use
* memcpy, not strcpy, to copy the string to a larger buffer, since there
|
| ︙ | ︙ |
Changes to generic/tclZipfs.c.
| ︙ | ︙ | |||
52 53 54 55 56 57 58 |
} \
} while (0)
#define ZIPFS_MEM_ERROR(interp) \
do { \
if (interp) { \
Tcl_SetObjResult(interp, Tcl_NewStringObj( \
"out of memory", -1)); \
| | | > | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
} \
} while (0)
#define ZIPFS_MEM_ERROR(interp) \
do { \
if (interp) { \
Tcl_SetObjResult(interp, Tcl_NewStringObj( \
"out of memory", -1)); \
Tcl_SetErrorCode(interp, "TCL", "MALLOC", (char *)NULL); \
} \
} while (0)
#define ZIPFS_POSIX_ERROR(interp,errstr) \
do { \
if (interp) { \
Tcl_SetObjResult(interp, Tcl_ObjPrintf( \
"%s: %s", errstr, Tcl_PosixError(interp))); \
} \
} while (0)
#define ZIPFS_ERROR_CODE(interp,errcode) \
do { \
if (interp) { \
Tcl_SetErrorCode(interp, \
"TCL", "ZIPFS", errcode, (char *)NULL); \
} \
} while (0)
#include "zlib.h"
#include "crypt.h"
#include "zutil.h"
#include "crc32.h"
|
| ︙ | ︙ | |||
96 97 98 99 100 101 102 103 | * Various constants and offsets found in ZIP archive files */ #define ZIP_SIG_LEN 4 /* * Local header of ZIP archive member (at very beginning of each member). */ | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | > > > > > > > > > > | | | | | | | | | | | < | > > > > > > | > > > > > > > > > > > > > > > > > > > < < < < < < < < < < < < < < < < < < > > | < < | | | | | | | > > > > > > > > > > > > > > > > > > | > | | > | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
* Various constants and offsets found in ZIP archive files
*/
#define ZIP_SIG_LEN 4
/*
* Local header of ZIP archive member (at very beginning of each member).
* C can't express this structure type even close to portably (thanks for
* nothing, Clang and MSVC).
*/
enum ZipLocalEntryOffsets {
ZIP_LOCAL_SIG_OFFS = 0, /* sig field offset */
ZIP_LOCAL_VERSION_OFFS = 4, /* version field offset */
ZIP_LOCAL_FLAGS_OFFS = 6, /* flags field offset */
ZIP_LOCAL_COMPMETH_OFFS = 8, /* compMethod field offset */
ZIP_LOCAL_MTIME_OFFS = 10, /* modTime field offset */
ZIP_LOCAL_MDATE_OFFS = 12, /* modDate field offset */
ZIP_LOCAL_CRC32_OFFS = 14, /* crc32 field offset */
ZIP_LOCAL_COMPLEN_OFFS = 18, /* compLen field offset */
ZIP_LOCAL_UNCOMPLEN_OFFS = 22, /* uncompLen field offset */
ZIP_LOCAL_PATHLEN_OFFS = 26, /* pathLen field offset */
ZIP_LOCAL_EXTRALEN_OFFS = 28, /* extraLen field offset */
ZIP_LOCAL_HEADER_LEN = 30 /* header part length */
};
#if 0
/* Recent enough GCC can do this. */
#define PACKED_LITTLE_ENDIAN \
__attribute__((packed, scalar_storage_order("little-endian")))
#else
#undef PACKED_LITTLE_ENDIAN /* Really don't support this yet! */
#endif
#ifdef PACKED_LITTLE_ENDIAN
/*
* Local header of ZIP archive member (at very beginning of each member).
*/
struct PACKED_LITTLE_ENDIAN ZipLocalEntry {
uint32_t sig; // == ZIP_LOCAL_HEADER_SIG
uint16_t version;
uint16_t flags;
uint16_t compMethod;
uint16_t modTime;
uint16_t modDate;
uint32_t crc32;
uint32_t compLen;
uint32_t uncompLen;
uint16_t pathLen;
uint16_t extraLen;
};
#endif
#define ZIP_LOCAL_HEADER_SIG 0x04034b50
enum ZipLocalFlags {
ZIP_LOCAL_FLAGS_UTF8 = 0x0800
};
/*
* Central header of ZIP archive member at end of ZIP file.
* C can't express this structure type even close to portably (thanks for
* nothing, Clang and MSVC).
*/
enum ZipCentralEntryOffsets {
ZIP_CENTRAL_SIG_OFFS = 0, /* sig field offset */
ZIP_CENTRAL_VERSIONMADE_OFFS = 4, /* versionMade field offset */
ZIP_CENTRAL_VERSION_OFFS = 6, /* version field offset */
ZIP_CENTRAL_FLAGS_OFFS = 8, /* flags field offset */
ZIP_CENTRAL_COMPMETH_OFFS = 10, /* compMethod field offset */
ZIP_CENTRAL_MTIME_OFFS = 12, /* modTime field offset */
ZIP_CENTRAL_MDATE_OFFS = 14, /* modDate field offset */
ZIP_CENTRAL_CRC32_OFFS = 16, /* crc32 field offset */
ZIP_CENTRAL_COMPLEN_OFFS = 20, /* compLen field offset */
ZIP_CENTRAL_UNCOMPLEN_OFFS = 24, /* uncompLen field offset */
ZIP_CENTRAL_PATHLEN_OFFS = 28, /* pathLen field offset */
ZIP_CENTRAL_EXTRALEN_OFFS = 30, /* extraLen field offset */
ZIP_CENTRAL_FCOMMENTLEN_OFFS = 32, /* commentLen field offset */
ZIP_CENTRAL_DISKFILE_OFFS = 34, /* diskFile field offset */
ZIP_CENTRAL_IATTR_OFFS = 36, /* intAttr field offset */
ZIP_CENTRAL_EATTR_OFFS = 38, /* extAttr field offset */
ZIP_CENTRAL_LOCALHDR_OFFS = 42, /* localHeaderOffset field offset */
ZIP_CENTRAL_HEADER_LEN = 46 /* header part length */
};
#ifdef PACKED_LITTLE_ENDIAN
/*
* Central header of ZIP archive member at end of ZIP file.
*/
struct PACKED_LITTLE_ENDIAN ZipCentralEntry {
uint32_t sig; // == ZIP_CENTRAL_HEADER_SIG
uint16_t versionMade;
uint16_t version;
uint16_t flags;
uint16_t compMethod;
uint16_t modTime;
uint16_t modDate;
uint32_t crc32;
uint32_t compLen;
uint32_t uncompLen;
uint16_t pathLen;
uint16_t extraLen;
uint16_t commentLen;
uint16_t diskFile;
uint16_t intAttr;
uint32_t extAttr;
uint32_t localHeaderOffset;
};
#endif
#define ZIP_CENTRAL_HEADER_SIG 0x02014b50
/*
* Central end signature at very end of ZIP file.
* C can't express this structure type even close to portably (thanks for
* nothing, Clang and MSVC).
*/
enum ZipCentralMainOffsets {
ZIP_CENTRAL_END_SIG_OFFS = 0, /* sig field offset */
ZIP_CENTRAL_DISKNO_OFFS = 4, /* diskNum field offset */
ZIP_CENTRAL_DISKDIR_OFFS = 6, /* diskDir field offset */
ZIP_CENTRAL_ENTS_OFFS = 8, /* entriesOffset field offset */
ZIP_CENTRAL_TOTALENTS_OFFS = 10, /* totalEntries field offset */
ZIP_CENTRAL_DIRSIZE_OFFS = 12, /* dirSize field offset */
ZIP_CENTRAL_DIRSTART_OFFS = 16, /* dirStart field offset */
ZIP_CENTRAL_COMMENTLEN_OFFS = 20, /* commentLen field offset */
ZIP_CENTRAL_END_LEN = 22 /* header part length */
};
#ifdef PACKED_LITTLE_ENDIAN
/*
* Central end signature at very end of ZIP file.
*/
struct PACKED_LITTLE_ENDIAN ZipCentralMain {
uint32_t sig; // == ZIP_CENTRAL_END_SIG
uint16_t diskNum;
uint16_t diskDir;
uint16_t entriesOffset;
uint16_t totalEntries;
uint32_t dirSize;
uint32_t dirStart;
uint16_t commentLen;
}
#endif
#define ZIP_CENTRAL_END_SIG 0x06054b50
#define ZIP_MIN_VERSION 20
enum ZipCompressionMethods {
ZIP_COMPMETH_STORED = 0,
ZIP_COMPMETH_DEFLATED = 8
};
#define ZIP_PASSWORD_END_SIG 0x5a5a4b50
#define ZIP_CRYPT_HDR_LEN 12
#define ZIP_MAX_FILE_SIZE INT_MAX
#define DEFAULT_WRITE_MAX_SIZE ZIP_MAX_FILE_SIZE
|
| ︙ | ︙ | |||
193 194 195 196 197 198 199 |
unsigned char *data; /* Memory mapped or malloc'ed file */
size_t length; /* Length of memory mapped file */
void *ptrToFree; /* Non-NULL if malloc'ed file */
size_t numFiles; /* Number of files in archive */
size_t baseOffset; /* Archive start */
size_t passOffset; /* Password start */
size_t directoryOffset; /* Archive directory start */
| | | | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
unsigned char *data; /* Memory mapped or malloc'ed file */
size_t length; /* Length of memory mapped file */
void *ptrToFree; /* Non-NULL if malloc'ed file */
size_t numFiles; /* Number of files in archive */
size_t baseOffset; /* Archive start */
size_t passOffset; /* Password start */
size_t directoryOffset; /* Archive directory start */
size_t directorySize; /* Size of archive directory */
unsigned char passBuf[264]; /* Password buffer */
size_t numOpen; /* Number of open files on archive */
struct ZipEntry *entries; /* List of files in archive */
struct ZipEntry *topEnts; /* List of top-level dirs in archive */
char *mountPoint; /* Mount point name */
Tcl_Size mountPointLen; /* Length of mount point name */
#ifdef _WIN32
HANDLE mountHandle; /* Handle used for direct file access. */
|
| ︙ | ︙ | |||
223 224 225 226 227 228 229 |
* -1 for zip64 */
int compressMethod; /* Compress method */
int isDirectory; /* 0 if file, 1 if directory, -1 if root */
int depth; /* Number of slashes in path. */
int crc32; /* CRC-32 as stored in ZIP */
int timestamp; /* Modification time */
int isEncrypted; /* True if data is encrypted */
| | < < < > > > > > > | 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
* -1 for zip64 */
int compressMethod; /* Compress method */
int isDirectory; /* 0 if file, 1 if directory, -1 if root */
int depth; /* Number of slashes in path. */
int crc32; /* CRC-32 as stored in ZIP */
int timestamp; /* Modification time */
int isEncrypted; /* True if data is encrypted */
int flags; /* See ZipEntryFlags for bit definitions. */
unsigned char *data; /* File data if written */
struct ZipEntry *next; /* Next file in the same archive */
struct ZipEntry *tnext; /* Next top-level dir in archive */
} ZipEntry;
enum ZipEntryFlags {
ZE_F_CRC_COMPARED = 1, /* If 1, the CRC has been compared. */
ZE_F_CRC_CORRECT = 2, /* Only meaningful if ZE_F_CRC_COMPARED is 1 */
ZE_F_VOLUME = 4 /* Entry corresponds to //zipfs:/ */
};
/*
* File channel for file contained in mounted ZIP archive.
*
* Regarding data buffers:
* For READ-ONLY files that are not encrypted and not compressed (zip STORE
* method), ubuf points directly to the mapped zip file data in memory. No
|
| ︙ | ︙ | |||
254 255 256 257 258 259 260 |
typedef struct ZipChannel {
ZipFile *zipFilePtr; /* The ZIP file holding this channel */
ZipEntry *zipEntryPtr; /* Pointer back to virtual file */
Tcl_Size maxWrite; /* Maximum size for write */
Tcl_Size numBytes; /* Number of bytes of uncompressed data */
Tcl_Size cursor; /* Seek position for next read or write*/
unsigned char *ubuf; /* Pointer to the uncompressed data */
| | | | | | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
typedef struct ZipChannel {
ZipFile *zipFilePtr; /* The ZIP file holding this channel */
ZipEntry *zipEntryPtr; /* Pointer back to virtual file */
Tcl_Size maxWrite; /* Maximum size for write */
Tcl_Size numBytes; /* Number of bytes of uncompressed data */
Tcl_Size cursor; /* Seek position for next read or write*/
unsigned char *ubuf; /* Pointer to the uncompressed data */
unsigned char *ubufToFree; /* NULL if ubuf points to memory that does not
* need freeing. Else memory to free (ubuf
* may point *inside* the block) */
Tcl_Size ubufSize; /* Size of allocated ubufToFree */
int iscompr; /* True if data is compressed */
int isDirectory; /* Set to 1 if directory, or -1 if root */
int isEncrypted; /* True if data is encrypted */
int mode; /* O_WRITE, O_APPEND, O_TRUNC etc.*/
unsigned long keys[3]; /* Key for decryption */
} ZipChannel;
static inline int
|
| ︙ | ︙ | |||
332 333 334 335 336 337 338 | static int ListMountPoints(Tcl_Interp *interp); static int ContainsMountPoint(const char *path, int pathLen); static void CleanupMount(ZipFile *zf); static Tcl_Obj * ScriptLibrarySetup(const char *dirName); static void SerializeCentralDirectoryEntry( const unsigned char *start, const unsigned char *end, unsigned char *buf, | | > | > | 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | static int ListMountPoints(Tcl_Interp *interp); static int ContainsMountPoint(const char *path, int pathLen); static void CleanupMount(ZipFile *zf); static Tcl_Obj * ScriptLibrarySetup(const char *dirName); static void SerializeCentralDirectoryEntry( const unsigned char *start, const unsigned char *end, unsigned char *buf, ZipEntry *z, size_t nameLength, long long dataStartOffset); static void SerializeCentralDirectorySuffix( const unsigned char *start, const unsigned char *end, unsigned char *buf, int entryCount, long long dataStartOffset, long long directoryStartOffset, long long suffixStartOffset); static void SerializeLocalEntryHeader( const unsigned char *start, const unsigned char *end, unsigned char *buf, ZipEntry *z, int nameLength, int align); static int IsCryptHeaderValid(ZipEntry *z, unsigned char cryptHdr[ZIP_CRYPT_HDR_LEN]); |
| ︙ | ︙ | |||
1242 1243 1244 1245 1246 1247 1248 |
int lenz = (int) strlen(z->name);
if ((lenz >= pathLen) &&
(z->name[pathLen] == '/' || z->name[pathLen] == '\0') &&
(strncmp(z->name, path, pathLen) == 0)) {
return 1;
}
}
| | | | | | | 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 |
int lenz = (int) strlen(z->name);
if ((lenz >= pathLen) &&
(z->name[pathLen] == '/' || z->name[pathLen] == '\0') &&
(strncmp(z->name, path, pathLen) == 0)) {
return 1;
}
}
} else if ((zf->mountPointLen >= pathLen)
&& (zf->mountPoint[pathLen] == '/'
|| zf->mountPoint[pathLen] == '\0'
|| pathLen == ZIPFS_VOLUME_LEN)
&& (strncmp(zf->mountPoint, path, pathLen) == 0)) {
/* Matched standard mount */
return 1;
}
}
return 0;
}
|
| ︙ | ︙ | |||
2372 2373 2374 2375 2376 2377 2378 |
ret = TCL_ERROR;
} else {
ret = ZipFSOpenArchive(interp, normPath, 1, zf);
if (ret != TCL_OK) {
Tcl_Free(zf);
} else {
ret = ZipFSCatalogFilesystem(
| | | 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 |
ret = TCL_ERROR;
} else {
ret = ZipFSOpenArchive(interp, normPath, 1, zf);
if (ret != TCL_OK) {
Tcl_Free(zf);
} else {
ret = ZipFSCatalogFilesystem(
interp, zf, mountPoint, passwd, normPath);
/* Note zf is already freed on error! */
}
}
}
Tcl_DecrRefCount(normZipPathObj);
if (ret == TCL_OK && interp) {
Tcl_DStringResult(interp, &ds);
|
| ︙ | ︙ | |||
2595 2596 2597 2598 2599 2600 2601 |
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
const char *mountPoint = NULL, *zipFile = NULL, *password = NULL;
int result;
if (objc > 4) {
| | < | 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 |
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
const char *mountPoint = NULL, *zipFile = NULL, *password = NULL;
int result;
if (objc > 4) {
Tcl_WrongNumArgs(interp, 1, objv, "?zipfile? ?mountpoint? ?password?");
return TCL_ERROR;
}
/*
* A single argument is treated as the mountpoint. Two arguments
* are treated as zipfile and mountpoint.
*/
if (objc > 1) {
|
| ︙ | ︙ | |||
2894 2895 2896 2897 2898 2899 2900 |
}
/*
* Convert to encoded form. Note that we use strlen() here; if someone's
* crazy enough to embed NULs in filenames, they deserve what they get!
*/
| | > | 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 |
}
/*
* Convert to encoded form. Note that we use strlen() here; if someone's
* crazy enough to embed NULs in filenames, they deserve what they get!
*/
if (Tcl_UtfToExternalDStringEx(interp, tclUtf8Encoding, zpathTcl,
TCL_INDEX_NONE, 0, &zpathDs, NULL) != TCL_OK) {
Tcl_DStringFree(&zpathDs);
return TCL_ERROR;
}
zpathExt = Tcl_DStringValue(&zpathDs);
zpathlen = strlen(zpathExt);
if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
| ︙ | ︙ | |||
3025 3026 3027 3028 3029 3030 3031 |
return TCL_ERROR;
}
kvbuf[i + ZIP_CRYPT_HDR_LEN] = UCHAR(zencode(keys, crc32tab, ch, tmp));
}
Tcl_ResetResult(interp);
init_keys(passwd, keys, crc32tab);
for (i = 0; i < ZIP_CRYPT_HDR_LEN - 2; i++) {
| | > | 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 |
return TCL_ERROR;
}
kvbuf[i + ZIP_CRYPT_HDR_LEN] = UCHAR(zencode(keys, crc32tab, ch, tmp));
}
Tcl_ResetResult(interp);
init_keys(passwd, keys, crc32tab);
for (i = 0; i < ZIP_CRYPT_HDR_LEN - 2; i++) {
kvbuf[i] = UCHAR(zencode(keys, crc32tab,
kvbuf[i + ZIP_CRYPT_HDR_LEN], tmp));
}
kvbuf[i++] = UCHAR(zencode(keys, crc32tab, crc >> 16, tmp));
kvbuf[i++] = UCHAR(zencode(keys, crc32tab, crc >> 24, tmp));
len = Tcl_Write(out, (char *) kvbuf, ZIP_CRYPT_HDR_LEN);
memset(kvbuf, 0, sizeof(kvbuf));
if (len != ZIP_CRYPT_HDR_LEN) {
goto writeErrorWithChannelOpen;
|
| ︙ | ︙ | |||
3276 3277 3278 3279 3280 3281 3282 |
static inline const char *
ComputeNameInArchive(
Tcl_Obj *pathObj, /* The path to the origin file */
Tcl_Obj *directNameObj, /* User-specified name for use in the ZIP
* archive */
const char *strip, /* A prefix to strip; may be NULL if no
* stripping need be done. */
| | | 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 |
static inline const char *
ComputeNameInArchive(
Tcl_Obj *pathObj, /* The path to the origin file */
Tcl_Obj *directNameObj, /* User-specified name for use in the ZIP
* archive */
const char *strip, /* A prefix to strip; may be NULL if no
* stripping need be done. */
Tcl_Size slen) /* The length of the prefix; must be 0 if no
* stripping need be done. */
{
const char *name;
Tcl_Size len;
if (directNameObj) {
name = TclGetString(directNameObj);
|
| ︙ | ︙ | |||
3351 3352 3353 3354 3355 3356 3357 3358 |
Tcl_Obj *passwordObj) /* The password for encoding things. NULL if
* there's no password protection. */
{
Tcl_Channel out;
int count, ret = TCL_ERROR;
Tcl_Size pwlen = 0, slen = 0, len, i = 0;
Tcl_Size lobjc;
long long directoryStartOffset;
| > > | | | 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 |
Tcl_Obj *passwordObj) /* The password for encoding things. NULL if
* there's no password protection. */
{
Tcl_Channel out;
int count, ret = TCL_ERROR;
Tcl_Size pwlen = 0, slen = 0, len, i = 0;
Tcl_Size lobjc;
long long dataStartOffset; /* The overall file offset of the start of the
* data section of the file. */
long long directoryStartOffset;
/* The overall file offset of the start of the
* central directory. */
long long suffixStartOffset;/* The overall file offset of the start of the
* suffix of the central directory (i.e.,
* where this data will be written). */
Tcl_Obj **lobjv, *list = mappingList;
ZipEntry *z;
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
|
| ︙ | ︙ | |||
3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 |
"write error: %s", Tcl_PosixError(interp)));
Tcl_Close(interp, out);
return TCL_ERROR;
}
}
memset(passBuf, 0, sizeof(passBuf));
Tcl_Flush(out);
}
/*
* Prepare the contents of the ZIP archive.
*/
Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS);
| > > > | 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 |
"write error: %s", Tcl_PosixError(interp)));
Tcl_Close(interp, out);
return TCL_ERROR;
}
}
memset(passBuf, 0, sizeof(passBuf));
Tcl_Flush(out);
dataStartOffset = Tcl_Tell(out);
} else {
dataStartOffset = 0;
}
/*
* Prepare the contents of the ZIP archive.
*/
Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS);
|
| ︙ | ︙ | |||
3567 3568 3569 3570 3571 3572 3573 |
hPtr = Tcl_FindHashEntry(&fileHash, name);
if (!hPtr) {
continue;
}
z = (ZipEntry *) Tcl_GetHashValue(hPtr);
| | > | | | 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 |
hPtr = Tcl_FindHashEntry(&fileHash, name);
if (!hPtr) {
continue;
}
z = (ZipEntry *) Tcl_GetHashValue(hPtr);
if (Tcl_UtfToExternalDStringEx(interp, tclUtf8Encoding, z->name,
TCL_INDEX_NONE, 0, &ds, NULL) != TCL_OK) {
ret = TCL_ERROR;
goto done;
}
name = Tcl_DStringValue(&ds);
len = Tcl_DStringLength(&ds);
SerializeCentralDirectoryEntry(start, end, (unsigned char *) buf,
z, len, dataStartOffset);
if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN)
!= ZIP_CENTRAL_HEADER_LEN)
|| (Tcl_Write(out, name, len) != len)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"write error: %s", Tcl_PosixError(interp)));
Tcl_DStringFree(&ds);
goto done;
}
Tcl_DStringFree(&ds);
count++;
}
/*
* Finalize the central directory.
*/
Tcl_Flush(out);
suffixStartOffset = Tcl_Tell(out);
SerializeCentralDirectorySuffix(start, end, (unsigned char *) buf,
count, dataStartOffset, directoryStartOffset, suffixStartOffset);
if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"write error: %s", Tcl_PosixError(interp)));
goto done;
}
Tcl_Flush(out);
ret = TCL_OK;
|
| ︙ | ︙ | |||
3730 3731 3732 3733 3734 3735 3736 |
unsigned char *buf, /* Where to serialize to */
ZipEntry *z, /* The description of what to serialize. */
int nameLength, /* The length of the name. */
int align) /* The number of alignment bytes. */
{
ZipWriteInt(start, end, buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG);
ZipWriteShort(start, end, buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION);
| | > | > > | > | > > > | | 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 |
unsigned char *buf, /* Where to serialize to */
ZipEntry *z, /* The description of what to serialize. */
int nameLength, /* The length of the name. */
int align) /* The number of alignment bytes. */
{
ZipWriteInt(start, end, buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG);
ZipWriteShort(start, end, buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION);
ZipWriteShort(start, end, buf + ZIP_LOCAL_FLAGS_OFFS,
z->isEncrypted + ZIP_LOCAL_FLAGS_UTF8);
ZipWriteShort(start, end, buf + ZIP_LOCAL_COMPMETH_OFFS,
z->compressMethod);
ZipWriteShort(start, end, buf + ZIP_LOCAL_MTIME_OFFS,
ToDosTime(z->timestamp));
ZipWriteShort(start, end, buf + ZIP_LOCAL_MDATE_OFFS,
ToDosDate(z->timestamp));
ZipWriteInt(start, end, buf + ZIP_LOCAL_CRC32_OFFS, z->crc32);
ZipWriteInt(start, end, buf + ZIP_LOCAL_COMPLEN_OFFS,
z->numCompressedBytes);
ZipWriteInt(start, end, buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->numBytes);
ZipWriteShort(start, end, buf + ZIP_LOCAL_PATHLEN_OFFS, nameLength);
ZipWriteShort(start, end, buf + ZIP_LOCAL_EXTRALEN_OFFS, align);
}
static void
SerializeCentralDirectoryEntry(
const unsigned char *start, /* The start of writable memory. */
const unsigned char *end, /* The end of writable memory. */
unsigned char *buf, /* Where to serialize to */
ZipEntry *z, /* The description of what to serialize. */
size_t nameLength, /* The length of the name. */
long long dataStartOffset) /* The overall file offset of the start of the
* data section of the file. */
{
ZipWriteInt(start, end, buf + ZIP_CENTRAL_SIG_OFFS,
ZIP_CENTRAL_HEADER_SIG);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_VERSIONMADE_OFFS,
ZIP_MIN_VERSION);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_FLAGS_OFFS,
z->isEncrypted + ZIP_LOCAL_FLAGS_UTF8);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_COMPMETH_OFFS,
z->compressMethod);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_MTIME_OFFS,
ToDosTime(z->timestamp));
ZipWriteShort(start, end, buf + ZIP_CENTRAL_MDATE_OFFS,
ToDosDate(z->timestamp));
ZipWriteInt(start, end, buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32);
ZipWriteInt(start, end, buf + ZIP_CENTRAL_COMPLEN_OFFS,
z->numCompressedBytes);
ZipWriteInt(start, end, buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->numBytes);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_PATHLEN_OFFS, nameLength);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_DISKFILE_OFFS, 0);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_IATTR_OFFS, 0);
ZipWriteInt(start, end, buf + ZIP_CENTRAL_EATTR_OFFS, 0);
ZipWriteInt(start, end, buf + ZIP_CENTRAL_LOCALHDR_OFFS,
z->offset - dataStartOffset);
}
static void
SerializeCentralDirectorySuffix(
const unsigned char *start, /* The start of writable memory. */
const unsigned char *end, /* The end of writable memory. */
unsigned char *buf, /* Where to serialize to */
int entryCount, /* The number of entries in the directory */
long long dataStartOffset,
/* The overall file offset of the start of the
* data file. */
long long directoryStartOffset,
/* The overall file offset of the start of the
* central directory. */
long long suffixStartOffset)/* The overall file offset of the start of the
* suffix of the central directory (i.e.,
* where this data will be written). */
{
ZipWriteInt(start, end, buf + ZIP_CENTRAL_END_SIG_OFFS,
ZIP_CENTRAL_END_SIG);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_DISKNO_OFFS, 0);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_DISKDIR_OFFS, 0);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_ENTS_OFFS, entryCount);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_TOTALENTS_OFFS, entryCount);
ZipWriteInt(start, end, buf + ZIP_CENTRAL_DIRSIZE_OFFS,
suffixStartOffset - directoryStartOffset);
ZipWriteInt(start, end, buf + ZIP_CENTRAL_DIRSTART_OFFS,
directoryStartOffset - dataStartOffset);
ZipWriteShort(start, end, buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0);
}
/*
*-------------------------------------------------------------------------
*
* ZipFSMkZipObjCmd, ZipFSLMkZipObjCmd --
|
| ︙ | ︙ | |||
3983 3984 3985 3986 3987 3988 3989 |
mntPoint = ZIPFS_VOLUME;
} else {
if (NormalizeMountPoint(interp, Tcl_GetString(objv[1]), &dsMount) != TCL_OK) {
return TCL_ERROR;
}
mntPoint = Tcl_DStringValue(&dsMount);
}
| | < < | | 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 |
mntPoint = ZIPFS_VOLUME;
} else {
if (NormalizeMountPoint(interp, Tcl_GetString(objv[1]), &dsMount) != TCL_OK) {
return TCL_ERROR;
}
mntPoint = Tcl_DStringValue(&dsMount);
}
(void)MapPathToZipfs(interp, mntPoint, Tcl_GetString(objv[objc - 1]),
&dsPath);
Tcl_SetObjResult(interp, Tcl_DStringToObj(&dsPath));
return TCL_OK;
}
/*
*-------------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
4397 4398 4399 4400 4401 4402 4403 |
if (ZipChannelWritable(info)) {
/*
* Copy channel data back into original file in archive.
*/
ZipEntry *z = info->zipEntryPtr;
assert(info->ubufToFree && info->ubuf);
unsigned char *newdata;
| | | | | 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 |
if (ZipChannelWritable(info)) {
/*
* Copy channel data back into original file in archive.
*/
ZipEntry *z = info->zipEntryPtr;
assert(info->ubufToFree && info->ubuf);
unsigned char *newdata;
newdata = (unsigned char *) Tcl_AttemptRealloc(
info->ubufToFree,
info->numBytes ? info->numBytes : 1); /* Bug [23dd83ce7c] */
if (newdata == NULL) {
/* Could not reallocate, keep existing buffer */
newdata = info->ubufToFree;
}
info->ubufToFree = NULL; /* Now newdata! */
info->ubuf = NULL;
info->ubufSize = 0;
|
| ︙ | ︙ | |||
4574 4575 4576 4577 4578 4579 4580 |
Tcl_Size needed = info->cursor + toWrite;
/* Tack on a bit for future growth. */
if (needed < (info->maxWrite - needed/2)) {
needed += needed / 2;
} else {
needed = info->maxWrite;
}
| | | | 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 |
Tcl_Size needed = info->cursor + toWrite;
/* Tack on a bit for future growth. */
if (needed < (info->maxWrite - needed/2)) {
needed += needed / 2;
} else {
needed = info->maxWrite;
}
unsigned char *newBuf = (unsigned char *)
Tcl_AttemptRealloc(info->ubufToFree, needed);
if (newBuf == NULL) {
*errloc = ENOMEM;
return -1;
}
info->ubufToFree = newBuf;
info->ubuf = info->ubufToFree;
info->ubufSize = needed;
|
| ︙ | ︙ | |||
5545 5546 5547 5548 5549 5550 5551 |
return -1;
}
if (types) {
wanted = types->type;
if ((wanted & TCL_GLOB_TYPE_MOUNT) && (wanted != TCL_GLOB_TYPE_MOUNT)) {
if (interp) {
ZIPFS_ERROR(interp,
| | | | 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 |
return -1;
}
if (types) {
wanted = types->type;
if ((wanted & TCL_GLOB_TYPE_MOUNT) && (wanted != TCL_GLOB_TYPE_MOUNT)) {
if (interp) {
ZIPFS_ERROR(interp,
"Internal error: TCL_GLOB_TYPE_MOUNT should not "
"be set in conjunction with other glob types.");
}
return TCL_ERROR;
}
if ((wanted & (TCL_GLOB_TYPE_DIR | TCL_GLOB_TYPE_FILE |
TCL_GLOB_TYPE_MOUNT)) == 0) {
/* Not looking for files,dirs,mounts. zipfs cannot have others */
return TCL_OK;
|
| ︙ | ︙ | |||
6007 6008 6009 6010 6011 6012 6013 |
break;
case ZIP_ATTR_OFFSET:
TclNewIntObj(*objPtrRef, z ? z->offset : 0);
break;
case ZIP_ATTR_MOUNT:
if (z) {
*objPtrRef = Tcl_NewStringObj(z->zipFilePtr->mountPoint,
| | | 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 |
break;
case ZIP_ATTR_OFFSET:
TclNewIntObj(*objPtrRef, z ? z->offset : 0);
break;
case ZIP_ATTR_MOUNT:
if (z) {
*objPtrRef = Tcl_NewStringObj(z->zipFilePtr->mountPoint,
z->zipFilePtr->mountPointLen);
} else {
*objPtrRef = Tcl_NewStringObj("", 0);
}
break;
case ZIP_ATTR_ARCHIVE:
*objPtrRef = Tcl_NewStringObj(z ? z->zipFilePtr->name : "", -1);
break;
|
| ︙ | ︙ |
Changes to library/init.tcl.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 | # # All rights reserved. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # # All rights reserved. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # package require -exact tcl 9.0.2 # Compute the auto path to use in this interpreter. # The values on the path come from several locations: # # The environment variable TCLLIBPATH # # tcl_library, which is the directory containing this init.tcl script. |
| ︙ | ︙ |
Changes to macosx/tclMacOSXBundle.c.
| ︙ | ︙ | |||
13 14 15 16 17 18 19 | #include "tclPort.h" #include "tclInt.h" #ifdef HAVE_COREFOUNDATION #include <CoreFoundation/CoreFoundation.h> | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include "tclPort.h"
#include "tclInt.h"
#ifdef HAVE_COREFOUNDATION
#include <CoreFoundation/CoreFoundation.h>
#include <dlfcn.h>
#ifdef TCL_DEBUG_LOAD
#define TclLoadDbgMsg(m, ...) \
do { \
fprintf(stderr, "%s:%d: %s(): " m ".\n", \
strrchr(__FILE__, '/')+1, __LINE__, __func__, \
##__VA_ARGS__); \
|
| ︙ | ︙ | |||
98 99 100 101 102 103 104 |
OpenResourceMap(
CFBundleRef bundleRef)
{
static int initialized = FALSE;
static short (*openresourcemap)(CFBundleRef) = NULL;
if (!initialized) {
| < < < < < < < < < < < < < < < < < < < | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
OpenResourceMap(
CFBundleRef bundleRef)
{
static int initialized = FALSE;
static short (*openresourcemap)(CFBundleRef) = NULL;
if (!initialized) {
{
openresourcemap = (short (*)(CFBundleRef))dlsym(RTLD_NEXT,
"CFBundleOpenBundleResourceMap");
#ifdef TCL_DEBUG_LOAD
if (!openresourcemap) {
const char *errMsg = dlerror();
TclLoadDbgMsg("dlsym() failed: %s", errMsg);
}
#endif /* TCL_DEBUG_LOAD */
}
initialized = TRUE;
}
if (openresourcemap) {
return openresourcemap(bundleRef);
}
return -1;
|
| ︙ | ︙ | |||
248 249 250 251 252 253 254 |
*/
CFURLGetFileSystemRepresentation(libURL, TRUE,
(unsigned char *) libraryPath, maxPathLen);
CFRelease(libURL);
}
if (versionedBundleRef) {
| < < < < < < < | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
*/
CFURLGetFileSystemRepresentation(libURL, TRUE,
(unsigned char *) libraryPath, maxPathLen);
CFRelease(libURL);
}
if (versionedBundleRef) {
{
CFRelease(versionedBundleRef);
}
}
}
if (libraryPath[0]) {
|
| ︙ | ︙ |
Changes to macosx/tclMacOSXFCmd.c.
| ︙ | ︙ | |||
18 19 20 21 22 23 24 | #include <libkern/OSByteOrder.h> #endif /* Darwin 8 copyfile API. */ #ifdef HAVE_COPYFILE #ifdef HAVE_COPYFILE_H #include <copyfile.h> | < < < < < < < < < < < < < < | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #include <libkern/OSByteOrder.h> #endif /* Darwin 8 copyfile API. */ #ifdef HAVE_COPYFILE #ifdef HAVE_COPYFILE_H #include <copyfile.h> #else /* HAVE_COPYFILE_H */ int copyfile(const char *from, const char *to, void *state, uint32_t flags); #define COPYFILE_ACL (1<<0) #define COPYFILE_XATTR (1<<2) #define COPYFILE_NOFOLLOW_SRC (1<<18) #endif /* HAVE_COPYFILE_H */ #endif /* HAVE_COPYFILE */ #ifdef WEAK_IMPORT_COPYFILE #define MayUseCopyFile() (copyfile != NULL) #elif defined(HAVE_COPYFILE) #define MayUseCopyFile() (1) |
| ︙ | ︙ |
Changes to macosx/tclMacOSXNotify.c.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 | * In macOS 10.12 the os_unfair_lock was introduced as a replacement for the * OSSpinLock, and the OSSpinLock was deprecated. */ #if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 #define USE_OS_UNFAIR_LOCK #include <os/lock.h> | < < < | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | * In macOS 10.12 the os_unfair_lock was introduced as a replacement for the * OSSpinLock, and the OSSpinLock was deprecated. */ #if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 #define USE_OS_UNFAIR_LOCK #include <os/lock.h> #endif #ifdef HAVE_COREFOUNDATION /* Traditional unix select-based notifier is * in tclUnixNotfy.c */ #include <CoreFoundation/CoreFoundation.h> #include <pthread.h> #if !defined(USE_OS_UNFAIR_LOCK) /* * We use the Darwin-native spinlock API rather than pthread mutexes for * notifier locking: this radically simplifies the implementation and lowers * overhead. Note that these are not pure spinlocks, they employ various * strategies to back off and relinquish the processor, making them immune to |
| ︙ | ︙ | |||
50 51 52 53 54 55 56 | #pragma GCC diagnostic ignored "-Wunused-function" /* * Use OSSpinLock API where available (Tiger or later). */ #include <libkern/OSAtomic.h> | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
#pragma GCC diagnostic ignored "-Wunused-function"
/*
* Use OSSpinLock API where available (Tiger or later).
*/
#include <libkern/OSAtomic.h>
/*
* Wrappers so that we get warnings in just one small part of this file.
*/
static inline void
SpinLockLock(
OSSpinLock *lock)
|
| ︙ | ︙ | |||
141 142 143 144 145 146 147 |
}
static inline bool
SpinLockTry(
OSSpinLock *lock)
{
return OSSpinLockTry(lock);
}
| < | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
}
static inline bool
SpinLockTry(
OSSpinLock *lock)
{
return OSSpinLockTry(lock);
}
#define SPINLOCK_INIT OS_SPINLOCK_INIT
#else
/*
* Otherwise, use commpage spinlock SPI directly.
*/
|
| ︙ | ︙ | |||
216 217 218 219 220 221 222 | #define UNLOCK_NOTIFIER_INIT SpinLockUnlock(¬ifierInitLock) #define LOCK_NOTIFIER SpinLockLock(¬ifierLock) #define UNLOCK_NOTIFIER SpinLockUnlock(¬ifierLock) #define LOCK_NOTIFIER_TSD SpinLockLock(&tsdPtr->tsdLock) #define UNLOCK_NOTIFIER_TSD SpinLockUnlock(&tsdPtr->tsdLock) #endif | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
#define UNLOCK_NOTIFIER_INIT SpinLockUnlock(¬ifierInitLock)
#define LOCK_NOTIFIER SpinLockLock(¬ifierLock)
#define UNLOCK_NOTIFIER SpinLockUnlock(¬ifierLock)
#define LOCK_NOTIFIER_TSD SpinLockLock(&tsdPtr->tsdLock)
#define UNLOCK_NOTIFIER_TSD SpinLockUnlock(&tsdPtr->tsdLock)
#endif
/*
* This structure is used to keep track of the notifier info for a registered
* file.
*/
typedef struct FileHandler {
int fd;
|
| ︙ | ︙ | |||
404 405 406 407 408 409 410 |
CFRunLoopTimerRef runLoopTimer;
/* Wakes up CFRunLoop after given timeout when
* running embedded. */
/* End tsdLock section */
CFTimeInterval waitTime; /* runLoopTimer wait time when running
* embedded. */
| < | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
CFRunLoopTimerRef runLoopTimer;
/* Wakes up CFRunLoop after given timeout when
* running embedded. */
/* End tsdLock section */
CFTimeInterval waitTime; /* runLoopTimer wait time when running
* embedded. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
* The following static indicates the number of threads that have initialized
* notifiers.
|
| ︙ | ︙ | |||
516 517 518 519 520 521 522 | int onList, int signalNotifier); #ifdef HAVE_PTHREAD_ATFORK static int atForkInit = 0; static void AtForkPrepare(void); static void AtForkParent(void); static void AtForkChild(void); | < < < < < < < < < < < < < < < < < < < < < < | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | int onList, int signalNotifier); #ifdef HAVE_PTHREAD_ATFORK static int atForkInit = 0; static void AtForkPrepare(void); static void AtForkParent(void); static void AtForkChild(void); #endif /* HAVE_PTHREAD_ATFORK */ /* *---------------------------------------------------------------------- * * LookUpFileHandler -- * |
| ︙ | ︙ | |||
702 703 704 705 706 707 708 |
LOCK_NOTIFIER_INIT;
#ifdef HAVE_PTHREAD_ATFORK
/*
* Install pthread_atfork handlers to reinitialize the notifier in the
* child of a fork.
*/
| | | 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
LOCK_NOTIFIER_INIT;
#ifdef HAVE_PTHREAD_ATFORK
/*
* Install pthread_atfork handlers to reinitialize the notifier in the
* child of a fork.
*/
if (!atForkInit) {
int result = pthread_atfork(AtForkPrepare, AtForkParent, AtForkChild);
if (result) {
Tcl_Panic("Tcl_InitNotifier: %s", "pthread_atfork failed");
}
atForkInit = 1;
}
|
| ︙ | ︙ | |||
745 746 747 748 749 750 751 | /* * Create notifier thread lazily in Tcl_WaitForEvent() to avoid * interfering with fork() followed immediately by execve() (we cannot * execve() when more than one thread is present). */ notifierThreadRunning = 0; | < < | 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 |
/*
* Create notifier thread lazily in Tcl_WaitForEvent() to avoid
* interfering with fork() followed immediately by execve() (we cannot
* execve() when more than one thread is present).
*/
notifierThreadRunning = 0;
}
notifierCount++;
UNLOCK_NOTIFIER_INIT;
return tsdPtr;
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
869 870 871 872 873 874 875 |
TclpFinalizeNotifier(
TCL_UNUSED(void *))
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
LOCK_NOTIFIER_INIT;
notifierCount--;
| < | 694 695 696 697 698 699 700 701 702 703 704 705 706 707 |
TclpFinalizeNotifier(
TCL_UNUSED(void *))
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
LOCK_NOTIFIER_INIT;
notifierCount--;
/*
* If this is the last thread to use the notifier, close the notifier pipe
* and wait for the background thread to terminate.
*/
if (notifierCount == 0) {
|
| ︙ | ︙ | |||
913 914 915 916 917 918 919 | TclAsyncMarkFromNotifier(); } } close(receivePipe); triggerPipe = -1; } | < | 737 738 739 740 741 742 743 744 745 746 747 748 749 750 |
TclAsyncMarkFromNotifier();
}
}
close(receivePipe);
triggerPipe = -1;
}
}
UNLOCK_NOTIFIER_INIT;
LOCK_NOTIFIER_TSD; /* For concurrency with Tcl_AlertNotifier */
if (tsdPtr->runLoop) {
tsdPtr->runLoop = NULL;
|
| ︙ | ︙ | |||
1602 1603 1604 1605 1606 1607 1608 |
OnOffWaitingList(
ThreadSpecificData *tsdPtr,
int onList,
int signalNotifier)
{
int changeWaitingList;
| < < < < < | 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 |
OnOffWaitingList(
ThreadSpecificData *tsdPtr,
int onList,
int signalNotifier)
{
int changeWaitingList;
changeWaitingList = (!onList ^ !tsdPtr->onList);
if (changeWaitingList) {
if (onList) {
tsdPtr->nextPtr = waitingListPtr;
if (waitingListPtr) {
waitingListPtr->prevPtr = tsdPtr;
}
|
| ︙ | ︙ | |||
1700 1701 1702 1703 1704 1705 1706 |
runLoopStatus = CFRunLoopRunInMode(kCFRunLoopDefaultMode,
waitTime, FALSE);
switch (runLoopStatus) {
case kCFRunLoopRunFinished:
Tcl_Panic("Tcl_Sleep: CFRunLoop finished");
break;
case kCFRunLoopRunStopped:
| < | 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 |
runLoopStatus = CFRunLoopRunInMode(kCFRunLoopDefaultMode,
waitTime, FALSE);
switch (runLoopStatus) {
case kCFRunLoopRunFinished:
Tcl_Panic("Tcl_Sleep: CFRunLoop finished");
break;
case kCFRunLoopRunStopped:
waitTime = waitEnd - CFAbsoluteTimeGetCurrent();
break;
case kCFRunLoopRunTimedOut:
waitTime = 0;
break;
}
} while (waitTime > 0);
|
| ︙ | ︙ | |||
2229 2230 2231 2232 2233 2234 2235 |
UNLOCK_NOTIFIER_INIT;
#endif
asyncPending = 0;
if (tsdPtr->runLoop) {
tsdPtr->runLoop = NULL;
| < < < < < < < < < < < < < < < < < < < < < | 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 |
UNLOCK_NOTIFIER_INIT;
#endif
asyncPending = 0;
if (tsdPtr->runLoop) {
tsdPtr->runLoop = NULL;
tsdPtr->runLoopSource = NULL;
tsdPtr->runLoopTimer = NULL;
}
if (notifierCount > 0) {
notifierCount = 1;
notifierThreadRunning = 0;
/*
* Restart the notifier thread for signal handling.
*/
StartNotifierThread();
}
}
|
| ︙ | ︙ |
Changes to tests/all.tcl.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 | # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. package prefer latest package require tcltest 2.5 namespace import ::tcltest::* | < | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
package prefer latest
package require tcltest 2.5
namespace import ::tcltest::*
configure -testdir [file normalize [file dirname [info script]]] {*}$argv
if {[singleProcess]} {
interp debug {} -frame 1
}
set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)]
unset -nocomplain env(ERROR_ON_FAILURES)
|
| ︙ | ︙ |
Changes to tests/clock.test.
| ︙ | ︙ | |||
358 359 360 361 362 363 364 |
clock format 0 -format "%s" -timezone :NOWHERE
} -returnCodes 1 -result {time zone ":NOWHERE" not found} -errorCode {CLOCK badTimeZone :NOWHERE}
foreach tz [list {*}{
../UNSAFEPATH/NOWHERE UNSAFEPATH/../GMT //UNSAFEPATH/NOWHERE
zipfs:/UNSAFEPATH/NOWHERE C:/UNSAFEPATH/NOWHERE
} [list $::tcl::clock::DataDir/GMT]
] {
| | | 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 |
clock format 0 -format "%s" -timezone :NOWHERE
} -returnCodes 1 -result {time zone ":NOWHERE" not found} -errorCode {CLOCK badTimeZone :NOWHERE}
foreach tz [list {*}{
../UNSAFEPATH/NOWHERE UNSAFEPATH/../GMT //UNSAFEPATH/NOWHERE
zipfs:/UNSAFEPATH/NOWHERE C:/UNSAFEPATH/NOWHERE
} [list $::tcl::clock::DataDir/GMT]
] {
test clock-1.5.1.$tz "clock format - bad timezone (not valid - unsafe path)" -body {
clock format 0 -format "%s" -timezone $tz
} -returnCodes 1 -result "time zone \":$tz\" not valid" -errorCode [list CLOCK badTimeZone :$tz]
}
test clock-1.6 "clock format - gmt + timezone" {
list [catch {clock format 0 -timezone :GMT -gmt true} msg] $msg $::errorCode
} {1 {cannot use -gmt and -timezone in same call} {CLOCK gmtWithTimezone}}
|
| ︙ | ︙ |
Changes to tests/expr.test.
| ︙ | ︙ | |||
7289 7290 7291 7292 7293 7294 7295 |
expr ${func}(1.0)
} -match glob -result *
test expr-53.6.$func {float classification: basic arg handling} -body {
expr ${func}(0x123)
} -match glob -result *
}
| | > > > > > > > | < > > > | | | | > > > > > | | > | | < < < < < < < < < < > | > > | > > | > > | > > | | > | | > | > > | > > | > > | < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < | 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 |
expr ${func}(1.0)
} -match glob -result *
test expr-53.6.$func {float classification: basic arg handling} -body {
expr ${func}(0x123)
} -match glob -result *
}
foreach {v r} {
1 normal
-1 normal
0x7fffffffffffffff normal
-0x7fffffffffffffff normal
0xffffffffffffffffff normal
-0xffffffffffffffffff normal
1.0 normal
-1.0 normal
0 zero
-0 zero
0.0 zero
-0.0 zero
1/Inf zero
-1/Inf zero
1e-314 subnormal
-1e-314 subnormal
.0999999**319 subnormal
-.0999999**319 subnormal
1e-320/.9 subnormal
-1e-320/.9 subnormal
1e5555 infinite
1e308**1e10 infinite
Inf infinite
-1e5555 infinite
-1e308**(1e10+1) infinite
-Inf infinite
NaN nan
} {
if {[regexp {[/\*]} $v]} { set v [expr $v] }
test expr-58.1($v)=$r "float classification: fpclassify($v) eq $r" {
fpclassify $v
} $r
test expr-58.2($v) "float classification: isfinite($v)" {
expr {isfinite($v)}
} [expr {$r ni {"infinite" "nan"}}]
test expr-58.3($v) "float classification: isinf($v)" {
expr {isinf($v)}
} [expr {$r eq "infinite"}]
test expr-58.4($v) "float classification: isnan($v)" {
expr {isnan($v)}
} [expr {$r eq "nan"}]
test expr-58.5($v) "float classification: isnormal($v)" {
expr {isnormal($v)}
} [expr {$r eq "normal"}]
test expr-58.6($v) "float classification: issubnormal($v)" {
expr {issubnormal($v)}
} [expr {$r eq "subnormal"}]
test expr-58.7($v) "float classification: isunordered(0 and $v)" {
expr {isunordered(0,$v) + isunordered($v,0)}
} [expr {$r eq "nan" ? 2 : 0}]
test expr-58.9($v) "float classification: isunordered(NaN and $v)" {
expr {isunordered(NaN,$v) + isunordered($v,NaN)}
} 2
}
unset -nocomplain v r
test expr-59.10 {float classification: fpclassify} -returnCodes error -body {
fpclassify
} -result {wrong # args: should be "fpclassify floatValue"}
test expr-59.11 {float classification: fpclassify} -returnCodes error -body {
fpclassify a b
} -result {wrong # args: should be "fpclassify floatValue"}
test expr-59.12 {float classification: fpclassify} -returnCodes error -body {
|
| ︙ | ︙ | |||
7379 7380 7381 7382 7383 7384 7385 |
} -returnCodes error -result {too many arguments for math function "isunordered"}
test expr-60.4 {float classification: basic arg handling} -body {
expr {isunordered(true, 1.0)}
} -returnCodes error -result {expected number but got "true"}
test expr-60.5 {float classification: basic arg handling} -body {
expr {isunordered("gorp", 1.0)}
} -returnCodes error -result {expected number but got "gorp"}
| | | | > > > | | | | < < < < < < < | < < < | | 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 |
} -returnCodes error -result {too many arguments for math function "isunordered"}
test expr-60.4 {float classification: basic arg handling} -body {
expr {isunordered(true, 1.0)}
} -returnCodes error -result {expected number but got "true"}
test expr-60.5 {float classification: basic arg handling} -body {
expr {isunordered("gorp", 1.0)}
} -returnCodes error -result {expected number but got "gorp"}
test expr-60.6a {float classification: basic arg handling, large bigint -> double and wide} -body {
expr "isunordered(0x[string repeat f 100], 0x7fffffffffffffff)"
} -result 0
test expr-60.6b {float classification: basic arg handling, large bigint -> double Inf and wide} -body {
expr "isunordered(0x[string repeat f 1000], 0x7fffffffffffffff)"
} -result 0
test expr-60.7 {float classification: basic arg handling} -body {
expr {isunordered(1.0, true)}
} -returnCodes error -result {expected number but got "true"}
test expr-60.8 {float classification: basic arg handling} -body {
expr {isunordered(1.0, "gorp")}
} -returnCodes error -result {expected number but got "gorp"}
test expr-60.9a {float classification: basic arg handling, wide and large bigint -> double} -body {
expr "isunordered(0x7fffffffffffffff, 0x[string repeat f 100])"
} -result 0
test expr-60.9b {float classification: basic arg handling, wide and large bigint -> double Inf} -body {
expr "isunordered(0x7fffffffffffffff, 0x[string repeat f 1000])"
} -result 0
test expr-62.1 {TIP 582: comments} -body {
expr {1 # + 2}
} -result 1
test expr-62.2 {TIP 582: comments} -body {
expr "1 #\n+ 2"
} -result 3
|
| ︙ | ︙ |
Changes to tests/fileSystem.test.
| ︙ | ︙ | |||
274 275 276 277 278 279 280 |
file normalize ~noonewiththisname
} -result [file join [pwd] ~noonewiththisname]
test filesystem-1.30.1 {normalisation of existing user} -body {
file normalize ~$::tcl_platform(user)
} -result [file join [pwd] ~$::tcl_platform(user)]
test filesystem-1.30.3 {file normalization should distinguish between ~ and ~user} -setup {
set oldhome $::env(HOME)
| | | | | 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
file normalize ~noonewiththisname
} -result [file join [pwd] ~noonewiththisname]
test filesystem-1.30.1 {normalisation of existing user} -body {
file normalize ~$::tcl_platform(user)
} -result [file join [pwd] ~$::tcl_platform(user)]
test filesystem-1.30.3 {file normalization should distinguish between ~ and ~user} -setup {
set oldhome $::env(HOME)
set olduserhome [file normalize [file home $::tcl_platform(user)]]
set ::env(HOME) [file join $oldhome temp]
} -cleanup {
set ::env(HOME) $oldhome
} -body {
list [string equal [file normalize [file home]] [file normalize $::env(HOME)]] \
[string equal $olduserhome [file normalize [file home $::tcl_platform(user)]]]
} -result {1 1}
test filesystem-1.31 {link normalisation: link near filesystem root} {testsetplatform} {
testsetplatform unix
file normalize /foo/../bar
} {/bar}
test filesystem-1.32 {link normalisation: link near filesystem root} {testsetplatform} {
testsetplatform unix
|
| ︙ | ︙ |
Changes to tests/icu.test.
| ︙ | ︙ | |||
216 217 218 219 220 221 222 |
} -result fiance\u0301
# Source is decomposed
set s \uFB01ance\u0301
test icu-normalize-1 {Default normalization} -constraints icu -body {
icu normalize $s
} -result \uFB01anc\u00e9
| | | | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
} -result fiance\u0301
# Source is decomposed
set s \uFB01ance\u0301
test icu-normalize-1 {Default normalization} -constraints icu -body {
icu normalize $s
} -result \uFB01anc\u00e9
test icu-normalize-nfc-1 {NFC normalization} -constraints icu -body {
icu normalize -mode nfc $s
} -result \uFB01anc\u00e9
test icu-normalize-nfd-1 {NFD normalization} -constraints icu -body {
icu normalize -mode nfd $s
} -result \uFB01ance\u0301
test icu-normalize-nfkc-1 {NFKC normalization} -constraints icu -body {
icu normalize -mode nfkc $s
} -result fianc\u00e9
test icu-normalize-nfkd-1 {NFKD normalization} -constraints icu -body {
icu normalize -mode nfkd $s
} -result fiance\u0301
# Source has multiple diacritics with different canonical ordering
foreach s [list \u1EC7 e\u0302\u0323 e\u0323\u0302] {
test icu-normalize-nfc-2-$s {fully composed} -constraints icu -body {
icu normalize -mode nfc $s
} -result \u1EC7
test icu-normalize-nfc-3-$s {fully decomposed} -constraints icu -body {
icu normalize -mode nfd $s
} -result e\u0323\u0302
}
}
namespace delete icu
::tcltest::cleanupTests
|
Changes to tests/info.test.
| ︙ | ︙ | |||
416 417 418 419 420 421 422 |
lsort [t1 23 24]
} -cleanup {unset a aa} -result {b c x y}
test info-12.2 {info locals option} {
proc t1 {x y} {
set xx1 2
set xx2 3
set y 4
| | | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
lsort [t1 23 24]
} -cleanup {unset a aa} -result {b c x y}
test info-12.2 {info locals option} {
proc t1 {x y} {
set xx1 2
set xx2 3
set y 4
return [info locals x*]
}
lsort [t1 2 3]
} {x xx1 xx2}
test info-12.3 {info locals option} -body {
info locals 1 2
} -returnCodes error -result {wrong # args: should be "info locals ?pattern?"}
test info-12.4 {info locals option} {
|
| ︙ | ︙ | |||
598 599 600 601 602 603 604 |
info sharedlibextension foo
} -result {wrong # args: should be "info sharedlibextension"}
test info-18.1 {info tclversion option} -body {
scan [info tclversion] "%d.%d%c" a b c
} -cleanup {unset -nocomplain a b c} -result 2
test info-18.2 {info tclversion option} -body {
| | | 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 |
info sharedlibextension foo
} -result {wrong # args: should be "info sharedlibextension"}
test info-18.1 {info tclversion option} -body {
scan [info tclversion] "%d.%d%c" a b c
} -cleanup {unset -nocomplain a b c} -result 2
test info-18.2 {info tclversion option} -body {
info tclv 2
} -returnCodes error -result {wrong # args: should be "info tclversion"}
test info-18.3 {info tclversion option} -body {
unset tcl_version
info tclversion
} -returnCodes error -setup {
set t $tcl_version
} -cleanup {
|
| ︙ | ︙ |
Changes to tests/init.test.
| ︙ | ︙ | |||
29 30 31 32 33 34 35 |
}
} -cleanup {
interp delete child
} -result {0 {} 0 {}}
test init-0.2 {no init.tcl from empty tcl_library, bug [43c94f95988f3057]} -setup {
cd [makeDirectory tmp]
| | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
}
} -cleanup {
interp delete child
} -result {0 {} 0 {}}
test init-0.2 {no init.tcl from empty tcl_library, bug [43c94f95988f3057]} -setup {
cd [makeDirectory tmp]
makeFile {set ::TEST_INIT 1} init.tcl [pwd]
unset -nocomplain org_tcl_lib
if {[info exists ::env(TCL_LIBRARY)]} {
set org_tcl_lib $::env(TCL_LIBRARY)
}
set res [file exists [file join [pwd] init.tcl]]
} -body {
# first without tcl_library set:
|
| ︙ | ︙ | |||
53 54 55 56 57 58 59 |
} -cleanup {
if {[info exists org_tcl_lib]} {
set ::env(TCL_LIBRARY) $org_tcl_lib
unset org_tcl_lib
} else {
unset -nocomplain ::env(TCL_LIBRARY)
}
| | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
} -cleanup {
if {[info exists org_tcl_lib]} {
set ::env(TCL_LIBRARY) $org_tcl_lib
unset org_tcl_lib
} else {
unset -nocomplain ::env(TCL_LIBRARY)
}
removeFile init.tcl [pwd]
cd [workingDirectory]
removeDirectory tmp
unset -nocomplain res
catch { interp delete child }
} -result {1 0 1}
# Six cases - white box testing
|
| ︙ | ︙ |
Changes to tests/interp.test.
| ︙ | ︙ | |||
2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 |
test interp-25.1 {testing aliasing of string commands} -setup {
catch {interp delete a}
} -body {
interp create a
a alias exec foo ;# Relies on exec being a string command!
interp delete a
} -result ""
#
# Interps result transmission
#
test interp-26.1 {result code transmission : interp eval direct} {
# Test that all the possibles error codes from Tcl get passed up
| > > > > > > > > > > > > > > > > > > > > > | 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 |
test interp-25.1 {testing aliasing of string commands} -setup {
catch {interp delete a}
} -body {
interp create a
a alias exec foo ;# Relies on exec being a string command!
interp delete a
} -result ""
test interp-25.2 {lambda on different interpreters, bug [67d5f75c36cbada6]} -setup {
catch {interp delete a}
interp create a
} -body {
set res {}
set lambda {{} { list OK from lambda }}
lappend res [apply $lambda]
lappend res [a eval [list apply $lambda]]
set lambda [list apply {{} { list OK from lambda }}]
lappend res [eval $lambda]
lappend res [a eval $lambda]
# cover also epoch change (command list is replaced):
a eval {proc list args {return {NO LIST}}}
lappend res [a eval $lambda]
lappend res [eval $lambda]
set res
} -cleanup {
interp delete a
unset -nocomplain res lambda
} -result [list {*}[lrepeat 4 {OK from lambda}] {NO LIST} {OK from lambda}]
#
# Interps result transmission
#
test interp-26.1 {result code transmission : interp eval direct} {
# Test that all the possibles error codes from Tcl get passed up
|
| ︙ | ︙ |
Changes to tests/lseq.test.
| ︙ | ︙ | |||
13 14 15 16 17 18 19 |
package require tcltest 2.5
namespace import -force ::tcltest::*
}
testConstraint arithSeriesDouble 1
testConstraint arithSeriesShimmer 1
testConstraint arithSeriesShimmerOk 1
| < | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package require tcltest 2.5
namespace import -force ::tcltest::*
}
testConstraint arithSeriesDouble 1
testConstraint arithSeriesShimmer 1
testConstraint arithSeriesShimmerOk 1
testConstraint has64BitLengths [expr {$tcl_platform(pointerSize) == 8}]
testConstraint has32BitLengths [expr {$tcl_platform(pointerSize) == 4}]
proc memusage {} {
set fd [open /proc/[pid]/statm]
set line [gets $fd]
if {[llength $line] != 7} {
|
| ︙ | ︙ | |||
811 812 813 814 815 816 817 818 819 820 821 822 823 824 |
test lseq-4.20 {lindex on lseq without index args, bug a9625d1f53554f9d} -body {
set res [lindex [lseq 1000]]
list [llength $res] [lindex $res 0] [lindex $res end]
} -cleanup {
unset -nocomplain res
} -result {1000 0 999}
test lseq-convertToList {does not result in a memory error} -body {
trace add variable var1 write [list ::apply [list args {
error {this is an error}
} [namespace current]]]
list [catch {set var1 [lindex [lreplace [lseq 1 2] 1 1 hello] 0]} cres] $cres
} -cleanup {unset var1 cres} -result {1 {can't set "var1": this is an error}}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 |
test lseq-4.20 {lindex on lseq without index args, bug a9625d1f53554f9d} -body {
set res [lindex [lseq 1000]]
list [llength $res] [lindex $res 0] [lindex $res end]
} -cleanup {
unset -nocomplain res
} -result {1000 0 999}
test lseq-4.21.1 {Corner cases: overflows by Inf} -body {
set res {}
lappend res [catch {lseq -1e5555} msg] $msg
lappend res [catch {lseq 1e5555} msg] $msg
lappend res [catch {lseq -Inf} msg] $msg
lappend res [catch {lseq Inf} msg] $msg
lappend res [catch {lseq -1e5555 0} msg] $msg
lappend res [catch {lseq 0 1e5555} msg] $msg
lappend res [catch {lseq -1e5555 1e5555} msg] $msg
lappend res [catch {lseq -Inf -Inf} msg] $msg
lappend res [catch {lseq Inf Inf} msg] $msg
lappend res [catch {lseq 0 .. Inf} msg] $msg
lappend res [catch {lseq -Inf .. 0} msg] $msg
lappend res [catch {lseq 0 .. -Inf} msg] $msg
lappend res [catch {lseq -Inf .. Inf} msg] $msg
lappend res [catch {lseq Inf .. -Inf} msg] $msg
} -cleanup {
unset -nocomplain res
} -result [list {*}{
1 {expected integer but got "-1e5555"}
1 {expected integer but got "1e5555"}
1 {expected integer but got "-Inf"}
1 {expected integer but got "Inf"}
1 {max length of a Tcl list exceeded}
1 {max length of a Tcl list exceeded}
1 {max length of a Tcl list exceeded}
1 {max length of a Tcl list exceeded}
1 {max length of a Tcl list exceeded}
1 {max length of a Tcl list exceeded}
1 {max length of a Tcl list exceeded}
1 {max length of a Tcl list exceeded}
1 {max length of a Tcl list exceeded}
1 {max length of a Tcl list exceeded}
}]
test lseq-4.21.2 {Corner cases: expected Inf} -body {
set res {}
lappend res [lseq {1e5555+0} count 5]
lappend res [lseq Inf count 5]
lappend res [lseq Inf count 5 by 100]
lappend res [lseq Inf count 5 by Inf]
lappend res [lseq 5 by Inf]
lappend res [lseq 0 count 5 by Inf]
lappend res [lseq 5 by 1e308]
lappend res [lseq 0 count 5 by 1e308]
lappend res [lseq 5 by 5e307]
lappend res [lseq 0 count 5 by 5e307]
} -cleanup {
unset -nocomplain res
} -result [list {*}{
{Inf Inf Inf Inf Inf}
{Inf Inf Inf Inf Inf}
{Inf Inf Inf Inf Inf}
{Inf Inf Inf Inf Inf}
{0.0 Inf Inf Inf Inf}
{0.0 Inf Inf Inf Inf}
{0.0 1e+308 Inf Inf Inf}
{0.0 1e+308 Inf Inf Inf}
{0.0 5e+307 1e+308 1.5e+308 Inf}
{0.0 5e+307 1e+308 1.5e+308 Inf}
}]
test lseq-4.21.3 {Corner cases: expected -Inf} -body {
set res {}
lappend res [lseq {-1e5555+0} count 5]
lappend res [lseq -Inf count 5]
lappend res [lseq -Inf count 5 by 100]
lappend res [lseq -Inf count 5 by -Inf]
lappend res [lseq 5 by -Inf]
lappend res [lseq 0 count 5 by -Inf]
lappend res [lseq 5 by -1e308]
lappend res [lseq 0 count 5 by -1e308]
lappend res [lseq 5 by -5e307]
lappend res [lseq 0 count 5 by -5e307]
} -cleanup {
unset -nocomplain res
} -result [list {*}{
{-Inf -Inf -Inf -Inf -Inf}
{-Inf -Inf -Inf -Inf -Inf}
{-Inf -Inf -Inf -Inf -Inf}
{-Inf -Inf -Inf -Inf -Inf}
{0.0 -Inf -Inf -Inf -Inf}
{0.0 -Inf -Inf -Inf -Inf}
{0.0 -1e+308 -Inf -Inf -Inf}
{0.0 -1e+308 -Inf -Inf -Inf}
{0.0 -5e+307 -1e+308 -1.5e+308 -Inf}
{0.0 -5e+307 -1e+308 -1.5e+308 -Inf}
}]
test lseq-4.21.4 {Corner cases: unexpected Inf - Inf, result to +/-NaN, unexpected NaN} -body {
set res {}
lappend res [list [catch {lseq Inf count 5 by -Inf} msg opt] $msg [dict getd $opt -errorcode ""]]
lappend res [list [catch {lseq -Inf count 5 by Inf} msg opt] $msg [dict getd $opt -errorcode ""]]
lappend res [list [catch {lseq {Inf - Inf} count 5} msg opt] $msg [dict getd $opt -errorcode ""]]
lappend res [list [catch {lseq NaN count 5} msg opt] $msg [dict getd $opt -errorcode ""]]
lappend res [list [catch {lseq NaN count 5 by 100} msg opt] $msg [dict getd $opt -errorcode ""]]
lappend res [list [catch {lseq NaN count 5 by NaN} msg opt] $msg [dict getd $opt -errorcode ""]]
lappend res [list [catch {lseq 5 by NaN} msg opt] $msg [dict getd $opt -errorcode ""]]
lappend res [list [catch {lseq 0 count 5 by NaN} msg opt] $msg [dict getd $opt -errorcode ""]]
join $res \n
} -cleanup {
unset -nocomplain res msg opt
} -result [join [lrepeat 8 {1 {domain error: argument not in valid range} {ARITH DOMAIN {domain error: argument not in valid range}}}] \n]
test lseq-4.21.5 {Corner cases: unexpected NaN} -body {
set res {}
lappend res [catch {lseq NaN} msg] $msg
lappend res [catch {lseq 0 .. NaN} msg] $msg
} -cleanup {
unset -nocomplain res msg
} -result {1 {expected integer but got "NaN"} 1 {cannot use non-numeric floating-point value "NaN" to estimate length of arith-series}}
test lseq-4.21.6 {Corner cases: empty list, reversed step} -body {
set res {}
lappend res [lseq -5 .. 0 by -1]
lappend res [lseq 5 .. 0 by 1]
lappend res [lseq 0 .. 5 by -1]
lappend res [lseq 0 .. -5 by 1]
} -cleanup {
unset -nocomplain res
} -result {{} {} {} {}}
test lseq-4.21.6-lran {Corner cases: lrange empty list, reversed step} -body {
set res {}
# not shared:
lappend res [lrange [lseq -5 .. 0 by -1] 1 end-1]
lappend res [lrange [lseq 5 .. 0 by 1] 1 end-1]
lappend res [lrange [lseq 0 .. 5 by -1] 1 end-1]
lappend res [lrange [lseq 0 .. -5 by 1] 1 end-1]
# shared:
lappend res [lrange [set l [lseq -5 .. 0 by -1]] 1 end-1]
lappend res [lrange [set l [lseq 5 .. 0 by 1]] 1 end-1]
lappend res [lrange [set l [lseq 0 .. 5 by -1]] 1 end-1]
lappend res [lrange [set l [lseq 0 .. -5 by 1]] 1 end-1]
} -cleanup {
unset -nocomplain res l
} -result {{} {} {} {} {} {} {} {}}
test lseq-4.21.6-lrev {Corner cases: lreverse empty list, reversed step} -body {
set res {}
# not shared:
lappend res [lreverse [lseq -5 .. 0 by -1]]
lappend res [lreverse [lseq 5 .. 0 by 1]]
lappend res [lreverse [lseq 0 .. 5 by -1]]
lappend res [lreverse [lseq 0 .. -5 by 1]]
# shared:
lappend res [lreverse [set l [lseq -5 .. 0 by -1]]]
lappend res [lreverse [set l [lseq 5 .. 0 by 1]]]
lappend res [lreverse [set l [lseq 0 .. 5 by -1]]]
lappend res [lreverse [set l [lseq 0 .. -5 by 1]]]
} -cleanup {
unset -nocomplain res l
} -result {{} {} {} {} {} {} {} {}}
test lseq-4.21.7 {Corner cases: non-empty list, normal step} -body {
set res {}
lappend res [lseq -5 .. 0 ]
lappend res [lseq 5 .. 0 by -1]
lappend res [lseq 0 .. 5 ]
lappend res [lseq 0 .. -5 by -1]
} -cleanup {
unset -nocomplain res
} -result [list {*}{
{-5 -4 -3 -2 -1 0}
{5 4 3 2 1 0}
{0 1 2 3 4 5}
{0 -1 -2 -3 -4 -5}
}]
test lseq-4.21.7-lran {Corner cases: lrange non-empty list, normal step} -body {
set res {}
# not shared:
lappend res [lrange [lseq -5 .. 0 ] 1 end-1]
lappend res [lrange [lseq 5 .. 0 by -1] 1 end-1]
lappend res [lrange [lseq 0 .. 5 ] 1 end-1]
lappend res [lrange [lseq 0 .. -5 by -1] 1 end-1]
# shared:
lappend res [lrange [set l [lseq -5 .. 0 ]] 1 end-1]
lappend res [lrange [set l [lseq 5 .. 0 by -1]] 1 end-1]
lappend res [lrange [set l [lseq 0 .. 5 ]] 1 end-1]
lappend res [lrange [set l [lseq 0 .. -5 by -1]] 1 end-1]
} -cleanup {
unset -nocomplain res l
} -result [lrepeat 2 {*}{
{-4 -3 -2 -1}
{4 3 2 1}
{1 2 3 4}
{-1 -2 -3 -4}
}]
test lseq-4.21.7-lrev {Corner cases: lreverse non-empty list, normal step} -body {
set res {}
# not shared:
lappend res [lreverse [lseq -5 .. 0 ]]
lappend res [lreverse [lseq 5 .. 0 by -1]]
lappend res [lreverse [lseq 0 .. 5 ]]
lappend res [lreverse [lseq 0 .. -5 by -1]]
# shared:
lappend res [lreverse [set l [lseq -5 .. 0 ]]]
lappend res [lreverse [set l [lseq 5 .. 0 by -1]]]
lappend res [lreverse [set l [lseq 0 .. 5 ]]]
lappend res [lreverse [set l [lseq 0 .. -5 by -1]]]
} -cleanup {
unset -nocomplain res l
} -result [lrepeat 2 {*}{
{0 -1 -2 -3 -4 -5}
{0 1 2 3 4 5}
{5 4 3 2 1 0}
{-5 -4 -3 -2 -1 0}
}]
test lseq-convertToList {does not result in a memory error} -body {
trace add variable var1 write [list ::apply [list args {
error {this is an error}
} [namespace current]]]
list [catch {set var1 [lindex [lreplace [lseq 1 2] 1 1 hello] 0]} cres] $cres
} -cleanup {unset var1 cres} -result {1 {can't set "var1": this is an error}}
|
| ︙ | ︙ |
Changes to tests/oo.test.
| ︙ | ︙ | |||
462 463 464 465 466 467 468 469 470 471 472 473 474 475 |
}
}
return $cnt
}} 10000
} -cleanup {
parent destroy
} -result 0
test oo-2.1 {basic test of OO functionality: constructor} -setup {
# This is a bit complex because it needs to run in a sub-interp as
# we're modifying the root object class's constructor
interp create subinterp
subinterp eval {
package require tcl::oo
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 |
}
}
return $cnt
}} 10000
} -cleanup {
parent destroy
} -result 0
test oo-1.25 {basic test of OO functionality: touch method after instance deletion, bug [0b809cd3fc8b6e5e]} -body {
set ::result {}
# test for eval and deletion of coro, in both cases the coroutine shall be deleted
foreach v {"eval" "del"} {
# 1st (deleted class)
oo::class create A
oo::define A method retard-it {} {yield}
coroutine tcoro [A new] retard-it
trace add command tcoro delete {apply {{args} {lappend ::result D}}}
A destroy
if {$v eq "eval"} { tcoro } else { rename tcoro {} }
# 2nd (deleted object of class)
oo::class create A
oo::define A method retard-it {} {yield}
set obj [A new]
coroutine tcoro $obj retard-it
trace add command tcoro delete {apply {{args} {lappend ::result D}}}
$obj destroy
if {$v eq "eval"} { tcoro } else { rename tcoro {} }
A destroy
# 3rd (deleted object)
set obj [oo::object new]
oo::objdefine $obj method retard-it {} {yield}
coroutine tcoro $obj retard-it
trace add command tcoro delete {apply {{args} {lappend ::result D}}}
$obj destroy
if {$v eq "eval"} { tcoro } else { rename tcoro {} }
}
set ::result
} -result [lrepeat 6 D]
test oo-2.1 {basic test of OO functionality: constructor} -setup {
# This is a bit complex because it needs to run in a sub-interp as
# we're modifying the root object class's constructor
interp create subinterp
subinterp eval {
package require tcl::oo
|
| ︙ | ︙ | |||
4031 4032 4033 4034 4035 4036 4037 |
variable x!
constructor {} {set x! 1}
method y {} {incr x!}
}
foo create bar
oo::objdefine bar {
variable y!
| | | 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 |
variable x!
constructor {} {set x! 1}
method y {} {incr x!}
}
foo create bar
oo::objdefine bar {
variable y!
method y {} {list [next] [incr y!] [info var] [info locals]}
export eval
}
bar y
list [bar y] [lsort [info object vars bar]] [bar eval {info vars *!}]
} -result {{3 2 y! {}} {x! y!} {x! y!}}
test oo-27.7 {variables declaration - one underlying variable space} -setup {
oo::class create parent
|
| ︙ | ︙ |
Changes to tests/scan.test.
| ︙ | ︙ | |||
555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
%llu a] $a
} -result {1 207698809136909011942886895}
test scan-5.20 {ignore digit separators} -setup {
set a {}; set b {}; set c {};
} -body {
list [scan "10_23_45" %d_%d_%d a b c] $a $b $c
} -result {3 10 23 45}
test scan-6.1 {floating-point scanning} -setup {
set a {}; set b {}; set c {}; set d {}
} -body {
list [scan "2.1 -3.0e8 .99962 a" "%f%g%e%f" a b c d] $a $b $c $d
} -result {3 2.1 -300000000.0 0.99962 {}}
test scan-6.2 {floating-point scanning} -setup {
| > > > > > | 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 |
%llu a] $a
} -result {1 207698809136909011942886895}
test scan-5.20 {ignore digit separators} -setup {
set a {}; set b {}; set c {};
} -body {
list [scan "10_23_45" %d_%d_%d a b c] $a $b $c
} -result {3 10 23 45}
test scan-5.21 {integer scanning, %j, %q, &z, %t} -setup {
set a {}; set b {}; set c {}; set d {}
} -body {
list [scan "42 43 44 45" "%jd %qd %zd %td" a b c d] $a $b $c $d
} -result {4 42 43 44 45}
test scan-6.1 {floating-point scanning} -setup {
set a {}; set b {}; set c {}; set d {}
} -body {
list [scan "2.1 -3.0e8 .99962 a" "%f%g%e%f" a b c d] $a $b $c $d
} -result {3 2.1 -300000000.0 0.99962 {}}
test scan-6.2 {floating-point scanning} -setup {
|
| ︙ | ︙ |
Changes to tests/zipfs.test.
| ︙ | ︙ | |||
916 917 918 919 920 921 922 923 924 925 926 927 928 929 |
# zip starts at offset 4
mount [zippath junk-at-start.zip] /testmt/a/b
} -cleanup {
cleanup
} -body {
zipfs info [file join [zipfs root] testmt a]
} -result {path "//zipfs:/testmt/a" not found in any zipfs volume} -returnCodes error
#
# zipfs canonical
test zipfs-canonical-minargs {zipfs canonical min args} -body {
zipfs canonical
} -returnCodes error -result {wrong # args: should be "zipfs canonical ?mountpoint? filename"}
test zipfs-canonical-maxargs {zipfs canonical max args} -body {
| > > > > > > > > > > > > > > > > | 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 |
# zip starts at offset 4
mount [zippath junk-at-start.zip] /testmt/a/b
} -cleanup {
cleanup
} -body {
zipfs info [file join [zipfs root] testmt a]
} -result {path "//zipfs:/testmt/a" not found in any zipfs volume} -returnCodes error
test zipfs-info-tcllib-1 "zipfs info offset on tcl library" -constraints zipfslib -body {
expr {[lindex [zipfs info [file dirname $::tcl_library]] 3] > 0}
} -result 1
test zipfs-info-tcllib-2 "extract zip using zipfs info" -constraints zipfslib -cleanup {
cleanup
} -body {
set mt [file dirname $::tcl_library]
lassign [zipfs info $mt] container_path - - offset
set fd [open $container_path rb]
chan seek $fd $offset
set zipdata [read $fd]
zipfs mountdata $zipdata /testmt
list [expr {$offset > 0}] [file exists [file join [zipfs root] testmt tcl_library]]
} -result {1 1}
#
# zipfs canonical
test zipfs-canonical-minargs {zipfs canonical min args} -body {
zipfs canonical
} -returnCodes error -result {wrong # args: should be "zipfs canonical ?mountpoint? filename"}
test zipfs-canonical-maxargs {zipfs canonical max args} -body {
|
| ︙ | ︙ |
Changes to unix/Makefile.in.
| ︙ | ︙ | |||
805 806 807 808 809 810 811 |
@MAKE_LIB@
@if test "${ZIPFS_BUILD}" = "1" ; then \
if test "x$(MACHER)" = "x" ; then \
cat ${TCL_ZIP_FILE} >> ${LIB_FILE}; \
else $(MACHER) append ${LIB_FILE} ${TCL_ZIP_FILE} /tmp/macher_output; \
mv /tmp/macher_output ${LIB_FILE}; chmod u+x ${LIB_FILE}; \
fi; \
| < < | 805 806 807 808 809 810 811 812 813 814 815 816 817 818 |
@MAKE_LIB@
@if test "${ZIPFS_BUILD}" = "1" ; then \
if test "x$(MACHER)" = "x" ; then \
cat ${TCL_ZIP_FILE} >> ${LIB_FILE}; \
else $(MACHER) append ${LIB_FILE} ${TCL_ZIP_FILE} /tmp/macher_output; \
mv /tmp/macher_output ${LIB_FILE}; chmod u+x ${LIB_FILE}; \
fi; \
fi
${STUB_LIB_FILE}: ${STUB_LIB_OBJS}
@if [ "x${LIB_FILE}" = "xlibtcl${MAJOR_VERSION}.${MINOR_VERSION}.dll" ] ; then \
( cd ${TOP_DIR}/win; ${MAKE} winextensions ); \
fi
rm -f $@
|
| ︙ | ︙ | |||
836 837 838 839 840 841 842 |
${CC_SEARCH_FLAGS} -o ${TCL_EXE}
@if test "${ZIPFS_BUILD}" = "2" ; then \
if test "x$(MACHER)" = "x" ; then \
cat ${TCL_ZIP_FILE} >> ${TCL_EXE}; \
else $(MACHER) append ${TCL_EXE} ${TCL_ZIP_FILE} /tmp/macher_output; \
mv /tmp/macher_output ${TCL_EXE}; chmod u+x ${TCL_EXE}; \
fi; \
| < < | 834 835 836 837 838 839 840 841 842 843 844 845 846 847 |
${CC_SEARCH_FLAGS} -o ${TCL_EXE}
@if test "${ZIPFS_BUILD}" = "2" ; then \
if test "x$(MACHER)" = "x" ; then \
cat ${TCL_ZIP_FILE} >> ${TCL_EXE}; \
else $(MACHER) append ${TCL_EXE} ${TCL_ZIP_FILE} /tmp/macher_output; \
mv /tmp/macher_output ${TCL_EXE}; chmod u+x ${TCL_EXE}; \
fi; \
fi
# Must be empty so it doesn't conflict with rule for ${TCL_EXE} above
${NATIVE_TCLSH}:
Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in
$(SHELL) config.status
|
| ︙ | ︙ | |||
899 900 901 902 903 904 905 |
${CC_SEARCH_FLAGS} -o ${TCLTEST_EXE}
@if test "${ZIPFS_BUILD}" = "2" ; then \
if test "x$(MACHER)" = "x" ; then \
cat ${TCL_ZIP_FILE} >> ${TCLTEST_EXE}; \
else $(MACHER) append ${TCLTEST_EXE} ${TCL_ZIP_FILE} /tmp/macher_output; \
mv /tmp/macher_output ${TCLTEST_EXE}; chmod u+x ${TCLTEST_EXE}; \
fi; \
| < < | 895 896 897 898 899 900 901 902 903 904 905 906 907 908 |
${CC_SEARCH_FLAGS} -o ${TCLTEST_EXE}
@if test "${ZIPFS_BUILD}" = "2" ; then \
if test "x$(MACHER)" = "x" ; then \
cat ${TCL_ZIP_FILE} >> ${TCLTEST_EXE}; \
else $(MACHER) append ${TCLTEST_EXE} ${TCL_ZIP_FILE} /tmp/macher_output; \
mv /tmp/macher_output ${TCLTEST_EXE}; chmod u+x ${TCLTEST_EXE}; \
fi; \
fi
# Note, in the targets below TCL_LIBRARY needs to be set or else "make test"
# won't work in the case where the compilation directory isn't the same as the
# source directory.
#
# Specifying TESTFLAGS on the command line is the standard way to pass args to
|
| ︙ | ︙ | |||
2329 2330 2331 2332 2333 2334 2335 |
printf "unknown" >$(TOP_DIR)/manifest.uuid)
dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in genstubs \
$(MAC_OSX_DIR)/configure $(TOP_DIR)/manifest.uuid dist-packages ${NATIVE_TCLSH}
rm -rf $(DISTDIR)
$(INSTALL_DATA_DIR) $(DISTDIR)/unix
$(DIST_INSTALL_DATA) $(TOP_DIR)/manifest.uuid $(DISTDIR)
| | | 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 |
printf "unknown" >$(TOP_DIR)/manifest.uuid)
dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in genstubs \
$(MAC_OSX_DIR)/configure $(TOP_DIR)/manifest.uuid dist-packages ${NATIVE_TCLSH}
rm -rf $(DISTDIR)
$(INSTALL_DATA_DIR) $(DISTDIR)/unix
$(DIST_INSTALL_DATA) $(TOP_DIR)/manifest.uuid $(DISTDIR)
$(DIST_INSTALL_DATA) $(UNIX_DIR)/*.c $(UNIX_DIR)/tclUnixPort.h $(DISTDIR)/unix
$(DIST_INSTALL_DATA) $(UNIX_DIR)/Makefile.in $(DISTDIR)/unix
$(DIST_INSTALL_DATA) $(UNIX_DIR)/configure.ac \
$(UNIX_DIR)/tcl.m4 $(UNIX_DIR)/aclocal.m4 \
$(UNIX_DIR)/tclConfig.sh.in $(UNIX_DIR)/tclooConfig.sh \
$(UNIX_DIR)/install-sh \
$(UNIX_DIR)/README $(UNIX_DIR)/tcl.spec \
$(UNIX_DIR)/installManPage $(UNIX_DIR)/tclConfig.h.in \
|
| ︙ | ︙ | |||
2418 2419 2420 2421 2422 2423 2424 | $(TOP_DIR)/win/tclConfig.sh.in $(TOP_DIR)/win/tclooConfig.sh \ $(TOP_DIR)/win/tcl.m4 $(TOP_DIR)/win/aclocal.m4 \ $(TOP_DIR)/win/tclsh.exe.manifest.in $(TOP_DIR)/win/tclUuid.h.in \ $(TOP_DIR)/win/gitmanifest.in $(TOP_DIR)/win/svnmanifest.in \ $(TOP_DIR)/win/x86_64-w64-mingw32-nmakehlp.exe $(DISTDIR)/win chmod 775 $(DISTDIR)/win/x86_64-w64-mingw32-nmakehlp.exe $(DIST_INSTALL_SCRIPT) $(TOP_DIR)/win/configure $(DISTDIR)/win | | > | 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 | $(TOP_DIR)/win/tclConfig.sh.in $(TOP_DIR)/win/tclooConfig.sh \ $(TOP_DIR)/win/tcl.m4 $(TOP_DIR)/win/aclocal.m4 \ $(TOP_DIR)/win/tclsh.exe.manifest.in $(TOP_DIR)/win/tclUuid.h.in \ $(TOP_DIR)/win/gitmanifest.in $(TOP_DIR)/win/svnmanifest.in \ $(TOP_DIR)/win/x86_64-w64-mingw32-nmakehlp.exe $(DISTDIR)/win chmod 775 $(DISTDIR)/win/x86_64-w64-mingw32-nmakehlp.exe $(DIST_INSTALL_SCRIPT) $(TOP_DIR)/win/configure $(DISTDIR)/win $(DIST_INSTALL_DATA) $(TOP_DIR)/win/*.c $(TOP_DIR)/win/*.ico $(TOP_DIR)/win/*.rc \ $(TOP_DIR)/win/tclWinInt.h $(TOP_DIR)/win/tclWinPort.h \ $(DISTDIR)/win $(DIST_INSTALL_DATA) $(TOP_DIR)/win/*.bat $(DISTDIR)/win $(DIST_INSTALL_DATA) $(TOP_DIR)/win/*.vc $(DISTDIR)/win $(DIST_INSTALL_DATA) $(TOP_DIR)/win/tcl.ds* $(DISTDIR)/win $(DIST_INSTALL_DATA) $(TOP_DIR)/win/README $(DISTDIR)/win $(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/win $(INSTALL_DATA_DIR) $(DISTDIR)/macosx |
| ︙ | ︙ | |||
2441 2442 2443 2444 2445 2446 2447 | $(UNIX_DIR)/dltest/README $(DISTDIR)/unix/dltest $(INSTALL_DATA_DIR) $(DISTDIR)/tools $(DIST_INSTALL_DATA) $(TOOL_DIR)/README $(TOOL_DIR)/*.c $(TOOL_DIR)/*.svg \ $(TOOL_DIR)/*.tcl $(TOOL_DIR)/*.bmp $(TOOL_DIR)/valgrind_suppress \ $(TOOL_DIR)/valgrind_check_success $(DISTDIR)/tools chmod 755 $(DISTDIR)/tools/checkLibraryDoc.tcl \ $(DISTDIR)/tools/findBadExternals.tcl \ | | | > | 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 | $(UNIX_DIR)/dltest/README $(DISTDIR)/unix/dltest $(INSTALL_DATA_DIR) $(DISTDIR)/tools $(DIST_INSTALL_DATA) $(TOOL_DIR)/README $(TOOL_DIR)/*.c $(TOOL_DIR)/*.svg \ $(TOOL_DIR)/*.tcl $(TOOL_DIR)/*.bmp $(TOOL_DIR)/valgrind_suppress \ $(TOOL_DIR)/valgrind_check_success $(DISTDIR)/tools chmod 755 $(DISTDIR)/tools/checkLibraryDoc.tcl \ $(DISTDIR)/tools/findBadExternals.tcl \ $(DISTDIR)/tools/loadICU.tcl $(DISTDIR)/tools/addVerToFile.tcl \ $(DISTDIR)/tools/makeTestCases.tcl $(DISTDIR)/tools/tclZIC.tcl \ $(DISTDIR)/tools/tcltk-man2html.tcl $(DISTDIR)/win/buildall.vc.bat \ $(DISTDIR)/unix/install-sh $(DISTDIR)/unix/installManPage $(INSTALL_DATA_DIR) $(DISTDIR)/pkgs $(DIST_INSTALL_DATA) $(TOP_DIR)/pkgs/README $(DISTDIR)/pkgs $(DIST_INSTALL_DATA) $(TOP_DIR)/pkgs/package.list.txt $(DISTDIR)/pkgs for i in `ls $(DISTROOT)/pkgs/*.tar.gz 2> /dev/null`; do \ tar -C $(DISTDIR)/pkgs -xzf "$$i"; \ done $(INSTALL_DATA_DIR) $(DISTDIR)/.github/workflows |
| ︙ | ︙ |
Changes to unix/configure.
| ︙ | ︙ | |||
2706 2707 2708 2709 2710 2711 2712 | TCL_VERSION=9.0 TCL_MAJOR_VERSION=9 TCL_MINOR_VERSION=0 | | | 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 |
TCL_VERSION=9.0
TCL_MAJOR_VERSION=9
TCL_MINOR_VERSION=0
TCL_PATCH_LEVEL=".2"
VERSION=${TCL_VERSION}
EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"}
EXTRA_BUILD_HTML=${EXTRA_BUILD_HTML:-"@:"}
#------------------------------------------------------------------------
# Setup configure arguments for bundled packages
|
| ︙ | ︙ | |||
10499 10500 10501 10502 10503 10504 10505 |
fi
printf "%s\n" "#define TCL_LOAD_FROM_MEMORY 1" >>confdefs.h
printf "%s\n" "#define TCL_WIDE_CLICKS 1" >>confdefs.h
| < < < < < < < < | | < < < < < < < | | | | | | | < < < < < < < | | | | < | 10499 10500 10501 10502 10503 10504 10505 10506 10507 10508 10509 10510 10511 10512 10513 10514 10515 10516 10517 10518 10519 10520 10521 10522 10523 10524 10525 10526 10527 10528 10529 10530 10531 10532 10533 10534 10535 10536 10537 10538 10539 10540 10541 10542 10543 10544 10545 10546 10547 10548 10549 10550 10551 10552 10553 10554 10555 10556 10557 10558 10559 10560 10561 10562 10563 10564 10565 10566 10567 10568 10569 10570 10571 10572 10573 10574 10575 10576 10577 10578 10579 10580 10581 10582 10583 10584 10585 10586 10587 10588 10589 10590 10591 |
fi
printf "%s\n" "#define TCL_LOAD_FROM_MEMORY 1" >>confdefs.h
printf "%s\n" "#define TCL_WIDE_CLICKS 1" >>confdefs.h
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if weak import is available" >&5
printf %s "checking if weak import is available... " >&6; }
if test ${tcl_cv_cc_weak_import+y}
then :
printf %s "(cached) " >&6
else case e in #(
e)
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int rand(void) __attribute__((weak_import));
int
main (void)
{
rand();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
tcl_cv_cc_weak_import=yes
else case e in #(
e) tcl_cv_cc_weak_import=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
CFLAGS=$hold_cflags ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_weak_import" >&5
printf "%s\n" "$tcl_cv_cc_weak_import" >&6; }
if test $tcl_cv_cc_weak_import = yes; then
printf "%s\n" "#define HAVE_WEAK_IMPORT 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if Darwin SUSv3 extensions are available" >&5
printf %s "checking if Darwin SUSv3 extensions are available... " >&6; }
if test ${tcl_cv_cc_darwin_c_source+y}
then :
printf %s "(cached) " >&6
else case e in #(
e)
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#define _DARWIN_C_SOURCE 1
#include <sys/cdefs.h>
int
main (void)
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
tcl_cv_cc_darwin_c_source=yes
else case e in #(
e) tcl_cv_cc_darwin_c_source=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS=$hold_cflags ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_darwin_c_source" >&5
printf "%s\n" "$tcl_cv_cc_darwin_c_source" >&6; }
if test $tcl_cv_cc_darwin_c_source = yes; then
printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h
fi
# Build .bundle dltest binaries in addition to .dylib
DLTEST_LD='${CC} -bundle -Wl,-w ${CFLAGS} ${LDFLAGS}'
DLTEST_SUFFIX=".bundle"
else
DLTEST_LD='${SHLIB_LD}'
DLTEST_SUFFIX=""
|
| ︙ | ︙ |
Changes to unix/configure.ac.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 |
/* override */ #undef PACKAGE_STRING
#endif /* _TCLCONFIG */])
])
TCL_VERSION=9.0
TCL_MAJOR_VERSION=9
TCL_MINOR_VERSION=0
| | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/* override */ #undef PACKAGE_STRING
#endif /* _TCLCONFIG */])
])
TCL_VERSION=9.0
TCL_MAJOR_VERSION=9
TCL_MINOR_VERSION=0
TCL_PATCH_LEVEL=".2"
VERSION=${TCL_VERSION}
EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"}
EXTRA_BUILD_HTML=${EXTRA_BUILD_HTML:-"@:"}
#------------------------------------------------------------------------
# Setup configure arguments for bundled packages
|
| ︙ | ︙ | |||
532 533 534 535 536 537 538 |
AC_CHECK_HEADERS(libkern/OSAtomic.h)
AC_CHECK_FUNCS(OSSpinLockLock)
fi
AC_DEFINE(TCL_LOAD_FROM_MEMORY, 1,
[Can this platform load code from memory?])
AC_DEFINE(TCL_WIDE_CLICKS, 1,
[Does this platform have wide high-resolution clicks?])
| < < | | < < < < < < < | | | | | | | | | | | < < < < < < < | | | | | | | < | 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
AC_CHECK_HEADERS(libkern/OSAtomic.h)
AC_CHECK_FUNCS(OSSpinLockLock)
fi
AC_DEFINE(TCL_LOAD_FROM_MEMORY, 1,
[Can this platform load code from memory?])
AC_DEFINE(TCL_WIDE_CLICKS, 1,
[Does this platform have wide high-resolution clicks?])
AC_CACHE_CHECK([if weak import is available], tcl_cv_cc_weak_import, [
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
int rand(void) __attribute__((weak_import));
]], [[rand();]])],
[tcl_cv_cc_weak_import=yes],[tcl_cv_cc_weak_import=no])
CFLAGS=$hold_cflags])
if test $tcl_cv_cc_weak_import = yes; then
AC_DEFINE(HAVE_WEAK_IMPORT, 1, [Is weak import available?])
fi
AC_CACHE_CHECK([if Darwin SUSv3 extensions are available],
tcl_cv_cc_darwin_c_source, [
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#define _DARWIN_C_SOURCE 1
#include <sys/cdefs.h>
]], [[]])],[tcl_cv_cc_darwin_c_source=yes],[tcl_cv_cc_darwin_c_source=no])
CFLAGS=$hold_cflags])
if test $tcl_cv_cc_darwin_c_source = yes; then
AC_DEFINE(_DARWIN_C_SOURCE, 1,
[Are Darwin SUSv3 extensions available?])
fi
# Build .bundle dltest binaries in addition to .dylib
DLTEST_LD='${CC} -bundle -Wl,-w ${CFLAGS} ${LDFLAGS}'
DLTEST_SUFFIX=".bundle"
else
DLTEST_LD='${SHLIB_LD}'
DLTEST_SUFFIX=""
|
| ︙ | ︙ |
Changes to unix/tcl.spec.
1 2 3 4 5 6 |
# This file is the basis for a binary Tcl RPM for Linux.
%{!?directory:%define directory /usr/local}
Name: tcl
Summary: Tcl scripting language development environment
| | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# This file is the basis for a binary Tcl RPM for Linux.
%{!?directory:%define directory /usr/local}
Name: tcl
Summary: Tcl scripting language development environment
Version: 9.0.2
Release: 2
License: BSD
Group: Development/Languages
Source: https://prdownloads.sourceforge.net/tcl/tcl%{version}-src.tar.gz
URL: https://www.tcl-lang.org/
Buildroot: /var/tmp/%{name}%{version}
%description
The Tcl (Tool Command Language) provides a powerful platform for
creating integration applications that tie together diverse
applications, protocols, devices, and frameworks. When paired with
|
| ︙ | ︙ |
Changes to unix/tclConfig.h.in.
1 2 3 4 5 6 7 8 9 |
/* ../unix/tclConfig.h.in. Generated from configure.ac by autoheader. */
#ifndef _TCLCONFIG
#define _TCLCONFIG
/* Is gettimeofday() actually declared in <sys/time.h>? */
#undef GETTOD_NOT_DECLARED
| < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* ../unix/tclConfig.h.in. Generated from configure.ac by autoheader. */
#ifndef _TCLCONFIG
#define _TCLCONFIG
/* Is gettimeofday() actually declared in <sys/time.h>? */
#undef GETTOD_NOT_DECLARED
/* Define to 1 if the system has the type 'blkcnt_t'. */
#undef HAVE_BLKCNT_T
/* Defined when compiler supports casting to union type. */
#undef HAVE_CAST_TO_UNION
/* Define to 1 if you have the 'cfmakeraw' function. */
|
| ︙ | ︙ |
Changes to unix/tclLoadDyld.c.
| ︙ | ︙ | |||
15 16 17 18 19 20 21 | #include "tclInt.h" #ifndef MODULE_SCOPE # define MODULE_SCOPE extern #endif | < < < < < < < < < < < < < < < < < < < < < | < | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
#include "tclInt.h"
#ifndef MODULE_SCOPE
# define MODULE_SCOPE extern
#endif
/*
* Use includes for the API we're using.
*/
#include <dlfcn.h>
#if defined(TCL_LOAD_FROM_MEMORY)
#if defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include <mach-o/dyld.h>
#include <mach-o/fat.h>
#include <mach-o/swap.h>
#include <mach-o/arch.h>
#include <libkern/OSByteOrder.h>
#include <mach/mach.h>
typedef struct Tcl_DyldModuleHandle {
struct Tcl_DyldModuleHandle *nextPtr;
NSModule module;
} Tcl_DyldModuleHandle;
#endif /* TCL_LOAD_FROM_MEMORY */
typedef struct {
void *dlHandle;
#if defined(TCL_LOAD_FROM_MEMORY)
const struct mach_header *dyldLibHeader;
Tcl_DyldModuleHandle *modulePtr;
#endif
} Tcl_DyldLoadHandle;
/*
* Static functions defined in this file.
*/
static void * FindSymbol(Tcl_Interp *interp,
Tcl_LoadHandle loadHandle, const char *symbol);
static void UnloadFile(Tcl_LoadHandle handle);
/*
*----------------------------------------------------------------------
*
* TclpDlopen --
*
* Dynamically loads a binary code file into memory and returns a handle
* to the new code.
|
| ︙ | ︙ | |||
156 157 158 159 160 161 162 |
* function which should be used for this
* file. */
int flags)
{
Tcl_DyldLoadHandle *dyldLoadHandle;
Tcl_LoadHandle newHandle;
void *dlHandle = NULL;
| | < < < < < < < < | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
* function which should be used for this
* file. */
int flags)
{
Tcl_DyldLoadHandle *dyldLoadHandle;
Tcl_LoadHandle newHandle;
void *dlHandle = NULL;
#if defined(TCL_LOAD_FROM_MEMORY)
const struct mach_header *dyldLibHeader = NULL;
Tcl_DyldModuleHandle *modulePtr = NULL;
#endif
const char *errMsg = NULL;
int result;
Tcl_DString ds;
const char *nativePath, *nativeFileName = NULL;
int dlopenflags = 0;
/*
* First try the full path the user gave us. This is particularly
* important if the cwd is inside a vfs, and we are trying to load using a
* relative path.
*/
nativePath = (const char *)Tcl_FSGetNativePath(pathPtr);
if (Tcl_UtfToExternalDStringEx(interp, NULL, TclGetString(pathPtr),
TCL_INDEX_NONE, 0, &ds, NULL) != TCL_OK) {
Tcl_DStringFree(&ds);
return TCL_ERROR;
}
nativeFileName = Tcl_DStringValue(&ds);
/*
* Use (RTLD_NOW|RTLD_LOCAL) as default, see [Bug #3216070]
*/
if (flags & TCL_LOAD_GLOBAL) {
dlopenflags |= RTLD_GLOBAL;
} else {
|
| ︙ | ︙ | |||
215 216 217 218 219 220 221 |
*/
dlHandle = dlopen(nativeFileName, dlopenflags);
if (!dlHandle) {
errMsg = dlerror();
}
}
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < | | < < < < < < < | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
*/
dlHandle = dlopen(nativeFileName, dlopenflags);
if (!dlHandle) {
errMsg = dlerror();
}
}
if (dlHandle) {
dyldLoadHandle = (Tcl_DyldLoadHandle *)Tcl_Alloc(sizeof(Tcl_DyldLoadHandle));
dyldLoadHandle->dlHandle = dlHandle;
#if defined(TCL_LOAD_FROM_MEMORY)
dyldLoadHandle->dyldLibHeader = dyldLibHeader;
dyldLoadHandle->modulePtr = modulePtr;
#endif /* TCL_LOAD_FROM_MEMORY */
newHandle = (Tcl_LoadHandle)Tcl_Alloc(sizeof(*newHandle));
newHandle->clientData = dyldLoadHandle;
newHandle->findSymbolProcPtr = &FindSymbol;
newHandle->unloadFileProcPtr = &UnloadFile;
*unloadProcPtr = &UnloadFile;
*loadHandle = newHandle;
result = TCL_OK;
} else {
Tcl_Obj *errObj;
TclNewObj(errObj);
if (errMsg != NULL) {
Tcl_AppendToObj(errObj, errMsg, TCL_INDEX_NONE);
}
Tcl_SetObjResult(interp, errObj);
result = TCL_ERROR;
}
Tcl_DStringFree(&ds);
return result;
}
|
| ︙ | ︙ | |||
351 352 353 354 355 356 357 |
if (Tcl_UtfToExternalDStringEx(interp, NULL, symbol, TCL_INDEX_NONE, 0, &ds, NULL) != TCL_OK) {
Tcl_DStringFree(&ds);
return NULL;
}
native = Tcl_DStringValue(&ds);
if (dyldLoadHandle->dlHandle) {
| < < | | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
if (Tcl_UtfToExternalDStringEx(interp, NULL, symbol, TCL_INDEX_NONE, 0, &ds, NULL) != TCL_OK) {
Tcl_DStringFree(&ds);
return NULL;
}
native = Tcl_DStringValue(&ds);
if (dyldLoadHandle->dlHandle) {
proc = (Tcl_LibraryInitProc *)dlsym(dyldLoadHandle->dlHandle, native);
if (!proc) {
errMsg = dlerror();
}
} else {
#if defined(TCL_LOAD_FROM_MEMORY)
NSSymbol nsSymbol = NULL;
Tcl_DString newName;
/*
* dyld adds an underscore to the beginning of symbol names.
*/
|
| ︙ | ︙ | |||
411 412 413 414 415 416 417 |
nsSymbol = NSLookupSymbolInModule(
dyldLoadHandle->modulePtr->module, native);
}
if (nsSymbol) {
proc = (Tcl_LibraryInitProc *)NSAddressOfSymbol(nsSymbol);
}
Tcl_DStringFree(&newName);
| | | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
nsSymbol = NSLookupSymbolInModule(
dyldLoadHandle->modulePtr->module, native);
}
if (nsSymbol) {
proc = (Tcl_LibraryInitProc *)NSAddressOfSymbol(nsSymbol);
}
Tcl_DStringFree(&newName);
#endif /* TCL_LOAD_FROM_MEMORY */
}
Tcl_DStringFree(&ds);
if (errMsg && (interp != NULL)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"cannot find symbol \"%s\": %s", symbol, errMsg));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol,
(char *)NULL);
|
| ︙ | ︙ | |||
452 453 454 455 456 457 458 |
Tcl_LoadHandle loadHandle) /* loadHandle returned by a previous call to
* TclpDlopen(). The loadHandle is a token
* that represents the loaded file. */
{
Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *)loadHandle->clientData;
if (dyldLoadHandle->dlHandle) {
| < < | | | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
Tcl_LoadHandle loadHandle) /* loadHandle returned by a previous call to
* TclpDlopen(). The loadHandle is a token
* that represents the loaded file. */
{
Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *)loadHandle->clientData;
if (dyldLoadHandle->dlHandle) {
(void) dlclose(dyldLoadHandle->dlHandle);
} else {
#if defined(TCL_LOAD_FROM_MEMORY)
Tcl_DyldModuleHandle *modulePtr = dyldLoadHandle->modulePtr;
while (modulePtr != NULL) {
void *ptr = modulePtr;
(void) NSUnLinkModule(modulePtr->module,
NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
modulePtr = modulePtr->nextPtr;
Tcl_Free(ptr);
}
#endif /* TCL_LOAD_FROM_MEMORY */
}
Tcl_Free(dyldLoadHandle);
Tcl_Free(loadHandle);
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
497 498 499 500 501 502 503 |
MODULE_SCOPE void *
TclpLoadMemoryGetBuffer(
size_t size) /* Size of desired buffer. */
{
void *buffer = NULL;
/*
| < < < < < | | | | | | < | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
MODULE_SCOPE void *
TclpLoadMemoryGetBuffer(
size_t size) /* Size of desired buffer. */
{
void *buffer = NULL;
/*
* We must allocate the buffer using vm_allocate, because
* NSCreateObjectFileImageFromMemory will dispose of it using
* vm_deallocate.
*/
if (vm_allocate(mach_task_self(), (vm_address_t *) &buffer, size, 1)) {
buffer = NULL;
}
return buffer;
}
#endif /* TCL_LOAD_FROM_MEMORY */
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 |
TclpLoadMemory(
void *buffer, /* Buffer containing the desired code
* (allocated with TclpLoadMemoryGetBuffer). */
size_t size, /* Allocation size of buffer. */
Tcl_Size codeSize, /* Size of code data read into buffer or -1 if
* an error occurred and the buffer should
* just be freed. */
Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr,
/* Filled with address of Tcl_FSUnloadFileProc
* function which should be used for this
* file. */
int flags)
{
Tcl_LoadHandle newHandle;
Tcl_DyldLoadHandle *dyldLoadHandle;
NSObjectFileImage dyldObjFileImage = NULL;
Tcl_DyldModuleHandle *modulePtr;
NSModule module;
| > < | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
TclpLoadMemory(
void *buffer, /* Buffer containing the desired code
* (allocated with TclpLoadMemoryGetBuffer). */
size_t size, /* Allocation size of buffer. */
Tcl_Size codeSize, /* Size of code data read into buffer or -1 if
* an error occurred and the buffer should
* just be freed. */
const char *path,
Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr,
/* Filled with address of Tcl_FSUnloadFileProc
* function which should be used for this
* file. */
int flags)
{
Tcl_LoadHandle newHandle;
Tcl_DyldLoadHandle *dyldLoadHandle;
NSObjectFileImage dyldObjFileImage = NULL;
Tcl_DyldModuleHandle *modulePtr;
NSModule module;
int nsflags = NSLINKMODULE_OPTION_RETURN_ON_ERROR;
/*
* Try to create an object file image that we can load from.
*/
if (codeSize >= 0) {
|
| ︙ | ︙ | |||
625 626 627 628 629 630 631 |
if (ms && !(ms >= mh_size && mh->magic == mh_magic &&
mh->filetype == MH_BUNDLE)) {
err = NSObjectFileImageInappropriateFile;
}
if (err == NSObjectFileImageSuccess) {
err = NSCreateObjectFileImageFromMemory(buffer, codeSize,
&dyldObjFileImage);
| < < < < < | 468 469 470 471 472 473 474 475 476 477 478 479 480 481 |
if (ms && !(ms >= mh_size && mh->magic == mh_magic &&
mh->filetype == MH_BUNDLE)) {
err = NSObjectFileImageInappropriateFile;
}
if (err == NSObjectFileImageSuccess) {
err = NSCreateObjectFileImageFromMemory(buffer, codeSize,
&dyldObjFileImage);
}
}
/*
* If it went wrong (or we were asked to just deallocate), get rid of the
* memory block.
*/
|
| ︙ | ︙ | |||
653 654 655 656 657 658 659 |
if (!(flags & 1)) {
nsflags |= NSLINKMODULE_OPTION_PRIVATE;
}
if (!(flags & 2)) {
nsflags |= NSLINKMODULE_OPTION_BINDNOW;
}
| | | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
if (!(flags & 1)) {
nsflags |= NSLINKMODULE_OPTION_PRIVATE;
}
if (!(flags & 2)) {
nsflags |= NSLINKMODULE_OPTION_BINDNOW;
}
module = NSLinkModule(dyldObjFileImage, (path ? path : "[Memory Based Bundle]"), nsflags);
NSDestroyObjectFileImage(dyldObjFileImage);
if (!module) {
NSLinkEditErrors editError;
int errorNumber;
const char *errorName, *errMsg;
NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg);
|
| ︙ | ︙ |
Changes to unix/tclUnixFCmd.c.
| ︙ | ︙ | |||
240 241 242 243 244 245 246 |
return realpath(path, resolved);
}
#else
# define Realpath realpath
#endif /* PURIFY */
#ifndef NO_REALPATH
| < < < < < < < < < < < < < < < < < < | < < < < < < < | < | | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
return realpath(path, resolved);
}
#else
# define Realpath realpath
#endif /* PURIFY */
#ifndef NO_REALPATH
# define haveRealpath 1
#endif /* NO_REALPATH */
#ifdef HAVE_FTS
#if defined(HAVE_STRUCT_STAT64) && !defined(__APPLE__)
/* fts doesn't do stat64 */
# define noFtsStat 1
#else
# define noFtsStat 0
#endif
#endif /* HAVE_FTS */
/*
*---------------------------------------------------------------------------
|
| ︙ | ︙ |
Changes to unix/tclUnixInit.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclUnixInit.c -- * * Contains the Unix-specific interpreter initialization functions. * * Copyright © 1995-1997 Sun Microsystems, Inc. * Copyright © 1999 Scriptics Corporation. * All rights reserved. */ #include "tclInt.h" #ifdef HAVE_LANGINFO # include <langinfo.h> | < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclUnixInit.c -- * * Contains the Unix-specific interpreter initialization functions. * * Copyright © 1995-1997 Sun Microsystems, Inc. * Copyright © 1999 Scriptics Corporation. * All rights reserved. */ #include "tclInt.h" #ifdef HAVE_LANGINFO # include <langinfo.h> #endif #include <sys/resource.h> #if defined(__FreeBSD__) && defined(__GNUC__) # include <floatingpoint.h> #endif #if defined(__bsdi__) # include <sys/param.h> |
| ︙ | ︙ | |||
317 318 319 320 321 322 323 |
{"zh_tw.big5", "big5"},
};
#ifdef HAVE_COREFOUNDATION
static int MacOSXGetLibraryPath(Tcl_Interp *interp,
int maxPathLen, char *tclLibPath);
#endif /* HAVE_COREFOUNDATION */
| < < < < < < < < < < < < < < | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
{"zh_tw.big5", "big5"},
};
#ifdef HAVE_COREFOUNDATION
static int MacOSXGetLibraryPath(Tcl_Interp *interp,
int maxPathLen, char *tclLibPath);
#endif /* HAVE_COREFOUNDATION */
/*
*---------------------------------------------------------------------------
*
* TclpInitPlatform --
*
* Initialize all the platform-dependent things like signals and
|
| ︙ | ︙ | |||
418 419 420 421 422 423 424 |
* In case the initial locale is not "C", ensure that the numeric
* processing is done in "C" locale regardless. This is needed because Tcl
* relies on routines like strtol/strtoul, but should not have locale dependent
* behavior.
*/
setlocale(LC_NUMERIC, "C");
| < < < < < < < < < < | 397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
* In case the initial locale is not "C", ensure that the numeric
* processing is done in "C" locale regardless. This is needed because Tcl
* relies on routines like strtol/strtoul, but should not have locale dependent
* behavior.
*/
setlocale(LC_NUMERIC, "C");
}
/*
*---------------------------------------------------------------------------
*
* TclpInitLibraryPath --
*
|
| ︙ | ︙ | |||
739 740 741 742 743 744 745 | * Side effects: * Sets "tclDefaultLibrary", "tcl_pkgPath", and "tcl_platform" Tcl * variables. * *---------------------------------------------------------------------- */ | | | 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 | * Side effects: * Sets "tclDefaultLibrary", "tcl_pkgPath", and "tcl_platform" Tcl * variables. * *---------------------------------------------------------------------- */ #if defined(HAVE_COREFOUNDATION) /* * Helper because whether CFLocaleCopyCurrent and CFLocaleGetIdentifier are * strongly or weakly bound varies by version of OSX, triggering warnings. */ static inline void InitMacLocaleInfoVar( |
| ︙ | ︙ | |||
774 775 776 777 778 779 780 |
if (!Tcl_CreateNamespace(interp, "::tcl::mac", NULL, NULL)) {
Tcl_ResetResult(interp);
}
Tcl_SetVar2(interp, "::tcl::mac::locale", NULL, loc, TCL_GLOBAL_ONLY);
}
CFRelease(localeRef);
}
| | | 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 |
if (!Tcl_CreateNamespace(interp, "::tcl::mac", NULL, NULL)) {
Tcl_ResetResult(interp);
}
Tcl_SetVar2(interp, "::tcl::mac::locale", NULL, loc, TCL_GLOBAL_ONLY);
}
CFRelease(localeRef);
}
#endif /*defined(HAVE_COREFOUNDATION)*/
void
TclpSetVariables(
Tcl_Interp *interp)
{
#ifdef __CYGWIN__
SYSTEM_INFO sysInfo;
|
| ︙ | ︙ | |||
799 800 801 802 803 804 805 |
#ifdef HAVE_COREFOUNDATION
char tclLibPath[MAXPATHLEN + 1];
/*
* Set msgcat fallback locale to current CFLocale identifier.
*/
| < < | 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 |
#ifdef HAVE_COREFOUNDATION
char tclLibPath[MAXPATHLEN + 1];
/*
* Set msgcat fallback locale to current CFLocale identifier.
*/
InitMacLocaleInfoVar(CFLocaleCopyCurrent, CFLocaleGetIdentifier, interp);
if (MacOSXGetLibraryPath(interp, MAXPATHLEN, tclLibPath) == TCL_OK) {
const char *str;
CFBundleRef bundleRef;
Tcl_DString ds;
Tcl_SetVar2(interp, "tclDefaultLibrary", NULL, tclLibPath, TCL_GLOBAL_ONLY);
|
| ︙ | ︙ |
Changes to unix/tclUnixPort.h.
| ︙ | ︙ | |||
555 556 557 558 559 560 561 | /* *--------------------------------------------------------------------------- * Include AvailabilityMacros.h here (when available) to ensure any symbolic * MAC_OS_X_VERSION_* constants passed on the command line are translated. *--------------------------------------------------------------------------- */ | < | < < < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < | 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 |
/*
*---------------------------------------------------------------------------
* Include AvailabilityMacros.h here (when available) to ensure any symbolic
* MAC_OS_X_VERSION_* constants passed on the command line are translated.
*---------------------------------------------------------------------------
*/
# include <AvailabilityMacros.h>
/*
*---------------------------------------------------------------------------
* Support for weak import.
*---------------------------------------------------------------------------
*/
# ifdef HAVE_WEAK_IMPORT
# ifndef WEAK_IMPORT_ATTRIBUTE
# define WEAK_IMPORT_ATTRIBUTE __attribute__((weak_import))
# endif
# endif /* HAVE_WEAK_IMPORT */
/*
* For now, test exec-17.1 fails (I/O setup after closing stdout) with
* posix_spawnp(), but the classic implementation (based on fork()+execvp())
* works well under macOS.
*/
# undef HAVE_POSIX_SPAWNP
# undef HAVE_VFORK
|
| ︙ | ︙ |
Changes to win/Makefile.in.
| ︙ | ︙ | |||
562 563 564 565 566 567 568 |
$(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) ${TCL_ZIP_FILE}
$(CC) $(CFLAGS) $(TCLSH_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \
tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE)
$(COPY) tclsh.exe.manifest $(TCLSH).manifest
@VC_MANIFEST_EMBED_EXE@
@if test "${ZIPFS_BUILD}" = "2" ; then \
cat ${TCL_ZIP_FILE} >> ${TCLSH}; \
| < < | 562 563 564 565 566 567 568 569 570 571 572 573 574 575 |
$(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) ${TCL_ZIP_FILE}
$(CC) $(CFLAGS) $(TCLSH_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \
tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE)
$(COPY) tclsh.exe.manifest $(TCLSH).manifest
@VC_MANIFEST_EMBED_EXE@
@if test "${ZIPFS_BUILD}" = "2" ; then \
cat ${TCL_ZIP_FILE} >> ${TCLSH}; \
fi
cat32.$(OBJEXT): cat.c
$(CC) -c $(CC_SWITCHES) -DUNICODE -D_UNICODE @DEPARG@ $(CC_OBJNAME)
$(CAT32): cat32.$(OBJEXT)
$(CC) $(CFLAGS) cat32.$(OBJEXT) $(CC_EXENAME) $(LIBS) $(LDFLAGS_CONSOLE)
|
| ︙ | ︙ | |||
587 588 589 590 591 592 593 |
${TCL_DLL_FILE}: ${TCL_LIB_FILE} ${TCL_OBJS} tcl.$(RES) @ZLIB_DLL_FILE@ @TOMMATH_DLL_FILE@ ${TCL_ZIP_FILE}
@$(RM) ${TCL_DLL_FILE} $(TCL_LIB_FILE)
@MAKE_DLL@ ${TCL_OBJS} tcl.$(RES) $(SHLIB_LD_LIBS)
$(COPY) tclsh.exe.manifest ${TCL_DLL_FILE}.manifest
@VC_MANIFEST_EMBED_DLL@
@if test "${ZIPFS_BUILD}" = "1" ; then \
cat ${TCL_ZIP_FILE} >> ${TCL_DLL_FILE}; \
| < < | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 |
${TCL_DLL_FILE}: ${TCL_LIB_FILE} ${TCL_OBJS} tcl.$(RES) @ZLIB_DLL_FILE@ @TOMMATH_DLL_FILE@ ${TCL_ZIP_FILE}
@$(RM) ${TCL_DLL_FILE} $(TCL_LIB_FILE)
@MAKE_DLL@ ${TCL_OBJS} tcl.$(RES) $(SHLIB_LD_LIBS)
$(COPY) tclsh.exe.manifest ${TCL_DLL_FILE}.manifest
@VC_MANIFEST_EMBED_DLL@
@if test "${ZIPFS_BUILD}" = "1" ; then \
cat ${TCL_ZIP_FILE} >> ${TCL_DLL_FILE}; \
fi
ifeq (,$(findstring --disable-shared,$(PKG_CFG_ARGS)))
${TCL_LIB_FILE}:
@$(RM) ${TCL_DLL_FILE} $(TCL_LIB_FILE)
else
${TCL_LIB_FILE}: ${TCL_OBJS} tclWinPanic.$(OBJEXT) ${DDE_OBJS} ${REG_OBJS}
|
| ︙ | ︙ |
Changes to win/configure.
| ︙ | ︙ | |||
2407 2408 2409 2410 2411 2412 2413 | # versions of autoconf incorrectly set SHELL to /bin/bash instead of # /bin/sh. The bash shell seems to suffer from some strange failures. SHELL=/bin/sh TCL_VERSION=9.0 TCL_MAJOR_VERSION=9 TCL_MINOR_VERSION=0 | | | 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 | # versions of autoconf incorrectly set SHELL to /bin/bash instead of # /bin/sh. The bash shell seems to suffer from some strange failures. SHELL=/bin/sh TCL_VERSION=9.0 TCL_MAJOR_VERSION=9 TCL_MINOR_VERSION=0 TCL_PATCH_LEVEL=".2" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.4 TCL_DDE_MAJOR_VERSION=1 TCL_DDE_MINOR_VERSION=4 DDEVER=$TCL_DDE_MAJOR_VERSION$TCL_DDE_MINOR_VERSION |
| ︙ | ︙ | |||
4232 4233 4234 4235 4236 4237 4238 |
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_win32" >&5
printf "%s\n" "$ac_cv_win32" >&6; }
if test "$ac_cv_win32" != "yes"; then
as_fn_error $? "${CC} cannot produce win32 executables." "$LINENO" 5
fi
| | | 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 |
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_win32" >&5
printf "%s\n" "$ac_cv_win32" >&6; }
if test "$ac_cv_win32" != "yes"; then
as_fn_error $? "${CC} cannot produce win32 executables." "$LINENO" 5
fi
if test "$do64bit" != "arm64" -a "$do64bit" != "aarch64"; then
extra_cflags="$extra_cflags -DHAVE_CPUID=1"
fi
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working -municode linker flag" >&5
printf %s "checking for working -municode linker flag... " >&6; }
if test ${ac_cv_municode+y}
|
| ︙ | ︙ | |||
4953 4954 4955 4956 4957 4958 4959 | if test "$do64bit" != "no" then : printf "%s\n" "#define MP_64BIT 1" >>confdefs.h | | | 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 |
if test "$do64bit" != "no"
then :
printf "%s\n" "#define MP_64BIT 1" >>confdefs.h
if test "$do64bit" = "arm64" -o "$do64bit" = "aarch64"
then :
if test "$GCC" = "yes"
then :
ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64-arm/libz.dll.a
|
| ︙ | ︙ | |||
5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 |
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_intrinsics" >&5
printf "%s\n" "$tcl_cv_intrinsics" >&6; }
if test "$tcl_cv_intrinsics" = "yes"; then
printf "%s\n" "#define HAVE_INTRIN_H 1" >>confdefs.h
fi
# See if the <wspiapi.h> header file is present
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wspiapi.h" >&5
printf %s "checking for wspiapi.h... " >&6; }
if test ${tcl_cv_wspiapi_h+y}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 |
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_intrinsics" >&5
printf "%s\n" "$tcl_cv_intrinsics" >&6; }
if test "$tcl_cv_intrinsics" = "yes"; then
printf "%s\n" "#define HAVE_INTRIN_H 1" >>confdefs.h
fi
# See if the compiler supports cpuid header.
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for cpuid.h" >&5
printf %s "checking for cpuid.h... " >&6; }
if test ${tcl_cv_cpuid_h+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <cpuid.h>
int
main (void)
{
__get_cpuid(0, 0, 0, 0, 0);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
tcl_cv_cpuid_h=yes
else case e in #(
e) tcl_cv_cpuid_h=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cpuid_h" >&5
printf "%s\n" "$tcl_cv_cpuid_h" >&6; }
if test "$tcl_cv_cpuid_h" = "yes"; then
printf "%s\n" "#define HAVE_CPUID_H 1" >>confdefs.h
fi
# See if the <wspiapi.h> header file is present
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wspiapi.h" >&5
printf %s "checking for wspiapi.h... " >&6; }
if test ${tcl_cv_wspiapi_h+y}
|
| ︙ | ︙ |
Changes to win/configure.ac.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 | # versions of autoconf incorrectly set SHELL to /bin/bash instead of # /bin/sh. The bash shell seems to suffer from some strange failures. SHELL=/bin/sh TCL_VERSION=9.0 TCL_MAJOR_VERSION=9 TCL_MINOR_VERSION=0 | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # versions of autoconf incorrectly set SHELL to /bin/bash instead of # /bin/sh. The bash shell seems to suffer from some strange failures. SHELL=/bin/sh TCL_VERSION=9.0 TCL_MAJOR_VERSION=9 TCL_MINOR_VERSION=0 TCL_PATCH_LEVEL=".2" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.4 TCL_DDE_MAJOR_VERSION=1 TCL_DDE_MINOR_VERSION=4 DDEVER=$TCL_DDE_MAJOR_VERSION$TCL_DDE_MINOR_VERSION |
| ︙ | ︙ | |||
125 126 127 128 129 130 131 |
tommath_lib_name=tommath.lib
AS_IF([test "$tcl_ok" = "yes"], [
AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}])
AC_SUBST(TOMMATH_DLL_FILE,[\${TOMMATH_DLL_FILE}])
AC_DEFINE(TCL_WITH_EXTERNAL_TOMMATH, 1, [Tcl with external libtommath])
AS_IF([test "$do64bit" != "no"], [
AC_DEFINE(MP_64BIT, 1, [Using libtommath.dll in 64-bit mode])
| | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
tommath_lib_name=tommath.lib
AS_IF([test "$tcl_ok" = "yes"], [
AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}])
AC_SUBST(TOMMATH_DLL_FILE,[\${TOMMATH_DLL_FILE}])
AC_DEFINE(TCL_WITH_EXTERNAL_TOMMATH, 1, [Tcl with external libtommath])
AS_IF([test "$do64bit" != "no"], [
AC_DEFINE(MP_64BIT, 1, [Using libtommath.dll in 64-bit mode])
AS_IF([test "$do64bit" = "arm64" -o "$do64bit" = "aarch64"], [
AS_IF([test "$GCC" = "yes"],[
AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64-arm/libz.dll.a])
AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64-arm/libtommath.dll.a])
zlib_lib_name=libz.dll.a
tommath_lib_name=libtommath.dll.a
], [
AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64-arm/zdll.lib])
|
| ︙ | ︙ | |||
250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
[tcl_cv_intrinsics=yes],
[tcl_cv_intrinsics=no])
)
if test "$tcl_cv_intrinsics" = "yes"; then
AC_DEFINE(HAVE_INTRIN_H, 1,
[Defined when the compilers supports intrinsics])
fi
# See if the <wspiapi.h> header file is present
AC_CACHE_CHECK(for wspiapi.h,
tcl_cv_wspiapi_h,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <wspiapi.h>
| > > > > > > > > > > > > > > > > > | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
[tcl_cv_intrinsics=yes],
[tcl_cv_intrinsics=no])
)
if test "$tcl_cv_intrinsics" = "yes"; then
AC_DEFINE(HAVE_INTRIN_H, 1,
[Defined when the compilers supports intrinsics])
fi
# See if the compiler supports cpuid header.
AC_CACHE_CHECK(for cpuid.h,
tcl_cv_cpuid_h,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <cpuid.h>
]], [[
__get_cpuid(0, 0, 0, 0, 0);
]])],
[tcl_cv_cpuid_h=yes],
[tcl_cv_cpuid_h=no])
)
if test "$tcl_cv_cpuid_h" = "yes"; then
AC_DEFINE(HAVE_CPUID_H, 1,
[Defined when cpuid.h exists])
fi
# See if the <wspiapi.h> header file is present
AC_CACHE_CHECK(for wspiapi.h,
tcl_cv_wspiapi_h,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <wspiapi.h>
|
| ︙ | ︙ |
Changes to win/tcl.m4.
| ︙ | ︙ | |||
589 590 591 592 593 594 595 |
]], [[]])],
[ac_cv_win32=no],
[ac_cv_win32=yes])
)
if test "$ac_cv_win32" != "yes"; then
AC_MSG_ERROR([${CC} cannot produce win32 executables.])
fi
| | | 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 |
]], [[]])],
[ac_cv_win32=no],
[ac_cv_win32=yes])
)
if test "$ac_cv_win32" != "yes"; then
AC_MSG_ERROR([${CC} cannot produce win32 executables.])
fi
if test "$do64bit" != "arm64" -a "$do64bit" != "aarch64"; then
extra_cflags="$extra_cflags -DHAVE_CPUID=1"
fi
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain"
AC_CACHE_CHECK(for working -municode linker flag,
ac_cv_municode,
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
| ︙ | ︙ |
Changes to win/tclWin32Dll.c.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | * Copyright © 1998-2000 Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclWinInt.h" | | > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | * Copyright © 1998-2000 Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclWinInt.h" #if defined(HAVE_CPUID_H) # include <cpuid.h> #elif defined(_MSC_VER) # include <intrin.h> #endif /* * The following variables keep track of information about this DLL on a * per-instance basis. Each time this DLL is loaded, it gets its own new data * segment with its own copy of all static and global information. |
| ︙ | ︙ | |||
433 434 435 436 437 438 439 |
int
TclWinCPUID(
int index, /* Which CPUID value to retrieve. */
int *regsPtr) /* Registers after the CPUID. */
{
int status = TCL_ERROR;
| > > > > > > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
int
TclWinCPUID(
int index, /* Which CPUID value to retrieve. */
int *regsPtr) /* Registers after the CPUID. */
{
int status = TCL_ERROR;
#if defined(HAVE_CPUID_H)
unsigned int *regs = (unsigned int *)regsPtr;
__get_cpuid(index, ®s[0], ®s[1], ®s[2], ®s[3]);
status = TCL_OK;
#elif defined(_MSC_VER) && defined(_WIN64) && defined(HAVE_CPUID)
__cpuid((int *)regsPtr, index);
status = TCL_OK;
#elif defined (_M_IX86)
/*
* Define a structure in the stack frame to hold the registers.
*/
struct {
DWORD dw0;
DWORD dw1;
|
| ︙ | ︙ | |||
607 608 609 610 611 612 613 |
regsPtr[3] = regs.dw3;
status = TCL_OK;
} __except(EXCEPTION_EXECUTE_HANDLER) {
/* do nothing */
}
| < | 493 494 495 496 497 498 499 500 501 502 503 504 505 506 |
regsPtr[3] = regs.dw3;
status = TCL_OK;
} __except(EXCEPTION_EXECUTE_HANDLER) {
/* do nothing */
}
#else
(void)index;
(void)regsPtr;
/*
* Don't know how to do assembly code for this compiler and/or
* architecture.
*/
|
| ︙ | ︙ |
Changes to win/tclWinFile.c.
| ︙ | ︙ | |||
855 856 857 858 859 860 861 | * The computed path is stored. * *--------------------------------------------------------------------------- */ void TclpFindExecutable( | | < < | 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 |
* The computed path is stored.
*
*---------------------------------------------------------------------------
*/
void
TclpFindExecutable(
TCL_UNUSED(const char *))
{
WCHAR wName[MAX_PATH];
char name[MAX_PATH * 3];
GetModuleFileNameW(NULL, wName, sizeof(wName)/sizeof(WCHAR));
WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, sizeof(name), NULL, NULL);
TclWinNoBackslash(name);
TclSetObjNameOfExecutable(Tcl_NewStringObj(name, TCL_INDEX_NONE), NULL);
}
|
| ︙ | ︙ |
Changes to win/tclWinInit.c.
| ︙ | ︙ | |||
39 40 41 42 43 44 45 |
* The following arrays contain the human readable strings for the
* processor values.
*/
#define NUMPROCESSORS 15
static const char *const processors[NUMPROCESSORS] = {
"intel", "mips", "alpha", "ppc", "shx", "arm", "ia64", "alpha64", "msil",
| | > > > > > > > > > < < < < < | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
* The following arrays contain the human readable strings for the
* processor values.
*/
#define NUMPROCESSORS 15
static const char *const processors[NUMPROCESSORS] = {
"intel", "mips", "alpha", "ppc", "shx", "arm", "ia64", "alpha64", "msil",
"amd64", "ia32_on_win64", "neutral", "arm64", "arm32_on_win64",
"ia32_on_arm64"
};
/*
* Forward declarations
*/
static TclInitProcessGlobalValueProc InitializeDefaultLibraryDir;
static TclInitProcessGlobalValueProc InitializeSourceLibraryDir;
static void AppendEnvironment(Tcl_Obj *listPtr, const char *lib);
/*
* The default directory in which the init.tcl file is expected to be found.
*/
static ProcessGlobalValue defaultLibraryDir =
{0, 0, NULL, NULL, InitializeDefaultLibraryDir, NULL, NULL};
static ProcessGlobalValue sourceLibraryDir =
{0, 0, NULL, NULL, InitializeSourceLibraryDir, NULL, NULL};
/*
*---------------------------------------------------------------------------
*
* TclpInitPlatform --
*
* Initialize all the platform-dependent things like signals,
|
| ︙ | ︙ | |||
399 400 401 402 403 404 405 |
{
UINT acp = GetACP();
Tcl_DStringInit(bufPtr);
if (acp == CP_UTF8) {
Tcl_DStringAppend(bufPtr, "utf-8", 5);
} else {
| | | > | 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 |
{
UINT acp = GetACP();
Tcl_DStringInit(bufPtr);
if (acp == CP_UTF8) {
Tcl_DStringAppend(bufPtr, "utf-8", 5);
} else {
Tcl_DStringSetLength(bufPtr, 2 + TCL_INTEGER_SPACE);
snprintf(Tcl_DStringValue(bufPtr), 2 + TCL_INTEGER_SPACE, "cp%d",
GetACP());
Tcl_DStringSetLength(bufPtr, strlen(Tcl_DStringValue(bufPtr)));
}
return Tcl_DStringValue(bufPtr);
}
const char *
TclpGetUserName(
|
| ︙ | ︙ | |||
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
*----------------------------------------------------------------------
*/
void
TclpSetVariables(
Tcl_Interp *interp) /* Interp to initialize. */
{
const char *ptr;
char buffer[TCL_INTEGER_SPACE * 2];
union {
SYSTEM_INFO info;
OemId oemId;
} sys;
static OSVERSIONINFOW osInfo;
static int osInfoInitialized = 0;
Tcl_DString ds;
Tcl_SetVar2Ex(interp, "tclDefaultLibrary", NULL,
TclGetProcessGlobalValue(&defaultLibraryDir), TCL_GLOBAL_ONLY);
if (!osInfoInitialized) {
HMODULE handle = GetModuleHandleW(L"NTDLL");
| > | | > | | < | > | 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
*----------------------------------------------------------------------
*/
void
TclpSetVariables(
Tcl_Interp *interp) /* Interp to initialize. */
{
typedef int(__stdcall getVersionProc)(void *);
const char *ptr;
char buffer[TCL_INTEGER_SPACE * 2];
union {
SYSTEM_INFO info;
OemId oemId;
} sys;
static OSVERSIONINFOW osInfo;
static int osInfoInitialized = 0;
Tcl_DString ds;
Tcl_SetVar2Ex(interp, "tclDefaultLibrary", NULL,
TclGetProcessGlobalValue(&defaultLibraryDir), TCL_GLOBAL_ONLY);
if (!osInfoInitialized) {
HMODULE handle = GetModuleHandleW(L"NTDLL");
getVersionProc *getVersion = (getVersionProc *) (void *)
GetProcAddress(handle, "RtlGetVersion");
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
if (!getVersion || getVersion(&osInfo)) {
GetVersionExW(&osInfo);
}
osInfoInitialized = 1;
}
GetSystemInfo(&sys.info);
/*
* Define the tcl_platform array.
*/
Tcl_SetVar2(interp, "tcl_platform", "platform", "windows",
TCL_GLOBAL_ONLY);
Tcl_SetVar2(interp, "tcl_platform", "os", "Windows NT", TCL_GLOBAL_ONLY);
if (osInfo.dwMajorVersion == 10 && osInfo.dwBuildNumber >= 22000) {
osInfo.dwMajorVersion = 11;
}
snprintf(buffer, sizeof(buffer), "%ld.%ld",
osInfo.dwMajorVersion, osInfo.dwMinorVersion);
Tcl_SetVar2(interp, "tcl_platform", "osVersion", buffer, TCL_GLOBAL_ONLY);
if (sys.oemId.wProcessorArchitecture < NUMPROCESSORS) {
Tcl_SetVar2(interp, "tcl_platform", "machine",
processors[sys.oemId.wProcessorArchitecture],
TCL_GLOBAL_ONLY);
}
|
| ︙ | ︙ | |||
538 539 540 541 542 543 544 |
TCL_GLOBAL_ONLY);
Tcl_DStringFree(&ds);
/*
* Define what the platform PATH separator is. [TIP #315]
*/
| | | 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
TCL_GLOBAL_ONLY);
Tcl_DStringFree(&ds);
/*
* Define what the platform PATH separator is. [TIP #315]
*/
Tcl_SetVar2(interp, "tcl_platform", "pathSeparator", ";", TCL_GLOBAL_ONLY);
}
/*
*----------------------------------------------------------------------
*
* TclpFindVariable --
*
|
| ︙ | ︙ |
Changes to win/tclWinInt.h.
| ︙ | ︙ | |||
87 88 89 90 91 92 93 | /* * State of the pipe-worker. * * State PTI_STATE_STOP possible from idle state only, worker owns TI structure. * Otherwise PTI_STATE_END used (main thread hold ownership of the TI). */ | | | | | | | > | > | > | > | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
/*
* State of the pipe-worker.
*
* State PTI_STATE_STOP possible from idle state only, worker owns TI structure.
* Otherwise PTI_STATE_END used (main thread hold ownership of the TI).
*/
enum PipeWorkerStates {
PTI_STATE_IDLE = 0, /* idle or not yet initialzed */
PTI_STATE_WORK = 1, /* in work */
PTI_STATE_STOP = 2, /* thread should stop work (owns TI structure) */
PTI_STATE_END = 4, /* thread should stop work (worker is busy) */
PTI_STATE_DOWN = 8 /* worker is down */
};
MODULE_SCOPE
TclPipeThreadInfo * TclPipeThreadCreateTI(TclPipeThreadInfo **pipeTIPtr,
void *clientData, HANDLE wakeEvent);
MODULE_SCOPE int TclPipeThreadWaitForSignal(
TclPipeThreadInfo **pipeTIPtr);
static inline void
TclPipeThreadSignal(
TclPipeThreadInfo **pipeTIPtr)
{
TclPipeThreadInfo *pipeTI = *pipeTIPtr;
if (pipeTI) {
SetEvent(pipeTI->evControl);
}
};
static inline int
TclPipeThreadIsAlive(
TclPipeThreadInfo **pipeTIPtr)
{
TclPipeThreadInfo *pipeTI = *pipeTIPtr;
return (pipeTI && pipeTI->state != PTI_STATE_DOWN);
};
MODULE_SCOPE int TclPipeThreadStopSignal(TclPipeThreadInfo **pipeTIPtr,
HANDLE wakeEvent);
MODULE_SCOPE void TclPipeThreadStop(TclPipeThreadInfo **pipeTIPtr,
HANDLE hThread);
MODULE_SCOPE void TclPipeThreadExit(TclPipeThreadInfo **pipeTIPtr);
#endif /* _TCLWININT */
|
Changes to win/tclWinReg.c.
| ︙ | ︙ | |||
1204 1205 1206 1207 1208 1209 1210 |
REGSAM mode) /* Mode flags to pass. */
{
DWORD result, size;
Tcl_DString subkey;
HKEY hKey;
REGSAM saveMode = mode;
static int checkExProc = 0;
| | > > > > | 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 |
REGSAM mode) /* Mode flags to pass. */
{
DWORD result, size;
Tcl_DString subkey;
HKEY hKey;
REGSAM saveMode = mode;
static int checkExProc = 0;
typedef LONG (* regDeleteKeyExProc) (HKEY, LPCWSTR, REGSAM, DWORD);
static regDeleteKeyExProc regDeleteKeyEx = (regDeleteKeyExProc) NULL;
/* Really RegDeleteKeyExW() but that's not
* available on all versions of Windows
* supported by Tcl. */
/*
* Do not allow NULL or empty key name.
*/
if (!keyName || *keyName == '\0') {
return ERROR_BADKEY;
|
| ︙ | ︙ | |||
1244 1245 1246 1247 1248 1249 1250 |
*/
if (mode && !checkExProc) {
HMODULE handle;
checkExProc = 1;
handle = GetModuleHandleW(L"ADVAPI32");
| | | | | | 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 |
*/
if (mode && !checkExProc) {
HMODULE handle;
checkExProc = 1;
handle = GetModuleHandleW(L"ADVAPI32");
regDeleteKeyEx = (regDeleteKeyExProc) (void *)
GetProcAddress(handle, "RegDeleteKeyExW");
}
if (mode && regDeleteKeyEx) {
result = regDeleteKeyEx(startKey, keyName, mode, 0);
} else {
result = RegDeleteKeyW(startKey, keyName);
}
break;
} else if (result == ERROR_SUCCESS) {
result = RecursiveDeleteKey(hKey,
(const WCHAR *) Tcl_DStringValue(&subkey), mode);
|
| ︙ | ︙ |
Changes to win/tclWinSerial.c.
| ︙ | ︙ | |||
28 29 30 31 32 33 34 | */ TCL_DECLARE_MUTEX(serialMutex) /* * Bit masks used in the flags field of the SerialInfo structure below. */ | | | | | | > | | | | | | | | | | > | | | | | > | > | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
*/
TCL_DECLARE_MUTEX(serialMutex)
/*
* Bit masks used in the flags field of the SerialInfo structure below.
*/
enum SerialFlags {
SERIAL_PENDING = 1 << 0, /* Message is pending in the queue. */
SERIAL_ASYNC = 1 << 1, /* Channel is non-blocking. */
/*
* Bit masks used in the sharedFlags field of the SerialInfo structure
* below.
*/
SERIAL_EOF = 1 << 2, /* Serial has reached EOF. */
SERIAL_ERROR = 1 << 4,
/*
* Bit masks used for noting whether to drain or discard output on close.
* They are disjoint from each other; at most one may be set at a time.
*/
SERIAL_CLOSE_DRAIN = 1<<6, /* Drain all output on close. */
SERIAL_CLOSE_DISCARD = 1<<7,/* Discard all output on close. */
SERIAL_CLOSE_MASK = 3<<6 /* Both two bits above. */
};
/*
* Default time to block between checking status on the serial port.
*/
#define SERIAL_DEFAULT_BLOCKTIME 10 /* 10 msec */
/*
* Win32 read/write error masks for values returned by ClearCommError()
*/
enum TclWinCommErrorMasks {
SERIAL_READ_ERRORS = /* Errors in the reader side. */
(CE_RXOVER | CE_OVERRUN | CE_RXPARITY | CE_FRAME | CE_BREAK),
SERIAL_WRITE_ERRORS = /* Errors in the writer side. */
(CE_TXFULL | CE_PTO)
};
/*
* This structure describes per-instance data for a serial based channel.
*/
typedef struct SerialInfo {
HANDLE handle;
struct SerialInfo *nextPtr; /* Pointer to next registered serial. */
Tcl_Channel channel; /* Pointer to channel structure. */
int validMask; /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, or TCL_EXCEPTION: indicates
* which operations are valid on the file. */
int watchMask; /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, or TCL_EXCEPTION: indicates
* which events should be reported. */
int flags; /* State flags, see above for a list. */
int readable; /* Flag that the channel is readable. */
int writable; /* Flag that the channel is writable. */
int blockTime; /* Maximum blocktime in msec. */
unsigned long long lastEventTime;
/* Time in milliseconds since last readable
* event. */
/* Next readable event only after blockTime */
DWORD error; /* pending error code returned by
* ClearCommError() */
DWORD lastError; /* last error code, can be fetched with
* fconfigure chan -lasterror */
DWORD sysBufRead; /* Win32 system buffer size for read ops,
|
| ︙ | ︙ | |||
376 377 378 379 380 381 382 |
static unsigned long long
SerialGetMilliseconds(void)
{
Tcl_Time time;
Tcl_GetTime(&time);
| | > | 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 |
static unsigned long long
SerialGetMilliseconds(void)
{
Tcl_Time time;
Tcl_GetTime(&time);
return (unsigned long long)time.sec * 1000
+ (unsigned long)time.usec / 1000;
}
/*
*----------------------------------------------------------------------
*
* SerialSetupProc --
*
|
| ︙ | ︙ | |||
557 558 559 560 561 562 563 | * Sets the device into blocking or non-blocking mode. * *---------------------------------------------------------------------- */ static int SerialBlockProc( | | | 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 |
* Sets the device into blocking or non-blocking mode.
*
*----------------------------------------------------------------------
*/
static int
SerialBlockProc(
void *instanceData, /* Instance data for channel. */
int mode) /* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
int errorCode = 0;
SerialInfo *infoPtr = (SerialInfo *) instanceData;
/*
|
| ︙ | ︙ | |||
596 597 598 599 600 601 602 | * Closes the physical channel. * *---------------------------------------------------------------------- */ static int SerialCloseProc( | | | 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 |
* Closes the physical channel.
*
*----------------------------------------------------------------------
*/
static int
SerialCloseProc(
void *instanceData, /* Pointer to SerialInfo structure. */
TCL_UNUSED(Tcl_Interp *),
int flags)
{
SerialInfo *serialPtr = (SerialInfo *) instanceData;
int errorCode = 0, result = 0;
SerialInfo *infoPtr, **nextPtrPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
| ︙ | ︙ | |||
850 851 852 853 854 855 856 | * Reads input from the actual channel. * *---------------------------------------------------------------------- */ static int SerialInputProc( | | | 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 |
* Reads input from the actual channel.
*
*----------------------------------------------------------------------
*/
static int
SerialInputProc(
void *instanceData, /* Serial state. */
char *buf, /* Where to store data read. */
int bufSize, /* How much space is available in the
* buffer? */
int *errorCode) /* Where to store error code. */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
DWORD bytesRead = 0;
|
| ︙ | ︙ | |||
957 958 959 960 961 962 963 | * Writes output on the actual channel. * *---------------------------------------------------------------------- */ static int SerialOutputProc( | | | 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 |
* Writes output on the actual channel.
*
*----------------------------------------------------------------------
*/
static int
SerialOutputProc(
void *instanceData, /* Serial state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCode) /* Where to store error code. */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
DWORD bytesWritten, timeout;
|
| ︙ | ︙ | |||
1187 1188 1189 1190 1191 1192 1193 | * None. * *---------------------------------------------------------------------- */ static void SerialWatchProc( | | | 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 |
* None.
*
*----------------------------------------------------------------------
*/
static void
SerialWatchProc(
void *instanceData, /* Serial state. */
int mask) /* What events to watch for, OR-ed combination
* of TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
{
SerialInfo **nextPtrPtr, *ptr;
SerialInfo *infoPtr = (SerialInfo *) instanceData;
int oldMask = infoPtr->watchMask;
|
| ︙ | ︙ | |||
1244 1245 1246 1247 1248 1249 1250 | * None. * *---------------------------------------------------------------------- */ static int SerialGetHandleProc( | | | | 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 |
* None.
*
*----------------------------------------------------------------------
*/
static int
SerialGetHandleProc(
void *instanceData, /* The serial state. */
TCL_UNUSED(int) /*direction*/,
void **handlePtr) /* Where to store the handle. */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
*handlePtr = (void *)infoPtr->handle;
return TCL_OK;
}
|
| ︙ | ︙ | |||
1276 1277 1278 1279 1280 1281 1282 |
*/
static DWORD WINAPI
SerialWriterThread(
LPVOID arg)
{
TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg;
| | | 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 |
*/
static DWORD WINAPI
SerialWriterThread(
LPVOID arg)
{
TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg;
SerialInfo *infoPtr = NULL; /* access info only after success init/wait */
DWORD bytesWritten, toWrite;
char *buf;
OVERLAPPED myWrite; /* Have an own OVERLAPPED in this thread. */
for (;;) {
/*
* Wait for the main thread to signal before attempting to write.
|
| ︙ | ︙ | |||
1606 1607 1608 1609 1610 1611 1612 | * May modify an option on a device. * *---------------------------------------------------------------------- */ static int SerialSetOptionProc( | | | < < | 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 |
* May modify an option on a device.
*
*----------------------------------------------------------------------
*/
static int
SerialSetOptionProc(
void *instanceData, /* Serial state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
const char *optionName, /* Which option to set? */
const char *value) /* New value for option. */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
DCB dcb;
BOOL result, flag;
size_t len, vlen;
Tcl_DString ds;
const WCHAR *native;
Tcl_Size argc;
const char **argv;
/*
* Parse options. This would be far easier if we had Tcl_Objs to work with
* as that would let us use Tcl_GetIndexFromObj()...
*/
len = strlen(optionName);
vlen = strlen(value);
|
| ︙ | ︙ | |||
1766 1767 1768 1769 1770 1771 1772 |
return TCL_ERROR;
}
if (argc != 2) {
badXchar:
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"bad value for -xchar: should be a list of"
| | > | 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 |
return TCL_ERROR;
}
if (argc != 2) {
badXchar:
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"bad value for -xchar: should be a list of"
" two elements with each a single 8-bit character",
TCL_INDEX_NONE));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "XCHAR", (char *)NULL);
}
Tcl_Free((void *)argv);
return TCL_ERROR;
}
/*
|
| ︙ | ︙ | |||
2030 2031 2032 2033 2034 2035 2036 | * reused at any time subsequent to the call. * *---------------------------------------------------------------------- */ static int SerialGetOptionProc( | | | < < | 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 |
* reused at any time subsequent to the call.
*
*----------------------------------------------------------------------
*/
static int
SerialGetOptionProc(
void *instanceData, /* Serial state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
const char *optionName, /* Option to get. */
Tcl_DString *dsPtr) /* Where to store value(s). */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
DCB dcb;
size_t len;
int valid = 0; /* Flag if valid option parsed. */
if (optionName == NULL) {
len = 0;
} else {
len = strlen(optionName);
}
/*
|
| ︙ | ︙ |
Changes to win/tclWinSock.c.
| ︙ | ︙ | |||
168 169 170 171 172 173 174 |
/*
* These bits may be OR'ed together into the "flags" field of a TcpState
* structure.
*/
enum TcpStateFlags {
| | | | | | | | | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
/*
* These bits may be OR'ed together into the "flags" field of a TcpState
* structure.
*/
enum TcpStateFlags {
TCP_NONBLOCKING = 1<<0, /* Socket with non-blocking I/O. */
TCP_ASYNC_CONNECT = 1<<1, /* Async connect in progress. */
SOCKET_EOF = 1<<2, /* A zero read happened on the socket. */
SOCKET_PENDING = 1<<3, /* A message has been sent for this socket */
TCP_ASYNC_PENDING = 1<<4, /* TcpConnect was called to process an async
* connect. This flag indicates that reentry is
* still pending. */
TCP_ASYNC_FAILED = 1<<5, /* An async connect finally failed. */
TCP_ASYNC_TEST_MODE = 1<<8 /* Async testing activated. Do not
* automatically continue connection
* process */
};
/*
* The following structure is what is added to the Tcl event queue when a
* socket event occurs.
|
| ︙ | ︙ |
Changes to win/tclWinThrd.c.
| ︙ | ︙ | |||
78 79 80 81 82 83 84 |
#if TCL_THREADS
typedef struct ThreadSpecificData {
HANDLE condEvent; /* Per-thread condition event */
struct ThreadSpecificData *nextPtr; /* Queue pointers */
struct ThreadSpecificData *prevPtr;
| | > > | | | | < | < < < | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
#if TCL_THREADS
typedef struct ThreadSpecificData {
HANDLE condEvent; /* Per-thread condition event */
struct ThreadSpecificData *nextPtr; /* Queue pointers */
struct ThreadSpecificData *prevPtr;
int flags; /* See ThreadStateFlags below */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
#endif /* TCL_THREADS */
/*
* State bits for the thread.
*/
enum ThreadStateFlags {
WIN_THREAD_UNINIT = 0x0, /* Uninitialized. Must be zero because of the
* way ThreadSpecificData is created. */
WIN_THREAD_RUNNING = 0x1, /* Running, not waiting. */
WIN_THREAD_BLOCKED = 0x2 /* Waiting, or trying to wait. */
};
/*
* The per condition queue pointers and the Mutex used to serialize access to
* the queue.
*/
typedef struct {
CRITICAL_SECTION condLock; /* Lock to serialize queuing on the
* condition. */
ThreadSpecificData *firstPtr; /* Queue pointers */
ThreadSpecificData *lastPtr;
} WinCondition;
/*
* Additions by AOL for specialized thread memory allocator.
*/
#ifdef USE_THREAD_ALLOC
|
| ︙ | ︙ |
Changes to win/vctool.bat.
| ︙ | ︙ |