Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | sync with head, add TclStrToD (TIP #132) |
|---|---|
| Timelines: | family | ancestors | descendants | both | kennykb-numerics-branch |
| Files: | files | file ages | folders |
| SHA1: |
82ce6a0c40bc8663bff42d4041a25ee0 |
| User & Date: | kennykb 2005-02-02 15:53:08.000 |
Context
|
2005-02-02
| ||
| 16:58 | updated makefiles, fixed buglets in tclStrToD.c with int overflow in exponents check-in: a976253da6 user: kennykb tags: kennykb-numerics-branch | |
| 15:53 | sync with head, add TclStrToD (TIP #132) check-in: 82ce6a0c40 user: kennykb tags: kennykb-numerics-branch | |
|
2005-01-21
| ||
| 19:20 | bugFix check-in: 69f5d6e3cf user: dgp tags: kennykb-numerics-branch | |
Changes
Changes to ChangeLog.
1 2 3 4 5 6 7 | 2005-01-21 Kevin B. Kenny <kennykb@acm.org> [kennykb-numerics-branch] * unix/Makefile.in: Updated Makefile to build libtommath on Unix as well as Windows. [Bug 1106865] | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
2005-02-01 Kevin B. Kenny <kennykb@acm.org>
[kennykb-numerics-branch] Merged with HEAD as of today.
* generic/tclInt.decls:
Changed numbers of new stubs to resolve a conflict.
* generic/tclInt.h:
Added new TclStrToD routine that replaces the native
'strtod' throughout Tcl.
* generic/tclCmdMZ (Tcl_StringObjCmd):
* generic/tclGet.c (Tcl_GetDouble):
* generic/tclObj.c (SetBooleanFromAny, SetDoubleFromAny):
* generic/tclParseExpr.c (GetLexeme):
* generic/tclScan.c (Tcl_ScanObjCmd):
Replaced all uses of the native 'strtod' with a TclStrToD
routine that performs correct rounding and handles denormals.
* generic/tclStrToD.c: (new file)
New scanning function for extracting 'double' from a string
that rounds correctly, and handles denormals and infinities.
These changes represent a partial implementation of TIP #132.
Output conversion of floating point numbers, and proper handling
of infinities within expressions, still need to be addressed.
2005-02-01 Don Porter <dgp@users.sourceforge.net>
* generic/tclExecute.c (TclCompEvalObj): Removed stray statement
left behind in prior code reorganization.
2005-01-31 Don Porter <dgp@users.sourceforge.net>
* unix/configure: autoconf-2.57
2005-01-30 Joe English <jenglish@users.sourceforge.net>
* unix/configure.in: Restored two double-evals that were
removed in the DBGX purge; these are still needed on some
platforms to account for TCL_TRIM_DOTS. [Bug 1112654]
* unix/configure: NOT REGENERATED: only have autoconf 2.59 here,
need to find someone with autoconf 2.57.
2005-01-28 Jeff Hobbs <jeffh@ActiveState.com>
* unix/configure, unix/tcl.m4: add solaris 64-bit gcc build
support. [Bug 1021871]
2005-01-28 Donal K. Fellows <donal.k.fellows@man.ac.uk>
* tests/expr-old.test (expr-old-37.2): Added test for [Bug 1109484]
2005-01-27 Jeff Hobbs <jeffh@ActiveState.com>
* generic/tclBasic.c (Tcl_ExprBoolean, Tcl_ExprDouble)
(Tcl_ExprLong): Fix to recognize Tcl_WideInt type. [Bug 1109484]
2005-01-26 Andreas Kupries <andreask@activestate.com>
TIP#218 IMPLEMENTATION
* generic/tclDecls.h: Regenerated from tcl.decls.
* generic/tclStubInit.c:
* doc/CrtChannel.3: Documentation of extended API,
* generic/tcl.decls: extended testsuite, and
* generic/tcl.h: implementation. Removal of old
* generic/tclIO.c: driver-specific TclpCut/Splice
* generic/tclInt.h: functions. Replaced with generic
* tests/io.test: thread-action calls through the
* unix/tclUnixChan.c: new hooks. Update of all builtin
* unix/tclUnixPipe.c: channel drivers to version 4.
* unix/tclUnixSock.c: Windows drivers extended to
* win/tclWinChan.c: manage thread state in a thread
* win/tclWinConsole.c: action handler.
* win/tclWinPipe.c:
* win/tclWinSerial.c:
* win/tclWinSock.c:
2005-01-25 Don Porter <dgp@users.sourceforge.net>
* library/auto.tcl: Updated [auto_reset] to clear auto-loaded
commands in namespaces other than :: and to clear auto-loaded commands
that do not happen to be procs. [Bug 1101670]
***POTENTIAL INCOMPATIBILITY***
2005-01-25 Daniel Steffen <das@users.sourceforge.net>
* unix/tcl.m4 (Darwin): fixed bug with static build linking to
dynamic library in /usr/lib etc instead of linking to static library
earlier in search path. [Tcl Bug 956908]
Removed obsolete references to Rhapsody.
* unix/configure: autoconf-2.57
2005-01-21 Andreas Kupries <andreask@activestate.com>
* generic/tclStubInit.c: Regenerated the stubs support code from
* generic/tclDecls.h: the modified tcl.decls (TIP #233, see below).
* doc/GetTime.3: Implemented TIP #233, i.e. the
* generic/tcl.decls: 'Virtualization of Tcl's Sense of Time'.
* generic/tcl.h: Declared, implemented, and documented the
* generic/tclInt.h: specified new API functions. Moved the
* unix/tclUnixEvent.c: native (OS) access to time information
* unix/tclUnixNotfy.c: into standard handler functions. Inserted
* unix/tclUnixTime.c: hooks calling on the handlers where native
* win/tclWinNotify.c: access was done before, and where scaling
* win/tclWinTime.c: between domains (real/virtual) is required.
2005-01-21 Andreas Kupries <andreask@activestate.com>
* generic/tclThread.c: Typo police. Fixed some nits
* generic/tclCmdAH.c: in header comments of functions.
* generic/tclBasic.c: (Missing --).
* generic/tclFileName.c:
2005-01-21 Donal K. Fellows <donal.k.fellows@man.ac.uk>
* doc/FileSystem.3: Add missing ARGUMENTS section definitions for
arguments to Tcl_FSLink. [Bug 1106272]
2005-01-21 Kevin B. Kenny <kennykb@acm.org>
[kennykb-numerics-branch]
* unix/Makefile.in: Updated Makefile to build libtommath on
Unix as well as Windows. [Bug 1106865]
|
| ︙ | ︙ |
Changes to doc/CrtChannel.3.
1 2 3 4 5 6 7 | '\" '\" Copyright (c) 1996-1997 Sun Microsystems, Inc. '\" Copyright (c) 1997-2000 Ajuba Solutions. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | '\" '\" Copyright (c) 1996-1997 Sun Microsystems, Inc. '\" Copyright (c) 1997-2000 Ajuba Solutions. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" '\" RCS: @(#) $Id: CrtChannel.3,v 1.24.2.1 2005/02/02 15:53:12 kennykb Exp $ .so man.macros .TH Tcl_CreateChannel 3 8.4 Tcl "Tcl Library Procedures" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_ChannelThreadActionProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered \- procedures for creating and manipulating channels .SH SYNOPSIS .nf \fB#include <tcl.h>\fR .sp Tcl_Channel \fBTcl_CreateChannel\fR(\fItypePtr, channelName, instanceData, mask\fR) .sp |
| ︙ | ︙ | |||
95 96 97 98 99 100 101 102 103 104 105 106 107 108 | .sp Tcl_DriverSeekProc * \fBTcl_ChannelSeekProc\fR(\fItypePtr\fR) .sp .VS 8.4 Tcl_DriverWideSeekProc * \fBTcl_ChannelWideSeekProc\fR(\fItypePtr\fR) .VE 8.4 .sp Tcl_DriverSetOptionProc * \fBTcl_ChannelSetOptionProc\fR(\fItypePtr\fR) .sp Tcl_DriverGetOptionProc * \fBTcl_ChannelGetOptionProc\fR(\fItypePtr\fR) | > > > | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | .sp Tcl_DriverSeekProc * \fBTcl_ChannelSeekProc\fR(\fItypePtr\fR) .sp .VS 8.4 Tcl_DriverWideSeekProc * \fBTcl_ChannelWideSeekProc\fR(\fItypePtr\fR) .sp Tcl_DriverThreadActionProc * \fBTcl_ChannelThreadActionProc\fR(\fItypePtr\fR) .VE 8.4 .sp Tcl_DriverSetOptionProc * \fBTcl_ChannelSetOptionProc\fR(\fItypePtr\fR) .sp Tcl_DriverGetOptionProc * \fBTcl_ChannelGetOptionProc\fR(\fItypePtr\fR) |
| ︙ | ︙ | |||
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 |
name is registered in the (thread)-global list of all channels (result
== 1) or not (result == 0).
.PP
\fBTcl_CutChannel\fR removes the specified \fIchannel\fR from the
(thread)global list of all channels (of the current thread).
Application to a channel still registered in some interpreter
is not allowed.
.PP
\fBTcl_SpliceChannel\fR adds the specified \fIchannel\fR to the
(thread)global list of all channels (of the current thread).
Application to a channel registered in some interpreter is not allowed.
.PP
\fBTcl_ClearChannelHandlers\fR removes all channelhandlers and event
scripts associated with the specified \fIchannel\fR, thus shutting
down all event processing for this channel.
.VE 8.4
.SH TCL_CHANNELTYPE
.PP
A channel driver provides a \fBTcl_ChannelType\fR structure that contains
pointers to functions that implement the various operations on a channel;
these operations are invoked as needed by the generic layer. The structure
was versioned starting in Tcl 8.3.2/8.4 to correct a problem with stacked
channel drivers. See the \fBOLD CHANNEL TYPES\fR section below for
details about the old structure.
.PP
The \fBTcl_ChannelType\fR structure contains the following fields:
.CS
typedef struct Tcl_ChannelType {
| > > > > > > > > > > | | | | | | | | | | | | | | | > > > | > > > > > | > > > | | | | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 |
name is registered in the (thread)-global list of all channels (result
== 1) or not (result == 0).
.PP
\fBTcl_CutChannel\fR removes the specified \fIchannel\fR from the
(thread)global list of all channels (of the current thread).
Application to a channel still registered in some interpreter
is not allowed.
.VS 8.5
Also notifies the driver if the \fBTcl_ChannelType\fR version is
\fBTCL_CHANNEL_VERSION_4\fR (or higher), and
\fBTcl_DriverThreadActionProc\fR is defined for it.
.VE 8.5
.PP
\fBTcl_SpliceChannel\fR adds the specified \fIchannel\fR to the
(thread)global list of all channels (of the current thread).
Application to a channel registered in some interpreter is not allowed.
.VS 8.5
Also notifies the driver if the \fBTcl_ChannelType\fR version is
\fBTCL_CHANNEL_VERSION_4\fR (or higher), and
\fBTcl_DriverThreadActionProc\fR is defined for it.
.VE 8.5
.PP
\fBTcl_ClearChannelHandlers\fR removes all channelhandlers and event
scripts associated with the specified \fIchannel\fR, thus shutting
down all event processing for this channel.
.VE 8.4
.SH TCL_CHANNELTYPE
.PP
A channel driver provides a \fBTcl_ChannelType\fR structure that contains
pointers to functions that implement the various operations on a channel;
these operations are invoked as needed by the generic layer. The structure
was versioned starting in Tcl 8.3.2/8.4 to correct a problem with stacked
channel drivers. See the \fBOLD CHANNEL TYPES\fR section below for
details about the old structure.
.PP
The \fBTcl_ChannelType\fR structure contains the following fields:
.CS
typedef struct Tcl_ChannelType {
char *\fItypeName\fR;
Tcl_ChannelTypeVersion \fIversion\fR;
Tcl_DriverCloseProc *\fIcloseProc\fR;
Tcl_DriverInputProc *\fIinputProc\fR;
Tcl_DriverOutputProc *\fIoutputProc\fR;
Tcl_DriverSeekProc *\fIseekProc\fR;
Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
Tcl_DriverWatchProc *\fIwatchProc\fR;
Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;
Tcl_DriverClose2Proc *\fIclose2Proc\fR;
Tcl_DriverBlockModeProc *\fIblockModeProc\fR;
Tcl_DriverFlushProc *\fIflushProc\fR;
Tcl_DriverHandlerProc *\fIhandlerProc\fR;
Tcl_DriverWideSeekProc *\fIwideSeekProc\fR;
Tcl_DriverThreadActionProc *\fIthreadActionProc\fR;
} Tcl_ChannelType;
.CE
.PP
The driver must provide implementations for all functions except
\fIblockModeProc\fR, \fIseekProc\fR, \fIsetOptionProc\fR,
\fIgetOptionProc\fR, and \fIclose2Proc\fR, which may be specified as
NULL. Other functions that can not be implemented for this type of
device should return \fBEINVAL\fR when invoked to indicate that they
are not implemented, except in the case of \fIflushProc\fR and
\fIhandlerProc\fR, which should specified as NULL if not otherwise defined.
.PP
The user should only use the above structure for \fBTcl_ChannelType\fR
instantiation. When referencing fields in a \fBTcl_ChannelType\fR
structure, the following functions should be used to obtain the values:
\fBTcl_ChannelName\fR, \fBTcl_ChannelVersion\fR,
\fBTcl_ChannelBlockModeProc\fR, \fBTcl_ChannelCloseProc\fR,
\fBTcl_ChannelClose2Proc\fR, \fBTcl_ChannelInputProc\fR,
\fBTcl_ChannelOutputProc\fR, \fBTcl_ChannelSeekProc\fR,
.VS 8.4
\fBTcl_ChannelWideSeekProc\fR,
\fBTcl_ChannelThreadActionProc\fR,
.VE 8.4
\fBTcl_ChannelSetOptionProc\fR, \fBTcl_ChannelGetOptionProc\fR,
\fBTcl_ChannelWatchProc\fR, \fBTcl_ChannelGetHandleProc\fR,
\fBTcl_ChannelFlushProc\fR, or \fBTcl_ChannelHandlerProc\fR.
.PP
The change to the structures was made in such a way that standard channel
types are binary compatible. However, channel types that use stacked
channels (i.e. TLS, Trf) have new versions to correspond to the above change
since the previous code for stacked channels had problems.
.SS TYPENAME
.PP
The \fItypeName\fR field contains a null-terminated string that
identifies the type of the device implemented by this driver, e.g.
\fBfile\fR or \fBsocket\fR.
.PP
This value can be retrieved with \fBTcl_ChannelName\fR, which returns
a pointer to the string.
.SS VERSION
.PP
The \fIversion\fR field should be set to the version of the structure
that you require. \fBTCL_CHANNEL_VERSION_2\fR is the minimum recommended.
.VS 8.4
\fBTCL_CHANNEL_VERSION_3\fR must be set to specifiy the \fIwideSeekProc\fR member.
.VE 8.4
.VS 8.5
\fBTCL_CHANNEL_VERSION_4\fR must be set to specifiy the
\fIthreadActionProc\fR member (includes \fIwideSeekProc\fR).
.VE 8.5
If it is not set to any of these, then this
\fBTcl_ChannelType\fR is assumed to have the original structure. See
\fBOLD CHANNEL TYPES\fR for more details. While Tcl will recognize
and function with either structures, stacked channels must be of at
least \fBTCL_CHANNEL_VERSION_2\fR to function correctly.
.PP
This value can be retrieved with \fBTcl_ChannelVersion\fR, which returns
.VS 8.4
one of \fBTCL_CHANNEL_VERSION_4\fR, \fBTCL_CHANNEL_VERSION_3\fR,
.VE 8.4
\fBTCL_CHANNEL_VERSION_2\fR or \fBTCL_CHANNEL_VERSION_1\fR.
.SS BLOCKMODEPROC
.PP
The \fIblockModeProc\fR field contains the address of a function called by
the generic layer to set blocking and nonblocking mode on the device.
\fIBlockModeProc\fR should match the following prototype:
|
| ︙ | ︙ | |||
771 772 773 774 775 776 777 778 779 780 781 782 783 784 | \fIInstanceData\fR is the same as the value passed to \fBTcl_CreateChannel\fR when this channel was created. The \fIinterestMask\fR is an OR-ed combination of \fBTCL_READABLE\fR or \fBTCL_WRITABLE\fR; it indicates what type of event occurred on this channel. .PP This value can be retrieved with \fBTcl_ChannelHandlerProc\fR, which returns a pointer to the function. .SH TCL_BADCHANNELOPTION .PP This procedure generates a "bad option" error message in an (optional) interpreter. It is used by channel drivers when an invalid Set/Get option is requested. Its purpose is to concatenate the generic options list to the specific ones and factorize the generic options error message string. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 |
\fIInstanceData\fR is the same as the value passed to \fBTcl_CreateChannel\fR
when this channel was created. The \fIinterestMask\fR is an OR-ed
combination of \fBTCL_READABLE\fR or \fBTCL_WRITABLE\fR; it indicates what
type of event occurred on this channel.
.PP
This value can be retrieved with \fBTcl_ChannelHandlerProc\fR, which returns
a pointer to the function.
.VS 8.4
.SS "THREADACTIONPROC"
.PP
The \fthreadActionProc\fR field contains the address of the function
called by the generic layer when a channel is created, closed, or
going to move to a different thread, i.e. whenever thread-specific
driver state might have to initialized or updated. It can be NULL.
The action \fITCL_CHANNEL_THREAD_REMOVE\fR is used to notify the
driver that it should update or remove any thread-specific data it
might be maintaining for the channel.
.PP
The action \fITCL_CHANNEL_THREAD_INSERT\fR is used to notify the
driver that it should update or initialize any thread-specific data it
might be maintaining using the calling thread as the associate. See
\fBTcl_CutChannel\fR and \fBTcl_SpliceChannel\fR for more detail.
.PP
.CS
typedef void Tcl_DriverThreadActionProc(
ClientData \fIinstanceData\fR,
int \fIaction\fR);
.CE
.PP
\fIInstanceData\fR is the same as the value passed to
\fBTcl_CreateChannel\fR when this channel was created.
.PP
These values can be retrieved with \fBTcl_ChannelThreadActionProc\fR,
which returns a pointer to the function.
.VE 8.4
.SH TCL_BADCHANNELOPTION
.PP
This procedure generates a "bad option" error message in an
(optional) interpreter. It is used by channel drivers when
an invalid Set/Get option is requested. Its purpose is to concatenate
the generic options list to the specific ones and factorize
the generic options error message string.
|
| ︙ | ︙ |
Changes to doc/FileSystem.3.
1 2 3 4 5 6 | '\" '\" Copyright (c) 2001 Vincent Darley '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | '\" '\" Copyright (c) 2001 Vincent Darley '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" '\" RCS: @(#) $Id: FileSystem.3,v 1.50.2.1 2005/02/02 15:53:12 kennykb Exp $ '\" .so man.macros .TH Filesystem 3 8.4 Tcl "Tcl Library Procedures" .BS .SH NAME Tcl_FSRegister, Tcl_FSUnregister, Tcl_FSData, Tcl_FSMountsChanged, Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile, Tcl_FSCopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDirectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile, Tcl_FSLoadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAttrsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpenFileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalizedPath, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNativePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_AllocStatBuf \- procedures to interact with any filesystem .SH SYNOPSIS |
| ︙ | ︙ | |||
224 225 226 227 228 229 230 231 232 233 234 235 236 237 | If non-NULL, filled with the number of elements in the split path. .AP Tcl_Obj *basePtr in The base path on to which to join the given elements. May be NULL. .AP int objc in The number of elements in \fIobjv\fR. .AP "Tcl_Obj *const" objv[] in The elements to join to the given base path. .BE .SH DESCRIPTION .PP There are several reasons for calling the \fBTcl_FS\fR API functions (e.g. \fBTcl_FSAccess\fR and \fBTcl_FSStat\fR) rather than calling system level functions like \fBaccess\fR and | > > > > > > > > > > > | 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 | If non-NULL, filled with the number of elements in the split path. .AP Tcl_Obj *basePtr in The base path on to which to join the given elements. May be NULL. .AP int objc in The number of elements in \fIobjv\fR. .AP "Tcl_Obj *const" objv[] in The elements to join to the given base path. .AP Tcl_Obj *linkNamePtr in The name of the link to be created or read. .AP Tcl_Obj *toPtr in What the link called \fIlinkNamePtr\fR should be linked to, or NULL if the symbolic link specified by \fIlinkNamePtr\fR is to be read. .AP int linkAction in OR-ed combination of flags indicating what kind of link should be created (will be ignored if \fItoPtr\fR is NULL). Valid bits to set are \fBTCL_CREATE_SYMBOLIC_LINK\fR and \fBTCL_CREATE_HARD_LINK\fR. When both flags are set and the underlying filesystem can do either, symbolic links are preferred. .BE .SH DESCRIPTION .PP There are several reasons for calling the \fBTcl_FS\fR API functions (e.g. \fBTcl_FSAccess\fR and \fBTcl_FSStat\fR) rather than calling system level functions like \fBaccess\fR and |
| ︙ | ︙ |
Changes to doc/GetTime.3.
| ︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | .SH NAME Tcl_GetTime \- get date and time .SH SYNOPSIS .nf \fB#include <tcl.h>\fR .sp \fBTcl_GetTime\fR(\fItimePtr\fR) .SH ARGUMENTS .AS "Tcl_Time *" timePtr out .AP "Tcl_Time *" timePtr out Points to memory in which to store the date and time information. .BE .SH DESCRIPTION .PP The \fBTcl_GetTime\fR function retrieves the current time as a \fITcl_Time\fR structure in memory the caller provides. This structure has the following definition: .CS | > > > > > > > > > > > > > > > > > > > > > > > | 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 | .SH NAME Tcl_GetTime \- get date and time .SH SYNOPSIS .nf \fB#include <tcl.h>\fR .sp \fBTcl_GetTime\fR(\fItimePtr\fR) .sp \fBTcl_SetTimeProc\fR(\fIgetProc, scaleProc, clientData\fR) .sp \fBTcl_QueryTimeProc\fR(\fIgetProcPtr, scaleProcPtr, clientDataPtr\fR) .SH ARGUMENTS .AS "Tcl_Time *" timePtr out .AP "Tcl_Time *" timePtr out Points to memory in which to store the date and time information. .AS "Tcl_GetTimeProc *" getProc in .AP "Tcl_GetTimeProc *" getProc in Pointer to handler function replacing Tcl_GetTime's access to the OS. .AS "Tcl_ScaleTimeProc *" scaleProc in .AP "Tcl_ScaleTimeProc *" scaleProc in Pointer to handler function for the conversion of time delays in the virtual domain to real-time. .AS "ClientData *" clientData in .AP "ClientData *" clientData in Value passed through to the two handler functions. .AS "Tcl_GetTimeProc **" getProcPtr inout .AP "Tcl_GetTimeProc **" getProcPtr inout Pointer to place the currently registered get handler function into. .AS "Tcl_ScaleTimeProc **" scaleProcPtr inout .AP "Tcl_ScaleTimeProc **" scaleProcPtr inout Pointer to place the currently registered scale handler function into. .AS "ClientData **" clientDataPtr inout .AP "ClientData **" clientDataPtr inout Pointer to place the currently registered pass-through value into. .BE .SH DESCRIPTION .PP The \fBTcl_GetTime\fR function retrieves the current time as a \fITcl_Time\fR structure in memory the caller provides. This structure has the following definition: .CS |
| ︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 | microseconds that have elapsed since the start of the second designated by \fIsec\fR. The Tcl library makes every effort to keep this number as precise as possible, subject to the limitations of the computer system. On multiprocessor variants of Windows, this number may be limited to the 10- or 20-ms granularity of the system clock. (On single-processor Windows systems, the \fIusec\fR field is derived from a performance counter and is highly precise.) .SH "SEE ALSO" clock .SH KEYWORDS date, time | > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | microseconds that have elapsed since the start of the second designated by \fIsec\fR. The Tcl library makes every effort to keep this number as precise as possible, subject to the limitations of the computer system. On multiprocessor variants of Windows, this number may be limited to the 10- or 20-ms granularity of the system clock. (On single-processor Windows systems, the \fIusec\fR field is derived from a performance counter and is highly precise.) .PP The \fBTcl_SetTime\fR function registers two related handler functions with the core. The first handler function is a replacement for \fBTcl_GetTime\fR, or rather the OS access made by \fBTcl_GetTime\fR. The other handler function is used by the Tcl notifier to convert wait/block times from the virtual domain into real time. .PP The \fBTcl_QueryTime\fR function returns the currently registered handler functions. If no external handlers were set then this will return the standard handlers accessing and processing the native time of the OS. The arguments to the function are allowed to be NULL; and any argument which is NULL is ignored and not set. .PP Any handler pair specified has to return data which is consistent between them. In other words, setting one handler of the pair to something assuming a 10-times slowdown, and the other handler of the pair to something assuming a two-times slowdown is wrong and not allowed. .PP The set handler functions are allowed to run the delivered time backwards, however this should be avoided. We have to allow it as the native time can run backwards as the user can fiddle with the system time one way or other. Note that the insertion of the hooks will not change the behaviour of the Tcl core with regard to this situation, i.e. the existing behaviour is retained. .SH "SEE ALSO" clock .SH KEYWORDS date, time |
Changes to generic/tcl.decls.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # tcl.decls -- # # This file contains the declarations for all supported public # functions that are exported by the Tcl library via the stubs table. # This file is used to generate the tclDecls.h, tclPlatDecls.h, # tclStub.c, and tclPlatStub.c files. # # # Copyright (c) 1998-1999 by Scriptics Corporation. # Copyright (c) 2001, 2002 by Kevin B. Kenny. All rights reserved. # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # tcl.decls -- # # This file contains the declarations for all supported public # functions that are exported by the Tcl library via the stubs table. # This file is used to generate the tclDecls.h, tclPlatDecls.h, # tclStub.c, and tclPlatStub.c files. # # # Copyright (c) 1998-1999 by Scriptics Corporation. # Copyright (c) 2001, 2002 by Kevin B. Kenny. All rights reserved. # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: tcl.decls,v 1.105.2.5 2005/02/02 15:53:14 kennykb Exp $ library tcl # Define the tcl interface with several sub interfaces: # tclPlat - platform specific public # tclInt - generic private # tclPlatInt - platform specific private |
| ︙ | ︙ | |||
1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 |
int Tcl_GetEnsembleFlags(Tcl_Interp *interp, Tcl_Command token,
int *flagsPtr)
}
declare 551 generic {
int Tcl_GetEnsembleNamespace(Tcl_Interp *interp, Tcl_Command token,
Tcl_Namespace **namespacePtrPtr)
}
# TIP #237:
| > > > > > > > > > > > > > > > | | | | | 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 |
int Tcl_GetEnsembleFlags(Tcl_Interp *interp, Tcl_Command token,
int *flagsPtr)
}
declare 551 generic {
int Tcl_GetEnsembleNamespace(Tcl_Interp *interp, Tcl_Command token,
Tcl_Namespace **namespacePtrPtr)
}
# TIP#233 (Virtualized Time)
declare 552 generic {
void Tcl_SetTimeProc (Tcl_GetTimeProc* getProc,
Tcl_ScaleTimeProc* scaleProc,
ClientData clientData)
}
declare 553 generic {
void Tcl_QueryTimeProc (Tcl_GetTimeProc** getProc,
Tcl_ScaleTimeProc** scaleProc,
ClientData* clientData)
}
# TIP#218 (Driver Thread Actions) davygrvy/akupries ChannelType ver 4
declare 554 generic {
Tcl_DriverThreadActionProc *Tcl_ChannelThreadActionProc(Tcl_ChannelType *chanTypePtr)
}
# TIP #237:
declare 555 generic {
Tcl_Obj* Tcl_NewBignumObj( mp_int* value )
}
declare 556 generic {
Tcl_Obj* Tcl_DbNewBignumObj( mp_int* value, CONST char* file, int line )
}
declare 557 generic {
void Tcl_SetBignumObj( Tcl_Obj* obj, mp_int* value )
}
declare 558 generic {
int Tcl_GetBignumFromObj( Tcl_Interp* interp, Tcl_Obj* obj, mp_int* value )
}
##############################################################################
# Define the platform specific public Tcl interface. These functions are
# only available on the designated platform.
|
| ︙ | ︙ |
Changes to generic/tcl.h.
| ︙ | ︙ | |||
9 10 11 12 13 14 15 | * Copyright (c) 1994-1998 Sun Microsystems, Inc. * Copyright (c) 1998-2000 by Scriptics Corporation. * Copyright (c) 2002 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | * Copyright (c) 1994-1998 Sun Microsystems, Inc. * Copyright (c) 1998-2000 by Scriptics Corporation. * Copyright (c) 2002 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tcl.h,v 1.191.2.6 2005/02/02 15:53:15 kennykb Exp $ */ #ifndef _TCL #define _TCL /* * * For C++ compilers, use extern "C" |
| ︙ | ︙ | |||
1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 |
long sec; /* Seconds. */
long usec; /* Microseconds. */
} Tcl_Time;
typedef void (Tcl_SetTimerProc) _ANSI_ARGS_((Tcl_Time *timePtr));
typedef int (Tcl_WaitForEventProc) _ANSI_ARGS_((Tcl_Time *timePtr));
/*
* Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler
* to indicate what sorts of events are of interest:
*/
#define TCL_READABLE (1<<1)
#define TCL_WRITABLE (1<<2)
| > > > > > | 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 |
long sec; /* Seconds. */
long usec; /* Microseconds. */
} Tcl_Time;
typedef void (Tcl_SetTimerProc) _ANSI_ARGS_((Tcl_Time *timePtr));
typedef int (Tcl_WaitForEventProc) _ANSI_ARGS_((Tcl_Time *timePtr));
/* TIP #233 (Virtualized Time)
*/
typedef void (Tcl_GetTimeProc) _ANSI_ARGS_ ((Tcl_Time* timebuf, ClientData clientData));
typedef void (Tcl_ScaleTimeProc) _ANSI_ARGS_ ((Tcl_Time* timebuf, ClientData clientData));
/*
* Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler
* to indicate what sorts of events are of interest:
*/
#define TCL_READABLE (1<<1)
#define TCL_WRITABLE (1<<2)
|
| ︙ | ︙ | |||
1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 | /* * Channel version tag. This was introduced in 8.3.2/8.4. */ #define TCL_CHANNEL_VERSION_1 ((Tcl_ChannelTypeVersion) 0x1) #define TCL_CHANNEL_VERSION_2 ((Tcl_ChannelTypeVersion) 0x2) #define TCL_CHANNEL_VERSION_3 ((Tcl_ChannelTypeVersion) 0x3) /* * Typedefs for the various operations in a channel type: */ typedef int (Tcl_DriverBlockModeProc) _ANSI_ARGS_(( ClientData instanceData, int mode)); typedef int (Tcl_DriverCloseProc) _ANSI_ARGS_((ClientData instanceData, | > > > > > > > > | 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 | /* * Channel version tag. This was introduced in 8.3.2/8.4. */ #define TCL_CHANNEL_VERSION_1 ((Tcl_ChannelTypeVersion) 0x1) #define TCL_CHANNEL_VERSION_2 ((Tcl_ChannelTypeVersion) 0x2) #define TCL_CHANNEL_VERSION_3 ((Tcl_ChannelTypeVersion) 0x3) #define TCL_CHANNEL_VERSION_4 ((Tcl_ChannelTypeVersion) 0x4) /* * TIP #218: Channel Actions, Ids for Tcl_DriverThreadActionProc */ #define TCL_CHANNEL_THREAD_INSERT (0) #define TCL_CHANNEL_THREAD_REMOVE (1) /* * Typedefs for the various operations in a channel type: */ typedef int (Tcl_DriverBlockModeProc) _ANSI_ARGS_(( ClientData instanceData, int mode)); typedef int (Tcl_DriverCloseProc) _ANSI_ARGS_((ClientData instanceData, |
| ︙ | ︙ | |||
1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 | ClientData instanceData)); typedef int (Tcl_DriverHandlerProc) _ANSI_ARGS_(( ClientData instanceData, int interestMask)); typedef Tcl_WideInt (Tcl_DriverWideSeekProc) _ANSI_ARGS_(( ClientData instanceData, Tcl_WideInt offset, int mode, int *errorCodePtr)); /* * The following declarations either map ckalloc and ckfree to * malloc and free, or they map them to procedures with all sorts * of debugging hooks defined in tclCkalloc.c. */ #ifdef TCL_MEM_DEBUG | > > > | 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 | ClientData instanceData)); typedef int (Tcl_DriverHandlerProc) _ANSI_ARGS_(( ClientData instanceData, int interestMask)); typedef Tcl_WideInt (Tcl_DriverWideSeekProc) _ANSI_ARGS_(( ClientData instanceData, Tcl_WideInt offset, int mode, int *errorCodePtr)); /* TIP #218, Channel Thread Actions */ typedef void (Tcl_DriverThreadActionProc) _ANSI_ARGS_ (( ClientData instanceData, int action)); /* * The following declarations either map ckalloc and ckfree to * malloc and free, or they map them to procedures with all sorts * of debugging hooks defined in tclCkalloc.c. */ #ifdef TCL_MEM_DEBUG |
| ︙ | ︙ | |||
1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 |
*/
Tcl_DriverWideSeekProc *wideSeekProc;
/* Procedure to call to seek
* on the channel which can
* handle 64-bit offsets. May be
* NULL, and must be NULL if
* seekProc is NULL. */
} Tcl_ChannelType;
/*
* The following flags determine whether the blockModeProc above should
* set the channel into blocking or nonblocking mode. They are passed
* as arguments to the blockModeProc procedure in the above structure.
*/
| > > > > > > > > > > | 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 |
*/
Tcl_DriverWideSeekProc *wideSeekProc;
/* Procedure to call to seek
* on the channel which can
* handle 64-bit offsets. May be
* NULL, and must be NULL if
* seekProc is NULL. */
/*
* Only valid in TCL_CHANNEL_VERSION_4 channels or later
* TIP #218, Channel Thread Actions
*/
Tcl_DriverThreadActionProc *threadActionProc;
/* Procedure to call to notify
* the driver of thread specific
* activity for a channel.
* May be NULL. */
} Tcl_ChannelType;
/*
* The following flags determine whether the blockModeProc above should
* set the channel into blocking or nonblocking mode. They are passed
* as arguments to the blockModeProc procedure in the above structure.
*/
|
| ︙ | ︙ |
Changes to generic/tclBasic.c.
| ︙ | ︙ | |||
9 10 11 12 13 14 15 | * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * Copyright (c) 2001, 2002 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * Copyright (c) 2001, 2002 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclBasic.c,v 1.136.2.3 2005/02/02 15:53:15 kennykb Exp $ */ #include "tclInt.h" #include "tclCompile.h" /* * Static procedures in this file: |
| ︙ | ︙ | |||
3878 3879 3880 3881 3882 3883 3884 |
exprPtr = Tcl_NewStringObj(string, length);
Tcl_IncrRefCount(exprPtr);
result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
if (result == TCL_OK) {
/*
* Store an integer based on the expression result.
*/
| | > > > > > > > > > > > > > > > > > > | 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 3913 3914 |
exprPtr = Tcl_NewStringObj(string, length);
Tcl_IncrRefCount(exprPtr);
result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
if (result == TCL_OK) {
/*
* Store an integer based on the expression result.
*/
if (resultPtr->typePtr == &tclIntType) {
*ptr = resultPtr->internalRep.longValue;
} else if (resultPtr->typePtr == &tclDoubleType) {
*ptr = (long) resultPtr->internalRep.doubleValue;
} else if (resultPtr->typePtr == &tclWideIntType) {
#ifndef TCL_WIDE_INT_IS_LONG
/*
* See Tcl_GetIntFromObj for conversion comments.
*/
Tcl_WideInt w = resultPtr->internalRep.wideValue;
if ((w >= -(Tcl_WideInt)(ULONG_MAX))
&& (w <= (Tcl_WideInt)(ULONG_MAX))) {
*ptr = Tcl_WideAsLong(w);
} else {
Tcl_SetResult(interp,
"integer value too large to represent as non-long integer",
TCL_STATIC);
result = TCL_ERROR;
}
#else
*ptr = resultPtr->internalRep.longValue;
#endif
} else {
Tcl_SetResult(interp,
"expression didn't have numeric value", TCL_STATIC);
result = TCL_ERROR;
}
Tcl_DecrRefCount(resultPtr); /* discard the result object */
} else {
|
| ︙ | ︙ | |||
3928 3929 3930 3931 3932 3933 3934 |
exprPtr = Tcl_NewStringObj(string, length);
Tcl_IncrRefCount(exprPtr);
result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
if (result == TCL_OK) {
/*
* Store a double based on the expression result.
*/
| | > > > > > > > > > > > > > > > > > > | 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 |
exprPtr = Tcl_NewStringObj(string, length);
Tcl_IncrRefCount(exprPtr);
result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
if (result == TCL_OK) {
/*
* Store a double based on the expression result.
*/
if (resultPtr->typePtr == &tclIntType) {
*ptr = (double) resultPtr->internalRep.longValue;
} else if (resultPtr->typePtr == &tclDoubleType) {
*ptr = resultPtr->internalRep.doubleValue;
} else if (resultPtr->typePtr == &tclWideIntType) {
#ifndef TCL_WIDE_INT_IS_LONG
/*
* See Tcl_GetIntFromObj for conversion comments.
*/
Tcl_WideInt w = resultPtr->internalRep.wideValue;
if ((w >= -(Tcl_WideInt)(ULONG_MAX))
&& (w <= (Tcl_WideInt)(ULONG_MAX))) {
*ptr = (double) Tcl_WideAsLong(w);
} else {
Tcl_SetResult(interp,
"integer value too large to represent as non-long integer",
TCL_STATIC);
result = TCL_ERROR;
}
#else
*ptr = (double) resultPtr->internalRep.longValue;
#endif
} else {
Tcl_SetResult(interp,
"expression didn't have numeric value", TCL_STATIC);
result = TCL_ERROR;
}
Tcl_DecrRefCount(resultPtr); /* discard the result object */
} else {
|
| ︙ | ︙ | |||
3978 3979 3980 3981 3982 3983 3984 |
exprPtr = Tcl_NewStringObj(string, length);
Tcl_IncrRefCount(exprPtr);
result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
if (result == TCL_OK) {
/*
* Store a boolean based on the expression result.
*/
| | > > > > > > | 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 |
exprPtr = Tcl_NewStringObj(string, length);
Tcl_IncrRefCount(exprPtr);
result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
if (result == TCL_OK) {
/*
* Store a boolean based on the expression result.
*/
if (resultPtr->typePtr == &tclIntType) {
*ptr = (resultPtr->internalRep.longValue != 0);
} else if (resultPtr->typePtr == &tclDoubleType) {
*ptr = (resultPtr->internalRep.doubleValue != 0.0);
} else if (resultPtr->typePtr == &tclWideIntType) {
#ifndef TCL_WIDE_INT_IS_LONG
*ptr = (resultPtr->internalRep.wideValue != 0);
#else
*ptr = (resultPtr->internalRep.longValue != 0);
#endif
} else {
result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
}
Tcl_DecrRefCount(resultPtr); /* discard the result object */
}
if (result != TCL_OK) {
/*
|
| ︙ | ︙ | |||
4638 4639 4640 4641 4642 4643 4644 |
iPtr->evalFlags |= TCL_ALLOW_EXCEPTIONS;
}
/*
*----------------------------------------------------------------------
*
| | | 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 |
iPtr->evalFlags |= TCL_ALLOW_EXCEPTIONS;
}
/*
*----------------------------------------------------------------------
*
* Tcl_GetVersion --
*
* Get the Tcl major, minor, and patchlevel version numbers and
* the release type. A patch is a release type TCL_FINAL_RELEASE
* with a patchLevel > 0.
*
* Results:
* None.
|
| ︙ | ︙ |
Changes to generic/tclCmdAH.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclCmdAH.c -- * * This file contains the top-level command routines for most of * the Tcl built-in commands whose names begin with the letters * A to H. * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1994-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. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tclCmdAH.c -- * * This file contains the top-level command routines for most of * the Tcl built-in commands whose names begin with the letters * A to H. * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1994-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. * * RCS: @(#) $Id: tclCmdAH.c,v 1.57.2.1 2005/02/02 15:53:17 kennykb Exp $ */ #include "tclInt.h" #include <locale.h> /* * Prototypes for local procedures defined in this file: |
| ︙ | ︙ | |||
370 371 372 373 374 375 376 |
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
| | | 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* Tcl_ContinueObjCmd --
*
* This procedure is invoked to process the "continue" Tcl command.
* See the user documentation for details on what it does.
*
* With the bytecode compiler, this procedure is only called when
* a command name is computed at runtime, and is "continue" or the name
* to which "continue" was renamed: e.g., "set z continue; $z"
|
| ︙ | ︙ |
Changes to generic/tclCmdMZ.c.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 | * Copyright (c) 1998-2000 Scriptics Corporation. * Copyright (c) 2002 ActiveState Corporation. * Copyright (c) 2003 Donal K. Fellows. * * 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 | * Copyright (c) 1998-2000 Scriptics Corporation. * Copyright (c) 2002 ActiveState Corporation. * Copyright (c) 2003 Donal K. Fellows. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclCmdMZ.c,v 1.115.2.1 2005/02/02 15:53:17 kennykb Exp $ */ #include "tclInt.h" #include "tclRegexp.h" /* *---------------------------------------------------------------------- |
| ︙ | ︙ | |||
1501 1502 1503 1504 1505 1506 1507 | result = 0; failat = -1; } break; } } errno = 0; | | | 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 |
result = 0;
failat = -1;
}
break;
}
}
errno = 0;
TclStrToD(string1, (CONST char **) &stop); /* INTL: Tcl source. */
if (errno == ERANGE) {
/*
* if (errno == ERANGE), then it was an over/underflow
* problem, but in this method, we only want to know
* yes or no, so bad flow returns 0 (false) and sets
* the failVarObj to the string length.
*/
|
| ︙ | ︙ |
Changes to generic/tclDecls.h.
1 2 3 4 5 6 7 8 9 10 | /* * tclDecls.h -- * * Declarations of functions in the platform independent public Tcl API. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* * tclDecls.h -- * * Declarations of functions in the platform independent public Tcl API. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclDecls.h,v 1.107.2.4 2005/02/02 15:53:18 kennykb Exp $ */ #ifndef _TCLDECLS #define _TCLDECLS #undef TCL_STORAGE_CLASS #ifdef BUILD_tcl |
| ︙ | ︙ | |||
3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 | #endif #ifndef Tcl_GetEnsembleNamespace_TCL_DECLARED #define Tcl_GetEnsembleNamespace_TCL_DECLARED /* 551 */ EXTERN int Tcl_GetEnsembleNamespace _ANSI_ARGS_(( Tcl_Interp * interp, Tcl_Command token, Tcl_Namespace ** namespacePtrPtr)); #endif #ifndef Tcl_NewBignumObj_TCL_DECLARED #define Tcl_NewBignumObj_TCL_DECLARED | > > > > > > > > > > > > > > > > > > > > > > | | | | | 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 |
#endif
#ifndef Tcl_GetEnsembleNamespace_TCL_DECLARED
#define Tcl_GetEnsembleNamespace_TCL_DECLARED
/* 551 */
EXTERN int Tcl_GetEnsembleNamespace _ANSI_ARGS_((
Tcl_Interp * interp, Tcl_Command token,
Tcl_Namespace ** namespacePtrPtr));
#endif
#ifndef Tcl_SetTimeProc_TCL_DECLARED
#define Tcl_SetTimeProc_TCL_DECLARED
/* 552 */
EXTERN void Tcl_SetTimeProc _ANSI_ARGS_((
Tcl_GetTimeProc* getProc,
Tcl_ScaleTimeProc* scaleProc,
ClientData clientData));
#endif
#ifndef Tcl_QueryTimeProc_TCL_DECLARED
#define Tcl_QueryTimeProc_TCL_DECLARED
/* 553 */
EXTERN void Tcl_QueryTimeProc _ANSI_ARGS_((
Tcl_GetTimeProc** getProc,
Tcl_ScaleTimeProc** scaleProc,
ClientData* clientData));
#endif
#ifndef Tcl_ChannelThreadActionProc_TCL_DECLARED
#define Tcl_ChannelThreadActionProc_TCL_DECLARED
/* 554 */
EXTERN Tcl_DriverThreadActionProc * Tcl_ChannelThreadActionProc _ANSI_ARGS_((
Tcl_ChannelType * chanTypePtr));
#endif
#ifndef Tcl_NewBignumObj_TCL_DECLARED
#define Tcl_NewBignumObj_TCL_DECLARED
/* 555 */
EXTERN Tcl_Obj* Tcl_NewBignumObj _ANSI_ARGS_((mp_int* value));
#endif
#ifndef Tcl_DbNewBignumObj_TCL_DECLARED
#define Tcl_DbNewBignumObj_TCL_DECLARED
/* 556 */
EXTERN Tcl_Obj* Tcl_DbNewBignumObj _ANSI_ARGS_((mp_int* value,
CONST char* file, int line));
#endif
#ifndef Tcl_SetBignumObj_TCL_DECLARED
#define Tcl_SetBignumObj_TCL_DECLARED
/* 557 */
EXTERN void Tcl_SetBignumObj _ANSI_ARGS_((Tcl_Obj* obj,
mp_int* value));
#endif
#ifndef Tcl_GetBignumFromObj_TCL_DECLARED
#define Tcl_GetBignumFromObj_TCL_DECLARED
/* 558 */
EXTERN int Tcl_GetBignumFromObj _ANSI_ARGS_((Tcl_Interp* interp,
Tcl_Obj* obj, mp_int* value));
#endif
typedef struct TclStubHooks {
struct TclPlatStubs *tclPlatStubs;
struct TclIntStubs *tclIntStubs;
|
| ︙ | ︙ | |||
4048 4049 4050 4051 4052 4053 4054 |
int (*tcl_SetEnsembleUnknownHandler) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, Tcl_Obj * unknownList)); /* 545 */
int (*tcl_SetEnsembleFlags) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, int flags)); /* 546 */
int (*tcl_GetEnsembleSubcommandList) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, Tcl_Obj ** subcmdListPtr)); /* 547 */
int (*tcl_GetEnsembleMappingDict) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, Tcl_Obj ** mapDictPtr)); /* 548 */
int (*tcl_GetEnsembleUnknownHandler) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, Tcl_Obj ** unknownListPtr)); /* 549 */
int (*tcl_GetEnsembleFlags) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, int * flagsPtr)); /* 550 */
int (*tcl_GetEnsembleNamespace) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, Tcl_Namespace ** namespacePtrPtr)); /* 551 */
| > > > | | | | | 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 |
int (*tcl_SetEnsembleUnknownHandler) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, Tcl_Obj * unknownList)); /* 545 */
int (*tcl_SetEnsembleFlags) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, int flags)); /* 546 */
int (*tcl_GetEnsembleSubcommandList) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, Tcl_Obj ** subcmdListPtr)); /* 547 */
int (*tcl_GetEnsembleMappingDict) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, Tcl_Obj ** mapDictPtr)); /* 548 */
int (*tcl_GetEnsembleUnknownHandler) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, Tcl_Obj ** unknownListPtr)); /* 549 */
int (*tcl_GetEnsembleFlags) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, int * flagsPtr)); /* 550 */
int (*tcl_GetEnsembleNamespace) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command token, Tcl_Namespace ** namespacePtrPtr)); /* 551 */
void (*tcl_SetTimeProc) _ANSI_ARGS_((Tcl_GetTimeProc* getProc, Tcl_ScaleTimeProc* scaleProc, ClientData clientData)); /* 552 */
void (*tcl_QueryTimeProc) _ANSI_ARGS_((Tcl_GetTimeProc** getProc, Tcl_ScaleTimeProc** scaleProc, ClientData* clientData)); /* 553 */
Tcl_DriverThreadActionProc * (*tcl_ChannelThreadActionProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 554 */
Tcl_Obj* (*tcl_NewBignumObj) _ANSI_ARGS_((mp_int* value)); /* 555 */
Tcl_Obj* (*tcl_DbNewBignumObj) _ANSI_ARGS_((mp_int* value, CONST char* file, int line)); /* 556 */
void (*tcl_SetBignumObj) _ANSI_ARGS_((Tcl_Obj* obj, mp_int* value)); /* 557 */
int (*tcl_GetBignumFromObj) _ANSI_ARGS_((Tcl_Interp* interp, Tcl_Obj* obj, mp_int* value)); /* 558 */
} TclStubs;
#ifdef __cplusplus
extern "C" {
#endif
extern TclStubs *tclStubsPtr;
#ifdef __cplusplus
|
| ︙ | ︙ | |||
6300 6301 6302 6303 6304 6305 6306 6307 6308 | #define Tcl_GetEnsembleFlags \ (tclStubsPtr->tcl_GetEnsembleFlags) /* 550 */ #endif #ifndef Tcl_GetEnsembleNamespace #define Tcl_GetEnsembleNamespace \ (tclStubsPtr->tcl_GetEnsembleNamespace) /* 551 */ #endif #ifndef Tcl_NewBignumObj #define Tcl_NewBignumObj \ | > > > > > > > > > > > > | | | | | 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 | #define Tcl_GetEnsembleFlags \ (tclStubsPtr->tcl_GetEnsembleFlags) /* 550 */ #endif #ifndef Tcl_GetEnsembleNamespace #define Tcl_GetEnsembleNamespace \ (tclStubsPtr->tcl_GetEnsembleNamespace) /* 551 */ #endif #ifndef Tcl_SetTimeProc #define Tcl_SetTimeProc \ (tclStubsPtr->tcl_SetTimeProc) /* 552 */ #endif #ifndef Tcl_QueryTimeProc #define Tcl_QueryTimeProc \ (tclStubsPtr->tcl_QueryTimeProc) /* 553 */ #endif #ifndef Tcl_ChannelThreadActionProc #define Tcl_ChannelThreadActionProc \ (tclStubsPtr->tcl_ChannelThreadActionProc) /* 554 */ #endif #ifndef Tcl_NewBignumObj #define Tcl_NewBignumObj \ (tclStubsPtr->tcl_NewBignumObj) /* 555 */ #endif #ifndef Tcl_DbNewBignumObj #define Tcl_DbNewBignumObj \ (tclStubsPtr->tcl_DbNewBignumObj) /* 556 */ #endif #ifndef Tcl_SetBignumObj #define Tcl_SetBignumObj \ (tclStubsPtr->tcl_SetBignumObj) /* 557 */ #endif #ifndef Tcl_GetBignumFromObj #define Tcl_GetBignumFromObj \ (tclStubsPtr->tcl_GetBignumFromObj) /* 558 */ #endif #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TCLDECLS */ |
Changes to generic/tclExecute.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclExecute.c -- * * This file contains procedures that execute byte-compiled Tcl * commands. * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * Copyright (c) 1998-2000 by Scriptics Corporation. * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tclExecute.c -- * * This file contains procedures that execute byte-compiled Tcl * commands. * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * Copyright (c) 1998-2000 by Scriptics Corporation. * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclExecute.c,v 1.167.2.2 2005/02/02 15:53:21 kennykb Exp $ */ #include "tclInt.h" #include "tclCompile.h" #ifndef TCL_NO_MATH # include <math.h> |
| ︙ | ︙ | |||
1004 1005 1006 1007 1008 1009 1010 |
recompileObj:
iPtr->errorLine = 1;
result = tclByteCodeType.setFromAnyProc(interp, objPtr);
if (result != TCL_OK) {
iPtr->numLevels--;
return result;
}
| < | 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 |
recompileObj:
iPtr->errorLine = 1;
result = tclByteCodeType.setFromAnyProc(interp, objPtr);
if (result != TCL_OK) {
iPtr->numLevels--;
return result;
}
codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
} else {
/*
* Make sure the Bytecode hasn't been invalidated by, e.g., someone
* redefining a command with a compile procedure (this might make the
* compiled code wrong).
* The object needs to be recompiled if it was compiled in/for a
|
| ︙ | ︙ |
Changes to generic/tclFileName.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclFileName.c -- * * This file contains routines for converting file names betwen * native and network form. * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclFileName.c -- * * This file contains routines for converting file names betwen * native and network form. * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclFileName.c,v 1.60.2.2 2005/02/02 15:53:23 kennykb Exp $ */ #include "tclInt.h" #include "tclRegexp.h" #include "tclFileSystem.h" /* For TclGetPathType() */ /* |
| ︙ | ︙ | |||
2304 2305 2306 2307 2308 2309 2310 |
return result;
}
/*
*---------------------------------------------------------------------------
*
| | | 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 |
return result;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_AllocStatBuf --
*
* This procedure allocates a Tcl_StatBuf on the heap. It exists
* so that extensions may be used unchanged on systems where
* largefile support is optional.
*
* Results:
* A pointer to a Tcl_StatBuf which may be deallocated by being
|
| ︙ | ︙ |
Changes to generic/tclGet.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclGet.c -- * * This file contains procedures to convert strings into * other forms, like integers or floating-point numbers or * booleans, doing syntax checking along the way. * * Copyright (c) 1990-1993 The Regents of the University of California. * Copyright (c) 1994-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. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tclGet.c -- * * This file contains procedures to convert strings into * other forms, like integers or floating-point numbers or * booleans, doing syntax checking along the way. * * Copyright (c) 1990-1993 The Regents of the University of California. * Copyright (c) 1994-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. * * RCS: @(#) $Id: tclGet.c,v 1.9.2.1 2005/02/02 15:53:24 kennykb Exp $ */ #include "tclInt.h" #include <math.h> /* |
| ︙ | ︙ | |||
216 217 218 219 220 221 222 |
int
Tcl_GetDouble(interp, string, doublePtr)
Tcl_Interp *interp; /* Interpreter used for error reporting. */
CONST char *string; /* String containing a floating-point number
* in a form acceptable to strtod. */
double *doublePtr; /* Place to store converted result. */
{
| | | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
int
Tcl_GetDouble(interp, string, doublePtr)
Tcl_Interp *interp; /* Interpreter used for error reporting. */
CONST char *string; /* String containing a floating-point number
* in a form acceptable to strtod. */
double *doublePtr; /* Place to store converted result. */
{
CONST char *end;
double d;
errno = 0;
d = TclStrToD(string, &end); /* INTL: Tcl source. */
if (end == string) {
badDouble:
if (interp != (Tcl_Interp *) NULL) {
Tcl_AppendResult(interp,
"expected floating-point number but got \"",
string, "\"", (char *) NULL);
}
|
| ︙ | ︙ |
Changes to generic/tclIO.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclIO.c -- * * This file provides the generic portions (those that are the same on * all platforms and for all channel types) of Tcl's IO facilities. * * Copyright (c) 1998-2000 Ajuba Solutions * Copyright (c) 1995-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. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclIO.c -- * * This file provides the generic portions (those that are the same on * all platforms and for all channel types) of Tcl's IO facilities. * * Copyright (c) 1998-2000 Ajuba Solutions * Copyright (c) 1995-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. * * RCS: @(#) $Id: tclIO.c,v 1.81.2.1 2005/02/02 15:53:24 kennykb Exp $ */ #include "tclInt.h" #include "tclIO.h" #include <assert.h> |
| ︙ | ︙ | |||
1201 1202 1203 1204 1205 1206 1207 |
/*
* Link the channel into the list of all channels; create an on-exit
* handler if there is not one already, to close off all the channels
* in the list on exit.
*
* JH: Could call Tcl_SpliceChannel, but need to avoid NULL check.
| < | > | | | < | > | | | > | 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 |
/*
* Link the channel into the list of all channels; create an on-exit
* handler if there is not one already, to close off all the channels
* in the list on exit.
*
* JH: Could call Tcl_SpliceChannel, but need to avoid NULL check.
*
* TIP #218.
* AK: Just initialize the field to NULL before invoking Tcl_SpliceChannel
* We need Tcl_SpliceChannel, for the threadAction calls.
* There is no real reason to duplicate all of this.
* NOTE: All drivers using thread actions now have to perform their TSD
* manipulation only in their thread action proc. Doing it when
* creating their instance structures will collide with the thread
* action activity and lead to damaged lists.
*/
statePtr->nextCSPtr = (ChannelState *) NULL;
Tcl_SpliceChannel ((Tcl_Channel) chanPtr);
/*
* Install this channel in the first empty standard channel slot, if
* the channel was previously closed explicitly.
*/
if ((tsdPtr->stdinChannel == NULL) &&
|
| ︙ | ︙ | |||
2378 2379 2380 2381 2382 2383 2384 | * Results: * Nothing. * * Side effects: * Resets the field 'nextCSPtr' of the specified channel state to NULL. * * NOTE: | | | 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 | * Results: * Nothing. * * Side effects: * Resets the field 'nextCSPtr' of the specified channel state to NULL. * * NOTE: * The channel to cut out of the list must not be referenced * in any interpreter. This is something this procedure cannot * check (despite the refcount) because the caller usually wants * fiddle with the channel (like transfering it to a different * thread) and thus keeps the refcount artifically high to prevent * its destruction. * *---------------------------------------------------------------------- |
| ︙ | ︙ | |||
2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 |
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
ChannelState *prevCSPtr; /* Preceding channel state in list of
* all states - used to splice a
* channel out of the list on close. */
ChannelState *statePtr = ((Channel *) chan)->state;
/* state of the channel stack. */
/*
* Remove this channel from of the list of all channels
* (in the current thread).
*/
if (tsdPtr->firstCSPtr && (statePtr == tsdPtr->firstCSPtr)) {
| > | 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 |
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
ChannelState *prevCSPtr; /* Preceding channel state in list of
* all states - used to splice a
* channel out of the list on close. */
ChannelState *statePtr = ((Channel *) chan)->state;
/* state of the channel stack. */
Tcl_DriverThreadActionProc *threadActionProc;
/*
* Remove this channel from of the list of all channels
* (in the current thread).
*/
if (tsdPtr->firstCSPtr && (statePtr == tsdPtr->firstCSPtr)) {
|
| ︙ | ︙ | |||
2422 2423 2424 2425 2426 2427 2428 |
Tcl_Panic("FlushChannel: damaged channel list");
}
prevCSPtr->nextCSPtr = statePtr->nextCSPtr;
}
statePtr->nextCSPtr = (ChannelState *) NULL;
| | > > | > > | | | > | > > | > > | 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 |
Tcl_Panic("FlushChannel: damaged channel list");
}
prevCSPtr->nextCSPtr = statePtr->nextCSPtr;
}
statePtr->nextCSPtr = (ChannelState *) NULL;
/* TIP #218, Channel Thread Actions */
threadActionProc = Tcl_ChannelThreadActionProc (Tcl_GetChannelType (chan));
if (threadActionProc != NULL) {
(*threadActionProc) (Tcl_GetChannelInstanceData(chan),
TCL_CHANNEL_THREAD_REMOVE);
}
}
/*
*----------------------------------------------------------------------
*
* Tcl_SpliceChannel --
*
* Adds a channel to the (thread-)global list of all channels
* (in that thread). Expects that the field 'nextChanPtr' in
* the channel is set to NULL.
*
* Results:
* Nothing.
*
* Side effects:
* Nothing.
*
* NOTE:
* The channel to splice into the list must not be referenced in any
* interpreter. This is something this procedure cannot check
* (despite the refcount) because the caller usually wants figgle
* with the channel (like transfering it to a different thread)
* and thus keeps the refcount artifically high to prevent its
* destruction.
*
*----------------------------------------------------------------------
*/
void
Tcl_SpliceChannel(chan)
Tcl_Channel chan; /* The channel being added. Must
* not be referenced in any
* interpreter. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
ChannelState *statePtr = ((Channel *) chan)->state;
Tcl_DriverThreadActionProc *threadActionProc;
if (statePtr->nextCSPtr != (ChannelState *) NULL) {
Tcl_Panic("Tcl_SpliceChannel: trying to add channel used in different list");
}
statePtr->nextCSPtr = tsdPtr->firstCSPtr;
tsdPtr->firstCSPtr = statePtr;
/*
* TIP #10. Mark the current thread as the new one managing this
* channel. Note: 'Tcl_GetCurrentThread' returns sensible
* values even for a non-threaded core.
*/
statePtr->managingThread = Tcl_GetCurrentThread();
/* TIP #218, Channel Thread Actions */
threadActionProc = Tcl_ChannelThreadActionProc (Tcl_GetChannelType (chan));
if (threadActionProc != NULL) {
(*threadActionProc) (Tcl_GetChannelInstanceData(chan),
TCL_CHANNEL_THREAD_INSERT);
}
}
/*
*----------------------------------------------------------------------
*
* Tcl_Close --
*
|
| ︙ | ︙ | |||
8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 |
Tcl_ChannelVersion(chanTypePtr)
Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
{
if (chanTypePtr->version == TCL_CHANNEL_VERSION_2) {
return TCL_CHANNEL_VERSION_2;
} else if (chanTypePtr->version == TCL_CHANNEL_VERSION_3) {
return TCL_CHANNEL_VERSION_3;
} else {
/*
* In <v2 channel versions, the version field is occupied
* by the Tcl_DriverBlockModeProc
*/
return TCL_CHANNEL_VERSION_1;
| > > | 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 |
Tcl_ChannelVersion(chanTypePtr)
Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
{
if (chanTypePtr->version == TCL_CHANNEL_VERSION_2) {
return TCL_CHANNEL_VERSION_2;
} else if (chanTypePtr->version == TCL_CHANNEL_VERSION_3) {
return TCL_CHANNEL_VERSION_3;
} else if (chanTypePtr->version == TCL_CHANNEL_VERSION_4) {
return TCL_CHANNEL_VERSION_4;
} else {
/*
* In <v2 channel versions, the version field is occupied
* by the Tcl_DriverBlockModeProc
*/
return TCL_CHANNEL_VERSION_1;
|
| ︙ | ︙ | |||
9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 |
{
if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_3)) {
return chanTypePtr->wideSeekProc;
} else {
return NULL;
}
}
#if 0
/*
* For future debugging work, a simple function to print the flags of
* a channel in semi-readable form.
*/
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 9316 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 |
{
if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_3)) {
return chanTypePtr->wideSeekProc;
} else {
return NULL;
}
}
/*
*----------------------------------------------------------------------
*
* Tcl_ChannelThreadActionProc --
*
* TIP #218, Channel Thread Actions.
* Return the Tcl_DriverThreadActionProc of the channel type.
*
* Results:
* A pointer to the proc.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
Tcl_DriverThreadActionProc *
Tcl_ChannelThreadActionProc(chanTypePtr)
Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
{
if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_4)) {
return chanTypePtr->threadActionProc;
} else {
return NULL;
}
}
#if 0
/*
* For future debugging work, a simple function to print the flags of
* a channel in semi-readable form.
*/
|
| ︙ | ︙ |
Changes to generic/tclInt.h.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | * Copyright (c) 1994-1998 Sun Microsystems, Inc. * Copyright (c) 1998-19/99 by Scriptics Corporation. * Copyright (c) 2001, 2002 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | * Copyright (c) 1994-1998 Sun Microsystems, Inc. * Copyright (c) 1998-19/99 by Scriptics Corporation. * Copyright (c) 2001, 2002 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclInt.h,v 1.202.2.5 2005/02/02 15:53:26 kennykb Exp $ */ #ifndef _TCLINT #define _TCLINT /* * Common include files needed by most of the Tcl source files are |
| ︙ | ︙ | |||
1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 | MODULE_SCOPE char * tclNativeExecutableName; MODULE_SCOPE int tclFindExecutableSearchDone; MODULE_SCOPE char * tclMemDumpFileName; MODULE_SCOPE TclPlatformType tclPlatform; MODULE_SCOPE Tcl_NotifierProcs tclOriginalNotifier; /* * Variables denoting the Tcl object types defined in the core. */ MODULE_SCOPE Tcl_ObjType tclBooleanType; MODULE_SCOPE Tcl_ObjType tclByteArrayType; MODULE_SCOPE Tcl_ObjType tclByteCodeType; | > > > > > > > > | 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 | MODULE_SCOPE char * tclNativeExecutableName; MODULE_SCOPE int tclFindExecutableSearchDone; MODULE_SCOPE char * tclMemDumpFileName; MODULE_SCOPE TclPlatformType tclPlatform; MODULE_SCOPE Tcl_NotifierProcs tclOriginalNotifier; /* TIP #233 (Virtualized Time) * Data for the time hooks, if any. */ MODULE_SCOPE Tcl_GetTimeProc* tclGetTimeProcPtr; MODULE_SCOPE Tcl_ScaleTimeProc* tclScaleTimeProcPtr; MODULE_SCOPE ClientData tclTimeClientData; /* * Variables denoting the Tcl object types defined in the core. */ MODULE_SCOPE Tcl_ObjType tclBooleanType; MODULE_SCOPE Tcl_ObjType tclByteArrayType; MODULE_SCOPE Tcl_ObjType tclByteCodeType; |
| ︙ | ︙ | |||
1965 1966 1967 1968 1969 1970 1971 | MODULE_SCOPE ClientData TclpGetNativeCwd _ANSI_ARGS_((ClientData clientData)); MODULE_SCOPE Tcl_FSDupInternalRepProc TclNativeDupInternalRep; MODULE_SCOPE Tcl_Obj* TclpObjLink _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_Obj *toPtr, int linkType)); MODULE_SCOPE int TclpObjChdir _ANSI_ARGS_((Tcl_Obj *pathPtr)); MODULE_SCOPE Tcl_Obj * TclPathPart _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_PathPart portion)); | < < < < | 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 | MODULE_SCOPE ClientData TclpGetNativeCwd _ANSI_ARGS_((ClientData clientData)); MODULE_SCOPE Tcl_FSDupInternalRepProc TclNativeDupInternalRep; MODULE_SCOPE Tcl_Obj* TclpObjLink _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_Obj *toPtr, int linkType)); MODULE_SCOPE int TclpObjChdir _ANSI_ARGS_((Tcl_Obj *pathPtr)); MODULE_SCOPE Tcl_Obj * TclPathPart _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_PathPart portion)); MODULE_SCOPE void TclpPanic _ANSI_ARGS_(TCL_VARARGS(CONST char *, format)); MODULE_SCOPE char * TclpReadlink _ANSI_ARGS_((CONST char *fileName, Tcl_DString *linkPtr)); MODULE_SCOPE void TclpReleaseFile _ANSI_ARGS_((TclFile file)); MODULE_SCOPE void TclpSetInterfaces (); MODULE_SCOPE void TclpSetVariables _ANSI_ARGS_((Tcl_Interp *interp)); |
| ︙ | ︙ | |||
2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 | MODULE_SCOPE void TclSetBgErrorHandler _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *cmdPrefix)); MODULE_SCOPE void TclSetProcessGlobalValue _ANSI_ARGS_ (( ProcessGlobalValue *pgvPtr, Tcl_Obj *newValue, Tcl_Encoding encoding)); MODULE_SCOPE VOID TclSignalExitThread _ANSI_ARGS_((Tcl_ThreadId id, int result)); MODULE_SCOPE int TclSubstTokens _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Token *tokenPtr, int count, int *tokensLeftPtr)); MODULE_SCOPE void TclTransferResult _ANSI_ARGS_(( Tcl_Interp *sourceInterp, int result, Tcl_Interp *targetInterp)); MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized _ANSI_ARGS_(( | > > | 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 | MODULE_SCOPE void TclSetBgErrorHandler _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *cmdPrefix)); MODULE_SCOPE void TclSetProcessGlobalValue _ANSI_ARGS_ (( ProcessGlobalValue *pgvPtr, Tcl_Obj *newValue, Tcl_Encoding encoding)); MODULE_SCOPE VOID TclSignalExitThread _ANSI_ARGS_((Tcl_ThreadId id, int result)); MODULE_SCOPE double TclStrToD _ANSI_ARGS_((CONST char* string, CONST char** endPtr)); MODULE_SCOPE int TclSubstTokens _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Token *tokenPtr, int count, int *tokensLeftPtr)); MODULE_SCOPE void TclTransferResult _ANSI_ARGS_(( Tcl_Interp *sourceInterp, int result, Tcl_Interp *targetInterp)); MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized _ANSI_ARGS_(( |
| ︙ | ︙ |
Changes to generic/tclObj.c.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | * Copyright (c) 1999 by Scriptics Corporation. * Copyright (c) 2001 by ActiveState Corporation. * Copyright (c) 2005 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | * Copyright (c) 1999 by Scriptics Corporation. * Copyright (c) 2001 by ActiveState Corporation. * Copyright (c) 2005 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclObj.c,v 1.72.2.4 2005/02/02 15:53:26 kennykb Exp $ */ #include "tclInt.h" #include "tommath.h" #include "tclCompile.h" /* |
| ︙ | ︙ | |||
1415 1416 1417 1418 1419 1420 1421 | * is non-zero and not "1". Such a string would result in * the boolean value true. We try converting to double. If * that succeeds and the resulting double is non-zero, we * have a "true". Note that numbers can't have embedded * NULLs. */ | | | 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 |
* is non-zero and not "1". Such a string would result in
* the boolean value true. We try converting to double. If
* that succeeds and the resulting double is non-zero, we
* have a "true". Note that numbers can't have embedded
* NULLs.
*/
dbl = TclStrToD(string, (CONST char **) &end);
if (end == string) {
goto badBoolean;
}
/*
* Make sure the string has no garbage after the end of
* the double.
|
| ︙ | ︙ | |||
1701 1702 1703 1704 1705 1706 1707 |
*/
static int
SetDoubleFromAny(interp, objPtr)
Tcl_Interp *interp; /* Used for error reporting if not NULL. */
register Tcl_Obj *objPtr; /* The object to convert. */
{
| | | | 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 |
*/
static int
SetDoubleFromAny(interp, objPtr)
Tcl_Interp *interp; /* Used for error reporting if not NULL. */
register Tcl_Obj *objPtr; /* The object to convert. */
{
CONST char *string, *end;
double newDouble;
int length;
/*
* Get the string representation. Make it up-to-date if necessary.
*/
string = Tcl_GetStringFromObj(objPtr, &length);
/*
* Now parse "objPtr"s string as an double. Numbers can't have embedded
* NULLs. We use an implementation here that doesn't report errors in
* interp if interp is NULL.
*/
errno = 0;
newDouble = TclStrToD(string, &end);
if (end == string) {
badDouble:
if (interp != NULL) {
Tcl_Obj *msg = Tcl_NewStringObj(
"expected floating-point number but got \"", -1);
TclAppendLimitedToObj(msg, string, length, 50, "");
Tcl_AppendToObj(msg, "\"", -1);
|
| ︙ | ︙ |
Changes to generic/tclParseExpr.c.
| ︙ | ︙ | |||
9 10 11 12 13 14 15 | * Copyright (c) 1997 Sun Microsystems, Inc. * Copyright (c) 1998-2000 by Scriptics Corporation. * Contributions from Don Porter, NIST, 2002. (not subject to US copyright) * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | * Copyright (c) 1997 Sun Microsystems, Inc. * Copyright (c) 1998-2000 by Scriptics Corporation. * Contributions from Don Porter, NIST, 2002. (not subject to US copyright) * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclParseExpr.c,v 1.23.2.1 2005/02/02 15:53:27 kennykb Exp $ */ #include "tclInt.h" /* * The stuff below is a bit of a hack so that this file can be used in * environments that include no UNIX, i.e. no errno: just arrange to use |
| ︙ | ︙ | |||
1662 1663 1664 1665 1666 1667 1668 |
} else if ((length = ParseMaxDoubleLength(src, end))) {
/*
* There are length characters that could be a double.
* Let strtod() tells us for sure. Need a writable copy
* so we can set an terminating NULL to keep strtod from
* scanning too far.
*/
| | > | | 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 |
} else if ((length = ParseMaxDoubleLength(src, end))) {
/*
* There are length characters that could be a double.
* Let strtod() tells us for sure. Need a writable copy
* so we can set an terminating NULL to keep strtod from
* scanning too far.
*/
char *startPtr;
CONST char *termPtr;
double doubleValue;
Tcl_DString toParse;
errno = 0;
Tcl_DStringInit(&toParse);
startPtr = Tcl_DStringAppend(&toParse, src, length);
doubleValue = TclStrToD(startPtr, &termPtr);
Tcl_DStringFree(&toParse);
if (termPtr != startPtr) {
if (errno != 0) {
if (interp != NULL) {
TclExprFloatError(interp, doubleValue);
}
parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
|
| ︙ | ︙ |
Changes to generic/tclScan.c.
1 2 3 4 5 6 7 8 9 10 | /* * tclScan.c -- * * This file contains the implementation of the "scan" command. * * Copyright (c) 1998 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* * tclScan.c -- * * This file contains the implementation of the "scan" command. * * Copyright (c) 1998 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclScan.c,v 1.16.2.1 2005/02/02 15:53:27 kennykb Exp $ */ #include "tclInt.h" /* * Flag values used by Tcl_ScanObjCmd. */ |
| ︙ | ︙ | |||
1140 1141 1142 1143 1144 1145 1146 |
/*
* Scan the value from the temporary buffer.
*/
if (!(flags & SCAN_SUPPRESS)) {
double dvalue;
*end = '\0';
| | | 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 |
/*
* Scan the value from the temporary buffer.
*/
if (!(flags & SCAN_SUPPRESS)) {
double dvalue;
*end = '\0';
dvalue = TclStrToD(buf, NULL);
objPtr = Tcl_NewDoubleObj(dvalue);
Tcl_IncrRefCount(objPtr);
objs[objIndex++] = objPtr;
}
break;
}
nconversions++;
|
| ︙ | ︙ |
Added generic/tclStrToD.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 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 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 |
/*
*----------------------------------------------------------------------
*
* tclStrToD.c --
*
* This file contains a TclStrToD procedure that handles conversion
* of string to double, with correct rounding even where extended
* precision is needed to achieve that.
*
* Copyright (c) 2005 by Kevin B. Kenny. All rights reserved.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclStrToD.c,v 1.1.2.1 2005/02/02 15:53:27 kennykb Exp $
*/
#include <tclInt.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <ctype.h>
#include <tommath.h>
#if ( FLT_RADIX == 2 ) && ( DBL_MANT_DIG == 53 ) && ( DBL_MAX_EXP == 1024 )
#define IEEE_FLOATING_POINT
#endif
TCL_DECLARE_MUTEX( initMutex );
/* The powers of ten that can be represented exactly as IEEE754 doubles. */
#define MAXPOW 22
static double pow10 [MAXPOW+1];
/* Inexact higher powers of ten */
static CONST double pow_10_2_n [] = {
1.0,
100.0,
10000.0,
1.0e+8,
1.0e+16,
1.0e+32,
1.0e+64,
1.0e+128,
1.0e+256
};
/* Flag for whether the constants have been initialized */
static volatile int constantsInitialized = 0;
/* Logarithm of the floating point radix. */
static int log2FLT_RADIX;
/* Number of bits in a double's significand */
static int mantBits;
/* Table of powers of 5**(2**n), up to 5**256 */
static mp_int pow5[9];
/* Static functions defined in this file */
static void InitializeConstants _ANSI_ARGS_((void));
static void FreeConstants _ANSI_ARGS_((ClientData));
static double RefineResult _ANSI_ARGS_((double approx, CONST char* start,
int nDigits, long exponent));
static double BignumToDouble _ANSI_ARGS_(( mp_int* a ));
static double ParseNaN _ANSI_ARGS_(( int signum, CONST char** end ));
/*
*----------------------------------------------------------------------
*
* TclStrToD --
*
* Scans a double from a string.
*
* Results:
* Returns the scanned number. In the case of underflow, returns
* an appropriately signed zero; in the case of overflow, returns
* an appropriately signed HUGE_VAL.
*
* Side effects:
* Stores a pointer to the end of the scanned number in '*endPtr',
* if endPtr is not NULL. If '*endPtr' is equal to 's' on return from
* this function, it indicates that the input string could not be
* recognized as a number.
* In the case of underflow or overflow, 'errno' is set to ERANGE.
*
*------------------------------------------------------------------------
*/
double
TclStrToD( CONST char* s,
/* String to scan */
CONST char ** endPtr )
/* Pointer to the end of the scanned number */
{
CONST char* p = s;
CONST char* startOfSignificand = NULL;
/* Start of the significand in the
* string */
int signum = 0; /* Sign of the significand */
double exactSignificand = 0.0;
/* Significand, represented exactly
* as a floating-point number */
int seenDigit = 0; /* Flag == 1 if a digit has been seen */
int nSigDigs = 0; /* Number of significant digits presented */
int nDigitsAfterDp = 0; /* Number of digits after the decimal point */
int nTrailZero = 0; /* Number of trailing zeros in the
* significand */
long exponent = 0; /* Exponent */
int seenDp = 0; /* Flag == 1 if decimal point has been seen */
char c; /* One character extracted from the input */
static int mmaxpow = 0; /* Largest power of ten that can be
* represented exactly in a 'double'. */
double v; /* Scanned value */
int machexp; /* Exponent of the machine rep of the
* scanned value */
int expt2; /* Exponent for computing first
* approximation to the true value */
int i, j;
InitializeConstants();
if ( mmaxpow == 0 ) {
int x = (int) (DBL_MANT_DIG * log((double) FLT_RADIX) / log( 5.0 ))
- 1;
if ( x < MAXPOW ) {
mmaxpow = x;
} else {
mmaxpow = MAXPOW;
}
}
/* Discard leading whitespace */
while ( isspace( *p ) ) {
++p;
}
/* Determine the sign of the significand */
switch( *p ) {
case '-':
signum = 1;
/* FALLTHROUGH */
case '+':
++p;
}
/* Discard leading zeroes */
while ( *p == '0' ) {
seenDigit = 1;
++p;
}
/*
* Scan digits from the significand. Simultaneously, keep track
* of the number of digits after the decimal point. Maintain
* a pointer to the start of the significand. Keep "exactSignificand"
* equal to the conversion of the DBL_DIG most significant digits.
*/
for ( ; ; ) {
c = *p;
if ( c == '.' && !seenDp ) {
seenDp = 1;
++p;
} else if ( isdigit(c) ) {
if ( c == '0' ) {
if ( startOfSignificand != NULL ) {
++nTrailZero;
}
} else {
if ( startOfSignificand == NULL ) {
startOfSignificand = p;
} else if ( nTrailZero ) {
if ( nTrailZero + nSigDigs < DBL_DIG ) {
exactSignificand *= pow10[ nTrailZero ];
} else if ( nSigDigs < DBL_DIG ) {
exactSignificand *= pow10[ DBL_DIG - nSigDigs ];
}
nSigDigs += nTrailZero;
}
if ( nSigDigs < DBL_DIG ) {
exactSignificand = 10. * exactSignificand + (c - '0');
}
++nSigDigs;
nTrailZero = 0;
}
if ( seenDp ) {
++nDigitsAfterDp;
}
seenDigit = 1;
++p;
} else {
break;
}
}
/*
* At this point, we've scanned the significand, and p points
* to the character beyond it. "startOfSignificand" is the first
* non-zero character in the significand. "nSigDigs" is the number
* of significant digits of the significand, not including any
* trailing zeroes. "exactSignificand" is a floating point number
* that represents, without loss of precision, the first
* min(DBL_DIG,n) digits of the significand. "nDigitsAfterDp"
* is the number of digits after the decimal point, again excluding
* trailing zeroes.
*
* Now scan 'E' format
*/
exponent = 0;
if ( seenDigit && ( *p == 'e' || *p == 'E' ) ) {
CONST char* stringSave = p;
++p;
c = *p;
if ( isdigit( c ) || c == '+' || c == '-' ) {
exponent = strtol( p, (char**)&p, 10 );
}
if ( p == stringSave + 1 ) {
p = stringSave;
exponent = 0;
}
}
exponent = exponent + nTrailZero - nDigitsAfterDp;
if ( !seenDigit ) {
/* Test for Inf */
if ( c == 'I' || c == 'i' ) {
if ( ( p[1] == 'N' || p[1] == 'n' )
&& ( p[2] == 'F' || p[2] == 'f' ) ) {
p += 3;
if ( ( p[0] == 'I' || p[0] == 'i' )
&& ( p[1] == 'N' || p[1] == 'n' )
&& ( p[2] == 'I' || p[2] == 'i' )
&& ( p[3] == 'T' || p[3] == 't' )
&& ( p[4] == 'Y' || p[1] == 'y' ) ) {
p += 5;
}
errno = ERANGE;
v = HUGE_VAL;
if ( endPtr != NULL ) {
*endPtr = p;
}
goto returnValue;
}
#ifdef IEEE_FLOATING_POINT
/* IEEE floating point supports NaN */
} else if ( (c == 'N' || c == 'n' )
&& ( sizeof(Tcl_WideUInt) == sizeof( double ) ) ) {
if ( ( p[1] == 'A' || p[1] == 'a' )
&& ( p[2] == 'N' || p[2] == 'n' ) ) {
p += 3;
if ( endPtr != NULL ) {
*endPtr = p;
}
return ParseNaN( signum, endPtr );
}
#endif
}
goto error;
}
if ( endPtr != NULL ) {
*endPtr = p;
}
/* Test for zero. */
if ( nSigDigs == 0 ) {
v = 0.0;
goto returnValue;
}
/*
* The easy cases are where we have an exact significand and
* the exponent is small enough that we can compute the value
* with only one roundoff. The code below that is surrounded
* with #if 0 corresponds to cases that Gay and Clinger claim
* function correctly. but have been observed to fail on mingw,
* returning some results that are off by 1 ulp.
* (Oddly enough, they function correctly on VC++6 on the same
* machine - and they pretty obviously are computing the products
* and quotients of exact floating point numbers.)
*/
if ( nSigDigs <= DBL_DIG ) {
if ( exponent >= 0 ) {
if ( exponent <= mmaxpow ) {
v = exactSignificand * pow10[ exponent ];
goto returnValue;
} else {
#if 0
int diff = DBL_DIG - nSigDigs;
if ( exponent - diff <= mmaxpow ) {
volatile double factor = exactSignificand * pow10[ diff ];
v = factor * pow10[ exponent - diff ];
goto returnValue;
}
#endif
}
} else {
#if 0
if ( exponent >= -mmaxpow ) {
v = exactSignificand / pow10[ -exponent ];
goto returnValue;
}
#endif
}
}
/*
* We don't have one of the easy cases, so we can't compute the
* scanned number exactly, and have to do it in multiple precision.
* Begin by testing for obvious overflows and underflows.
*/
if ( nSigDigs + exponent - 1
> DBL_MAX_EXP * log( (double) FLT_RADIX ) / log( 10. ) ) {
v = HUGE_VAL;
errno = ERANGE;
goto returnValue;
}
if ( nSigDigs + exponent - 1
< floor ( ( DBL_MIN_EXP - DBL_MANT_DIG )
* log( (double) FLT_RADIX ) / log( 10. ) ) ) {
v = 0.;
goto returnValue;
}
/*
* Nothing exceeds the boundaries of the tables, at least.
* Compute an approximate value for the number, with
* no possibility of overflow because we manage the exponent
* separately.
*/
if ( nSigDigs > DBL_DIG ) {
expt2 = exponent + nSigDigs - DBL_DIG;
} else {
expt2 = exponent;
}
v = frexp( exactSignificand, &machexp );
if ( expt2 > 0 ) {
v = frexp( v * pow10[ expt2 & 0xf ], &j );
machexp += j;
for ( i = 4; i < 9; ++i ) {
if ( expt2 & ( 1 << i ) ) {
v = frexp( v * pow_10_2_n[ i ], &j );
machexp += j;
}
}
} else {
v = frexp( v / pow10[ (-expt2) & 0xf ], &j );
machexp += j;
for ( i = 4; i < 9; ++i ) {
if ( (-expt2) & ( 1 << i ) ) {
v = frexp( v / pow_10_2_n[ i ], &j );
machexp += j;
}
}
}
/*
* A first approximation is that the result will be v * 2 ** machexp.
* v is greater than or equal to 0.5 and less than 1.
* If machexp > DBL_MAX_EXP * log2(FLT_RADIX), there is an overflow.
*/
if ( machexp > DBL_MAX_EXP * log2FLT_RADIX ) {
v = HUGE_VAL;
errno = ERANGE;
goto returnValue;
}
v = ldexp( v, machexp );
if ( v == 0 ) {
/* DBL_MIN is known to be incorrect on MSVC6, and ldexp
* doesn't work with denormals. */
v = ldexp( 1.0, DBL_MIN_EXP * log2FLT_RADIX );
v *= ldexp( 1.0, (-DBL_MANT_DIG) * log2FLT_RADIX );
}
/*
* We have a first approximation in v. Now we need to refine it.
*/
v = RefineResult( v, startOfSignificand, nSigDigs, exponent );
/* In a very few cases, a second iteration is needed. e.g., 457e-102 */
v = RefineResult( v, startOfSignificand, nSigDigs, exponent );
/* Handle underflow */
returnValue:
if ( nSigDigs != 0 && v == 0.0 ) {
errno = ERANGE;
}
/* Return a number with correct sign */
if ( signum ) {
return -v;
} else {
return v;
}
/* Come here on an invalid input */
error:
if ( endPtr != NULL ) {
*endPtr = s;
}
return 0.0;
}
/*
*----------------------------------------------------------------------
*
* InitializeConstants --
*
* Initializes constants that are needed for string-to-double
* conversion.
*
* Results:
* None.
*
* Side effects:
* The log base 2 of the floating point radix, the number of
* bits in a double mantissa, and a table of the powers of five
* and ten are computed and stored.
*
*----------------------------------------------------------------------
*/
static void
InitializeConstants( void )
{
int i;
double d;
if ( !constantsInitialized ) {
Tcl_MutexLock( &initMutex );
if ( !constantsInitialized ) {
frexp( (double) FLT_RADIX, &log2FLT_RADIX );
--log2FLT_RADIX;
mantBits = DBL_MANT_DIG * log2FLT_RADIX;
d = 1.0;
for ( i = 0; i <= MAXPOW; ++i ) {
pow10[i] = d;
d *= 10.0;
}
for ( i = 0; i < 9; ++i ) {
mp_init( pow5 + i );
}
mp_set( pow5, 5 );
for ( i = 0; i < 8; ++i ) {
mp_sqr( pow5+i, pow5+i+1 );
}
Tcl_CreateExitHandler( FreeConstants, (ClientData) NULL );
}
constantsInitialized = 1;
Tcl_MutexUnlock( &initMutex );
}
}
/*
*----------------------------------------------------------------------
*
* FreeConstants --
*
* Cleans up this file on exit.
*
* Results:
* None
*
* Side effects:
* Memory allocated by InitializeConstants is freed.
*
*----------------------------------------------------------------------
*/
static void
FreeConstants( ClientData unused )
{
int i;
Tcl_MutexLock( &initMutex );
constantsInitialized = 0;
for ( i = 0; i < 9; ++i ) {
mp_clear( pow5 + i );
}
Tcl_MutexUnlock( &initMutex );
}
/*
*----------------------------------------------------------------------
*
* RefineResult --
*
* Given a poor approximation to a floating point number, returns
* a better one (The better approximation is correct to within
* 1 ulp, and is entirely correct if the poor approximation is
* correct to 1 ulp.)
*
* Results:
* Returns the improved result.
*
*----------------------------------------------------------------------
*/
static double
RefineResult( double approxResult,
/* Approximate result of conversion */
CONST char* sigStart,
/* Pointer to start of significand in
* input string. */
int nSigDigs, /* Number of significant digits */
long exponent ) /* Power of ten to multiply by significand */
{
int M2, M5; /* Powers of 2 and of 5 needed to put
* the decimal and binary numbers over
* a common denominator. */
double significand; /* Sigificand of the binary number */
int binExponent; /* Exponent of the binary number */
int msb; /* Most significant bit position of an
* intermediate result */
int nDigits; /* Number of mp_digit's in an intermediate
* result */
mp_int twoMv; /* Approx binary value expressed as an
* exact integer scaled by the multiplier 2M */
mp_int twoMd; /* Exact decimal value expressed as an
* exact integer scaled by the multiplier 2M */
int scale; /* Scale factor for M */
int multiplier; /* Power of two to scale M */
double num, den; /* Numerator and denominator of the
* correction term */
double quot; /* Correction term */
double minincr; /* Lower bound on the absolute value
* of the correction term. */
int i;
CONST char* p;
/*
* Find a common denominator for the decimal and binary fractions.
* The common denominator will be 2**M2 + 5**M5.
*/
significand = frexp( approxResult, &binExponent );
i = mantBits - binExponent;
if ( i < 0 ) {
M2 = 0;
} else {
M2 = i;
}
if ( exponent > 0 ) {
M5 = 0;
} else {
M5 = -exponent;
if ( (M5-1) > M2 ) {
M2 = M5-1;
}
}
/*
* The floating point number is significand*2**binExponent.
* The 2**-1 bit of the significand (the most significant)
* corresponds to the 2**(binExponent+M2 + 1) bit of 2*M2*v.
* Allocate enough digits to hold that quantity, then
* convert the significand to a large integer, scaled
* appropriately. Then multiply by the appropriate power of 5.
*/
msb = binExponent + M2; /* 1008 */
nDigits = msb / DIGIT_BIT + 1;
mp_init_size( &twoMv, nDigits );
i = ( msb % DIGIT_BIT + 1 );
twoMv.used = nDigits;
significand *= ldexp( 1.0, i );
while ( -- nDigits >= 0 ) {
twoMv.dp[nDigits] = (mp_digit) significand;
significand -= (mp_digit) significand;
significand = ldexp( significand, DIGIT_BIT );
}
for ( i = 0; i <= 8; ++i ) {
if ( M5 & ( 1 << i ) ) {
mp_mul( &twoMv, pow5+i, &twoMv );
}
}
/*
* Collect the decimal significand as a high precision integer.
* The least significant bit corresponds to bit M2+exponent+1
* so it will need to be shifted left by that many bits after
* being multiplied by 5**(M5+exponent).
*/
mp_init( &twoMd ); mp_zero( &twoMd );
i = nSigDigs;
for ( p = sigStart ; ; ++p ) {
char c = *p;
if ( isdigit( c ) ) {
mp_mul_d( &twoMd, (unsigned) 10, &twoMd );
mp_add_d( &twoMd, (unsigned) (c - '0'), &twoMd );
--i;
if ( i == 0 ) break;
}
}
for ( i = 0; i <= 8; ++i ) {
if ( (M5+exponent) & ( 1 << i ) ) {
mp_mul( &twoMd, pow5+i, &twoMd );
}
}
mp_mul_2d( &twoMd, M2+exponent+1, &twoMd );
mp_sub( &twoMd, &twoMv, &twoMd );
/*
* The result, 2Mv-2Md, needs to be divided by 2M to yield a correction
* term. Because 2M may well overflow a double, we need to scale the
* denominator by a factor of 2**binExponent-mantBits
*/
scale = binExponent - mantBits - 1;
mp_set( &twoMv, 1 );
for ( i = 0; i <= 8; ++i ) {
if ( M5 & ( 1 << i ) ) {
mp_mul( &twoMv, pow5+i, &twoMv );
}
}
multiplier = M2 + scale + 1;
if ( multiplier > 0 ) {
mp_mul_2d( &twoMv, multiplier, &twoMv );
} else if ( multiplier < 0 ) {
mp_div_2d( &twoMv, -multiplier, &twoMv, NULL );
}
/*
* If the result is less than unity, the error is less than 1/2 unit
* in the last place, so there's no correction to make.
*/
if ( mp_cmp_mag( &twoMd, &twoMv ) == MP_LT ) {
return approxResult;
}
/*
* Convert the numerator and denominator of the corrector term
* accurately to floating point numbers.
*/
num = BignumToDouble( &twoMd );
den = BignumToDouble( &twoMv );
/*
* MSVC's ldexp underflows suddenly; avoid sudden underflow by
* doing ldexp in two steps.
*/
if ( scale < DBL_MIN_EXP * log2FLT_RADIX ) {
quot = ldexp( 1., DBL_MIN_EXP * log2FLT_RADIX + mantBits )
* ldexp( num/den, scale - DBL_MIN_EXP * log2FLT_RADIX - mantBits );
} else {
quot = ldexp( num/den, scale );
}
minincr = ldexp( 1.0, binExponent - mantBits );
if ( quot < 0. && quot > -minincr ) {
quot = -minincr;
} else if ( quot > 0. && quot < minincr ) {
quot = minincr;
}
mp_clear( &twoMd );
mp_clear( &twoMv );
return approxResult + quot;
}
/*
*----------------------------------------------------------------------
*
* BignumToDouble --
*
* Convert an arbitrary-precision integer to a native floating
* point number.
*
* Results:
* Returns the converted number. Sets errno to ERANGE if the
* number is too large to convert.
*
*----------------------------------------------------------------------
*/
static double
BignumToDouble( mp_int* a )
/* Integer to convert */
{
mp_int b;
int bits;
int shift;
int i;
double r;
/* Determine how many bits we need, and extract that many from
* the input. Round to nearest unit in the last place. */
bits = mp_count_bits( a );
shift = mantBits + 1 - bits;
mp_init( &b );
if ( shift > 0 ) {
mp_mul_2d( a, shift, &b );
} else if ( shift < 0 ) {
mp_div_2d( a, -shift, &b, NULL );
} else {
mp_copy( a, &b );
}
mp_add_d( &b, 1, &b );
mp_div_2d( &b, 1, &b, NULL );
/* Accumulate the result, one mp_digit at a time */
r = 0.0;
for ( i = b.used-1; i >= 0; --i ) {
r = ldexp( r, DIGIT_BIT ) + b.dp[i];
}
mp_clear( &b );
/*
* Test for overflow, and scale the result to the correct number
* of bits.
*/
if ( bits / log2FLT_RADIX > DBL_MAX_EXP ) {
errno = ERANGE;
r = HUGE_VAL;
} else {
r = ldexp( r, bits - mantBits );
}
/* Return the result with the appropriate sign. */
if ( a->sign == MP_ZPOS ) {
return r;
} else {
return -r;
}
}
/*
*----------------------------------------------------------------------
*
* ParseNaN --
*
* Parses a "not a number" from an input string, and returns the
* double precision NaN corresponding to it.
*
* Side effects:
* Advances endPtr to follow any (hex) in the input string.
*
* If the NaN is followed by a left paren, a string of spaes
* and hexadecimal digits, and a right paren, endPtr is advanced
* to follow it.
*
* The string of hexadecimal digits is OR'ed into the resulting
* NaN, and the signum is set as well. Note that a signalling NaN
* is never returned.
*
*----------------------------------------------------------------------
*/
double
ParseNaN( int signum, /* Flag == 1 if minus sign has been
* seen in front of NaN */
CONST char** endPtr )
/* Pointer-to-pointer to char following "NaN"
* in the input string */
{
CONST char* p = *endPtr;
char c;
union {
Tcl_WideUInt iv;
double dv;
} theNaN;
/* Scan off a hex number in parentheses. Embedded blanks are ok. */
theNaN.iv = 0;
if ( *p == '(' ) {
++p;
for ( ; ; ) {
c = *p++;
if ( isspace(c) ) {
continue;
} else if ( c == ')' ) {
*endPtr = p;
break;
} else if ( isdigit(c) ) {
c -= '0';
} else if ( c >= 'A' && c <= 'F' ) {
c = c - 'A' + 10;
} else if ( c >= 'a' && c <= 'f' ) {
c = c - 'a' + 10;
} else {
theNaN.iv = ( ((Tcl_WideUInt) 0x7ff8) << 48 )
| ( ((Tcl_WideUInt) signum) << 63 );
return theNaN.dv;
}
theNaN.iv = (theNaN.iv << 4) | c;
}
}
/*
* Mask the hex number down to the least significant 52 bits.
*
* If the result is zero, make it 1 so that we don't return Inf
* instead of NaN
*/
theNaN.iv &= ( ((Tcl_WideUInt) 1) << 51 ) - 1;
if ( theNaN.iv == 0 ) {
theNaN.iv = 1;
}
if ( signum ) {
theNaN.iv |= ((Tcl_WideUInt) 0xfff8) << 48;
} else {
theNaN.iv |= ((Tcl_WideUInt) 0x7ff8) << 48;
}
*endPtr = p;
return theNaN.dv;
}
|
Changes to generic/tclStubInit.c.
1 2 3 4 5 6 7 8 9 10 | /* * tclStubInit.c -- * * This file contains the initializers for the Tcl stub vectors. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* * tclStubInit.c -- * * This file contains the initializers for the Tcl stub vectors. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclStubInit.c,v 1.109.2.5 2005/02/02 15:53:27 kennykb Exp $ */ #include "tclInt.h" /* * Remove macros that will interfere with the definitions below. */ |
| ︙ | ︙ | |||
969 970 971 972 973 974 975 |
Tcl_SetEnsembleUnknownHandler, /* 545 */
Tcl_SetEnsembleFlags, /* 546 */
Tcl_GetEnsembleSubcommandList, /* 547 */
Tcl_GetEnsembleMappingDict, /* 548 */
Tcl_GetEnsembleUnknownHandler, /* 549 */
Tcl_GetEnsembleFlags, /* 550 */
Tcl_GetEnsembleNamespace, /* 551 */
| > > > | | | | | 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 |
Tcl_SetEnsembleUnknownHandler, /* 545 */
Tcl_SetEnsembleFlags, /* 546 */
Tcl_GetEnsembleSubcommandList, /* 547 */
Tcl_GetEnsembleMappingDict, /* 548 */
Tcl_GetEnsembleUnknownHandler, /* 549 */
Tcl_GetEnsembleFlags, /* 550 */
Tcl_GetEnsembleNamespace, /* 551 */
Tcl_SetTimeProc, /* 552 */
Tcl_QueryTimeProc, /* 553 */
Tcl_ChannelThreadActionProc, /* 554 */
Tcl_NewBignumObj, /* 555 */
Tcl_DbNewBignumObj, /* 556 */
Tcl_SetBignumObj, /* 557 */
Tcl_GetBignumFromObj, /* 558 */
};
/* !END!: Do not edit above this line. */
|
Changes to generic/tclTest.c.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 | * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-2000 Ajuba Solutions. * Copyright (c) 2003 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-2000 Ajuba Solutions. * Copyright (c) 2003 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclTest.c,v 1.86.2.2 2005/02/02 15:53:29 kennykb Exp $ */ #define TCL_TEST #include "tclInt.h" /* * Required for Testregexp*Cmd |
| ︙ | ︙ | |||
2273 2274 2275 2276 2277 2278 2279 |
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST char **argv; /* Argument strings. */
{
long exprResult;
char buf[4 + TCL_INTEGER_SPACE];
int result;
| | > > > > > | | 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 |
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST char **argv; /* Argument strings. */
{
long exprResult;
char buf[4 + TCL_INTEGER_SPACE];
int result;
if (argc != 2) {
Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
" expression\"", (char *) NULL);
return TCL_ERROR;
}
Tcl_SetResult(interp, "This is a result", TCL_STATIC);
result = Tcl_ExprLong(interp, argv[1], &exprResult);
if (result != TCL_OK) {
return result;
}
sprintf(buf, ": %ld", exprResult);
Tcl_AppendResult(interp, buf, NULL);
return TCL_OK;
}
|
| ︙ | ︙ |
Changes to generic/tclThread.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclThread.c -- * * This file implements Platform independent thread operations. * Most of the real work is done in the platform dependent files. * * Copyright (c) 1998 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* * tclThread.c -- * * This file implements Platform independent thread operations. * Most of the real work is done in the platform dependent files. * * Copyright (c) 1998 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclThread.c,v 1.8.2.1 2005/02/02 15:53:29 kennykb Exp $ */ #include "tclInt.h" /* * There are three classes of synchronization objects: * mutexes, thread data keys, and condition variables. |
| ︙ | ︙ | |||
305 306 307 308 309 310 311 |
{
RememberSyncObject((char *)mutexPtr, &mutexRecord);
}
/*
*----------------------------------------------------------------------
*
| | | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
{
RememberSyncObject((char *)mutexPtr, &mutexRecord);
}
/*
*----------------------------------------------------------------------
*
* Tcl_MutexFinalize --
*
* Finalize a single mutex and remove it from the
* list of remembered objects.
*
* Results:
* None.
*
|
| ︙ | ︙ | |||
378 379 380 381 382 383 384 |
{
RememberSyncObject((char *)condPtr, &condRecord);
}
/*
*----------------------------------------------------------------------
*
| | | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
{
RememberSyncObject((char *)condPtr, &condRecord);
}
/*
*----------------------------------------------------------------------
*
* Tcl_ConditionFinalize --
*
* Finalize a single condition variable and remove it from the
* list of remembered objects.
*
* Results:
* None.
*
|
| ︙ | ︙ |
Changes to library/auto.tcl.
1 2 3 4 5 | # auto.tcl -- # # utility procs formerly in init.tcl dealing with auto execution # of commands and can be auto loaded themselves. # | | | < | | | | | > | | > | > > > | 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 |
# auto.tcl --
#
# utility procs formerly in init.tcl dealing with auto execution
# of commands and can be auto loaded themselves.
#
# RCS: @(#) $Id: auto.tcl,v 1.21.2.1 2005/02/02 15:53:30 kennykb Exp $
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994-1998 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# auto_reset --
#
# Destroy all cached information for auto-loading and auto-execution,
# so that the information gets recomputed the next time it's needed.
# Also delete any commands that are listed in the auto-load index.
#
# Arguments:
# None.
proc auto_reset {} {
if {[array exists ::auto_index]} {
foreach cmdName [array names ::auto_index] {
set fqcn [namespace which $cmdName]
if {$fqcn eq ""} {continue}
rename $fqcn {}
}
}
unset -nocomplain ::auto_execs ::auto_index ::tcl::auto_oldpath
if {[catch {llength $::auto_path}]} {
set ::auto_path [list [info library]]
} else {
if {[info library] ni $::auto_path} {
lappend ::auto_path [info library]
}
}
}
# tcl_findLibrary --
#
# This is a utility for extensions that searches for a library directory
# using a canonical searching algorithm. A side effect is to source
# the initialization script and set a global library variable.
|
| ︙ | ︙ |
Added libtommath/bn_fast_s_mp_sqr.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
#include <tommath.h>
#ifdef BN_FAST_S_MP_SQR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
/* fast squaring
*
* This is the comba method where the columns of the product
* are computed first then the carries are computed. This
* has the effect of making a very simple inner loop that
* is executed the most
*
* W2 represents the outer products and W the inner.
*
* A further optimizations is made because the inner
* products are of the form "A * B * 2". The *2 part does
* not need to be computed until the end which is good
* because 64-bit shifts are slow!
*
* Based on Algorithm 14.16 on pp.597 of HAC.
*
*/
/* the jist of squaring...
you do like mult except the offset of the tmpx [one that starts closer to zero]
can't equal the offset of tmpy. So basically you set up iy like before then you min it with
(ty-tx) so that it never happens. You double all those you add in the inner loop
After that loop you do the squares and add them in.
Remove W2 and don't memset W
*/
int fast_s_mp_sqr (mp_int * a, mp_int * b)
{
int olduse, res, pa, ix, iz;
mp_digit W[MP_WARRAY], *tmpx;
mp_word W1;
/* grow the destination as required */
pa = a->used + a->used;
if (b->alloc < pa) {
if ((res = mp_grow (b, pa)) != MP_OKAY) {
return res;
}
}
/* number of output digits to produce */
W1 = 0;
for (ix = 0; ix < pa; ix++) {
int tx, ty, iy;
mp_word _W;
mp_digit *tmpy;
/* clear counter */
_W = 0;
/* get offsets into the two bignums */
ty = MIN(a->used-1, ix);
tx = ix - ty;
/* setup temp aliases */
tmpx = a->dp + tx;
tmpy = a->dp + ty;
/* this is the number of times the loop will iterrate, essentially its
while (tx++ < a->used && ty-- >= 0) { ... }
*/
iy = MIN(a->used-tx, ty+1);
/* now for squaring tx can never equal ty
* we halve the distance since they approach at a rate of 2x
* and we have to round because odd cases need to be executed
*/
iy = MIN(iy, (ty-tx+1)>>1);
/* execute loop */
for (iz = 0; iz < iy; iz++) {
_W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
}
/* double the inner product and add carry */
_W = _W + _W + W1;
/* even columns have the square term in them */
if ((ix&1) == 0) {
_W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
}
/* store it */
W[ix] = (mp_digit) _W;
/* make next carry */
W1 = _W >> ((mp_word)DIGIT_BIT);
}
/* setup dest */
olduse = b->used;
b->used = a->used+a->used;
{
mp_digit *tmpb;
tmpb = b->dp;
for (ix = 0; ix < pa; ix++) {
*tmpb++ = W[ix] & MP_MASK;
}
/* clear unused digits [that existed in the old copy of c] */
for (; ix < olduse; ix++) {
*tmpb++ = 0;
}
}
mp_clamp (b);
return MP_OKAY;
}
#endif
|
Changes to tests/expr-old.test.
| ︙ | ︙ | |||
9 10 11 12 13 14 15 | # Copyright (c) 1991-1994 The Regents of the University of California. # Copyright (c) 1994-1997 Sun Microsystems, Inc. # Copyright (c) 1998-2000 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# Copyright (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: expr-old.test,v 1.22.2.1 2005/02/02 15:53:30 kennykb Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2.1
namespace import -force ::tcltest::*
}
if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {
|
| ︙ | ︙ | |||
957 958 959 960 961 962 963 |
list [catch {expr {$x+1}} msg] $msg
} {1 {can't use integer value too large to represent as operand of "+"}}
testConstraint testexprlong [llength [info commands testexprlong]]
testConstraint testexprstring [llength [info commands testexprstring]]
test expr-old-37.1 {Check that Tcl_ExprLong doesn't modify interpreter result if no error} testexprlong {
| | > > > > | 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 |
list [catch {expr {$x+1}} msg] $msg
} {1 {can't use integer value too large to represent as operand of "+"}}
testConstraint testexprlong [llength [info commands testexprlong]]
testConstraint testexprstring [llength [info commands testexprstring]]
test expr-old-37.1 {Check that Tcl_ExprLong doesn't modify interpreter result if no error} testexprlong {
testexprlong 4+1
} {This is a result: 5}
#Check for [Bug 1109484]
test expr-old-37.2 {Tcl_ExprLong handles wide ints gracefully} testexprlong {
testexprlong wide(1)+2
} {This is a result: 3}
test expr-old-38.1 {Verify Tcl_ExprString's basic operation} testexprstring {
list [testexprstring "1+4"] [testexprstring "2*3+4.2"] \
[catch {testexprstring "1+"} msg] $msg
} {5 10.2 1 {syntax error in expression "1+": premature end of expression}}
#
|
| ︙ | ︙ |
Changes to tests/io.test.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | # Copyright (c) 1991-1994 The Regents of the University of California. # Copyright (c) 1994-1997 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# Copyright (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: io.test,v 1.65.2.1 2005/02/02 15:53:31 kennykb Exp $
if {[catch {package require tcltest 2}]} {
puts stderr "Skipping tests in [info script]. tcltest 2 required."
return
}
namespace eval ::tcl::test::io {
|
| ︙ | ︙ | |||
1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 |
set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
puts [gets $f]
}
close $f
set f [open "|[list [interpreter] $path(script) [array get path]]" r]
set c [gets $f]
close $f
set c
} hello
test io-15.1 {Tcl_CreateCloseHandler} emptyTest {
} {}
test io-16.1 {Tcl_DeleteCloseHandler} emptyTest {
| > > > > > > | 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 |
set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
puts [gets $f]
}
close $f
set f [open "|[list [interpreter] $path(script) [array get path]]" r]
set c [gets $f]
close $f
# Added delay to give Windows time to stop the spawned process and clean
# up its grip on the file test1. Added delete as proper test cleanup.
# The failing tests were 18.1 and 18.2 as first re-users of file "test1".
after 10000
file delete $path(script)
file delete $path(test1)
set c
} hello
test io-15.1 {Tcl_CreateCloseHandler} emptyTest {
} {}
test io-16.1 {Tcl_DeleteCloseHandler} emptyTest {
|
| ︙ | ︙ |
Changes to unix/configure.
| ︙ | ︙ | |||
7265 7266 7267 7268 7269 7270 7271 |
# FreeBSD-3 doesn't handle version numbers with dots.
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
TCL_LIB_VERSIONS_OK=nodots
;;
esac
;;
| | | | 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 |
# FreeBSD-3 doesn't handle version numbers with dots.
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
TCL_LIB_VERSIONS_OK=nodots
;;
esac
;;
Darwin-*)
SHLIB_CFLAGS="-fno-common"
SHLIB_LD="cc -dynamiclib \${LDFLAGS}"
TCL_SHLIB_LD_EXTRAS="-compatibility_version ${TCL_VERSION} -current_version \${VERSION} -install_name \${DYLIB_INSTALL_DIR}/\${TCL_LIB_FILE} -prebind -seg1addr 0xa000000"
TK_SHLIB_LD_EXTRAS="-compatibility_version ${TK_VERSION} -current_version \${VERSION} -install_name \${DYLIB_INSTALL_DIR}/\${TK_LIB_FILE} -prebind -seg1addr 0xb000000"
SHLIB_LD_LIBS='${LIBS}'
SHLIB_SUFFIX=".dylib"
DL_OBJS="tclLoadDyld.o"
PLAT_OBJS=\$\(MAC\_OSX_OBJS\)
DL_LIBS=""
LDFLAGS="$LDFLAGS -prebind -Wl,-search_paths_first"
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
CFLAGS_OPTIMIZE="-Os"
LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
cat >>confdefs.h <<\_ACEOF
#define MAC_OSX_TCL 1
|
| ︙ | ︙ | |||
7510 7511 7512 7513 7514 7515 7516 | SHLIB_CFLAGS="-KPIC" # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then arch=`isainfo` if test "$arch" = "sparcv9 sparc" ; then if test "$GCC" = "yes" ; then | > | | > > > > > > > | | > > > > > > > > > | 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 |
SHLIB_CFLAGS="-KPIC"
# Check to enable 64-bit flags for compiler/linker
if test "$do64bit" = "yes" ; then
arch=`isainfo`
if test "$arch" = "sparcv9 sparc" ; then
if test "$GCC" = "yes" ; then
if test "`gcc -dumpversion | awk -F. '{print $1}'`" -lt "3" ; then
{ echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
else
do64bit_ok=yes
CFLAGS="$CFLAGS -m64 -mcpu=v9"
LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
SHLIB_CFLAGS="-fPIC"
SHLIB_LD_FLAGS=""
fi
else
do64bit_ok=yes
if test "$do64bitVIS" = "yes" ; then
CFLAGS="$CFLAGS -xarch=v9a"
LDFLAGS_ARCH="-xarch=v9a"
else
CFLAGS="$CFLAGS -xarch=v9"
LDFLAGS_ARCH="-xarch=v9"
fi
fi
else
{ echo "$as_me:$LINENO: WARNING: 64bit mode only supported sparcv9 system" >&5
echo "$as_me: WARNING: 64bit mode only supported sparcv9 system" >&2;}
fi
fi
# Note: need the LIBS below, otherwise Tk won't find Tcl's
# symbols when dynamically loaded into tclsh.
SHLIB_LD_LIBS='${LIBS}'
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS="-ldl"
if test "$GCC" = "yes" ; then
SHLIB_LD="$CC -shared"
CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
if test "$do64bit_ok" = "yes" ; then
# We need to specify -static-libgcc or we need to
# add the path to the sparv9 libgcc.
SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
# for finding sparcv9 libgcc, get the regular libgcc
# path, remove so name and append 'sparcv9'
#v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
#CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
fi
else
SHLIB_LD="/usr/ccs/bin/ld -G -z text"
CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
fi
;;
ULTRIX-4.*)
|
| ︙ | ︙ | |||
7616 7617 7618 7619 7620 7621 7622 |
echo "${ECHO_T}$found" >&6
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
;;
esac
if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
| | | | 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 |
echo "${ECHO_T}$found" >&6
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
;;
esac
if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
{ echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
fi
if test "$do64bit" = "yes" -a "$do64bit_ok" = "yes" ; then
cat >>confdefs.h <<\_ACEOF
#define TCL_CFG_DO64BIT 1
_ACEOF
|
| ︙ | ︙ | |||
7873 7874 7875 7876 7877 7878 7879 | ;; BSD/OS*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*) ;; | | | 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 | ;; BSD/OS*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*) ;; Darwin-*) ;; RISCos-*) ;; SCO_SV-3.2*) ;; ULTRIX-4.*) ;; |
| ︙ | ︙ | |||
13457 13458 13459 13460 13461 13462 13463 |
echo "$as_me:$LINENO: result: standard shared library" >&5
echo "${ECHO_T}standard shared library" >&6
FRAMEWORK_BUILD=0
fi
# tclConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
| > > | > | 13474 13475 13476 13477 13478 13479 13480 13481 13482 13483 13484 13485 13486 13487 13488 13489 13490 13491 |
echo "$as_me:$LINENO: result: standard shared library" >&5
echo "${ECHO_T}standard shared library" >&6
FRAMEWORK_BUILD=0
fi
# tclConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# since on some platforms TCL_LIB_FILE contains shell escapes.
# (See also: TCL_TRIM_DOTS).
eval "TCL_LIB_FILE=${TCL_LIB_FILE}"
# Note: in the following variable, it's important to use the absolute
# path name of the Tcl directory rather than "..": this is because
# AIX remembers this path and will attempt to use it at run-time to look
# up the Tcl library.
if test "$FRAMEWORK_BUILD" = "1" ; then
|
| ︙ | ︙ | |||
13520 13521 13522 13523 13524 13525 13526 13527 13528 13529 13530 13531 13532 13533 13534 |
#--------------------------------------------------------------------
# The statements below define various symbols relating to Tcl
# stub support.
#--------------------------------------------------------------------
# Replace ${VERSION} with contents of ${TCL_VERSION}
eval "TCL_STUB_LIB_FILE=libtclstub${TCL_UNSHARED_LIB_SUFFIX}"
if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
TCL_STUB_LIB_FLAG="-ltclstub${TCL_VERSION}"
else
TCL_STUB_LIB_FLAG="-ltclstub`echo ${TCL_VERSION} | tr -d .`"
fi
| > > > | 13540 13541 13542 13543 13544 13545 13546 13547 13548 13549 13550 13551 13552 13553 13554 13555 13556 13557 |
#--------------------------------------------------------------------
# The statements below define various symbols relating to Tcl
# stub support.
#--------------------------------------------------------------------
# Replace ${VERSION} with contents of ${TCL_VERSION}
# double-eval to account for TCL_TRIM_DOTS.
#
eval "TCL_STUB_LIB_FILE=libtclstub${TCL_UNSHARED_LIB_SUFFIX}"
eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
TCL_STUB_LIB_FLAG="-ltclstub${TCL_VERSION}"
else
TCL_STUB_LIB_FLAG="-ltclstub`echo ${TCL_VERSION} | tr -d .`"
fi
|
| ︙ | ︙ |
Changes to unix/configure.in.
1 2 3 4 5 | #! /bin/bash -norc dnl This file is an input file used by the GNU "autoconf" program to dnl generate the file "configure", which is run during Tcl installation dnl to configure the system for the local environment. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | #! /bin/bash -norc dnl This file is an input file used by the GNU "autoconf" program to dnl generate the file "configure", which is run during Tcl installation dnl to configure the system for the local environment. # # RCS: @(#) $Id: configure.in,v 1.123.2.4 2005/02/02 15:53:59 kennykb Exp $ AC_INIT([tcl],[8.5]) AC_PREREQ(2.57) dnl AC_CONFIG_HEADERS([tclConfig.h]) dnl AC_CONFIG_COMMANDS_PRE([DEFS=-DHAVE_TCL_CONFIG_H]) TCL_VERSION=8.5 |
| ︙ | ︙ | |||
435 436 437 438 439 440 441 |
TCL_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}
TCL_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX}
eval "TCL_LIB_FILE=libtcl${LIB_SUFFIX}"
SC_ENABLE_FRAMEWORK
# tclConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
| > > | > | 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
TCL_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}
TCL_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX}
eval "TCL_LIB_FILE=libtcl${LIB_SUFFIX}"
SC_ENABLE_FRAMEWORK
# tclConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# since on some platforms TCL_LIB_FILE contains shell escapes.
# (See also: TCL_TRIM_DOTS).
eval "TCL_LIB_FILE=${TCL_LIB_FILE}"
# Note: in the following variable, it's important to use the absolute
# path name of the Tcl directory rather than "..": this is because
# AIX remembers this path and will attempt to use it at run-time to look
# up the Tcl library.
if test "$FRAMEWORK_BUILD" = "1" ; then
|
| ︙ | ︙ | |||
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 |
#--------------------------------------------------------------------
# The statements below define various symbols relating to Tcl
# stub support.
#--------------------------------------------------------------------
# Replace ${VERSION} with contents of ${TCL_VERSION}
eval "TCL_STUB_LIB_FILE=libtclstub${TCL_UNSHARED_LIB_SUFFIX}"
if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
TCL_STUB_LIB_FLAG="-ltclstub${TCL_VERSION}"
else
TCL_STUB_LIB_FLAG="-ltclstub`echo ${TCL_VERSION} | tr -d .`"
fi
| > > > | 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 |
#--------------------------------------------------------------------
# The statements below define various symbols relating to Tcl
# stub support.
#--------------------------------------------------------------------
# Replace ${VERSION} with contents of ${TCL_VERSION}
# double-eval to account for TCL_TRIM_DOTS.
#
eval "TCL_STUB_LIB_FILE=libtclstub${TCL_UNSHARED_LIB_SUFFIX}"
eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
TCL_STUB_LIB_FLAG="-ltclstub${TCL_VERSION}"
else
TCL_STUB_LIB_FLAG="-ltclstub`echo ${TCL_VERSION} | tr -d .`"
fi
|
| ︙ | ︙ |
Changes to unix/tcl.m4.
| ︙ | ︙ | |||
1385 1386 1387 1388 1389 1390 1391 |
# FreeBSD-3 doesn't handle version numbers with dots.
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
TCL_LIB_VERSIONS_OK=nodots
;;
esac
;;
| | | | 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 |
# FreeBSD-3 doesn't handle version numbers with dots.
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
TCL_LIB_VERSIONS_OK=nodots
;;
esac
;;
Darwin-*)
SHLIB_CFLAGS="-fno-common"
SHLIB_LD="cc -dynamiclib \${LDFLAGS}"
TCL_SHLIB_LD_EXTRAS="-compatibility_version ${TCL_VERSION} -current_version \${VERSION} -install_name \${DYLIB_INSTALL_DIR}/\${TCL_LIB_FILE} -prebind -seg1addr 0xa000000"
TK_SHLIB_LD_EXTRAS="-compatibility_version ${TK_VERSION} -current_version \${VERSION} -install_name \${DYLIB_INSTALL_DIR}/\${TK_LIB_FILE} -prebind -seg1addr 0xb000000"
SHLIB_LD_LIBS='${LIBS}'
SHLIB_SUFFIX=".dylib"
DL_OBJS="tclLoadDyld.o"
PLAT_OBJS=\$\(MAC\_OSX_OBJS\)
DL_LIBS=""
LDFLAGS="$LDFLAGS -prebind -Wl,-search_paths_first"
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
CFLAGS_OPTIMIZE="-Os"
LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
AC_DEFINE(MAC_OSX_TCL, 1, ["Is this a Mac I see before me?"])
AC_DEFINE(HAVE_CFBUNDLE, 1, [Do we have access to Mac bundles?])
AC_DEFINE(USE_VFORK, 1, [Should we use vfork() instead of fork()?])
|
| ︙ | ︙ | |||
1592 1593 1594 1595 1596 1597 1598 | # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) SHLIB_CFLAGS="-KPIC" | | > | > > > > > > > | > > > > > > > > > | 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 |
# won't define thread-safe library routines.
AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
[Do we really want to follow the standard? Yes we do!])
SHLIB_CFLAGS="-KPIC"
# Check to enable 64-bit flags for compiler/linker
if test "$do64bit" = "yes" ; then
arch=`isainfo`
if test "$arch" = "sparcv9 sparc" ; then
if test "$GCC" = "yes" ; then
if test "`gcc -dumpversion | awk -F. '{print [$]1}'`" -lt "3" ; then
AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
else
do64bit_ok=yes
CFLAGS="$CFLAGS -m64 -mcpu=v9"
LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
SHLIB_CFLAGS="-fPIC"
SHLIB_LD_FLAGS=""
fi
else
do64bit_ok=yes
if test "$do64bitVIS" = "yes" ; then
CFLAGS="$CFLAGS -xarch=v9a"
LDFLAGS_ARCH="-xarch=v9a"
else
CFLAGS="$CFLAGS -xarch=v9"
LDFLAGS_ARCH="-xarch=v9"
fi
fi
else
AC_MSG_WARN([64bit mode only supported sparcv9 system])
fi
fi
# Note: need the LIBS below, otherwise Tk won't find Tcl's
# symbols when dynamically loaded into tclsh.
SHLIB_LD_LIBS='${LIBS}'
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS="-ldl"
if test "$GCC" = "yes" ; then
SHLIB_LD="$CC -shared"
CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
if test "$do64bit_ok" = "yes" ; then
# We need to specify -static-libgcc or we need to
# add the path to the sparv9 libgcc.
SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
# for finding sparcv9 libgcc, get the regular libgcc
# path, remove so name and append 'sparcv9'
#v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
#CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
fi
else
SHLIB_LD="/usr/ccs/bin/ld -G -z text"
CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
fi
;;
ULTRIX-4.*)
|
| ︙ | ︙ | |||
1666 1667 1668 1669 1670 1671 1672 |
AC_MSG_RESULT($found)
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
;;
esac
if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
| | | 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 |
AC_MSG_RESULT($found)
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
;;
esac
if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
fi
if test "$do64bit" = "yes" -a "$do64bit_ok" = "yes" ; then
AC_DEFINE(TCL_CFG_DO64BIT, 1, [Is this a 64-bit build?])
fi
# Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic
|
| ︙ | ︙ | |||
1793 1794 1795 1796 1797 1798 1799 | ;; BSD/OS*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*) ;; | | | 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 | ;; BSD/OS*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*) ;; Darwin-*) ;; RISCos-*) ;; SCO_SV-3.2*) ;; ULTRIX-4.*) ;; |
| ︙ | ︙ |
Changes to unix/tclUnixChan.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclUnixChan.c * * Common channel driver for Unix channels based on files, command * pipes and TCP sockets. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclUnixChan.c * * Common channel driver for Unix channels based on files, command * pipes and TCP sockets. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclUnixChan.c,v 1.53.2.1 2005/02/02 15:54:01 kennykb Exp $ */ #include "tclInt.h" /* Internal definitions for Tcl. */ #include "tclIO.h" /* To get Channel type declaration. */ /* * sys/ioctl.h has already been included by tclPort.h. Including termios.h |
| ︙ | ︙ | |||
228 229 230 231 232 233 234 235 236 237 238 239 240 241 | static int FileInputProc _ANSI_ARGS_((ClientData instanceData, char *buf, int toRead, int *errorCode)); static int FileOutputProc _ANSI_ARGS_(( ClientData instanceData, CONST char *buf, int toWrite, int *errorCode)); static int FileSeekProc _ANSI_ARGS_((ClientData instanceData, long offset, int mode, int *errorCode)); static Tcl_WideInt FileWideSeekProc _ANSI_ARGS_((ClientData instanceData, Tcl_WideInt offset, int mode, int *errorCode)); static void FileWatchProc _ANSI_ARGS_((ClientData instanceData, int mask)); static void TcpAccept _ANSI_ARGS_((ClientData data, int mask)); static int TcpBlockModeProc _ANSI_ARGS_((ClientData data, int mode)); | > > > > | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | static int FileInputProc _ANSI_ARGS_((ClientData instanceData, char *buf, int toRead, int *errorCode)); static int FileOutputProc _ANSI_ARGS_(( ClientData instanceData, CONST char *buf, int toWrite, int *errorCode)); static int FileSeekProc _ANSI_ARGS_((ClientData instanceData, long offset, int mode, int *errorCode)); #ifdef DEPRECATED static void FileThreadActionProc _ANSI_ARGS_ (( ClientData instanceData, int action)); #endif static Tcl_WideInt FileWideSeekProc _ANSI_ARGS_((ClientData instanceData, Tcl_WideInt offset, int mode, int *errorCode)); static void FileWatchProc _ANSI_ARGS_((ClientData instanceData, int mask)); static void TcpAccept _ANSI_ARGS_((ClientData data, int mask)); static int TcpBlockModeProc _ANSI_ARGS_((ClientData data, int mode)); |
| ︙ | ︙ | |||
287 288 289 290 291 292 293 |
/*
* This structure describes the channel type structure for file based IO:
*/
static Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
| | > > > > > | > > | > > | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 |
/*
* This structure describes the channel type structure for file based IO:
*/
static Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
TCL_CHANNEL_VERSION_4, /* v4 channel */
FileCloseProc, /* Close proc. */
FileInputProc, /* Input proc. */
FileOutputProc, /* Output proc. */
FileSeekProc, /* Seek proc. */
NULL, /* Set option proc. */
NULL, /* Get option proc. */
FileWatchProc, /* Initialize notifier. */
FileGetHandleProc, /* Get OS handles out of channel. */
NULL, /* close2proc. */
FileBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
FileWideSeekProc, /* wide seek proc. */
#ifdef DEPRECATED
FileThreadActionProc, /* thread actions */
#else
NULL,
#endif
};
#ifdef SUPPORTS_TTY
/*
* This structure describes the channel type structure for serial IO.
* Note that this type is a subclass of the "file" type.
*/
static Tcl_ChannelType ttyChannelType = {
"tty", /* Type name. */
TCL_CHANNEL_VERSION_4, /* v4 channel */
TtyCloseProc, /* Close proc. */
FileInputProc, /* Input proc. */
#if BAD_TIP35_FLUSH
TtyOutputProc, /* Output proc. */
#else /* !BAD_TIP35_FLUSH */
FileOutputProc, /* Output proc. */
#endif /* BAD_TIP35_FLUSH */
NULL, /* Seek proc. */
TtySetOptionProc, /* Set option proc. */
TtyGetOptionProc, /* Get option proc. */
FileWatchProc, /* Initialize notifier. */
FileGetHandleProc, /* Get OS handles out of channel. */
NULL, /* close2proc. */
FileBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
NULL, /* wide seek proc. */
NULL, /* thread action proc. */
};
#endif /* SUPPORTS_TTY */
/*
* This structure describes the channel type structure for TCP socket
* based IO:
*/
static Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
TCL_CHANNEL_VERSION_4, /* v4 channel */
TcpCloseProc, /* Close proc. */
TcpInputProc, /* Input proc. */
TcpOutputProc, /* Output proc. */
NULL, /* Seek proc. */
NULL, /* Set option proc. */
TcpGetOptionProc, /* Get option proc. */
TcpWatchProc, /* Initialize notifier. */
TcpGetHandleProc, /* Get OS handles out of channel. */
NULL, /* close2proc. */
TcpBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
NULL, /* wide seek proc. */
NULL, /* thread action proc. */
};
/*
*----------------------------------------------------------------------
*
* FileBlockModeProc --
|
| ︙ | ︙ | |||
1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 |
#endif /* SUPPORTS_TTY */
{
translation = NULL;
channelTypePtr = &fileChannelType;
fsPtr = (FileState *) ckalloc((unsigned) sizeof(FileState));
}
fsPtr->validMask = channelPermissions | TCL_EXCEPTION;
fsPtr->fd = fd;
fsPtr->channel = Tcl_CreateChannel(channelTypePtr, channelName,
(ClientData) fsPtr, channelPermissions);
if (translation != NULL) {
| > > > > > > > > > | 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 |
#endif /* SUPPORTS_TTY */
{
translation = NULL;
channelTypePtr = &fileChannelType;
fsPtr = (FileState *) ckalloc((unsigned) sizeof(FileState));
}
#ifdef DEPRECATED
if (channelTypePtr == &fileChannelType) {
/* TIP #218. Removed the code inserting the new structure
* into the global list. This is now handled in the thread
* action callbacks, and only there.
*/
fsPtr->nextPtr = NULL;
}
#endif /* DEPRECATED */
fsPtr->validMask = channelPermissions | TCL_EXCEPTION;
fsPtr->fd = fd;
fsPtr->channel = Tcl_CreateChannel(channelTypePtr, channelName,
(ClientData) fsPtr, channelPermissions);
if (translation != NULL) {
|
| ︙ | ︙ | |||
3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 |
&& (abortTime.usec <= now.usec))) {
break;
}
}
return result;
}
/*
*----------------------------------------------------------------------
*
| > | | < | | < | | > > | | < | < > > | > | > > > > > | < > > | < > | > > | < < | < < > > | < < < < < < | > > | 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 |
&& (abortTime.usec <= now.usec))) {
break;
}
}
return result;
}
#ifdef DEPRECATED
/*
*----------------------------------------------------------------------
*
* FileThreadActionProc --
*
* Insert or remove any thread local refs to this channel.
*
* Results:
* None.
*
* Side effects:
* None. This is a no-op under unix.
*
*----------------------------------------------------------------------
*/
static void
FileThreadActionProc (instanceData, action)
ClientData instanceData;
int action;
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
FileState *fsPtr = (FileState *) instanceData;
if (action == TCL_CHANNEL_THREAD_INSERT) {
fsPtr->nextPtr = tsdPtr->firstFilePtr;
tsdPtr->firstFilePtr = fsPtr;
} else {
FileState **nextPtrPtr;
int removed = 0;
for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
if ((*nextPtrPtr) == fsPtr) {
(*nextPtrPtr) = fsPtr->nextPtr;
removed = 1;
break;
}
}
/*
* This could happen if the channel was created in one
* thread and then moved to another without updating
* the thread local data in each thread.
*/
if (!removed) {
Tcl_Panic("file info ptr not on thread channel list");
}
}
}
#endif
|
Changes to unix/tclUnixEvent.c.
1 2 3 4 5 6 7 8 9 10 | /* * tclUnixEvent.c -- * * This file implements Unix specific event related routines. * * Copyright (c) 1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tclUnixEvent.c -- * * This file implements Unix specific event related routines. * * Copyright (c) 1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclUnixEvent.c,v 1.5.2.1 2005/02/02 15:54:01 kennykb Exp $ */ #include "tclInt.h" /* *---------------------------------------------------------------------- * * Tcl_Sleep -- * * Delay execution for the specified number of milliseconds. |
| ︙ | ︙ | |||
30 31 32 33 34 35 36 |
*/
void
Tcl_Sleep(ms)
int ms; /* Number of milliseconds to sleep. */
{
struct timeval delay;
| | > | > | > | | | > > > > > > > | 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 |
*/
void
Tcl_Sleep(ms)
int ms; /* Number of milliseconds to sleep. */
{
struct timeval delay;
Tcl_Time before, after, vdelay;
/*
* The only trick here is that select appears to return early
* under some conditions, so we have to check to make sure that
* the right amount of time really has elapsed. If it's too
* early, go back to sleep again.
*/
Tcl_GetTime(&before);
after = before;
after.sec += ms/1000;
after.usec += (ms%1000)*1000;
if (after.usec > 1000000) {
after.usec -= 1000000;
after.sec += 1;
}
while (1) {
/* TIP #233: Scale from virtual time to real-time for select */
vdelay.sec = after.sec - before.sec;
vdelay.usec = after.usec - before.usec;
if (vdelay.usec < 0) {
vdelay.usec += 1000000;
vdelay.sec -= 1;
}
if ((vdelay.sec != 0) || (vdelay.usec != 0)) {
(*tclScaleTimeProcPtr) (&vdelay, tclTimeClientData);
}
delay.tv_sec = vdelay.sec;
delay.tv_usec = vdelay.usec;
/*
* Special note: must convert delay.tv_sec to int before comparing
* to zero, since delay.tv_usec is unsigned on some platforms.
*/
if ((((int) delay.tv_sec) < 0)
|| ((delay.tv_usec == 0) && (delay.tv_sec == 0))) {
|
| ︙ | ︙ |
Changes to unix/tclUnixNotfy.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclUnixNotify.c -- * * This file contains the implementation of the select-based * Unix-specific notifier, which is the lowest-level part of the * Tcl event loop. This file works together with * ../generic/tclNotify.c. * * Copyright (c) 1995-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. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tclUnixNotify.c -- * * This file contains the implementation of the select-based * Unix-specific notifier, which is the lowest-level part of the * Tcl event loop. This file works together with * ../generic/tclNotify.c. * * Copyright (c) 1995-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. * * RCS: @(#) $Id: tclUnixNotfy.c,v 1.18.2.2 2005/02/02 15:54:01 kennykb Exp $ */ #include "tclInt.h" #include <signal.h> extern TclStubs tclStubs; extern Tcl_NotifierProcs tclOriginalNotifier; |
| ︙ | ︙ | |||
648 649 650 651 652 653 654 |
int
Tcl_WaitForEvent(timePtr)
Tcl_Time *timePtr; /* Maximum block time, or NULL. */
{
FileHandler *filePtr;
FileHandlerEvent *fileEvPtr;
| < > > > > > > > > > > > > > > > > > > > | | | > > > > > > | | | 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 |
int
Tcl_WaitForEvent(timePtr)
Tcl_Time *timePtr; /* Maximum block time, or NULL. */
{
FileHandler *filePtr;
FileHandlerEvent *fileEvPtr;
int mask;
Tcl_Time myTime;
#ifdef TCL_THREADS
int waitForFiles;
Tcl_Time *myTimePtr;
#else
/* Impl. notes: timeout & timeoutPtr are used if, and only if
* threads are not enabled. They are the arguments for the regular
* select() used when the core is not thread-enabled. */
struct timeval timeout, *timeoutPtr;
int numFound;
#endif
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (tclStubs.tcl_WaitForEvent != tclOriginalNotifier.waitForEventProc) {
return tclStubs.tcl_WaitForEvent(timePtr);
}
/*
* Set up the timeout structure. Note that if there are no events to
* check for, we return with a negative result rather than blocking
* forever.
*/
if (timePtr) {
/* TIP #233 (Virtualized Time). Is virtual time in effect ?
* And do we actually have something to scale ? If yes to both
* then we call the handler to do this scaling */
myTime.sec = timePtr->sec;
myTime.usec = timePtr->usec;
(*tclScaleTimeProcPtr) (&myTime, tclTimeClientData);
#ifdef TCL_THREADS
myTimePtr = &myTime;
#else
timeout.tv_sec = myTime.sec;
timeout.tv_usec = myTime.usec;
timeoutPtr = &timeout;
#endif
#ifndef TCL_THREADS
} else if (tsdPtr->numFdBits == 0) {
/*
* If there are no threads, no timeout, and no fds registered,
* then there are no events possible and we must avoid deadlock.
* Note that this is not entirely correct because there might
* be a signal that could interrupt the select call, but we
* don't handle that case if we aren't using threads.
*/
return -1;
#endif
} else {
#ifdef TCL_THREADS
myTimePtr = NULL;
#else
timeoutPtr = NULL;
#endif
}
#ifdef TCL_THREADS
/*
* Place this thread on the list of interested threads, signal the
* notifier thread, and wait for a response or a timeout.
*/
Tcl_MutexLock(¬ifierMutex);
waitForFiles = (tsdPtr->numFdBits > 0);
if (myTimePtr != NULL && myTimePtr->sec == 0 && myTimePtr->usec == 0) {
/*
* Cannot emulate a polling select with a polling condition variable.
* Instead, pretend to wait for files and tell the notifier
* thread what we are doing. The notifier thread makes sure
* it goes through select with its select mask in the same state
* as ours currently is. We block until that happens.
*/
waitForFiles = 1;
tsdPtr->pollState = POLL_WANT;
myTimePtr = NULL;
} else {
tsdPtr->pollState = 0;
}
if (waitForFiles) {
/*
* Add the ThreadSpecificData structure of this thread to the list
|
| ︙ | ︙ | |||
736 737 738 739 740 741 742 |
}
FD_ZERO( &(tsdPtr->readyMasks.readable) );
FD_ZERO( &(tsdPtr->readyMasks.writable) );
FD_ZERO( &(tsdPtr->readyMasks.exceptional) );
if (!tsdPtr->eventReady) {
| | | 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 |
}
FD_ZERO( &(tsdPtr->readyMasks.readable) );
FD_ZERO( &(tsdPtr->readyMasks.writable) );
FD_ZERO( &(tsdPtr->readyMasks.exceptional) );
if (!tsdPtr->eventReady) {
Tcl_ConditionWait(&tsdPtr->waitCV, ¬ifierMutex, myTimePtr);
}
tsdPtr->eventReady = 0;
if (waitForFiles && tsdPtr->onList) {
/*
* Remove the ThreadSpecificData structure of this thread from the
* waiting list. Alert the notifier thread to recompute its select
|
| ︙ | ︙ |
Changes to unix/tclUnixPipe.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclUnixPipe.c -- * * This file implements the UNIX-specific exec pipeline functions, * the "pipe" channel driver, and the "pid" Tcl command. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-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. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclUnixPipe.c -- * * This file implements the UNIX-specific exec pipeline functions, * the "pipe" channel driver, and the "pid" Tcl command. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-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. * * RCS: @(#) $Id: tclUnixPipe.c,v 1.26.2.1 2005/02/02 15:54:01 kennykb Exp $ */ #include "tclInt.h" #ifdef USE_VFORK #define fork vfork #endif |
| ︙ | ︙ | |||
67 68 69 70 71 72 73 |
/*
* This structure describes the channel type structure for command pipe
* based IO:
*/
static Tcl_ChannelType pipeChannelType = {
"pipe", /* Type name. */
| | > > | 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 |
/*
* This structure describes the channel type structure for command pipe
* based IO:
*/
static Tcl_ChannelType pipeChannelType = {
"pipe", /* Type name. */
TCL_CHANNEL_VERSION_4, /* v4 channel */
PipeCloseProc, /* Close proc. */
PipeInputProc, /* Input proc. */
PipeOutputProc, /* Output proc. */
NULL, /* Seek proc. */
NULL, /* Set option proc. */
NULL, /* Get option proc. */
PipeWatchProc, /* Initialize notifier. */
PipeGetHandleProc, /* Get OS handles out of channel. */
NULL, /* close2proc. */
PipeBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
NULL, /* wide seek proc */
NULL, /* thread action proc */
};
/*
*----------------------------------------------------------------------
*
* TclpMakeFile --
*
|
| ︙ | ︙ |
Changes to unix/tclUnixSock.c.
1 2 3 4 5 6 7 8 9 10 | /* * tclUnixSock.c -- * * This file contains Unix-specific socket related code. * * Copyright (c) 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* * tclUnixSock.c -- * * This file contains Unix-specific socket related code. * * Copyright (c) 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclUnixSock.c,v 1.9.2.1 2005/02/02 15:54:02 kennykb Exp $ */ #include "tclInt.h" /* * There is no portable macro for the maximum length * of host names returned by gethostbyname(). We should only |
| ︙ | ︙ | |||
142 143 144 145 146 147 148 149 |
*/
int
TclpHasSockets(interp)
Tcl_Interp *interp; /* Not used. */
{
return TCL_OK;
}
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 142 143 144 145 146 147 148 149 |
*/
int
TclpHasSockets(interp)
Tcl_Interp *interp; /* Not used. */
{
return TCL_OK;
}
|
Changes to unix/tclUnixTime.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclUnixTime.c -- * * Contains Unix specific versions of Tcl functions that * obtain time values from the operating system. * * Copyright (c) 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* * tclUnixTime.c -- * * Contains Unix specific versions of Tcl functions that * obtain time values from the operating system. * * Copyright (c) 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclUnixTime.c,v 1.22.2.1 2005/02/02 15:54:02 kennykb Exp $ */ #include "tclInt.h" #include <locale.h> #define TM_YEAR_BASE 1900 #define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0)) |
| ︙ | ︙ | |||
41 42 43 44 45 46 47 48 49 50 51 52 53 54 | * empty string if the variable was * not set. */ /* Static functions declared in this file */ static void SetTZIfNecessary _ANSI_ARGS_((void)); static void CleanupMemory _ANSI_ARGS_((ClientData)); /* *----------------------------------------------------------------------------- * * TclpGetSeconds -- * * This procedure returns the number of seconds from the epoch. On | > > > > > > > > > > > | 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 | * empty string if the variable was * not set. */ /* Static functions declared in this file */ static void SetTZIfNecessary _ANSI_ARGS_((void)); static void CleanupMemory _ANSI_ARGS_((ClientData)); static void NativeScaleTime _ANSI_ARGS_ ((Tcl_Time* timebuf, ClientData clientData)); static void NativeGetTime _ANSI_ARGS_ ((Tcl_Time* timebuf, ClientData clientData)); /* TIP #233 (Virtualized Time) * Data for the time hooks, if any. */ Tcl_GetTimeProc* tclGetTimeProcPtr = NativeGetTime; Tcl_ScaleTimeProc* tclScaleTimeProcPtr = NativeScaleTime; ClientData tclTimeClientData = NULL; /* *----------------------------------------------------------------------------- * * TclpGetSeconds -- * * This procedure returns the number of seconds from the epoch. On |
| ︙ | ︙ | |||
88 89 90 91 92 93 94 95 |
*-----------------------------------------------------------------------------
*/
unsigned long
TclpGetClicks()
{
unsigned long now;
#ifdef NO_GETTOD
| > > | > > | > | | < | < < > | > | | 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 |
*-----------------------------------------------------------------------------
*/
unsigned long
TclpGetClicks()
{
unsigned long now;
#ifdef NO_GETTOD
if (tclGetTimeProcPtr != NativeGetTime) {
Tcl_Time time;
(*tclGetTimeProcPtr) (&time, tclTimeClientData);
now = time.sec*1000000 + time.usec;
} else {
/* A semi-NativeGetTime, specialized to clicks */
struct tms dummy;
now = (unsigned long) times(&dummy);
}
#else
Tcl_Time time;
(*tclGetTimeProcPtr) (&time, tclTimeClientData);
now = time.sec*1000000 + time.usec;
#endif
return now;
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
*----------------------------------------------------------------------
*
* Tcl_GetTime --
*
* Gets the current system time in seconds and microseconds
* since the beginning of the epoch: 00:00 UCT, January 1, 1970.
*
* Results:
* Returns the current time in timePtr.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Tcl_GetTime(timePtr)
Tcl_Time *timePtr; /* Location to store time information. */
{
| > > > < < | < < < | 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 |
*----------------------------------------------------------------------
*
* Tcl_GetTime --
*
* Gets the current system time in seconds and microseconds
* since the beginning of the epoch: 00:00 UCT, January 1, 1970.
*
* This function is hooked, allowing users to specify their
* own virtual system time.
*
* Results:
* Returns the current time in timePtr.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Tcl_GetTime(timePtr)
Tcl_Time *timePtr; /* Location to store time information. */
{
(*tclGetTimeProcPtr) (timePtr, tclTimeClientData);
}
/*
*----------------------------------------------------------------------
*
* TclpGetDate --
*
|
| ︙ | ︙ | |||
380 381 382 383 384 385 386 |
*/
struct tm*
TclpLocaltime_unix( timePtr )
CONST time_t* timePtr;
{
return TclpLocaltime( timePtr );
}
| | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
*/
struct tm*
TclpLocaltime_unix( timePtr )
CONST time_t* timePtr;
{
return TclpLocaltime( timePtr );
}
/*
*----------------------------------------------------------------------
*
* Tcl_SetTimeProc --
*
* TIP #233 (Virtualized Time)
* Registers two handlers for the virtualization of Tcl's
* access to time information.
*
* Results:
* None.
*
* Side effects:
* Remembers the handlers, alters core behaviour.
*
*----------------------------------------------------------------------
*/
void
Tcl_SetTimeProc (getProc, scaleProc, clientData)
Tcl_GetTimeProc* getProc;
Tcl_ScaleTimeProc* scaleProc;
ClientData clientData;
{
tclGetTimeProcPtr = getProc;
tclScaleTimeProcPtr = scaleProc;
tclTimeClientData = clientData;
}
/*
*----------------------------------------------------------------------
*
* Tcl_QueryTimeProc --
*
* TIP #233 (Virtualized Time)
* Query which time handlers are registered.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Tcl_QueryTimeProc (getProc, scaleProc, clientData)
Tcl_GetTimeProc** getProc;
Tcl_ScaleTimeProc** scaleProc;
ClientData* clientData;
{
if (getProc) {
*getProc = tclGetTimeProcPtr;
}
if (scaleProc) {
*scaleProc = tclScaleTimeProcPtr;
}
if (clientData) {
*clientData = tclTimeClientData;
}
}
/*
*----------------------------------------------------------------------
*
* NativeScaleTime --
*
* TIP #233
* Scale from virtual time to the real-time. For native scaling the
* relationship is 1:1 and nothing has to be done.
*
* Results:
* Scales the time in timePtr.
*
* Side effects:
* See above.
*
*----------------------------------------------------------------------
*/
static void
NativeScaleTime (timePtr, clientData)
Tcl_Time* timePtr;
ClientData clientData;
{
/* Native scale is 1:1. Nothing is done */
}
/*
*----------------------------------------------------------------------
*
* NativeGetTime --
*
* TIP #233
* Gets the current system time in seconds and microseconds
* since the beginning of the epoch: 00:00 UCT, January 1, 1970.
*
* Results:
* Returns the current time in timePtr.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static void
NativeGetTime (timePtr, clientData)
Tcl_Time* timePtr;
ClientData clientData;
{
struct timeval tv;
struct timezone tz;
(void) gettimeofday(&tv, &tz);
timePtr->sec = tv.tv_sec;
timePtr->usec = tv.tv_usec;
}
/*
*----------------------------------------------------------------------
*
* SetTZIfNecessary --
*
* Determines whether a call to 'tzset' is needed prior to the
* next call to 'localtime' or examination of the 'timezone' variable.
|
| ︙ | ︙ |
Changes to win/Makefile.in.
1 2 3 4 5 6 7 | # # This file is a Makefile for Tcl. If it has the name "Makefile.in" # then it is a template for a Makefile; to generate the actual Makefile, # run "./configure", which is a configuration script generated by the # "autoconf" program (constructs like "@foo@" will get replaced in the # actual Makefile. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # # This file is a Makefile for Tcl. If it has the name "Makefile.in" # then it is a template for a Makefile; to generate the actual Makefile, # run "./configure", which is a configuration script generated by the # "autoconf" program (constructs like "@foo@" will get replaced in the # actual Makefile. # # RCS: @(#) $Id: Makefile.in,v 1.84.2.5 2005/02/02 15:54:02 kennykb Exp $ VERSION = @TCL_VERSION@ #---------------------------------------------------------------- # Things you can change to personalize the Makefile for your own # site (you can make these changes in either Makefile.in or # Makefile, but changes to Makefile will get lost if you re-run |
| ︙ | ︙ | |||
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
tclPreserve.$(OBJEXT) \
tclProc.$(OBJEXT) \
tclRegexp.$(OBJEXT) \
tclResolve.$(OBJEXT) \
tclResult.$(OBJEXT) \
tclScan.$(OBJEXT) \
tclStringObj.$(OBJEXT) \
tclStubInit.$(OBJEXT) \
tclStubLib.$(OBJEXT) \
tclThread.$(OBJEXT) \
tclThreadAlloc.$(OBJEXT) \
tclThreadJoin.$(OBJEXT) \
tclThreadStorage.$(OBJEXT) \
tclTimer.$(OBJEXT) \
tclTomMathInterface.$(OBJEXT) \
tclTrace.$(OBJEXT) \
tclUtf.$(OBJEXT) \
tclUtil.$(OBJEXT) \
tclVar.$(OBJEXT)
TOMMATH_OBJS = \
bncore.${OBJEXT} \
bn_reverse.${OBJEXT} \
bn_fast_s_mp_mul_digs.${OBJEXT} \
bn_mp_add.${OBJEXT} \
bn_mp_add_d.${OBJEXT} \
bn_mp_clamp.${OBJEXT} \
bn_mp_clear.${OBJEXT} \
bn_mp_clear_multi.${OBJEXT} \
bn_mp_cmp.${OBJEXT} \
bn_mp_cmp_mag.${OBJEXT} \
| > > | 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
tclPreserve.$(OBJEXT) \
tclProc.$(OBJEXT) \
tclRegexp.$(OBJEXT) \
tclResolve.$(OBJEXT) \
tclResult.$(OBJEXT) \
tclScan.$(OBJEXT) \
tclStringObj.$(OBJEXT) \
tclStrToD.$(OBJEXT) \
tclStubInit.$(OBJEXT) \
tclStubLib.$(OBJEXT) \
tclThread.$(OBJEXT) \
tclThreadAlloc.$(OBJEXT) \
tclThreadJoin.$(OBJEXT) \
tclThreadStorage.$(OBJEXT) \
tclTimer.$(OBJEXT) \
tclTomMathInterface.$(OBJEXT) \
tclTrace.$(OBJEXT) \
tclUtf.$(OBJEXT) \
tclUtil.$(OBJEXT) \
tclVar.$(OBJEXT)
TOMMATH_OBJS = \
bncore.${OBJEXT} \
bn_reverse.${OBJEXT} \
bn_fast_s_mp_mul_digs.${OBJEXT} \
bn_fast_s_mp_sqr.${OBJEXT} \
bn_mp_add.${OBJEXT} \
bn_mp_add_d.${OBJEXT} \
bn_mp_clamp.${OBJEXT} \
bn_mp_clear.${OBJEXT} \
bn_mp_clear_multi.${OBJEXT} \
bn_mp_cmp.${OBJEXT} \
bn_mp_cmp_mag.${OBJEXT} \
|
| ︙ | ︙ | |||
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 |
bn_mp_exch.${OBJEXT} \
bn_mp_grow.${OBJEXT} \
bn_mp_init.${OBJEXT} \
bn_mp_init_copy.${OBJEXT} \
bn_mp_init_multi.${OBJEXT} \
bn_mp_init_size.${OBJEXT} \
bn_mp_karatsuba_mul.${OBJEXT} \
bn_mp_lshd.${OBJEXT} \
bn_mp_mod.${OBJEXT} \
bn_mp_mod_2d.${OBJEXT} \
bn_mp_mul.${OBJEXT} \
bn_mp_mul_2.${OBJEXT} \
bn_mp_mul_2d.${OBJEXT} \
bn_mp_mul_d.${OBJEXT} \
bn_mp_radix_size.${OBJEXT} \
bn_mp_radix_smap.${OBJEXT} \
bn_mp_read_radix.${OBJEXT} \
bn_mp_rshd.${OBJEXT} \
bn_mp_sub.${OBJEXT} \
bn_mp_sub_d.${OBJEXT} \
bn_mp_toom_mul.${OBJEXT} \
bn_mp_toradix_n.${OBJEXT} \
bn_mp_zero.${OBJEXT} \
bn_s_mp_add.${OBJEXT} \
bn_s_mp_mul_digs.${OBJEXT} \
bn_s_mp_sub.${OBJEXT}
WIN_OBJS = \
tclWin32Dll.$(OBJEXT) \
tclWinChan.$(OBJEXT) \
tclWinConsole.$(OBJEXT) \
| > > > > > | 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 |
bn_mp_exch.${OBJEXT} \
bn_mp_grow.${OBJEXT} \
bn_mp_init.${OBJEXT} \
bn_mp_init_copy.${OBJEXT} \
bn_mp_init_multi.${OBJEXT} \
bn_mp_init_size.${OBJEXT} \
bn_mp_karatsuba_mul.${OBJEXT} \
bn_mp_karatsuba_sqr.$(OBJEXT) \
bn_mp_lshd.${OBJEXT} \
bn_mp_mod.${OBJEXT} \
bn_mp_mod_2d.${OBJEXT} \
bn_mp_mul.${OBJEXT} \
bn_mp_mul_2.${OBJEXT} \
bn_mp_mul_2d.${OBJEXT} \
bn_mp_mul_d.${OBJEXT} \
bn_mp_radix_size.${OBJEXT} \
bn_mp_radix_smap.${OBJEXT} \
bn_mp_read_radix.${OBJEXT} \
bn_mp_rshd.${OBJEXT} \
bn_mp_set.${OBJEXT} \
bn_mp_sqr.${OBJEXT} \
bn_mp_sub.${OBJEXT} \
bn_mp_sub_d.${OBJEXT} \
bn_mp_toom_mul.${OBJEXT} \
bn_mp_toom_sqr.${OBJEXT} \
bn_mp_toradix_n.${OBJEXT} \
bn_mp_zero.${OBJEXT} \
bn_s_mp_add.${OBJEXT} \
bn_s_mp_mul_digs.${OBJEXT} \
bn_s_mp_sqr.${OBJEXT} \
bn_s_mp_sub.${OBJEXT}
WIN_OBJS = \
tclWin32Dll.$(OBJEXT) \
tclWinChan.$(OBJEXT) \
tclWinConsole.$(OBJEXT) \
|
| ︙ | ︙ |
Changes to win/makefile.vc.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | # # Copyright (c) 1995-1996 Sun Microsystems, Inc. # Copyright (c) 1998-2000 Ajuba Solutions. # Copyright (c) 2001 ActiveState Corporation. # Copyright (c) 2001-2004 David Gravereaux. # #------------------------------------------------------------------------------ | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # # Copyright (c) 1995-1996 Sun Microsystems, Inc. # Copyright (c) 1998-2000 Ajuba Solutions. # Copyright (c) 2001 ActiveState Corporation. # Copyright (c) 2001-2004 David Gravereaux. # #------------------------------------------------------------------------------ # RCS: @(#) $Id: makefile.vc,v 1.135.2.1 2005/02/02 15:54:02 kennykb Exp $ #------------------------------------------------------------------------------ !if !defined(MSDEVDIR) && !defined(MSVCDIR) MSG = ^ You'll need to run vcvars32.bat from Developer Studio, first, to setup^ the environment. Jump to this line to read the new instructions. !error $(MSG) |
| ︙ | ︙ | |||
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 | $(TMP_DIR)\tclPreserve.obj \ $(TMP_DIR)\tclProc.obj \ $(TMP_DIR)\tclRegexp.obj \ $(TMP_DIR)\tclResolve.obj \ $(TMP_DIR)\tclResult.obj \ $(TMP_DIR)\tclScan.obj \ $(TMP_DIR)\tclStringObj.obj \ $(TMP_DIR)\tclStubInit.obj \ $(TMP_DIR)\tclStubLib.obj \ $(TMP_DIR)\tclThread.obj \ $(TMP_DIR)\tclThreadAlloc.obj \ $(TMP_DIR)\tclThreadJoin.obj \ $(TMP_DIR)\tclThreadStorage.obj \ $(TMP_DIR)\tclTimer.obj \ $(TMP_DIR)\tclTrace.obj \ $(TMP_DIR)\tclUtf.obj \ $(TMP_DIR)\tclUtil.obj \ $(TMP_DIR)\tclVar.obj \ $(TMP_DIR)\tclWin32Dll.obj \ $(TMP_DIR)\tclWinChan.obj \ $(TMP_DIR)\tclWinConsole.obj \ $(TMP_DIR)\tclWinSerial.obj \ $(TMP_DIR)\tclWinError.obj \ $(TMP_DIR)\tclWinFCmd.obj \ $(TMP_DIR)\tclWinFile.obj \ $(TMP_DIR)\tclWinInit.obj \ $(TMP_DIR)\tclWinLoad.obj \ $(TMP_DIR)\tclWinNotify.obj \ $(TMP_DIR)\tclWinPipe.obj \ $(TMP_DIR)\tclWinSock.obj \ $(TMP_DIR)\tclWinThrd.obj \ $(TMP_DIR)\tclWinTime.obj \ !if !$(STATIC_BUILD) $(TMP_DIR)\tcl.res !endif TCLSTUBOBJS = $(TMP_DIR)\tclStubLib.obj ### The following paths CANNOT have spaces in them. COMPATDIR = $(ROOT)\compat DOCDIR = $(ROOT)\doc GENERICDIR = $(ROOT)\generic TOOLSDIR = $(ROOT)\tools WINDIR = $(ROOT)\win #--------------------------------------------------------------------- # Compile flags #--------------------------------------------------------------------- | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | $(TMP_DIR)\tclPreserve.obj \ $(TMP_DIR)\tclProc.obj \ $(TMP_DIR)\tclRegexp.obj \ $(TMP_DIR)\tclResolve.obj \ $(TMP_DIR)\tclResult.obj \ $(TMP_DIR)\tclScan.obj \ $(TMP_DIR)\tclStringObj.obj \ $(TMP_DIR)\tclStrToD.obj \ $(TMP_DIR)\tclStubInit.obj \ $(TMP_DIR)\tclStubLib.obj \ $(TMP_DIR)\tclThread.obj \ $(TMP_DIR)\tclThreadAlloc.obj \ $(TMP_DIR)\tclThreadJoin.obj \ $(TMP_DIR)\tclThreadStorage.obj \ $(TMP_DIR)\tclTimer.obj \ $(TMP_DIR)\tclTomMathInterface.obj \ $(TMP_DIR)\tclTrace.obj \ $(TMP_DIR)\tclUtf.obj \ $(TMP_DIR)\tclUtil.obj \ $(TMP_DIR)\tclVar.obj \ $(TMP_DIR)\tclWin32Dll.obj \ $(TMP_DIR)\tclWinChan.obj \ $(TMP_DIR)\tclWinConsole.obj \ $(TMP_DIR)\tclWinSerial.obj \ $(TMP_DIR)\tclWinError.obj \ $(TMP_DIR)\tclWinFCmd.obj \ $(TMP_DIR)\tclWinFile.obj \ $(TMP_DIR)\tclWinInit.obj \ $(TMP_DIR)\tclWinLoad.obj \ $(TMP_DIR)\tclWinNotify.obj \ $(TMP_DIR)\tclWinPipe.obj \ $(TMP_DIR)\tclWinSock.obj \ $(TMP_DIR)\tclWinThrd.obj \ $(TMP_DIR)\tclWinTime.obj \ $(TMP_DIR)\bncore.obj \ $(TMP_DIR)\bn_reverse.obj \ $(TMP_DIR)\bn_fast_s_mp_mul_digs.obj \ $(TMP_DIR)\bn_fast_s_mp_sqr.obj \ $(TMP_DIR)\bn_mp_add.obj \ $(TMP_DIR)\bn_mp_add_d.obj \ $(TMP_DIR)\bn_mp_clamp.obj \ $(TMP_DIR)\bn_mp_clear.obj \ $(TMP_DIR)\bn_mp_clear_multi.obj \ $(TMP_DIR)\bn_mp_cmp.obj \ $(TMP_DIR)\bn_mp_cmp_mag.obj \ $(TMP_DIR)\bn_mp_copy.obj \ $(TMP_DIR)\bn_mp_count_bits.obj \ $(TMP_DIR)\bn_mp_div.obj \ $(TMP_DIR)\bn_mp_div_d.obj \ $(TMP_DIR)\bn_mp_div_2.obj \ $(TMP_DIR)\bn_mp_div_2d.obj \ $(TMP_DIR)\bn_mp_div_3.obj \ $(TMP_DIR)\bn_mp_exch.obj \ $(TMP_DIR)\bn_mp_grow.obj \ $(TMP_DIR)\bn_mp_init.obj \ $(TMP_DIR)\bn_mp_init_copy.obj \ $(TMP_DIR)\bn_mp_init_multi.obj \ $(TMP_DIR)\bn_mp_init_size.obj \ $(TMP_DIR)\bn_mp_karatsuba_mul.obj \ $(TMP_DIR)\bn_mp_karatsuba_sqr.obj \ $(TMP_DIR)\bn_mp_lshd.obj \ $(TMP_DIR)\bn_mp_mod.obj \ $(TMP_DIR)\bn_mp_mod_2d.obj \ $(TMP_DIR)\bn_mp_mul.obj \ $(TMP_DIR)\bn_mp_mul_2.obj \ $(TMP_DIR)\bn_mp_mul_2d.obj \ $(TMP_DIR)\bn_mp_mul_d.obj \ $(TMP_DIR)\bn_mp_radix_size.obj \ $(TMP_DIR)\bn_mp_radix_smap.obj \ $(TMP_DIR)\bn_mp_read_radix.obj \ $(TMP_DIR)\bn_mp_rshd.obj \ $(TMP_DIR)\bn_mp_set.obj \ $(TMP_DIR)\bn_mp_sqr.obj \ $(TMP_DIR)\bn_mp_sub.obj \ $(TMP_DIR)\bn_mp_sub_d.obj \ $(TMP_DIR)\bn_mp_toom_mul.obj \ $(TMP_DIR)\bn_mp_toom_sqr.obj \ $(TMP_DIR)\bn_mp_toradix_n.obj \ $(TMP_DIR)\bn_mp_zero.obj \ $(TMP_DIR)\bn_s_mp_add.obj \ $(TMP_DIR)\bn_s_mp_mul_digs.obj \ $(TMP_DIR)\bn_s_mp_sqr.obj \ $(TMP_DIR)\bn_s_mp_sub.obj \ !if !$(STATIC_BUILD) $(TMP_DIR)\tcl.res !endif TCLSTUBOBJS = $(TMP_DIR)\tclStubLib.obj ### The following paths CANNOT have spaces in them. COMPATDIR = $(ROOT)\compat DOCDIR = $(ROOT)\doc GENERICDIR = $(ROOT)\generic TOMMATHDIR = $(ROOT)\libtommath TOOLSDIR = $(ROOT)\tools WINDIR = $(ROOT)\win #--------------------------------------------------------------------- # Compile flags #--------------------------------------------------------------------- |
| ︙ | ︙ | |||
388 389 390 391 392 393 394 | !if $(DEBUG) && !$(UNCHECKED) crt = -MTd !else crt = -MT !endif !endif | | | | 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 | !if $(DEBUG) && !$(UNCHECKED) crt = -MTd !else crt = -MT !endif !endif TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(TOMMATHDIR)" BASE_CFLAGS = $(cflags) $(cdebug) $(crt) $(TCL_INCLUDES) \ -DTCL_PIPE_DLL=\"$(TCLPIPEDLLNAME)\" -DTCL_TOMMATH CON_CFLAGS = $(cflags) $(cdebug) $(crt) -DCONSOLE TCL_CFLAGS = $(BASE_CFLAGS) $(OPTDEFINES) STUB_CFLAGS = $(cflags) $(cdebug) $(OPTDEFINES) #--------------------------------------------------------------------- # Link flags |
| ︙ | ︙ | |||
831 832 833 834 835 836 837 838 839 840 841 842 843 844 |
# Implicit rules
#---------------------------------------------------------------------
{$(WINDIR)}.c{$(TMP_DIR)}.obj::
$(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
$<
<<
{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
$(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
$<
<<
{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
| > > > > > | 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 |
# Implicit rules
#---------------------------------------------------------------------
{$(WINDIR)}.c{$(TMP_DIR)}.obj::
$(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
$<
<<
{$(TOMMATHDIR)}.c{$(TMP_DIR)}.obj::
$(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
$<
<<
{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
$(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
$<
<<
{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
|
| ︙ | ︙ |
Changes to win/tclWinChan.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclWinChan.c * * Channel drivers for Windows channels based on files, command * pipes and TCP sockets. * * Copyright (c) 1995-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. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* * tclWinChan.c * * Channel drivers for Windows channels based on files, command * pipes and TCP sockets. * * Copyright (c) 1995-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. * * RCS: @(#) $Id: tclWinChan.c,v 1.37.2.2 2005/02/02 15:54:03 kennykb Exp $ */ #include "tclWinInt.h" #include "tclIO.h" /* * State flags used in the info structures below. |
| ︙ | ︙ | |||
93 94 95 96 97 98 99 | static int FileSeekProc _ANSI_ARGS_((ClientData instanceData, long offset, int mode, int *errorCode)); static Tcl_WideInt FileWideSeekProc _ANSI_ARGS_((ClientData instanceData, Tcl_WideInt offset, int mode, int *errorCode)); static void FileSetupProc _ANSI_ARGS_((ClientData clientData, int flags)); static void FileWatchProc _ANSI_ARGS_((ClientData instanceData, | | > > | > | 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 |
static int FileSeekProc _ANSI_ARGS_((ClientData instanceData,
long offset, int mode, int *errorCode));
static Tcl_WideInt FileWideSeekProc _ANSI_ARGS_((ClientData instanceData,
Tcl_WideInt offset, int mode, int *errorCode));
static void FileSetupProc _ANSI_ARGS_((ClientData clientData,
int flags));
static void FileWatchProc _ANSI_ARGS_((ClientData instanceData,
int mask));
static void FileThreadActionProc _ANSI_ARGS_ ((
ClientData instanceData, int action));
/*
* This structure describes the channel type structure for file based IO.
*/
static Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
TCL_CHANNEL_VERSION_4, /* v4 channel */
FileCloseProc, /* Close proc. */
FileInputProc, /* Input proc. */
FileOutputProc, /* Output proc. */
FileSeekProc, /* Seek proc. */
NULL, /* Set option proc. */
NULL, /* Get option proc. */
FileWatchProc, /* Set up the notifier to watch the channel. */
FileGetHandleProc, /* Get an OS handle from channel. */
NULL, /* close2proc. */
FileBlockProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
FileWideSeekProc, /* Wide seek proc. */
FileThreadActionProc, /* Thread action proc. */
};
#if defined(HAVE_NO_SEH) && defined(TCL_MEM_DEBUG)
static void *INITIAL_ESP, *INITIAL_EBP, *INITIAL_HANDLER;
static void *RESTORED_ESP, *RESTORED_EBP, *RESTORED_HANDLER;
#endif /* HAVE_NO_SEH && TCL_MEM_DEBUG */
|
| ︙ | ︙ | |||
426 427 428 429 430 431 432 |
*/
tsdPtr = TCL_TSD_INIT(&dataKey);
for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr == fileInfoPtr) {
/*
* This channel exists on the thread local list. It should
| | | | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 |
*/
tsdPtr = TCL_TSD_INIT(&dataKey);
for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr == fileInfoPtr) {
/*
* This channel exists on the thread local list. It should
* have been removed by an earlier Threadaction call,
* but do that now since just deallocating fileInfoPtr would
* leave an deallocated pointer on the thread local list.
*/
FileThreadActionProc(fileInfoPtr,TCL_CHANNEL_THREAD_REMOVE);
break;
}
}
ckfree((char *)fileInfoPtr);
return errorCode;
}
|
| ︙ | ︙ | |||
1303 1304 1305 1306 1307 1308 1309 |
infoPtr = infoPtr->nextPtr) {
if (infoPtr->handle == (HANDLE) handle) {
return (permissions==infoPtr->validMask) ? infoPtr->channel : NULL;
}
}
infoPtr = (FileInfo *) ckalloc((unsigned) sizeof(FileInfo));
| > > > > | < | 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 |
infoPtr = infoPtr->nextPtr) {
if (infoPtr->handle == (HANDLE) handle) {
return (permissions==infoPtr->validMask) ? infoPtr->channel : NULL;
}
}
infoPtr = (FileInfo *) ckalloc((unsigned) sizeof(FileInfo));
/* TIP #218. Removed the code inserting the new structure
* into the global list. This is now handled in the thread
* action callbacks, and only there.
*/
infoPtr->nextPtr = NULL;
infoPtr->validMask = permissions;
infoPtr->watchMask = 0;
infoPtr->flags = appendMode;
infoPtr->handle = handle;
infoPtr->dirty = 0;
wsprintfA(channelName, "file%lx", (int) infoPtr);
|
| ︙ | ︙ | |||
1369 1370 1371 1372 1373 1374 1375 |
}
}
}
/*
*----------------------------------------------------------------------
*
| | | < | | < | | < | > > > > > | | < < < < < < | | | | | | | | | | | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 |
}
}
}
/*
*----------------------------------------------------------------------
*
* FileThreadActionProc --
*
* Insert or remove any thread local refs to this channel.
*
* Results:
* None.
*
* Side effects:
* Changes thread local list of valid channels.
*
*----------------------------------------------------------------------
*/
static void
FileThreadActionProc (instanceData, action)
ClientData instanceData;
int action;
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
FileInfo *infoPtr = (FileInfo *) instanceData;
if (action == TCL_CHANNEL_THREAD_INSERT) {
infoPtr->nextPtr = tsdPtr->firstFilePtr;
tsdPtr->firstFilePtr = infoPtr;
} else {
FileInfo **nextPtrPtr;
int removed = 0;
for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
if ((*nextPtrPtr) == infoPtr) {
(*nextPtrPtr) = infoPtr->nextPtr;
removed = 1;
break;
}
}
/*
* This could happen if the channel was created in one thread
* and then moved to another without updating the thread
* local data in each thread.
*/
if (!removed) {
Tcl_Panic("file info ptr not on thread channel list");
}
}
}
|
Changes to win/tclWinConsole.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclWinConsole.c -- * * This file implements the Windows-specific console functions, * and the "console" channel driver. * * Copyright (c) 1999 by Scriptics Corp. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* * tclWinConsole.c -- * * This file implements the Windows-specific console functions, * and the "console" channel driver. * * Copyright (c) 1999 by Scriptics Corp. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclWinConsole.c,v 1.12.2.1 2005/02/02 15:54:04 kennykb Exp $ */ #include "tclWinInt.h" #include <fcntl.h> #include <io.h> #include <sys/stat.h> |
| ︙ | ︙ | |||
144 145 146 147 148 149 150 | static void ConsoleCheckProc(ClientData clientData, int flags); static int ConsoleCloseProc(ClientData instanceData, Tcl_Interp *interp); static int ConsoleEventProc(Tcl_Event *evPtr, int flags); static void ConsoleExitHandler(ClientData clientData); static int ConsoleGetHandleProc(ClientData instanceData, int direction, ClientData *handlePtr); | | > > > | > > | | 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 |
static void ConsoleCheckProc(ClientData clientData, int flags);
static int ConsoleCloseProc(ClientData instanceData,
Tcl_Interp *interp);
static int ConsoleEventProc(Tcl_Event *evPtr, int flags);
static void ConsoleExitHandler(ClientData clientData);
static int ConsoleGetHandleProc(ClientData instanceData,
int direction, ClientData *handlePtr);
static void ConsoleInit(void);
static int ConsoleInputProc(ClientData instanceData, char *buf,
int toRead, int *errorCode);
static int ConsoleOutputProc(ClientData instanceData,
CONST char *buf, int toWrite, int *errorCode);
static DWORD WINAPI ConsoleReaderThread(LPVOID arg);
static void ConsoleSetupProc(ClientData clientData, int flags);
static void ConsoleWatchProc(ClientData instanceData, int mask);
static DWORD WINAPI ConsoleWriterThread(LPVOID arg);
static void ProcExitHandler(ClientData clientData);
static int WaitForRead(ConsoleInfo *infoPtr, int blocking);
static void ConsoleThreadActionProc _ANSI_ARGS_ ((
ClientData instanceData, int action));
/*
* This structure describes the channel type structure for command console
* based IO.
*/
static Tcl_ChannelType consoleChannelType = {
"console", /* Type name. */
TCL_CHANNEL_VERSION_4, /* v4 channel */
ConsoleCloseProc, /* Close proc. */
ConsoleInputProc, /* Input proc. */
ConsoleOutputProc, /* Output proc. */
NULL, /* Seek proc. */
NULL, /* Set option proc. */
NULL, /* Get option proc. */
ConsoleWatchProc, /* Set up notifier to watch the channel. */
ConsoleGetHandleProc, /* Get an OS handle from channel. */
NULL, /* close2proc. */
ConsoleBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
NULL, /* wide seek proc */
ConsoleThreadActionProc, /* thread action proc */
};
/*
*----------------------------------------------------------------------
*
* ConsoleInit --
*
* This function initializes the static variables for this file.
*
* Results:
* None.
*
* Side effects:
* Creates a new event source.
*
*----------------------------------------------------------------------
*/
static void
ConsoleInit()
{
ThreadSpecificData *tsdPtr;
/*
* Check the initialized flag first, then check again in the mutex.
* This is a speed enhancement.
|
| ︙ | ︙ | |||
220 221 222 223 224 225 226 |
tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
if (tsdPtr == NULL) {
tsdPtr = TCL_TSD_INIT(&dataKey);
tsdPtr->firstConsolePtr = NULL;
Tcl_CreateEventSource(ConsoleSetupProc, ConsoleCheckProc, NULL);
Tcl_CreateThreadExitHandler(ConsoleExitHandler, NULL);
}
| < | 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
if (tsdPtr == NULL) {
tsdPtr = TCL_TSD_INIT(&dataKey);
tsdPtr->firstConsolePtr = NULL;
Tcl_CreateEventSource(ConsoleSetupProc, ConsoleCheckProc, NULL);
Tcl_CreateThreadExitHandler(ConsoleExitHandler, NULL);
}
}
/*
*----------------------------------------------------------------------
*
* ConsoleExitHandler --
*
|
| ︙ | ︙ | |||
1165 1166 1167 1168 1169 1170 1171 | /* * Alert the foreground thread. Note that we need to treat this like * a critical section so the foreground thread does not terminate * this thread while we are holding a mutex in the notifier code. */ Tcl_MutexLock(&consoleMutex); | > > | > | 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 |
/*
* Alert the foreground thread. Note that we need to treat this like
* a critical section so the foreground thread does not terminate
* this thread while we are holding a mutex in the notifier code.
*/
Tcl_MutexLock(&consoleMutex);
if (infoPtr->threadId != NULL) {
/* TIP #218. When in flight ignore the event, no one will receive it anyway */
Tcl_ThreadAlert(infoPtr->threadId);
}
Tcl_MutexUnlock(&consoleMutex);
}
return 0;
}
/*
|
| ︙ | ︙ | |||
1251 1252 1253 1254 1255 1256 1257 | /* * Alert the foreground thread. Note that we need to treat this like * a critical section so the foreground thread does not terminate * this thread while we are holding a mutex in the notifier code. */ Tcl_MutexLock(&consoleMutex); | > > | > | 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 |
/*
* Alert the foreground thread. Note that we need to treat this like
* a critical section so the foreground thread does not terminate
* this thread while we are holding a mutex in the notifier code.
*/
Tcl_MutexLock(&consoleMutex);
if (infoPtr->threadId != NULL) {
/* TIP #218. When in flight ignore the event, no one will receive it anyway */
Tcl_ThreadAlert(infoPtr->threadId);
}
Tcl_MutexUnlock(&consoleMutex);
}
return 0;
}
|
| ︙ | ︙ | |||
1286 1287 1288 1289 1290 1291 1292 |
TclWinOpenConsoleChannel(handle, channelName, permissions)
HANDLE handle;
char *channelName;
int permissions;
{
char encoding[4 + TCL_INTEGER_SPACE];
ConsoleInfo *infoPtr;
| < | > > > < < | 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 |
TclWinOpenConsoleChannel(handle, channelName, permissions)
HANDLE handle;
char *channelName;
int permissions;
{
char encoding[4 + TCL_INTEGER_SPACE];
ConsoleInfo *infoPtr;
DWORD id, modes;
ConsoleInit();
/*
* See if a channel with this handle already exists.
*/
infoPtr = (ConsoleInfo *) ckalloc((unsigned) sizeof(ConsoleInfo));
memset(infoPtr, 0, sizeof(ConsoleInfo));
infoPtr->validMask = permissions;
infoPtr->handle = handle;
infoPtr->channel = (Tcl_Channel) NULL;
wsprintfA(encoding, "cp%d", GetConsoleCP());
infoPtr->threadId = Tcl_GetCurrentThread();
/*
* Use the pointer for the name of the result channel.
* This keeps the channel names unique, since some may share
* handles (stdin/stdout/stderr for instance).
*/
wsprintfA(channelName, "file%lx", (int) infoPtr);
infoPtr->channel = Tcl_CreateChannel(&consoleChannelType, channelName,
(ClientData) infoPtr, permissions);
if (permissions & TCL_READABLE) {
/*
* Make sure the console input buffer is ready for only character
* input notifications and the buffer is set for line buffering.
* IOW, we only want to catch when complete lines are ready for
* reading.
*/
|
| ︙ | ︙ | |||
1356 1357 1358 1359 1360 1361 1362 |
Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");
Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", encoding);
return infoPtr->channel;
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 |
Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");
Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", encoding);
return infoPtr->channel;
}
/*
*----------------------------------------------------------------------
*
* ConsoleThreadActionProc --
*
* Insert or remove any thread local refs to this channel.
*
* Results:
* None.
*
* Side effects:
* Changes thread local list of valid channels.
*
*----------------------------------------------------------------------
*/
static void
ConsoleThreadActionProc (instanceData, action)
ClientData instanceData;
int action;
{
ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
/* We do not access firstConsolePtr in the thread structures. This is
* not for all serials managed by the thread, but only those we are
* watching. Removal of the filevent handlers before transfer thus
* takes care of this structure.
*/
Tcl_MutexLock(&consoleMutex);
if (action == TCL_CHANNEL_THREAD_INSERT) {
/* We can't copy the thread information from the channel when
* the channel is created. At this time the channel back
* pointer has not been set yet. However in that case the
* threadId has already been set by TclpCreateCommandChannel
* itself, so the structure is still good.
*/
ConsoleInit ();
if (infoPtr->channel != NULL) {
infoPtr->threadId = Tcl_GetChannelThread (infoPtr->channel);
}
} else {
infoPtr->threadId = NULL;
}
Tcl_MutexUnlock(&consoleMutex);
}
|
Changes to win/tclWinNotify.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclWinNotify.c -- * * This file contains Windows-specific procedures for the notifier, * which is the lowest-level part of the Tcl event loop. This file * works together with ../generic/tclNotify.c. * * Copyright (c) 1995-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. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclWinNotify.c -- * * This file contains Windows-specific procedures for the notifier, * which is the lowest-level part of the Tcl event loop. This file * works together with ../generic/tclNotify.c. * * Copyright (c) 1995-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. * * RCS: @(#) $Id: tclWinNotify.c,v 1.16.2.1 2005/02/02 15:54:04 kennykb Exp $ */ #include "tclInt.h" /* * The follwing static indicates whether this module has been initialized. */ |
| ︙ | ︙ | |||
440 441 442 443 444 445 446 |
}
/*
* Compute the timeout in milliseconds.
*/
if (timePtr) {
| > > > > > | > > > > > | 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
}
/*
* Compute the timeout in milliseconds.
*/
if (timePtr) {
/* TIP #233 (Virtualized Time). Convert virtual domain delay
* to real-time.
*/
Tcl_Time myTime;
myTime.sec = timePtr->sec;
myTime.usec = timePtr->usec;
(*tclScaleTimeProcPtr) (&myTime, tclTimeClientData);
timeout = myTime.sec * 1000 + myTime.usec / 1000;
} else {
timeout = INFINITE;
}
/*
* Check to see if there are any messages in the queue before waiting
* because MsgWaitForMultipleObjects will not wake up if there are events
|
| ︙ | ︙ | |||
540 541 542 543 544 545 546 |
* up some of the corner cases in the test suite. We get around
* this problem by repeating the 'Sleep' call as many times
* as necessary to make the clock advance by the requisite amount.
*/
Tcl_Time now; /* Current wall clock time */
Tcl_Time desired; /* Desired wakeup time */
| > | > > > | | > > > > > | > | > > > | 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 |
* up some of the corner cases in the test suite. We get around
* this problem by repeating the 'Sleep' call as many times
* as necessary to make the clock advance by the requisite amount.
*/
Tcl_Time now; /* Current wall clock time */
Tcl_Time desired; /* Desired wakeup time */
Tcl_Time vdelay; /* Time to sleep, for scaling virtual -> real */
DWORD sleepTime; /* Time to sleep, real-time */
vdelay.sec = ms / 1000;
vdelay.usec = (ms % 1000) * 1000;
Tcl_GetTime( &now );
desired.sec = now.sec + vdelay.sec;
desired.usec = now.usec + vdelay.usec;
if ( desired.usec > 1000000 ) {
++desired.sec;
desired.usec -= 1000000;
}
/* TIP #233: Scale delay from virtual to real-time */
(*tclScaleTimeProcPtr) (&vdelay, tclTimeClientData);
sleepTime = vdelay.sec * 1000 + vdelay.usec / 1000;
for ( ; ; ) {
Sleep( sleepTime );
Tcl_GetTime( &now );
if ( now.sec > desired.sec ) {
break;
} else if ( ( now.sec == desired.sec )
&& ( now.usec >= desired.usec ) ) {
break;
}
vdelay.sec = desired.sec - now.sec;
vdelay.usec = desired.usec - now.usec;
(*tclScaleTimeProcPtr) (&vdelay, tclTimeClientData);
sleepTime = vdelay.sec * 1000 + vdelay.usec / 1000;
}
}
|
Changes to win/tclWinPipe.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclWinPipe.c -- * * This file implements the Windows-specific exec pipeline functions, * the "pipe" channel driver, and the "pid" Tcl command. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* * tclWinPipe.c -- * * This file implements the Windows-specific exec pipeline functions, * the "pipe" channel driver, and the "pid" Tcl command. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclWinPipe.c,v 1.53.2.1 2005/02/02 15:54:04 kennykb Exp $ */ #include "tclWinInt.h" #include <fcntl.h> #include <io.h> #include <sys/stat.h> |
| ︙ | ︙ | |||
201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
static void PipeSetupProc(ClientData clientData, int flags);
static void PipeWatchProc(ClientData instanceData, int mask);
static DWORD WINAPI PipeWriterThread(LPVOID arg);
static void ProcExitHandler(ClientData clientData);
static int TempFileName(WCHAR name[MAX_PATH]);
static int WaitForRead(PipeInfo *infoPtr, int blocking);
/*
* This structure describes the channel type structure for command pipe
* based IO.
*/
static Tcl_ChannelType pipeChannelType = {
"pipe", /* Type name. */
| > > > | > > | 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 |
static void PipeSetupProc(ClientData clientData, int flags);
static void PipeWatchProc(ClientData instanceData, int mask);
static DWORD WINAPI PipeWriterThread(LPVOID arg);
static void ProcExitHandler(ClientData clientData);
static int TempFileName(WCHAR name[MAX_PATH]);
static int WaitForRead(PipeInfo *infoPtr, int blocking);
static void PipeThreadActionProc _ANSI_ARGS_ ((
ClientData instanceData, int action));
/*
* This structure describes the channel type structure for command pipe
* based IO.
*/
static Tcl_ChannelType pipeChannelType = {
"pipe", /* Type name. */
TCL_CHANNEL_VERSION_4, /* v4 channel */
TCL_CLOSE2PROC, /* Close proc. */
PipeInputProc, /* Input proc. */
PipeOutputProc, /* Output proc. */
NULL, /* Seek proc. */
NULL, /* Set option proc. */
NULL, /* Get option proc. */
PipeWatchProc, /* Set up notifier to watch the channel. */
PipeGetHandleProc, /* Get an OS handle from channel. */
PipeClose2Proc, /* close2proc */
PipeBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
NULL, /* wide seek proc */
PipeThreadActionProc, /* thread action proc */
};
/*
*----------------------------------------------------------------------
*
* PipeInit --
*
|
| ︙ | ︙ | |||
1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 |
infoPtr->writeFile = writeFile;
infoPtr->errorFile = errorFile;
infoPtr->numPids = numPids;
infoPtr->pidPtr = pidPtr;
infoPtr->writeBuf = 0;
infoPtr->writeBufLen = 0;
infoPtr->writeError = 0;
/*
* Use one of the fds associated with the channel as the
* channel id.
*/
if (readFile) {
| > | 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 |
infoPtr->writeFile = writeFile;
infoPtr->errorFile = errorFile;
infoPtr->numPids = numPids;
infoPtr->pidPtr = pidPtr;
infoPtr->writeBuf = 0;
infoPtr->writeBufLen = 0;
infoPtr->writeError = 0;
infoPtr->channel = (Tcl_Channel) NULL;
/*
* Use one of the fds associated with the channel as the
* channel id.
*/
if (readFile) {
|
| ︙ | ︙ | |||
2973 2974 2975 2976 2977 2978 2979 | /* * Alert the foreground thread. Note that we need to treat this like * a critical section so the foreground thread does not terminate * this thread while we are holding a mutex in the notifier code. */ Tcl_MutexLock(&pipeMutex); | > > | > | 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 |
/*
* Alert the foreground thread. Note that we need to treat this like
* a critical section so the foreground thread does not terminate
* this thread while we are holding a mutex in the notifier code.
*/
Tcl_MutexLock(&pipeMutex);
if (infoPtr->threadId != NULL) {
/* TIP #218. When in flight ignore the event, no one will receive it anyway */
Tcl_ThreadAlert(infoPtr->threadId);
}
Tcl_MutexUnlock(&pipeMutex);
}
return 0;
}
/*
|
| ︙ | ︙ | |||
3061 3062 3063 3064 3065 3066 3067 | /* * Alert the foreground thread. Note that we need to treat this like * a critical section so the foreground thread does not terminate * this thread while we are holding a mutex in the notifier code. */ Tcl_MutexLock(&pipeMutex); | > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 |
/*
* Alert the foreground thread. Note that we need to treat this like
* a critical section so the foreground thread does not terminate
* this thread while we are holding a mutex in the notifier code.
*/
Tcl_MutexLock(&pipeMutex);
if (infoPtr->threadId != NULL) {
/* TIP #218. When in flight ignore the event, no one will receive it anyway */
Tcl_ThreadAlert(infoPtr->threadId);
}
Tcl_MutexUnlock(&pipeMutex);
}
return 0;
}
/*
*----------------------------------------------------------------------
*
* PipeThreadActionProc --
*
* Insert or remove any thread local refs to this channel.
*
* Results:
* None.
*
* Side effects:
* Changes thread local list of valid channels.
*
*----------------------------------------------------------------------
*/
static void
PipeThreadActionProc (instanceData, action)
ClientData instanceData;
int action;
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
/* We do not access firstPipePtr in the thread structures. This is
* not for all pipes managed by the thread, but only those we are
* watching. Removal of the filevent handlers before transfer thus
* takes care of this structure.
*/
Tcl_MutexLock(&pipeMutex);
if (action == TCL_CHANNEL_THREAD_INSERT) {
/* We can't copy the thread information from the channel when
* the channel is created. At this time the channel back
* pointer has not been set yet. However in that case the
* threadId has already been set by TclpCreateCommandChannel
* itself, so the structure is still good.
*/
PipeInit ();
if (infoPtr->channel != NULL) {
infoPtr->threadId = Tcl_GetChannelThread (infoPtr->channel);
}
} else {
infoPtr->threadId = NULL;
}
Tcl_MutexUnlock(&pipeMutex);
}
|
Changes to win/tclWinSerial.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclWinSerial.c -- * * This file implements the Windows-specific serial port functions, * and the "serial" channel driver. * * Copyright (c) 1999 by Scriptics Corp. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * Serial functionality implemented by Rolf.Schroedter@dlr.de * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tclWinSerial.c -- * * This file implements the Windows-specific serial port functions, * and the "serial" channel driver. * * Copyright (c) 1999 by Scriptics Corp. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * Serial functionality implemented by Rolf.Schroedter@dlr.de * * RCS: @(#) $Id: tclWinSerial.c,v 1.28.2.1 2005/02/02 15:54:05 kennykb Exp $ */ #include "tclWinInt.h" #include <fcntl.h> #include <io.h> #include <sys/stat.h> |
| ︙ | ︙ | |||
196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
Tcl_DString *dsPtr));
static int SerialSetOptionProc _ANSI_ARGS_((
ClientData instanceData,
Tcl_Interp *interp, CONST char *optionName,
CONST char *value));
static DWORD WINAPI SerialWriterThread(LPVOID arg);
/*
* This structure describes the channel type structure for command serial
* based IO.
*/
static Tcl_ChannelType serialChannelType = {
"serial", /* Type name. */
| > > > | > > | 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 |
Tcl_DString *dsPtr));
static int SerialSetOptionProc _ANSI_ARGS_((
ClientData instanceData,
Tcl_Interp *interp, CONST char *optionName,
CONST char *value));
static DWORD WINAPI SerialWriterThread(LPVOID arg);
static void SerialThreadActionProc _ANSI_ARGS_ ((
ClientData instanceData, int action));
/*
* This structure describes the channel type structure for command serial
* based IO.
*/
static Tcl_ChannelType serialChannelType = {
"serial", /* Type name. */
TCL_CHANNEL_VERSION_4, /* v4 channel */
SerialCloseProc, /* Close proc. */
SerialInputProc, /* Input proc. */
SerialOutputProc, /* Output proc. */
NULL, /* Seek proc. */
SerialSetOptionProc, /* Set option proc. */
SerialGetOptionProc, /* Get option proc. */
SerialWatchProc, /* Set up notifier to watch the channel. */
SerialGetHandleProc, /* Get an OS handle from channel. */
NULL, /* close2proc. */
SerialBlockProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
NULL, /* wide seek proc */
SerialThreadActionProc, /* thread action proc */
};
/*
*----------------------------------------------------------------------
*
* SerialInit --
*
|
| ︙ | ︙ | |||
1380 1381 1382 1383 1384 1385 1386 | * Alert the foreground thread. Note that we need to treat * this like a critical section so the foreground thread does * not terminate this thread while we are holding a mutex in * the notifier code. */ Tcl_MutexLock(&serialMutex); | > > | > | 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 |
* Alert the foreground thread. Note that we need to treat
* this like a critical section so the foreground thread does
* not terminate this thread while we are holding a mutex in
* the notifier code.
*/
Tcl_MutexLock(&serialMutex);
if (infoPtr->threadId != NULL) {
/* TIP #218. When in flight ignore the event, no one will receive it anyway */
Tcl_ThreadAlert(infoPtr->threadId);
}
Tcl_MutexUnlock(&serialMutex);
}
return 0;
}
/*
|
| ︙ | ︙ | |||
1454 1455 1456 1457 1458 1459 1460 |
Tcl_Channel
TclWinOpenSerialChannel(handle, channelName, permissions)
HANDLE handle;
char *channelName;
int permissions;
{
SerialInfo *infoPtr;
| < | | | > > > > > > > > > > < < < < < < < < | 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 |
Tcl_Channel
TclWinOpenSerialChannel(handle, channelName, permissions)
HANDLE handle;
char *channelName;
int permissions;
{
SerialInfo *infoPtr;
DWORD id;
SerialInit();
infoPtr = (SerialInfo *) ckalloc((unsigned) sizeof(SerialInfo));
memset(infoPtr, 0, sizeof(SerialInfo));
infoPtr->validMask = permissions;
infoPtr->handle = handle;
infoPtr->channel = (Tcl_Channel) NULL;
infoPtr->readable = 0;
infoPtr->writable = 1;
infoPtr->toWrite = infoPtr->writeQueue = 0;
infoPtr->blockTime = SERIAL_DEFAULT_BLOCKTIME;
infoPtr->lastEventTime = 0;
infoPtr->lastError = infoPtr->error = 0;
infoPtr->threadId = Tcl_GetCurrentThread();
infoPtr->sysBufRead = 4096;
infoPtr->sysBufWrite = 4096;
/*
* Use the pointer to keep the channel names unique, in case
* the handles are shared between multiple channels (stdin/stdout).
*/
wsprintfA(channelName, "file%lx", (int) infoPtr);
infoPtr->channel = Tcl_CreateChannel(&serialChannelType, channelName,
(ClientData) infoPtr, permissions);
SetupComm(handle, infoPtr->sysBufRead, infoPtr->sysBufWrite);
PurgeComm(handle,
PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
/*
* default is blocking
|
| ︙ | ︙ | |||
2154 2155 2156 2157 2158 2159 2160 |
if (valid) {
return TCL_OK;
} else {
return Tcl_BadChannelOption(interp, optionName,
"mode pollinterval lasterror queue sysbuffer ttystatus xchar");
}
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 |
if (valid) {
return TCL_OK;
} else {
return Tcl_BadChannelOption(interp, optionName,
"mode pollinterval lasterror queue sysbuffer ttystatus xchar");
}
}
/*
*----------------------------------------------------------------------
*
* SerialThreadActionProc --
*
* Insert or remove any thread local refs to this channel.
*
* Results:
* None.
*
* Side effects:
* Changes thread local list of valid channels.
*
*----------------------------------------------------------------------
*/
static void
SerialThreadActionProc (instanceData, action)
ClientData instanceData;
int action;
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
/* We do not access firstSerialPtr in the thread structures. This is
* not for all serials managed by the thread, but only those we are
* watching. Removal of the filevent handlers before transfer thus
* takes care of this structure.
*/
Tcl_MutexLock(&serialMutex);
if (action == TCL_CHANNEL_THREAD_INSERT) {
/* We can't copy the thread information from the channel when
* the channel is created. At this time the channel back
* pointer has not been set yet. However in that case the
* threadId has already been set by TclpCreateCommandChannel
* itself, so the structure is still good.
*/
SerialInit ();
if (infoPtr->channel != NULL) {
infoPtr->threadId = Tcl_GetChannelThread (infoPtr->channel);
}
} else {
infoPtr->threadId = NULL;
}
Tcl_MutexUnlock(&serialMutex);
}
|
Changes to win/tclWinSock.c.
1 2 3 4 5 6 7 8 9 10 | /* * tclWinSock.c -- * * This file contains Windows-specific socket related code. * * Copyright (c) 1995-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. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* * tclWinSock.c -- * * This file contains Windows-specific socket related code. * * Copyright (c) 1995-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. * * RCS: @(#) $Id: tclWinSock.c,v 1.44.2.1 2005/02/02 15:54:05 kennykb Exp $ */ #include "tclWinInt.h" /* * Make sure to remove the redirection defines set in tclWinPort.h * that is in use in other sections of the core, except for us. |
| ︙ | ︙ | |||
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
static Tcl_DriverOutputProc TcpOutputProc;
static Tcl_DriverWatchProc TcpWatchProc;
static Tcl_DriverGetHandleProc TcpGetHandleProc;
static int WaitForSocketEvent _ANSI_ARGS_((
SocketInfo *infoPtr, int events,
int *errorCodePtr));
static DWORD WINAPI SocketThread _ANSI_ARGS_((LPVOID arg));
/*
* This structure describes the channel type structure for TCP socket
* based IO.
*/
static Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
| > > > > | > > | 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
static Tcl_DriverOutputProc TcpOutputProc;
static Tcl_DriverWatchProc TcpWatchProc;
static Tcl_DriverGetHandleProc TcpGetHandleProc;
static int WaitForSocketEvent _ANSI_ARGS_((
SocketInfo *infoPtr, int events,
int *errorCodePtr));
static DWORD WINAPI SocketThread _ANSI_ARGS_((LPVOID arg));
static void TcpThreadActionProc _ANSI_ARGS_ ((
ClientData instanceData, int action));
/*
* This structure describes the channel type structure for TCP socket
* based IO.
*/
static Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
TCL_CHANNEL_VERSION_4, /* v4 channel */
TcpCloseProc, /* Close proc. */
TcpInputProc, /* Input proc. */
TcpOutputProc, /* Output proc. */
NULL, /* Seek proc. */
TcpSetOptionProc, /* Set option proc. */
TcpGetOptionProc, /* Get option proc. */
TcpWatchProc, /* Set up notifier to watch this channel. */
TcpGetHandleProc, /* Get an OS handle from channel. */
NULL, /* close2proc. */
TcpBlockProc, /* Set socket into (non-)blocking mode. */
NULL, /* flush proc. */
NULL, /* handler proc. */
NULL, /* wide seek proc */
TcpThreadActionProc, /* thread action proc */
};
/*
*----------------------------------------------------------------------
*
* InitSockets --
|
| ︙ | ︙ | |||
966 967 968 969 970 971 972 |
/* ARGSUSED */
static int
TcpCloseProc(instanceData, interp)
ClientData instanceData; /* The socket to close. */
Tcl_Interp *interp; /* Unused. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
| | | 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 |
/* ARGSUSED */
static int
TcpCloseProc(instanceData, interp)
ClientData instanceData; /* The socket to close. */
Tcl_Interp *interp; /* Unused. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
/* TIP #218 */
int errorCode = 0;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
* Check that WinSock is initialized; do not call it if not, to
* prevent system crashes. This can happen at exit time if the exit
* handler for WinSock ran before other exit handlers that want to
|
| ︙ | ︙ | |||
991 992 993 994 995 996 997 |
if (winSock.closesocket(infoPtr->socket) == SOCKET_ERROR) {
TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
errorCode = Tcl_GetErrno();
}
}
| | | > > > < < < < < < < < < < < | | 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 |
if (winSock.closesocket(infoPtr->socket) == SOCKET_ERROR) {
TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
errorCode = Tcl_GetErrno();
}
}
/* TIP #218. Removed the code removing the structure
* from the global socket list. This is now done by
* the thread action callbacks, and only there. This
* happens before this code is called. We can free
* without fear of damaging the list.
*/
ckfree((char *) infoPtr);
return errorCode;
}
/*
*----------------------------------------------------------------------
*
* NewSocketInfo --
*
* This function allocates and initializes a new SocketInfo
* structure.
*
* Results:
* Returns a newly allocated SocketInfo.
*
* Side effects:
* None, except for allocation of memory.
*
*----------------------------------------------------------------------
*/
static SocketInfo *
NewSocketInfo(socket)
SOCKET socket;
|
| ︙ | ︙ | |||
1045 1046 1047 1048 1049 1050 1051 |
infoPtr->readyEvents = 0;
infoPtr->selectEvents = 0;
infoPtr->acceptEventCount = 0;
infoPtr->acceptProc = NULL;
infoPtr->acceptProcData = NULL;
infoPtr->lastError = 0;
| | > > > | < < | | | 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 |
infoPtr->readyEvents = 0;
infoPtr->selectEvents = 0;
infoPtr->acceptEventCount = 0;
infoPtr->acceptProc = NULL;
infoPtr->acceptProcData = NULL;
infoPtr->lastError = 0;
/* TIP #218. Removed the code inserting the new structure
* into the global list. This is now handled in the thread
* action callbacks, and only there.
*/
infoPtr->nextPtr = NULL;
return infoPtr;
}
/*
*----------------------------------------------------------------------
*
* CreateSocket --
*
* This function opens a new socket and initializes the
* SocketInfo structure.
*
* Results:
* Returns a new SocketInfo, or NULL with an error in interp.
*
* Side effects:
* None, except for allocation of memory.
*
*----------------------------------------------------------------------
*/
static SocketInfo *
CreateSocket(interp, port, host, server, myaddr, myport, async)
Tcl_Interp *interp; /* For error reporting; can be NULL. */
|
| ︙ | ︙ | |||
2661 2662 2663 2664 2665 2666 2667 |
*/
if (!SocketsEnabled()) {
return (struct servent *) NULL;
}
return winSock.getservbyname(name, proto);
}
| < < | | < | | < | | | < | > > > > > | > | > | > < > > | | | > > | < > | < > > | | | | | | | | > | | | | | | | | < < < | < < | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 |
*/
if (!SocketsEnabled()) {
return (struct servent *) NULL;
}
return winSock.getservbyname(name, proto);
}
/*
*----------------------------------------------------------------------
*
* TcpThreadActionProc --
*
* Insert or remove any thread local refs to this channel.
*
* Results:
* None.
*
* Side effects:
* Changes thread local list of valid channels.
*
*----------------------------------------------------------------------
*/
static void
TcpThreadActionProc (instanceData, action)
ClientData instanceData;
int action;
{
ThreadSpecificData *tsdPtr;
SocketInfo *infoPtr = (SocketInfo *) instanceData;
int notifyCmd;
if (action == TCL_CHANNEL_THREAD_INSERT) {
/*
* Ensure that socket subsystem is initialized in this thread, or
* else sockets will not work.
*/
Tcl_MutexLock(&socketMutex);
InitSockets();
Tcl_MutexUnlock(&socketMutex);
tsdPtr = TCL_TSD_INIT(&dataKey);
WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
infoPtr->nextPtr = tsdPtr->socketList;
tsdPtr->socketList = infoPtr;
SetEvent(tsdPtr->socketListLock);
notifyCmd = SELECT;
} else {
SocketInfo **nextPtrPtr;
int removed = 0;
tsdPtr = TCL_TSD_INIT(&dataKey);
/* TIP #218, Bugfix: All access to socketList has to be protected by the lock */
WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
for (nextPtrPtr = &(tsdPtr->socketList); (*nextPtrPtr) != NULL;
nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
if ((*nextPtrPtr) == infoPtr) {
(*nextPtrPtr) = infoPtr->nextPtr;
removed = 1;
break;
}
}
SetEvent(tsdPtr->socketListLock);
/*
* This could happen if the channel was created in one thread
* and then moved to another without updating the thread
* local data in each thread.
*/
if (!removed) {
Tcl_Panic("file info ptr not on thread channel list");
}
notifyCmd = UNSELECT;
}
/*
* Ensure that, or stop, notifications for the socket occur in this thread.
*/
SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
(WPARAM) notifyCmd, (LPARAM) infoPtr);
}
|
Changes to win/tclWinTime.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclWinTime.c -- * * Contains Windows specific versions of Tcl functions that * obtain time values from the operating system. * * Copyright 1995-1998 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* * tclWinTime.c -- * * Contains Windows specific versions of Tcl functions that * obtain time values from the operating system. * * Copyright 1995-1998 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclWinTime.c,v 1.28.2.1 2005/02/02 15:54:07 kennykb Exp $ */ #include "tclInt.h" #define SECSPERDAY (60L * 60L * 24L) #define SECSPERYEAR (SECSPERDAY * 365L) #define SECSPER4YEAR (SECSPERYEAR * 4L + SECSPERDAY) |
| ︙ | ︙ | |||
134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
Tcl_WideInt perfCounter,
Tcl_WideInt perfFreq
));
static Tcl_WideInt AccumulateSample _ANSI_ARGS_((
Tcl_WideInt perfCounter,
Tcl_WideUInt fileTime
));
/*
*----------------------------------------------------------------------
*
* TclpGetSeconds --
*
* This procedure returns the number of seconds from the epoch.
| > > > > > > > > > > > | 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 |
Tcl_WideInt perfCounter,
Tcl_WideInt perfFreq
));
static Tcl_WideInt AccumulateSample _ANSI_ARGS_((
Tcl_WideInt perfCounter,
Tcl_WideUInt fileTime
));
static void NativeScaleTime _ANSI_ARGS_ ((Tcl_Time* timebuf, ClientData clientData));
static void NativeGetTime _ANSI_ARGS_ ((Tcl_Time* timebuf, ClientData clientData));
/* TIP #233 (Virtualized Time)
* Data for the time hooks, if any.
*/
Tcl_GetTimeProc* tclGetTimeProcPtr = NativeGetTime;
Tcl_ScaleTimeProc* tclScaleTimeProcPtr = NativeScaleTime;
ClientData tclTimeClientData = NULL;
/*
*----------------------------------------------------------------------
*
* TclpGetSeconds --
*
* This procedure returns the number of seconds from the epoch.
|
| ︙ | ︙ | |||
156 157 158 159 160 161 162 |
*----------------------------------------------------------------------
*/
unsigned long
TclpGetSeconds()
{
Tcl_Time t;
| | > | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
*----------------------------------------------------------------------
*/
unsigned long
TclpGetSeconds()
{
Tcl_Time t;
/* Tcl_GetTime inlined */
(*tclGetTimeProcPtr) (&t, tclTimeClientData);
return t.sec;
}
/*
*----------------------------------------------------------------------
*
* TclpGetClicks --
|
| ︙ | ︙ | |||
191 192 193 194 195 196 197 |
* Use the Tcl_GetTime abstraction to get the time in microseconds,
* as nearly as we can, and return it.
*/
Tcl_Time now; /* Current Tcl time */
unsigned long retval; /* Value to return */
| | > > | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
* Use the Tcl_GetTime abstraction to get the time in microseconds,
* as nearly as we can, and return it.
*/
Tcl_Time now; /* Current Tcl time */
unsigned long retval; /* Value to return */
/* Tcl_GetTime inlined */
(*tclGetTimeProcPtr) (&now, tclTimeClientData);
retval = ( now.sec * 1000000 ) + now.usec;
return retval;
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
*
*----------------------------------------------------------------------
*/
void
Tcl_GetTime(timePtr)
Tcl_Time *timePtr; /* Location to store time information. */
{
struct timeb t;
int useFtime = 1; /* Flag == TRUE if we need to fall back
* on ftime rather than using the perf
* counter */
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
*
*----------------------------------------------------------------------
*/
void
Tcl_GetTime(timePtr)
Tcl_Time *timePtr; /* Location to store time information. */
{
(*tclGetTimeProcPtr) (timePtr, tclTimeClientData);
}
/*
*----------------------------------------------------------------------
*
* NativeScaleTime --
*
* TIP #233
* Scale from virtual time to the real-time. For native scaling the
* relationship is 1:1 and nothing has to be done.
*
* Results:
* Scales the time in timePtr.
*
* Side effects:
* See above.
*
*----------------------------------------------------------------------
*/
static void
NativeScaleTime (timePtr, clientData)
Tcl_Time* timePtr;
ClientData clientData;
{
/* Native scale is 1:1. Nothing is done */
}
/*
*----------------------------------------------------------------------
*
* NativeGetTime --
*
* TIP #233
* Gets the current system time in seconds and microseconds
* since the beginning of the epoch: 00:00 UCT, January 1, 1970.
*
* Results:
* Returns the current time in timePtr.
*
* Side effects:
* On the first call, initializes a set of static variables to
* keep track of the base value of the performance counter, the
* corresponding wall clock (obtained through ftime) and the
* frequency of the performance counter. Also spins a thread
* whose function is to wake up periodically and monitor these
* values, adjusting them as necessary to correct for drift
* in the performance counter's oscillator.
*
*----------------------------------------------------------------------
*/
static void
NativeGetTime (timePtr, clientData)
Tcl_Time* timePtr;
ClientData clientData;
{
struct timeb t;
int useFtime = 1; /* Flag == TRUE if we need to fall back
* on ftime rather than using the perf
* counter */
|
| ︙ | ︙ | |||
1178 1179 1180 1181 1182 1183 1184 |
/*
* The MS implementation of localtime is thread safe because
* it returns the time in a block of thread-local storage,
* and Windows does not provide a Posix localtime_r function.
*/
return localtime( timePtr );
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 1315 1316 1317 1318 1319 1320 |
/*
* The MS implementation of localtime is thread safe because
* it returns the time in a block of thread-local storage,
* and Windows does not provide a Posix localtime_r function.
*/
return localtime( timePtr );
}
/*
*----------------------------------------------------------------------
*
* Tcl_SetTimeProc --
*
* TIP #233 (Virtualized Time)
* Registers two handlers for the virtualization of Tcl's
* access to time information.
*
* Results:
* None.
*
* Side effects:
* Remembers the handlers, alters core behaviour.
*
*----------------------------------------------------------------------
*/
void
Tcl_SetTimeProc (getProc, scaleProc, clientData)
Tcl_GetTimeProc* getProc;
Tcl_ScaleTimeProc* scaleProc;
ClientData clientData;
{
tclGetTimeProcPtr = getProc;
tclScaleTimeProcPtr = scaleProc;
tclTimeClientData = clientData;
}
/*
*----------------------------------------------------------------------
*
* Tcl_QueryTimeProc --
*
* TIP #233 (Virtualized Time)
* Query which time handlers are registered.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Tcl_QueryTimeProc (getProc, scaleProc, clientData)
Tcl_GetTimeProc** getProc;
Tcl_ScaleTimeProc** scaleProc;
ClientData* clientData;
{
if (getProc) {
*getProc = tclGetTimeProcPtr;
}
if (scaleProc) {
*scaleProc = tclScaleTimeProcPtr;
}
if (clientData) {
*clientData = tclTimeClientData;
}
}
|