Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cefd1f2e6 | ||
|
|
e6ca6caa2e | ||
|
|
76a4df192b | ||
|
|
2c47ecc37b | ||
|
|
f50091eae7 | ||
|
|
e803430f83 | ||
|
|
a43e59c36a | ||
|
|
3187daa417 | ||
|
|
25eb6f30ba | ||
|
|
fe38772e86 | ||
|
|
f5f35eb289 |
@@ -1,36 +1,219 @@
|
||||
2000-04-27 Eric Melski <ericm@scriptics.com>
|
||||
2000-07-26 Jeff Hobbs <hobbs@scriptics.com>
|
||||
|
||||
* doc/library.n: Added entries for auto_qualify and auto_import
|
||||
[Bug: 1271].
|
||||
* merged core-8-3-1-io-rewrite back into core-8-3-1-branch.
|
||||
The core-8-3-1-io-rewrite branch should now be considered defunct.
|
||||
|
||||
* doc/Init.3: Manual entry for Tcl_Init [Bug: 1820].
|
||||
* generic/tclStubInit.c:
|
||||
* generic/tclDecls.h:
|
||||
* generic/tcl.decls:
|
||||
* generic/tcl.h:
|
||||
* generic/tclIO.c: moved the Tcl_Channel* macros from tcl.h to
|
||||
tclIO.c and made them proper stubbed functions. These are:
|
||||
Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc,
|
||||
Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc,
|
||||
Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelSetOptionProc,
|
||||
Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc,
|
||||
Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc,
|
||||
and Tcl_ChannelHandlerProc. These should be used to access the
|
||||
Tcl_ChannelType structure instead of direct pointer dereferencing.
|
||||
|
||||
* doc/expr.n: Added documentation for each of the math library
|
||||
functions that expr supports [Bug: 1054].
|
||||
* unix/Makefile.in: undid 07-25 Makefile.in changes because we
|
||||
don't really want to force all private makefiles on everyone.
|
||||
This needs to be addressed again in the future. Best possible
|
||||
solution is to create a tcl/ subdir in the installing include dir
|
||||
(as is done already with the lib dir).
|
||||
|
||||
2000-04-26 Eric Melski <ericm@scriptics.com>
|
||||
* tests/iogt.test: added RCS string, marked tests 2.* to be
|
||||
unixOnly due to underlying system differences.
|
||||
|
||||
* doc/memory.n: Man page for Tcl "memory" command, which is
|
||||
created when TCL_MEM_DEBUG is defined at compile time.
|
||||
* tests/all.tcl: corrected additional sets by Kupries for testing.
|
||||
|
||||
* doc/TCL_MEM_DEBUG.3: Man page with overall information about
|
||||
TCL_MEM_DEBUG usage.
|
||||
2000-07-25 Brent Welch <welch@ajubasolutions.com>
|
||||
|
||||
* doc/DumpActiveMemory.3: Man page for Tcl_DumpActiveMemory,
|
||||
Tcl_InitMemory, and Tcl_ValidateAllMemory [Bug: 1816, 1835].
|
||||
* unix/Makefile.in: Need to install all the Tcl headers because
|
||||
Itcl depends on internal headers.
|
||||
|
||||
* generic/tclCkalloc.c: Fixed some function headers.
|
||||
2000-07-25 Andreas Kupries <a.kupries@westend.com>
|
||||
|
||||
* unix/mkLinks: Regen'd with new mkLinks.tcl.
|
||||
* tests/iogt.test: (line 866f) New tests iogt-6.[01], highlighting
|
||||
buffering trouble when stacking and unstacking transformations.
|
||||
iogt-6.0 is solved, see the changes below. iogt-6.1 remains, for
|
||||
now, due to the perceived complexity of solutions.
|
||||
|
||||
* unix/mkLinks.tcl: Fixed indentation, made link setup more
|
||||
intelligent (only do one existance test per man page, instead of
|
||||
one per function).
|
||||
* generic/tclIO.h: (line 139f) struct Channel, added a buffer
|
||||
queue, to hold data pushed back when stacking a transformation.
|
||||
|
||||
* doc/library.n: Fixed .SH NAME macro to include each function
|
||||
documented on the page, so that mkLinks will know about the
|
||||
functions listed there, and so that the Windows help file index
|
||||
will get set up correctly [Bug: 1898, 5273].
|
||||
* generic/tclIO.c:
|
||||
(line 91f, line 7434f) New internal function 'CopyBuffer'.
|
||||
Derived from 'CopyAndTranslateBuffer', with translation
|
||||
removed.
|
||||
(line 1025f, line 1212f): Initialization of new queue.
|
||||
(line 1164f, Tcl_StackChannel): Pushback of input queue.
|
||||
(line 1293f, Tcl_UnstackChannel): Discard input and pushback.
|
||||
(line 3748f, Tcl_ReadRaw): Modified to use data in the push back
|
||||
area before going to the driver. Uses 'CopyBuffer', s.a.
|
||||
(line 4702f, GetInput): Modified to use data in the push back
|
||||
area before going to the driver.
|
||||
(line 4867f, Tcl_Seek): Modified to take pushback of the topmost
|
||||
channel in a stack into account.
|
||||
(line 5620f, Tcl_InputBuffered): See above. Added
|
||||
'Tcl_ChannelBuffered'. Analogue to 'Tcl_InputBuffered' but for
|
||||
the buffer area in the channel.
|
||||
|
||||
* generic/tcl.decls: New public API 'Tcl_ChannelBuffered'. S.a.
|
||||
|
||||
2000-07-19 Jeff Hobbs <hobbs@scriptics.com>
|
||||
|
||||
* tests/socket.test: removed doTestsWithRemoteServer constraint
|
||||
from socket-12.*. It requires 'exec', not a remote server.
|
||||
Cleaned up some coding errors.
|
||||
|
||||
2000-07-18 Brent Welch <welch@ajubasolutions.com>
|
||||
|
||||
* win/Makefile.in: Added rules for static tcldde and tclreg libraries.
|
||||
|
||||
2000-07-17 Jeff Hobbs <hobbs@scriptics.com>
|
||||
|
||||
* README:
|
||||
* win/README:
|
||||
* win/README.binary:
|
||||
* win/configure.in:
|
||||
* unix/configure.in:
|
||||
* unix/tcl.spec:
|
||||
* tools/tcl.wse.in:
|
||||
* generic/tcl.h (TCL_RELEASE_SERIAL): updated to patchlevel 8.3.2
|
||||
|
||||
* unix/Makefile.in:
|
||||
* win/Makefile.in:
|
||||
* win/makefile.vc: added tclIOGT.c to objects list to compile.
|
||||
|
||||
* generic/tclStubInit.c:
|
||||
* generic/tclIntDecls.h:
|
||||
* generic/tclInt.decls: commented out internal decls for
|
||||
TclTestChannelCmd and TclTestChannelEventCmd as they were moved to
|
||||
tclTest.c. Added new decls for TclChannelEventScriptInvoker and
|
||||
TclChannelTransform.
|
||||
|
||||
* generic/tclIO.h: new file that contains the main internal
|
||||
structures of Tcl_Channel code to allow for multiple files to
|
||||
access them.
|
||||
* generic/tclTest.c:
|
||||
* generic/tclIO.c: broke into 3 files - tclIO.c core code, tclIO.h
|
||||
header code, and tclIOGT.c - the giot test code from Kupries. The
|
||||
channel test code also moved to tclTest.c.
|
||||
* generic/tclIO.c (CloseChannel): stopped masking out of the
|
||||
TCL_READABLE|TCL_WRITABLE bits from the state flags in
|
||||
CloseChannel, instead adding extra intelligence to
|
||||
CheckChannelErrors with a new CHANNEL_RAW_MODE bit for special
|
||||
behavior when called from Raw channel APIs.
|
||||
|
||||
2000-07-13 Jeff Hobbs <hobbs@scriptics.com>
|
||||
|
||||
* generic/tclIO.c (StackSetBlockMode): moved set of chanPtr
|
||||
outside of blockModeProc check to avoid infinite loop when
|
||||
blockModeProc was NULL (Kupries). updated TransformSeekProc to
|
||||
not call Tcl_Seek directly (Kupries).
|
||||
|
||||
* win/tclWinChan.c: updated fileChannelType to v2 channel struct
|
||||
* win/tclWinConsole.c: updated consoleChannelType to v2 channel struct
|
||||
* win/tclWinPipe.c: updated pipeChannelType to v2 channel struct
|
||||
* win/tclWinSerial.c: updated serialChannelType to v2 channel struct
|
||||
* win/tclWinSock.c: updated tcpChannelType to v2 channel struct
|
||||
|
||||
2000-07-11 Brent Welch <welch@ajubasolutions.com>
|
||||
|
||||
* win/tclConfig.sh.in: Cleaned up unix-specific autoconf variables.
|
||||
|
||||
2000-07-11 Jeff Hobbs <hobbs@scriptics.com>
|
||||
|
||||
* tests/iogt.test: made tests [345].0 not run by default as they
|
||||
were failing in the new design, but I'm not convinced that the
|
||||
returned result isn't correct.
|
||||
|
||||
* generic/tclDecls.h:
|
||||
* generic/tclStubInit.c:
|
||||
* generic/tcl.decls: added Tcl_GetTopChannel C API that returns
|
||||
the current top channel of a channel stack. Tcl_GetChannel was
|
||||
changed earlier to return the bottommost channel of a stack
|
||||
because that is the one that is guaranteed to stay around the
|
||||
longest, and this was needed to compensate for certain
|
||||
operations that want to look at the state of the main channel.
|
||||
Most channel APIs already compensate for grabbing the top, so it
|
||||
shouldn't be needed often.
|
||||
|
||||
* generic/tclIO.c (Tcl_StackChannel, Tcl_UnstackChannel): Added
|
||||
flushing of buffers (Kupries), removed use of DownChannel macro,
|
||||
added Tcl_GetTopChannel public API to get to the top channel of
|
||||
the channel stack (necessary for TLS). Rewrote Tcl_NotifyChannel
|
||||
for new channel design (Kupries). Did some code cleanup in the
|
||||
transform code. tclIO.c must still be broken into bits (separate
|
||||
out test code and giot code, create tclIO.h).
|
||||
|
||||
2000-07-10 Andreas Kupries <a.kupries@westend.com>
|
||||
|
||||
* tests/iogt.test: Reverted some earlier changes as a fix by Jeff
|
||||
revived the original and correct behaviour. IOW, the tests showed
|
||||
a genuine error and I didn't see it :(.
|
||||
|
||||
* generic/tclIO.c (Tcl_Read|Write_Raw): Changed to directly use
|
||||
the drivers and not DoRead|DoWrite. The latter use the buffering
|
||||
system, encoding and eol-translation and this wreaks havoc with
|
||||
the data going through the transformations. Both procedures use
|
||||
CheckForchannelErrors and let it believe that there is no
|
||||
background copy in progress or else stacked channels could not
|
||||
be used for that.
|
||||
|
||||
* generic/tclIO.c (TclCopyChannel, CopyData): Moved access to the
|
||||
topmost channel from the first to the second procedure to make
|
||||
the decision about that at the last possible time (Callbacks can
|
||||
change the stacking).
|
||||
|
||||
test suite: failures of iogt-[345].0
|
||||
|
||||
2000-07-06 Jeff Hobbs <hobbs@scriptics.com>
|
||||
|
||||
* tests/iogt.test: new tests for stacked channel stuff based off
|
||||
new 'testchannel transform|unstack' code (Kupries IOGT extension).
|
||||
* generic/tcl.decls:
|
||||
* generic/tcl.h:
|
||||
* generic/tclDecls.h:
|
||||
* generic/tclStubsInit.c:
|
||||
* generic/tclIO.c (TclCopyChannel): complete rewrite of Tcl
|
||||
Channel code for stacked channels. HOBBS: ADD MORE WHEN DONE.
|
||||
|
||||
2000-06-02 Jeff Hobbs <hobbs@scriptics.com>
|
||||
|
||||
* generic/tclIO.c (CloseChannel): removed the &ing out of
|
||||
(TCL_READABLE|TCL_WRITABLE) from the flags, as CloseChannel does
|
||||
this on the next pass through for the top channel, and it appeared
|
||||
to be causing hangs by not allowing the final flush.
|
||||
|
||||
2000-06-01 Jeff Hobbs <hobbs@scriptics.com>
|
||||
|
||||
* generic/tclIO.c (CloseChannel): Rewrote CloseChannel code to
|
||||
unstack a channel during the close process. Fixed a refcount bug
|
||||
in Tcl_UnstackChannel. [Bug: 5623]
|
||||
(CloseChannel): further extended CloseChannel in the stacked case
|
||||
to effect certain operations on the next channel that would have
|
||||
been done in Tcl_Close. Also added CHANNEL_CLOSED and removed
|
||||
(TCL_READABLE|TCL_WRITABLE) bits from chanPtr->flags. Changed
|
||||
final reset of the WatchProc to check the chanDownPtr's (next)
|
||||
interestMask.
|
||||
|
||||
2000-05-29 Sandeep Tamhankar <sandeep@scriptics.com>
|
||||
|
||||
* tests/http.test
|
||||
* doc/http.n
|
||||
* library/http2.3/http.tcl: Fixed bug 5741, where unsuccessful
|
||||
geturl calls sometimes leaked memory and resources (sockets).
|
||||
Also, switched around some of the logic so that http::wait never
|
||||
throws an exception. This is because in an asynchronous geturl,
|
||||
the command callback will probably end up doing all the error
|
||||
handling anyway, and in an asynchronous situation, the user
|
||||
expects to check the state when the transaction completes, as
|
||||
opposed to being thrown an exception. For the http package, this
|
||||
menas the user can check http::status for "error" and http::error
|
||||
for the error message after doing the http::wait.
|
||||
|
||||
2000-04-26 Jeff Hobbs <hobbs@scriptics.com>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
README: Tcl
|
||||
This is the Tcl 8.3.1 source distribution.
|
||||
This is the Tcl 8.3.2 source distribution.
|
||||
You can get any release of Tcl from:
|
||||
http://dev.scriptics.com/registration/<version>.tml
|
||||
Tcl/Tk is also available through NetCVS:
|
||||
http://dev.scriptics.com/software/tcltk/netcvs.html
|
||||
|
||||
RCS: @(#) $Id: README,v 1.31 2000/04/26 17:31:19 hobbs Exp $
|
||||
RCS: @(#) $Id: README,v 1.31.2.1 2000/07/27 01:39:13 hobbs Exp $
|
||||
|
||||
Contents
|
||||
--------
|
||||
@@ -49,7 +49,7 @@ The home page for this release, including new features, is
|
||||
http://dev.scriptics.com/software/tcltk/8.3.html
|
||||
|
||||
Detailed release notes can be found at
|
||||
http://dev.scriptics.com/software/tcltk/relnotes/tcl8.3.1.txt
|
||||
http://dev.scriptics.com/software/tcltk/relnotes/tcl8.3.2.txt
|
||||
|
||||
Information about Tcl itself can be found at
|
||||
http://dev.scriptics.com/scripting/
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
'\"
|
||||
'\" Copyright (c) 1992-1999 Karl Lehenbauer and Mark Diekhans.
|
||||
'\" Copyright (c) 2000 by Scriptics Corporation.
|
||||
'\" All rights reserved.
|
||||
'\"
|
||||
'\" RCS: @(#) $Id: DumpActiveMemory.3,v 1.2 2000/04/28 00:47:48 ericm Exp $
|
||||
'\"
|
||||
.so man.macros
|
||||
.TH "Tcl_DumpActiveMemory" 3 8.1 Tcl "Tcl Library Procedures"
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_DumpActiveMemory, Tcl_InitMemory, Tcl_ValidateAllMemory \- Validated memory allocation interface.
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
.sp
|
||||
int
|
||||
\fBTcl_DumpActiveMemory\fR(\fIfileName\fR)
|
||||
.sp
|
||||
void
|
||||
\fBTcl_InitMemory\fR(\fIinterp\fR)
|
||||
.sp
|
||||
void
|
||||
\fBTcl_ValidateAllMemory\fR(\fIfileName, line\fR)
|
||||
|
||||
.SH ARGUMENTS
|
||||
.AP Tcl_Interp *interp in
|
||||
Tcl interpreter in which to add commands.
|
||||
.AP char *fileName in
|
||||
For \fBTcl_DumpActiveMemory\fR, name of the file to which memory
|
||||
information will be written. For \fBTcl_ValidateAllMemory\fR, name of
|
||||
the file from which the call is being made (normally \fB__FILE__\fR).
|
||||
.AP int line in
|
||||
Line number at which the call to \fBTcl_ValidateAllMemory\fR is made
|
||||
(normally \fB__LINE__\fR).
|
||||
.BE
|
||||
|
||||
.SH DESCRIPTION
|
||||
These functions provide access to Tcl memory debugging information.
|
||||
They are only available when Tcl has been compiled with
|
||||
\fBTCL_MEM_DEBUG\fR defined at compile-time.
|
||||
.PP
|
||||
\fBTcl_DumpActiveMemory\fR will output a list of all currently
|
||||
allocated memory to the specified file. The information output for
|
||||
each allocated block of memory is: starting and ending addresses
|
||||
(excluding guard zone), size, source file where \fBckalloc\fR was
|
||||
called to allocate the block and line number in that file. It is
|
||||
especially useful to call \fBTcl_DumpActiveMemory\fR after the Tcl
|
||||
interpreter has been deleted.
|
||||
.PP
|
||||
\fBTcl_InitMemory\fR adds the Tcl \fBmemory\fR command to the
|
||||
interpreter given by \fIinterp\fR. It is called by \fBTcl_Main\fR
|
||||
when Tcl has been compiled with \fBTCL_MEM_DEBUG\fR defined.
|
||||
.PP
|
||||
\fBTcl_ValidateAllMemory\fR forces a validation of the guard zones of
|
||||
all currently allocated blocks of memory. Normally validation of a
|
||||
block occurs when its freed, unless full validation is enabled, in
|
||||
which case validation of all blocks occurs when \fBckalloc\fR and
|
||||
\fBckfree\fR are called. This function forces the validation to occur
|
||||
at any point.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
TCL_MEM_DEBUG, memory
|
||||
|
||||
.SH KEYWORDS
|
||||
memory, debug
|
||||
|
||||
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
'\"
|
||||
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
|
||||
'\" All rights reserved.
|
||||
'\"
|
||||
'\" RCS: @(#) $Id: Init.3,v 1.1 2000/04/28 00:47:48 ericm Exp $
|
||||
'\"
|
||||
.so man.macros
|
||||
.TH Tcl_Init 3 8.0 Tcl "Tcl Library Procedures"
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_Init \- find and source initialization script
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
.sp
|
||||
int
|
||||
\fBTcl_Init\fR(\fIinterp\fR)
|
||||
.SH ARGUMENTS
|
||||
.AP Tcl_Interp *interp in
|
||||
Interpreter to initialize.
|
||||
.BE
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\fBTcl_Init\fR is a helper procedure that finds and \fBsource\fR's the
|
||||
\fBinit.tcl\fR script, which should exist somewhere on the Tcl library
|
||||
path. On Macintosh systems, it additionally checks for an \fBInit\fR
|
||||
resource and sources the contents of that resource if \fBinit.tcl\fR
|
||||
cannot be found.
|
||||
.PP
|
||||
\fBTcl_Init\fR is typically called from \fBTcl_AppInit\fR procedures.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
Tcl_AppInit, Tcl_Main
|
||||
|
||||
.SH KEYWORDS
|
||||
application, initialization, interpreter
|
||||
@@ -1,81 +0,0 @@
|
||||
'\"
|
||||
'\" Copyright (c) 1992-1999 Karl Lehenbauer and Mark Diekhans.
|
||||
'\" Copyright (c) 2000 by Scriptics Corporation.
|
||||
'\" All rights reserved.
|
||||
'\"
|
||||
'\" RCS: @(#) $Id: TCL_MEM_DEBUG.3,v 1.2 2000/04/28 00:47:49 ericm Exp $
|
||||
'\"
|
||||
.so man.macros
|
||||
.TH TCL_MEM_DEBUG 3 8.1 Tcl "Tcl Library Procedures"
|
||||
.BS
|
||||
.SH NAME
|
||||
TCL_MEM_DEBUG \- Compile-time flag to enable Tcl memory debugging.
|
||||
|
||||
.SH DESCRIPTION
|
||||
When Tcl is compiled with \fBTCL_MEM_DEBUG\fR defined, a powerful set
|
||||
of memory debugging aids are included in the compiled binary. This
|
||||
includes C and Tcl functions which can aid with debugging
|
||||
memory leaks, memory allocation overruns, and other memory related
|
||||
errors.
|
||||
|
||||
.SH ENABLING MEMORY DEBUGGING
|
||||
.PP
|
||||
To enable memory debugging, Tcl should be recompiled from scratch with
|
||||
\fBTCL_MEM_DEBUG\fR defined. This will also compile in a non-stub
|
||||
version of \fBTcl_InitMemory\fR to add the \fBmemory\fR command to Tcl.
|
||||
.PP
|
||||
\fBTCL_MEM_DEBUG\fR must be either left defined for all modules or undefined
|
||||
for all modules that are going to be linked together. If they are not, link
|
||||
errors will occur, with either \fBTclDbCkfree\fR and \fBTcl_DbCkalloc\fR or
|
||||
\fBTcl_Ckalloc\fR and \fBTcl_Ckfree\fR being undefined.
|
||||
.PP
|
||||
Once memory debugging support has been compiled into Tcl, the C
|
||||
functions \fBTcl_ValidateAllMemory\fR, and \fBTcl_DumpActiveMemory\fR,
|
||||
and the Tcl \fBmemory\fR command can be used to validate and examine
|
||||
memory usage.
|
||||
|
||||
.SH GUARD ZONES
|
||||
.PP
|
||||
When memory debugging is enabled, whenever a call to \fBckalloc\fR is
|
||||
made, slightly more memory than requested is allocated so the memory debugging
|
||||
code can keep track of the allocated memory, and eight-byte ``guard
|
||||
zones'' are placed in front of and behind the space that will be
|
||||
returned to the caller. (The size of the guard zone is defined by the
|
||||
C #define \fBGUARD_SIZE\fR in \fIbaseline/src/ckalloc.c\fR -- it can
|
||||
be extended if you suspect large overwrite problems, at some cost in
|
||||
performance.) A known pattern is written into the guard zones and, on
|
||||
a call to \fBckfree\fR, the guard zones of the space being freed are
|
||||
checked to see if either zone has been modified in any way. If one
|
||||
has been, the guard bytes and their new contents are identified, and a
|
||||
``low guard failed'' or ``high guard failed'' message is issued. The
|
||||
``guard failed'' message includes the address of the memory packet and
|
||||
the file name and line number of the code that called \fBckfree\fR.
|
||||
This allows you to detect the common sorts of one-off problems, where
|
||||
not enough space was allocated to contain the data written, for
|
||||
example.
|
||||
|
||||
.SH DEBUGGING DIFFICULT MEMORY CORRUPTION PROBLEMS
|
||||
.PP
|
||||
Normally, Tcl compiled with memory debugging enabled will make it easy
|
||||
to isolate a corruption problem. Turning on memory validation with
|
||||
the memory command can help isolate difficult problems. If you
|
||||
suspect (or know) that corruption is occurring before the Tcl
|
||||
interpreter comes up far enough for you to issue commands, you can set
|
||||
\fBMEM_VALIDATE\fR define, recompile tclCkalloc.c and rebuild Tcl.
|
||||
This will enable memory validation from the first call to
|
||||
\fBckalloc\fR, again, at a large performance impact.
|
||||
.PP
|
||||
If you are desperate and validating memory on every call to
|
||||
\fBckalloc\fR and \fBckfree\fR isn't enough, you can explicitly call
|
||||
\fBTcl_ValidateAllMemory\fR directly at any point. It takes a \fIchar
|
||||
*\fR and an \fIint\fR which are normally the filename and line number
|
||||
of the caller, but they can actually be anything you want. Remember
|
||||
to remove the calls after you find the problem.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
memory, Tcl_ValidateAllMemory, Tcl_DumpActiveMemory
|
||||
|
||||
.SH KEYWORDS
|
||||
memory, debug
|
||||
|
||||
|
||||
+11
-77
@@ -5,7 +5,7 @@
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
'\" RCS: @(#) $Id: expr.n,v 1.3 2000/04/28 00:47:49 ericm Exp $
|
||||
'\" RCS: @(#) $Id: expr.n,v 1.2 1998/09/14 18:39:52 stanton Exp $
|
||||
'\"
|
||||
.so man.macros
|
||||
.TH expr n 8.0 Tcl "Tcl Built-In Commands"
|
||||
@@ -184,80 +184,30 @@ invoking the \fBexpr\fR command.
|
||||
Tcl supports the following mathematical functions in expressions:
|
||||
.DS
|
||||
.ta 3c 6c 9c
|
||||
\fBabs\fR \fBcosh\fR \fBlog\fR \fBsqrt\fR
|
||||
\fBacos\fR \fBdouble\fR \fBlog10\fR \fBsrand\fR
|
||||
\fBasin\fR \fBexp\fR \fBpow\fR \fBtan\fR
|
||||
\fBatan\fR \fBfloor\fR \fBrand\fR \fBtanh\fR
|
||||
\fBatan2\fR \fBfmod\fR \fBround\fR
|
||||
\fBceil\fR \fBhypot\fR \fBsin\fR
|
||||
\fBcos\fR \fBint\fR \fBsinh\fR
|
||||
\fBacos\fR \fBcos\fR \fBhypot\fR \fBsinh\fR
|
||||
\fBasin\fR \fBcosh\fR \fBlog\fR \fBsqrt\fR
|
||||
\fBatan\fR \fBexp\fR \fBlog10\fR \fBtan\fR
|
||||
\fBatan2\fR \fBfloor\fR \fBpow\fR \fBtanh\fR
|
||||
\fBceil\fR \fBfmod\fR \fBsin\fR
|
||||
.DE
|
||||
.PP
|
||||
Each of these functions invokes the math library function of the same
|
||||
name; see the manual entries for the library functions for details
|
||||
on what they do. Tcl also implements the following functions for
|
||||
conversion between integers and floating-point numbers and the
|
||||
generation of random numbers:
|
||||
.TP
|
||||
\fBabs(\fIarg\fB)\fR
|
||||
Returns the absolute value of \fIarg\fR. \fIArg\fR may be either
|
||||
integer or floating-point, and the result is returned in the same form.
|
||||
.TP
|
||||
\fBacos(\fIarg\fB)\fR
|
||||
Returns the arc cosine of \fIarg\fR, in the range [0,pi]
|
||||
radians. \fIArg\fR should be in the range [-1,1].
|
||||
.TP
|
||||
\fBasin(\fIarg\fB)\fR
|
||||
Returns the arc sine of \fIarg\fR, in the range [-pi/2,pi/2] radians.
|
||||
\fIArg\fR should be in the range [-1,1].
|
||||
.TP
|
||||
\fBatan(\fIarg\fB)\fR
|
||||
Returns the arc tangent of \fIarg\fR, in the range [-pi/2,pi/2] radians.
|
||||
.TP
|
||||
\fBatan2(\fIx, y\fB)\fR
|
||||
Returns the arc tangent of \fIy\fR/\fIx\fR, in the range [-pi,pi]
|
||||
radians. \fIx\fR and \fIy\fR cannot both be 0.
|
||||
.TP
|
||||
\fBceil(\fIarg\fB)\fR
|
||||
Returns the smallest integer value not less than \fIarg\fR.
|
||||
.TP
|
||||
\fBcos(\fIarg\fB)\fR
|
||||
Returns the cosine of \fIarg\fR, measured in radians.
|
||||
.TP
|
||||
\fBcosh(\fIarg\fB)\fR
|
||||
Returns the hyperbolic cosine of \fIarg\fR. If the result would cause
|
||||
an overflow, an error is returned.
|
||||
.TP
|
||||
\fBdouble(\fIarg\fB)\fR
|
||||
If \fIarg\fR is a floating value, returns \fIarg\fR, otherwise converts
|
||||
\fIarg\fR to floating and returns the converted value.
|
||||
.TP
|
||||
\fBexp(\fIarg\fB)\fR
|
||||
Returns the exponential of \fIarg\fR, defined as e**\fIarg\fR. If the
|
||||
result would cause an overflow, an error is returned.
|
||||
.TP
|
||||
\fBfloor(\fIarg\fB)\fR
|
||||
Returns the largest integral value not greater than \fIarg\fR.
|
||||
.TP
|
||||
\fBfmod(\fIx, y\fB)\fR
|
||||
Returns the floating-point remainder of the division of \fIx\fR by
|
||||
\fIy\fR. If \fIy\fR is 0, an error is returned.
|
||||
.TP
|
||||
\fBhypot(\fIx, y\fB)\fR
|
||||
Computes the length of the hypotenuse of a right-angled triangle
|
||||
(\fIx\fR*\fIx\fR+\fIy\fR*\fIy\fR).
|
||||
.TP
|
||||
\fBint(\fIarg\fB)\fR
|
||||
If \fIarg\fR is an integer value, returns \fIarg\fR, otherwise converts
|
||||
\fIarg\fR to integer by truncation and returns the converted value.
|
||||
.TP
|
||||
\fBlog(\fIarg\fB)\fR
|
||||
Returns the natural logarithm of \fIarg\fR. \fIArg\fR must be a
|
||||
positive value.
|
||||
.TP
|
||||
\fBlog10(\fIarg\fB)\fR
|
||||
Returns the base 10 logarithm of \fIarg\fR. \fIArg\fR must be a
|
||||
positive value.
|
||||
.TP
|
||||
\fBpow(\fIx, y\fB)\fR
|
||||
Computes the value of \fIx\fR raised to the power \fIy\fR. If \fIx\fR
|
||||
is negative, \fIy\fR must be an integer value.
|
||||
.TP
|
||||
\fBrand()\fR
|
||||
Returns a floating point number from zero to just less than one or,
|
||||
in mathematical terms, the range [0,1). The seed comes from the
|
||||
@@ -268,26 +218,10 @@ function.
|
||||
If \fIarg\fR is an integer value, returns \fIarg\fR, otherwise converts
|
||||
\fIarg\fR to integer by rounding and returns the converted value.
|
||||
.TP
|
||||
\fBsin(\fIarg\fB)\fR
|
||||
Returns the sine of \fIarg\fR, measured in radians.
|
||||
.TP
|
||||
\fBsinh(\fIarg\fB)\fR
|
||||
Returns the hyperbolic sine of \fIarg\fR. If the result would cause
|
||||
an overflow, an error is returned.
|
||||
.TP
|
||||
\fBsqrt(\fIarg\fB)\fR
|
||||
Returns the square root of \fIarg\fR. \fIArg\fR must be non-negative.
|
||||
.TP
|
||||
\fBsrand(\fIarg\fB)\fR
|
||||
The \fIarg\fR, which must be an integer, is used to reset the seed for
|
||||
the random number generator. Returns the first random number from
|
||||
that seed. Each interpreter has it's own seed.
|
||||
.TP
|
||||
\fBtan(\fIarg\fB)\fR
|
||||
Returns the tangent of \fIarg\fR, measured in radians.
|
||||
.TP
|
||||
\fBtanh(\fIarg\fB)\fR
|
||||
Returns the hyperbolic tangent of \fIarg\fR.
|
||||
.PP
|
||||
In addition to these predefined functions, applications may
|
||||
define additional functions using \fBTcl_CreateMathFunc\fR().
|
||||
|
||||
+58
-21
@@ -1,11 +1,11 @@
|
||||
'\"
|
||||
'\" Copyright (c) 1995-1997 Sun Microsystems, Inc.
|
||||
'\" Copyright (c) 1999 by Scriptics Corporation.
|
||||
'\" Copyright (c) 1998-2000 by 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: http.n,v 1.10 2000/04/09 23:55:54 welch Exp $
|
||||
'\" RCS: @(#) $Id: http.n,v 1.10.2.1 2000/05/31 01:28:56 sandeep Exp $
|
||||
'\"
|
||||
.so man.macros
|
||||
.TH "Http" n 8.3 Tcl "Tcl Built-In Commands"
|
||||
@@ -14,7 +14,7 @@
|
||||
.SH NAME
|
||||
Http \- Client-side implementation of the HTTP/1.0 protocol.
|
||||
.SH SYNOPSIS
|
||||
\fBpackage require http ?2.2?\fP
|
||||
\fBpackage require http ?2.3?\fP
|
||||
.sp
|
||||
\fB::http::config \fI?options?\fR
|
||||
.sp
|
||||
@@ -32,8 +32,12 @@ Http \- Client-side implementation of the HTTP/1.0 protocol.
|
||||
.sp
|
||||
\fB::http::code \fItoken\fR
|
||||
.sp
|
||||
\fB::http::ncode \fItoken\fR
|
||||
.sp
|
||||
\fB::http::data \fItoken\fR
|
||||
.sp
|
||||
\fB::http::error \fItoken\fR
|
||||
.sp
|
||||
\fB::http::cleanup \fItoken\fR
|
||||
.sp
|
||||
\fB::http::register \fIproto port command\fR
|
||||
@@ -57,9 +61,8 @@ Its \fIoptions \fR determine whether a GET, POST, or HEAD transaction
|
||||
is performed.
|
||||
The return value of \fB::http::geturl\fR is a token for the transaction.
|
||||
The value is also the name of an array in the ::http namespace
|
||||
that contains state
|
||||
information about the transaction. The elements of this array are
|
||||
described in the STATE ARRAY section.
|
||||
that contains state information about the transaction. The elements
|
||||
of this array are described in the STATE ARRAY section.
|
||||
.PP
|
||||
If the \fB-command\fP option is specified, then
|
||||
the HTTP operation is done in the background.
|
||||
@@ -262,12 +265,20 @@ any. This sets the \fBstate(status)\fP value to \fIwhy\fP, which defaults to \f
|
||||
\fB::http::wait\fP \fItoken\fP
|
||||
This is a convenience procedure that blocks and waits for the
|
||||
transaction to complete. This only works in trusted code because it
|
||||
uses \fBvwait\fR.
|
||||
uses \fBvwait\fR. Also, it's not useful for the case where
|
||||
\fB::http::geturl\fP is called \fIwithout\fP the \fB-command\fP option
|
||||
because in this case the \fB::http::geturl\fP call doesn't return
|
||||
until the HTTP transaction is complete, and thus there's nothing to
|
||||
wait for.
|
||||
.TP
|
||||
\fB::http::data\fP \fItoken\fP
|
||||
This is a convenience procedure that returns the \fBbody\fP element
|
||||
(i.e., the URL data) of the state array.
|
||||
.TP
|
||||
\fB::http::error\fP \fItoken\fP
|
||||
This is a convenience procedure that returns the \fBerror\fP element
|
||||
of the state array.
|
||||
.TP
|
||||
\fB::http::status\fP \fItoken\fP
|
||||
This is a convenience procedure that returns the \fBstatus\fP element of
|
||||
the state array.
|
||||
@@ -276,15 +287,24 @@ the state array.
|
||||
This is a convenience procedure that returns the \fBhttp\fP element of the
|
||||
state array.
|
||||
.TP
|
||||
\fB::http::ncode\fP \fItoken\fP
|
||||
This is a convenience procedure that returns just the numeric return
|
||||
code (200, 404, etc.) from the \fBhttp\fP element of the state array.
|
||||
.TP
|
||||
\fB::http::size\fP \fItoken\fP
|
||||
This is a convenience procedure that returns the \fBcurrentsize\fP
|
||||
element of the state array.
|
||||
element of the state array, which represents the number of bytes
|
||||
received from the URL in the \fB::http::geturl\fP call.
|
||||
.TP
|
||||
\fB::http::cleanup\fP \fItoken\fP
|
||||
This procedure cleans up the state associated with the connection
|
||||
identified by \fItoken\fP. After this call, the procedures
|
||||
like \fB::http::data\fP cannot be used to get information
|
||||
about the operation.
|
||||
about the operation. It is \fIstrongly\fP recommended that you call
|
||||
this function after you're done with a given HTTP request. Not doing
|
||||
so will result in memory not being freed, and if your app calls
|
||||
\fB::http::geturl\fP enough times, the memory leak could cause a
|
||||
performance hit...or worse.
|
||||
.TP
|
||||
\fB::http::register\fP \fIproto port command\fP
|
||||
This procedure allows one to provide custom HTTP transport types
|
||||
@@ -309,19 +329,36 @@ registered via \fBhttp::register\fR.
|
||||
The \fBhttp::geturl\fP procedure will raise errors in the following cases:
|
||||
invalid command line options,
|
||||
an invalid URL,
|
||||
or a URL on a non-existent host,
|
||||
a URL on a non-existent host,
|
||||
or a URL at a bad port on an existing host.
|
||||
These errors mean that it
|
||||
cannot even start the network transaction.
|
||||
It will also raise an error if it gets an I/O error while
|
||||
writing out the HTTP request header.
|
||||
For synchronous \fB::http::geturl\fP calls (where \fB-command\fP is
|
||||
not specified), it will raise an error if it gets an I/O error while
|
||||
reading the HTTP reply headers or data. Because \fB::http::geturl\fP
|
||||
doesn't return a token in these cases, it does all the required
|
||||
cleanup and there's no issue of your app having to call
|
||||
\fB::http::cleanup\fP.
|
||||
.PP
|
||||
The \fBhttp::wait\fP procedure will raise errors if an I/O error
|
||||
occurs while reading the HTTP reply headers or data. If the
|
||||
\fB-command\fP flag is not passed to \fBhttp::geturl\fP,
|
||||
then it will call \fBhttp::wait\fP and so these errors will
|
||||
occur in \fBhttp::geturl\fP.
|
||||
If you get an error from \fBhttp::wait\fP, you must still call
|
||||
\fBhttp::cleanup\fP to delete the state array.
|
||||
For asynchronous \fB::http::geturl\fP calls, all of the above error
|
||||
situations apply, except that if there's any error while
|
||||
reading the
|
||||
HTTP reply headers or data, no exception is thrown. This is because
|
||||
after writing the HTTP headers, \fB::http::geturl\fP returns, and the
|
||||
rest of the HTTP transaction occurs in the background. The command
|
||||
callback can check if any error occurred during the read by calling
|
||||
\fB::http::status\fP to check the status and if it's \fIerror\fP,
|
||||
calling \fB::http::error\fP to get the error message.
|
||||
.PP
|
||||
Alternatively, if the main program flow reaches a point where it needs
|
||||
to know the result of the asynchronous HTTP request, it can call
|
||||
\fB::http::wait\fP and then check status and error, just as the
|
||||
callback does.
|
||||
.PP
|
||||
In any case, you must still call
|
||||
\fBhttp::cleanup\fP to delete the state array when you're done.
|
||||
.PP
|
||||
There are other possible results of the HTTP transaction
|
||||
determined by examining the status from \fBhttp::status\fP.
|
||||
@@ -336,12 +373,11 @@ procedure returns a value like "HTTP 404 File not found".
|
||||
.TP
|
||||
eof
|
||||
If the server closes the socket without replying, then no error
|
||||
is rasied, but the status of the transaction will be \fBeof\fP.
|
||||
is raised, but the status of the transaction will be \fBeof\fP.
|
||||
.TP
|
||||
error
|
||||
In this case \fBhttp::wait\fP should have raised an error.
|
||||
The error message will also be stored in the \fBerror\fP status
|
||||
array element.
|
||||
array element, accessible via \fB::http::error\fP.
|
||||
.PP
|
||||
Another error possibility is that \fBhttp::geturl\fP is unable to
|
||||
write all the post query data to the server before the server
|
||||
@@ -424,7 +460,8 @@ the post query data to the server.
|
||||
.TP
|
||||
\fBstatus\fR
|
||||
Either \fBok\fR, for successful completion, \fBreset\fR for
|
||||
user-reset, or \fBerror\fR for an error condition. During the
|
||||
user-reset, \fBtimeout\fP if a timeout occurred before the transaction
|
||||
could complete, or \fBerror\fR for an error condition. During the
|
||||
transaction this value is the empty string.
|
||||
.TP
|
||||
\fBtotalsize\fR
|
||||
|
||||
+57
-72
@@ -5,20 +5,18 @@
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
'\" RCS: @(#) $Id: library.n,v 1.13 2000/04/28 00:47:49 ericm Exp $
|
||||
'\" RCS: @(#) $Id: library.n,v 1.11 2000/04/15 18:42:56 ericm Exp $
|
||||
.so man.macros
|
||||
.TH library n "8.0" Tcl "Tcl Built-In Commands"
|
||||
.BS
|
||||
.SH NAME
|
||||
auto_execok, auto_import, auto_load, auto_mkindex, auto_mkindex_old, auto_qualify, auto_reset, tcl_findLibrary, parray, tcl_endOfWord, tcl_startOfNextWord, tcl_startOfPreviousWord, tcl_wordBreakAfter, tcl_wordBreakBefore \- standard library of Tcl procedures
|
||||
library \- standard library of Tcl procedures
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fBauto_execok \fIcmd\fR
|
||||
\fBauto_import \fIpattern\fR
|
||||
\fBauto_load \fIcmd\fR
|
||||
\fBauto_mkindex \fIdir pattern pattern ...\fR
|
||||
\fBauto_mkindex_old \fIdir pattern pattern ...\fR
|
||||
\fBauto_qualify \fIcommand namespace\fR
|
||||
\fBauto_reset\fR
|
||||
\fBtcl_findLibrary \fIbasename version patch initScript enVarName varName\fR
|
||||
\fBparray \fIarrayName\fR
|
||||
@@ -75,61 +73,65 @@ remembers information about previous searches in an array named
|
||||
same \fIcmd\fR. The command \fBauto_reset\fR may be used to force
|
||||
\fBauto_execok\fR to forget its cached information.
|
||||
.TP
|
||||
\fBauto_import \fIpattern\fR
|
||||
\fBAuto_import\fR is invoked during \fBnamespace import\fR to see if
|
||||
the imported commands specified by \fIpattern\fR reside in an
|
||||
autoloaded library. If so, the commands are loaded so that they will
|
||||
be available to the interpreter for creating the import links. If the
|
||||
commands do not reside in an autoloaded library, \fBauto_import\fR
|
||||
does nothing.
|
||||
.TP
|
||||
\fBauto_load \fIcmd\fR
|
||||
This command attempts to load the definition for a Tcl command named
|
||||
\fIcmd\fR. To do this, it searches an \fIauto-load path\fR, which is
|
||||
a list of one or more directories. The auto-load path is given by the
|
||||
global variable \fB$auto_path\fR if it exists. If there is no
|
||||
\fB$auto_path\fR variable, then the TCLLIBPATH environment variable is
|
||||
used, if it exists. Otherwise the auto-load path consists of just the
|
||||
Tcl library directory. Within each directory in the auto-load path
|
||||
there must be a file \fBtclIndex\fR that describes one or more
|
||||
commands defined in that directory and a script to evaluate to load
|
||||
each of the commands. The \fBtclIndex\fR file should be generated
|
||||
with the \fBauto_mkindex\fR command. If \fIcmd\fR is found in an
|
||||
index file, then the appropriate script is evaluated to create the
|
||||
command. The \fBauto_load\fR command returns 1 if \fIcmd\fR was
|
||||
successfully created. The command returns 0 if there was no index
|
||||
entry for \fIcmd\fR or if the script didn't actually define \fIcmd\fR
|
||||
(e.g. because index information is out of date). If an error occurs
|
||||
while processing the script, then that error is returned.
|
||||
\fBAuto_load\fR only reads the index information once and saves it in
|
||||
the array \fBauto_index\fR; future calls to \fBauto_load\fR check for
|
||||
\fIcmd\fR in the array rather than re-reading the index files. The
|
||||
cached index information may be deleted with the command
|
||||
\fBauto_reset\fR. This will force the next \fBauto_load\fR command to
|
||||
reload the index database from disk.
|
||||
\fIcmd\fR.
|
||||
To do this, it searches an \fIauto-load path\fR, which is a list of
|
||||
one or more directories.
|
||||
The auto-load path is given by the global variable \fB$auto_path\fR
|
||||
if it exists.
|
||||
If there is no \fB$auto_path\fR variable, then the TCLLIBPATH environment
|
||||
variable is used, if it exists.
|
||||
Otherwise the auto-load path consists of just the Tcl library directory.
|
||||
Within each directory in the auto-load path there must be a file
|
||||
\fBtclIndex\fR that describes one
|
||||
or more commands defined in that directory
|
||||
and a script to evaluate to load each of the commands.
|
||||
The \fBtclIndex\fR file should be generated with the
|
||||
\fBauto_mkindex\fR command.
|
||||
If \fIcmd\fR is found in an index file, then the appropriate
|
||||
script is evaluated to create the command.
|
||||
The \fBauto_load\fR command returns 1 if \fIcmd\fR was successfully
|
||||
created.
|
||||
The command returns 0 if there was no index entry for \fIcmd\fR
|
||||
or if the script didn't actually define \fIcmd\fR (e.g. because
|
||||
index information is out of date).
|
||||
If an error occurs while processing the script, then that error
|
||||
is returned.
|
||||
\fBAuto_load\fR only reads the index information once and saves it
|
||||
in the array \fBauto_index\fR; future calls to \fBauto_load\fR
|
||||
check for \fIcmd\fR in the array rather than re-reading the index
|
||||
files.
|
||||
The cached index information may be deleted with the command
|
||||
\fBauto_reset\fR.
|
||||
This will force the next \fBauto_load\fR command to reload the
|
||||
index database from disk.
|
||||
.TP
|
||||
\fBauto_mkindex \fIdir pattern pattern ...\fR
|
||||
Generates an index suitable for use by \fBauto_load\fR. The command
|
||||
searches \fIdir\fR for all files whose names match any of the
|
||||
\fIpattern\fR arguments (matching is done with the \fBglob\fR
|
||||
command), generates an index of all the Tcl command procedures defined
|
||||
in all the matching files, and stores the index information in a file
|
||||
named \fBtclIndex\fR in \fIdir\fR. If no pattern is given a pattern of
|
||||
\fB*.tcl\fR will be assumed. For example, the command
|
||||
Generates an index suitable for use by \fBauto_load\fR.
|
||||
The command searches \fIdir\fR for all files whose names match
|
||||
any of the \fIpattern\fR arguments
|
||||
(matching is done with the \fBglob\fR command),
|
||||
generates an index of all the Tcl command
|
||||
procedures defined in all the matching files, and stores the
|
||||
index information in a file named \fBtclIndex\fR in \fIdir\fR.
|
||||
If no pattern is given a pattern of \fB*.tcl\fR will be assumed.
|
||||
For example, the command
|
||||
.RS
|
||||
.CS
|
||||
\fBauto_mkindex foo *.tcl\fR
|
||||
.CE
|
||||
.LP
|
||||
will read all the \fB.tcl\fR files in subdirectory \fBfoo\fR and
|
||||
generate a new index file \fBfoo/tclIndex\fR.
|
||||
will read all the \fB.tcl\fR files in subdirectory \fBfoo\fR
|
||||
and generate a new index file \fBfoo/tclIndex\fR.
|
||||
.PP
|
||||
\fBAuto_mkindex\fR parses the Tcl scripts by sourcing them into a
|
||||
slave interpreter and monitoring the proc and namespace commands that
|
||||
are executed. Extensions can use the (undocumented)
|
||||
auto_mkindex_parser package to register other commands that can
|
||||
contribute to the auto_load index. You will have to read through
|
||||
auto.tcl to see how this works.
|
||||
\fBAuto_mkindex\fR parses the Tcl scripts by sourcing them
|
||||
into a slave interpreter and monitoring the proc and
|
||||
namespace commands that are executed.
|
||||
Extensions can use the (undocumented)
|
||||
auto_mkindex_parser package to register other commands that
|
||||
can contribute to the auto_load index.
|
||||
You will have to read through auto.tcl to see how this works.
|
||||
.PP
|
||||
\fBAuto_mkindex_old\fR parses the Tcl scripts in a relatively
|
||||
unsophisticated way: if any line contains the word \fBproc\fR
|
||||
@@ -145,29 +147,12 @@ code or procedure names with special characters like \fB$\fR,
|
||||
.TP
|
||||
\fBauto_reset\fR
|
||||
Destroys all the information cached by \fBauto_execok\fR and
|
||||
\fBauto_load\fR. This information will be re-read from disk the next
|
||||
time it is needed. \fBAuto_reset\fR also deletes any procedures
|
||||
listed in the auto-load index, so that fresh copies of them will be
|
||||
loaded the next time that they're used.
|
||||
.TP
|
||||
\fBauto_qualify \fIcommand namespace\fR
|
||||
Computes a list of fully qualified names for \fIcommand\fR. This list
|
||||
mirrors the path a standard Tcl interpreter follows for command
|
||||
lookups: first it looks for the command in the current namespace, and
|
||||
then in the global namespace. Accordingly, if \fIcommand\fR is
|
||||
relative and \fInamespace\fR is not \fB::\fR, the list returned has
|
||||
two elements: \fIcommand\fR scoped by \fInamespace\fR, as if it were
|
||||
a command in the \fInamespace\fR namespace; and \fIcommand\fR as if it
|
||||
were a command in the global namespace. Otherwise, if either
|
||||
\fIcommand\fR is absolute (it begins with \fB::\fR), or
|
||||
\fInamespace\fR is \fB::\fR, the list contains only \fIcommand\fR as
|
||||
if it were a command in the global namespace.
|
||||
.RS
|
||||
.PP
|
||||
\fBAuto_qualify\fR is used by the auto-loading facilities in Tcl, both
|
||||
for producing auto-loading indexes such as \fIpkgIndex.tcl\fR, and for
|
||||
performing the actual auto-loading of functions at runtime.
|
||||
.RE
|
||||
\fBauto_load\fR.
|
||||
This information will be re-read from disk the next time it is
|
||||
needed.
|
||||
\fBAuto_reset\fR also deletes any procedures listed in the auto-load
|
||||
index, so that fresh copies of them will be loaded the next time
|
||||
that they're used.
|
||||
.TP
|
||||
\fBtcl_findLibrary \fIbasename version patch initScript enVarName varName\fR
|
||||
This is a standard search procedure for use by extensions during
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
'\"
|
||||
'\" Copyright (c) 1992-1999 by Karl Lehenbauer and Mark Diekhans
|
||||
'\" Copyright (c) 2000 by Scriptics Corporation.
|
||||
'\" All rights reserved.
|
||||
'\"
|
||||
'\" RCS: @(#) $Id: memory.n,v 1.2 2000/04/28 00:47:49 ericm Exp $
|
||||
'\"
|
||||
.so man.macros
|
||||
.TH memory n 8.1 Tcl "Tcl Built-In Commands"
|
||||
.BS
|
||||
.SH NAME
|
||||
memory \- Control Tcl memory debugging capabilities.
|
||||
.SH SYNOPSIS
|
||||
\fBmemory \fIoption \fR?\fIarg arg ...\fR?
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The \fBmemory\fR command gives the Tcl developer control of Tcl's memory
|
||||
debugging capabilities. The memory command has several suboptions, which are
|
||||
described below. It is only available when Tcl has been compiled with
|
||||
memory debugging enabled (when \fBTCL_MEM_DEBUG\fR is defined at
|
||||
compile time).
|
||||
.TP
|
||||
\fBmemory info\fR
|
||||
Produces a report containing the total allocations and frees since
|
||||
Tcl began, the current packets allocated (the current
|
||||
number of calls to \fBckalloc\fR not met by a corresponding call
|
||||
to \fBckfree\fR), the current bytes allocated, and the maximum number
|
||||
of packets and bytes allocated.
|
||||
.TP
|
||||
\fBmemory trace [on|off]\fR
|
||||
.br
|
||||
Turns memory tracing on or off. When memory tracing is on, every call
|
||||
to \fBckalloc\fR causes a line of trace information to be written to
|
||||
\fIstderr\fR, consisting of the word \fIckalloc\fR, followed by the
|
||||
address returned, the amount of memory allocated, and the C filename
|
||||
and line number of the code performing the allocation. For example:
|
||||
.CS
|
||||
ckalloc 40e478 98 tclProc.c 1406
|
||||
.CE
|
||||
Calls to \fBckfree\fR are traced in the same manner.
|
||||
.TP
|
||||
\fBmemory validate [on|off]\fR
|
||||
Turns memory validation on or off. When memory validation is enabled,
|
||||
on every call to \fBckalloc\fR or \fBckfree\fR, the guard zones are
|
||||
checked for every piece of memory currently in existence that was
|
||||
allocated by \fBckalloc\fR. This has a large performance impact and
|
||||
should only be used when overwrite problems are strongly suspected.
|
||||
The advantage of enabling memory validation is that a guard zone
|
||||
overwrite can be detected on the first call to \fBckalloc\fR or
|
||||
\fBckfree\fR after the overwrite occurred, rather than when the
|
||||
specific memory with the overwritten guard zone(s) is freed, which may
|
||||
occur long after the overwrite occurred.
|
||||
.TP
|
||||
\fBmemory trace_on_at_malloc\fR \fIcount\fR
|
||||
Enable memory tracing after \fIcount\fR \fBckalloc\fR's have been performed.
|
||||
For example, if you enter \fBmemory trace_on_at_malloc 100\fR,
|
||||
after the 100th call to \fBckalloc\fR, memory trace information will begin
|
||||
being displayed for all allocations and frees. Since there can be a lot
|
||||
of memory activity before a problem occurs, judicious use of this option
|
||||
can reduce the slowdown caused by tracing (and the amount of trace information
|
||||
produced), if you can identify a number of allocations that occur before
|
||||
the problem sets in. The current number of memory allocations that have
|
||||
occurred since Tcl started is printed on a guard zone failure.
|
||||
.TP
|
||||
\fBmemory break_on_malloc\fR \fIcount\fR
|
||||
After the \fBcount\fR allocations have been performed, \fBckalloc\fR's
|
||||
output a message to this effect and that it is now attempting to enter
|
||||
the C debugger. Tcl will then issue a \fISIGINT\fR signal against itself.
|
||||
If you are running Tcl under a C debugger, it should then enter the debugger
|
||||
command mode.
|
||||
.TP
|
||||
\fB memory display\fR \fIfile\fR
|
||||
Write a list of all currently allocated memory to the specified file.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
ckalloc, ckfree, Tcl_ValidateAllMemory, Tcl_DumpActiveMemory, TCL_MEM_DEBUG
|
||||
|
||||
.SH KEYWORDS
|
||||
memory, debug
|
||||
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
'\" RCS: @(#) $Id: scan.n,v 1.4 1999/11/19 06:33:59 hobbs Exp $
|
||||
'\" RCS: @(#) $Id: scan.n,v 1.4.2.1 2000/06/14 01:38:00 hershey Exp $
|
||||
'\"
|
||||
.so man.macros
|
||||
.TH scan n 8.3 Tcl "Tcl Built-In Commands"
|
||||
@@ -14,7 +14,7 @@
|
||||
.SH NAME
|
||||
scan \- Parse string using conversion specifiers in the style of sscanf
|
||||
.SH SYNOPSIS
|
||||
\fBscan \fIstring format varName \fR?\fIvarName ...\fR?
|
||||
\fBscan \fIstring format \fR?\fIvarName ...\fR?
|
||||
.BE
|
||||
|
||||
.SH INTRODUCTION
|
||||
|
||||
+62
-2
@@ -10,7 +10,7 @@
|
||||
# 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.33 2000/04/09 16:04:17 kupries Exp $
|
||||
# RCS: @(#) $Id: tcl.decls,v 1.33.2.1 2000/07/27 01:39:14 hobbs Exp $
|
||||
|
||||
library tcl
|
||||
|
||||
@@ -987,7 +987,7 @@ declare 281 generic {
|
||||
int mask, Tcl_Channel prevChan)
|
||||
}
|
||||
declare 282 generic {
|
||||
void Tcl_UnstackChannel(Tcl_Interp *interp, Tcl_Channel chan)
|
||||
int Tcl_UnstackChannel(Tcl_Interp *interp, Tcl_Channel chan)
|
||||
}
|
||||
declare 283 generic {
|
||||
Tcl_Channel Tcl_GetStackedChannel(Tcl_Channel chan)
|
||||
@@ -1358,6 +1358,66 @@ declare 393 generic {
|
||||
ClientData clientData, int stackSize, int flags)
|
||||
}
|
||||
|
||||
declare 394 generic {
|
||||
int Tcl_ReadRaw (Tcl_Channel chan, char *dst, int bytesToRead)
|
||||
}
|
||||
declare 395 generic {
|
||||
int Tcl_WriteRaw (Tcl_Channel chan, char *src, int srcLen)
|
||||
}
|
||||
declare 396 generic {
|
||||
Tcl_Channel Tcl_GetTopChannel (Tcl_Channel chan)
|
||||
}
|
||||
declare 397 generic {
|
||||
int Tcl_ChannelBuffered (Tcl_Channel chan)
|
||||
}
|
||||
declare 398 generic {
|
||||
char * Tcl_ChannelName(Tcl_ChannelType *chanTypePtr)
|
||||
}
|
||||
declare 399 generic {
|
||||
Tcl_ChannelTypeVersion Tcl_ChannelVersion(Tcl_ChannelType *chanTypePtr)
|
||||
}
|
||||
declare 400 generic {
|
||||
Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc(Tcl_ChannelType \
|
||||
*chanTypePtr)
|
||||
}
|
||||
declare 401 generic {
|
||||
Tcl_DriverCloseProc * Tcl_ChannelCloseProc(Tcl_ChannelType *chanTypePtr)
|
||||
}
|
||||
declare 402 generic {
|
||||
Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc(Tcl_ChannelType *chanTypePtr)
|
||||
}
|
||||
declare 403 generic {
|
||||
Tcl_DriverInputProc * Tcl_ChannelInputProc(Tcl_ChannelType *chanTypePtr)
|
||||
}
|
||||
declare 404 generic {
|
||||
Tcl_DriverOutputProc * Tcl_ChannelOutputProc(Tcl_ChannelType *chanTypePtr)
|
||||
}
|
||||
declare 405 generic {
|
||||
Tcl_DriverSeekProc * Tcl_ChannelSeekProc(Tcl_ChannelType *chanTypePtr)
|
||||
}
|
||||
declare 406 generic {
|
||||
Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc(Tcl_ChannelType \
|
||||
*chanTypePtr)
|
||||
}
|
||||
declare 407 generic {
|
||||
Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc(Tcl_ChannelType \
|
||||
*chanTypePtr)
|
||||
}
|
||||
declare 408 generic {
|
||||
Tcl_DriverWatchProc * Tcl_ChannelWatchProc(Tcl_ChannelType *chanTypePtr)
|
||||
}
|
||||
declare 409 generic {
|
||||
Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc(Tcl_ChannelType \
|
||||
*chanTypePtr)
|
||||
}
|
||||
declare 410 generic {
|
||||
Tcl_DriverFlushProc * Tcl_ChannelFlushProc(Tcl_ChannelType *chanTypePtr)
|
||||
}
|
||||
declare 411 generic {
|
||||
Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc(Tcl_ChannelType \
|
||||
*chanTypePtr)
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
|
||||
# Define the platform specific public Tcl interface. These functions are
|
||||
|
||||
+46
-22
@@ -12,7 +12,7 @@
|
||||
* 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.70 2000/04/19 08:32:44 hobbs Exp $
|
||||
* RCS: @(#) $Id: tcl.h,v 1.70.2.1 2000/07/27 01:39:14 hobbs Exp $
|
||||
*/
|
||||
|
||||
#ifndef _TCL
|
||||
@@ -59,10 +59,10 @@ extern "C" {
|
||||
#define TCL_MAJOR_VERSION 8
|
||||
#define TCL_MINOR_VERSION 3
|
||||
#define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE
|
||||
#define TCL_RELEASE_SERIAL 1
|
||||
#define TCL_RELEASE_SERIAL 2
|
||||
|
||||
#define TCL_VERSION "8.3"
|
||||
#define TCL_PATCH_LEVEL "8.3.1"
|
||||
#define TCL_PATCH_LEVEL "8.3.2"
|
||||
|
||||
/*
|
||||
* The following definitions set up the proper options for Windows
|
||||
@@ -386,6 +386,7 @@ typedef struct Tcl_ThreadId_ *Tcl_ThreadId;
|
||||
typedef struct Tcl_TimerToken_ *Tcl_TimerToken;
|
||||
typedef struct Tcl_Trace_ *Tcl_Trace;
|
||||
typedef struct Tcl_Var_ *Tcl_Var;
|
||||
typedef struct Tcl_ChannelTypeVersion_ *Tcl_ChannelTypeVersion;
|
||||
|
||||
/*
|
||||
* Definition of the interface to procedures implementing threads.
|
||||
@@ -1140,7 +1141,7 @@ typedef int (Tcl_WaitForEventProc) _ANSI_ARGS_((Tcl_Time *timePtr));
|
||||
*/
|
||||
|
||||
#define TCL_CLOSE_READ (1<<1)
|
||||
#define TCL_CLOSE_WRITE (1<<2)
|
||||
#define TCL_CLOSE_WRITE (1<<2)
|
||||
|
||||
/*
|
||||
* Value to use as the closeProc for a channel that supports the
|
||||
@@ -1149,6 +1150,13 @@ typedef int (Tcl_WaitForEventProc) _ANSI_ARGS_((Tcl_Time *timePtr));
|
||||
|
||||
#define TCL_CLOSE2PROC ((Tcl_DriverCloseProc *)1)
|
||||
|
||||
/*
|
||||
* 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)
|
||||
|
||||
/*
|
||||
* Typedefs for the various operations in a channel type:
|
||||
*/
|
||||
@@ -1176,6 +1184,10 @@ typedef void (Tcl_DriverWatchProc) _ANSI_ARGS_((
|
||||
typedef int (Tcl_DriverGetHandleProc) _ANSI_ARGS_((
|
||||
ClientData instanceData, int direction,
|
||||
ClientData *handlePtr));
|
||||
typedef int (Tcl_DriverFlushProc) _ANSI_ARGS_((
|
||||
ClientData instanceData));
|
||||
typedef int (Tcl_DriverHandlerProc) _ANSI_ARGS_((
|
||||
ClientData instanceData, int interestMask));
|
||||
|
||||
/*
|
||||
* The following declarations either map ckalloc and ckfree to
|
||||
@@ -1224,38 +1236,50 @@ typedef enum Tcl_EolTranslation {
|
||||
* One such structure exists for each type (kind) of channel.
|
||||
* It collects together in one place all the functions that are
|
||||
* part of the specific channel type.
|
||||
*
|
||||
* It is recommend that the Tcl_Channel* functions are used to access
|
||||
* elements of this structure, instead of direct accessing.
|
||||
*/
|
||||
|
||||
typedef struct Tcl_ChannelType {
|
||||
char *typeName; /* The name of the channel type in Tcl
|
||||
* commands. This storage is owned by
|
||||
* channel type. */
|
||||
Tcl_DriverBlockModeProc *blockModeProc;
|
||||
/* Set blocking mode for the
|
||||
* raw channel. May be NULL. */
|
||||
* commands. This storage is owned by
|
||||
* channel type. */
|
||||
Tcl_ChannelTypeVersion version; /* Version of the channel type. */
|
||||
Tcl_DriverCloseProc *closeProc; /* Procedure to call to close the
|
||||
* channel, or TCL_CLOSE2PROC if the
|
||||
* close2Proc should be used
|
||||
* instead. */
|
||||
* channel, or TCL_CLOSE2PROC if the
|
||||
* close2Proc should be used
|
||||
* instead. */
|
||||
Tcl_DriverInputProc *inputProc; /* Procedure to call for input
|
||||
* on channel. */
|
||||
* on channel. */
|
||||
Tcl_DriverOutputProc *outputProc; /* Procedure to call for output
|
||||
* on channel. */
|
||||
* on channel. */
|
||||
Tcl_DriverSeekProc *seekProc; /* Procedure to call to seek
|
||||
* on the channel. May be NULL. */
|
||||
* on the channel. May be NULL. */
|
||||
Tcl_DriverSetOptionProc *setOptionProc;
|
||||
/* Set an option on a channel. */
|
||||
/* Set an option on a channel. */
|
||||
Tcl_DriverGetOptionProc *getOptionProc;
|
||||
/* Get an option from a channel. */
|
||||
/* Get an option from a channel. */
|
||||
Tcl_DriverWatchProc *watchProc; /* Set up the notifier to watch
|
||||
* for events on this channel. */
|
||||
* for events on this channel. */
|
||||
Tcl_DriverGetHandleProc *getHandleProc;
|
||||
/* Get an OS handle from the channel
|
||||
* or NULL if not supported. */
|
||||
Tcl_DriverClose2Proc *close2Proc; /* Procedure to call to close the
|
||||
* or NULL if not supported. */
|
||||
Tcl_DriverClose2Proc *close2Proc; /* Procedure to call to close the
|
||||
* channel if the device supports
|
||||
* closing the read & write sides
|
||||
* independently. */
|
||||
Tcl_DriverBlockModeProc *blockModeProc;
|
||||
/* Set blocking mode for the
|
||||
* raw channel. May be NULL. */
|
||||
/*
|
||||
* Only valid in TCL_CHANNEL_VERSION_2 channels
|
||||
*/
|
||||
Tcl_DriverFlushProc *flushProc; /* Procedure to call to flush a
|
||||
* channel. May be NULL. */
|
||||
Tcl_DriverHandlerProc *handlerProc; /* Procedure to call to handle a
|
||||
* channel event. This will be passed
|
||||
* up the stacked channel chain. */
|
||||
} Tcl_ChannelType;
|
||||
|
||||
/*
|
||||
@@ -1264,8 +1288,8 @@ typedef struct Tcl_ChannelType {
|
||||
* as arguments to the blockModeProc procedure in the above structure.
|
||||
*/
|
||||
|
||||
#define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */
|
||||
#define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking
|
||||
#define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */
|
||||
#define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking
|
||||
* mode. */
|
||||
|
||||
/*
|
||||
|
||||
+22
-55
@@ -13,7 +13,7 @@
|
||||
*
|
||||
* This code contributed by Karl Lehenbauer and Mark Diekhans
|
||||
*
|
||||
* RCS: @(#) $Id: tclCkalloc.c,v 1.8 2000/04/27 01:47:01 ericm Exp $
|
||||
* RCS: @(#) $Id: tclCkalloc.c,v 1.7 1999/11/19 06:34:23 hobbs Exp $
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
@@ -179,34 +179,20 @@ TclDumpMemoryInfo(outFile)
|
||||
maximum_bytes_malloced);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* ValidateMemory --
|
||||
*
|
||||
* Validate memory guard zones for a particular chunk of allocated
|
||||
* memory.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Prints validation information about the allocated memory to stderr.
|
||||
* Procedure to validate allocted memory guard zones.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ValidateMemory(memHeaderP, file, line, nukeGuards)
|
||||
struct mem_header *memHeaderP; /* Memory chunk to validate */
|
||||
char *file; /* File containing the call to
|
||||
* Tcl_ValidateAllMemory */
|
||||
int line; /* Line number of call to
|
||||
* Tcl_ValidateAllMemory */
|
||||
int nukeGuards; /* If non-zero, indicates that the
|
||||
* memory guards are to be reset to 0
|
||||
* after they have been printed */
|
||||
struct mem_header *memHeaderP;
|
||||
char *file;
|
||||
int line;
|
||||
int nukeGuards;
|
||||
{
|
||||
unsigned char *hiPtr;
|
||||
int idx;
|
||||
@@ -267,21 +253,14 @@ ValidateMemory(memHeaderP, file, line, nukeGuards)
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_ValidateAllMemory --
|
||||
*
|
||||
* Validate memory guard regions for all allocated memory.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Displays memory validation information to stderr.
|
||||
* Validates guard regions for all allocated memory.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
Tcl_ValidateAllMemory (file, line)
|
||||
char *file; /* File from which Tcl_ValidateAllMemory was called */
|
||||
int line; /* Line number of call to Tcl_ValidateAllMemory */
|
||||
char *file;
|
||||
int line;
|
||||
{
|
||||
struct mem_header *memScanP;
|
||||
|
||||
@@ -299,18 +278,16 @@ Tcl_ValidateAllMemory (file, line)
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_DumpActiveMemory --
|
||||
*
|
||||
* Displays all allocated memory to a file; if no filename is given,
|
||||
* information will be written to stderr.
|
||||
* Displays all allocated memory to stderr.
|
||||
*
|
||||
* Results:
|
||||
* Return TCL_ERROR if an error accessing the file occures, `errno'
|
||||
* will have the file error number left in it.
|
||||
* Return TCL_ERROR if an error accessing the file occures, `errno'
|
||||
* will have the file error number left in it.
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
Tcl_DumpActiveMemory (fileName)
|
||||
char *fileName; /* Name of the file to write info to */
|
||||
char *fileName;
|
||||
{
|
||||
FILE *fileP;
|
||||
struct mem_header *memScanP;
|
||||
@@ -620,14 +597,13 @@ Tcl_Realloc(ptr, size)
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* MemoryCmd --
|
||||
* Implements the Tcl "memory" command, which provides Tcl-level
|
||||
* control of Tcl memory debugging information.
|
||||
* memory info
|
||||
* memory display
|
||||
* memory break_on_malloc count
|
||||
* memory trace_on_at_malloc count
|
||||
* memory trace on|off
|
||||
* memory validate on|off
|
||||
* Implements the TCL memory command:
|
||||
* memory info
|
||||
* memory display
|
||||
* break_on_malloc count
|
||||
* trace_on_at_malloc count
|
||||
* trace on|off
|
||||
* validate on|off
|
||||
*
|
||||
* Results:
|
||||
* Standard TCL results.
|
||||
@@ -793,22 +769,13 @@ CheckmemCmd(clientData, interp, argc, argv)
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_InitMemory --
|
||||
*
|
||||
* Create the "memory" and "checkmem" commands in the given
|
||||
* interpreter.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* New commands are added to the interpreter.
|
||||
* Initialize the memory command.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
Tcl_InitMemory(interp)
|
||||
Tcl_Interp *interp; /* Interpreter in which commands should be added */
|
||||
Tcl_Interp *interp;
|
||||
{
|
||||
TclInitDbCkalloc();
|
||||
Tcl_CreateCommand (interp, "memory", MemoryCmd, (ClientData) NULL,
|
||||
|
||||
+145
-3
@@ -8,7 +8,7 @@
|
||||
* 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.34 2000/04/09 16:04:17 kupries Exp $
|
||||
* RCS: @(#) $Id: tclDecls.h,v 1.34.2.1 2000/07/27 01:39:15 hobbs Exp $
|
||||
*/
|
||||
|
||||
#ifndef _TCLDECLS
|
||||
@@ -909,7 +909,7 @@ EXTERN Tcl_Channel Tcl_StackChannel _ANSI_ARGS_((Tcl_Interp * interp,
|
||||
ClientData instanceData, int mask,
|
||||
Tcl_Channel prevChan));
|
||||
/* 282 */
|
||||
EXTERN void Tcl_UnstackChannel _ANSI_ARGS_((Tcl_Interp * interp,
|
||||
EXTERN int Tcl_UnstackChannel _ANSI_ARGS_((Tcl_Interp * interp,
|
||||
Tcl_Channel chan));
|
||||
/* 283 */
|
||||
EXTERN Tcl_Channel Tcl_GetStackedChannel _ANSI_ARGS_((Tcl_Channel chan));
|
||||
@@ -1228,6 +1228,58 @@ EXTERN int Tcl_CreateThread _ANSI_ARGS_((Tcl_ThreadId * idPtr,
|
||||
Tcl_ThreadCreateProc proc,
|
||||
ClientData clientData, int stackSize,
|
||||
int flags));
|
||||
/* 394 */
|
||||
EXTERN int Tcl_ReadRaw _ANSI_ARGS_((Tcl_Channel chan,
|
||||
char * dst, int bytesToRead));
|
||||
/* 395 */
|
||||
EXTERN int Tcl_WriteRaw _ANSI_ARGS_((Tcl_Channel chan,
|
||||
char * src, int srcLen));
|
||||
/* 396 */
|
||||
EXTERN Tcl_Channel Tcl_GetTopChannel _ANSI_ARGS_((Tcl_Channel chan));
|
||||
/* 397 */
|
||||
EXTERN int Tcl_ChannelBuffered _ANSI_ARGS_((Tcl_Channel chan));
|
||||
/* 398 */
|
||||
EXTERN char * Tcl_ChannelName _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 399 */
|
||||
EXTERN Tcl_ChannelTypeVersion Tcl_ChannelVersion _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 400 */
|
||||
EXTERN Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 401 */
|
||||
EXTERN Tcl_DriverCloseProc * Tcl_ChannelCloseProc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 402 */
|
||||
EXTERN Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 403 */
|
||||
EXTERN Tcl_DriverInputProc * Tcl_ChannelInputProc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 404 */
|
||||
EXTERN Tcl_DriverOutputProc * Tcl_ChannelOutputProc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 405 */
|
||||
EXTERN Tcl_DriverSeekProc * Tcl_ChannelSeekProc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 406 */
|
||||
EXTERN Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 407 */
|
||||
EXTERN Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 408 */
|
||||
EXTERN Tcl_DriverWatchProc * Tcl_ChannelWatchProc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 409 */
|
||||
EXTERN Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 410 */
|
||||
EXTERN Tcl_DriverFlushProc * Tcl_ChannelFlushProc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
/* 411 */
|
||||
EXTERN Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc _ANSI_ARGS_((
|
||||
Tcl_ChannelType * chanTypePtr));
|
||||
|
||||
typedef struct TclStubHooks {
|
||||
struct TclPlatStubs *tclPlatStubs;
|
||||
@@ -1577,7 +1629,7 @@ typedef struct TclStubs {
|
||||
void (*tcl_GetVersion) _ANSI_ARGS_((int * major, int * minor, int * patchLevel, int * type)); /* 279 */
|
||||
void (*tcl_InitMemory) _ANSI_ARGS_((Tcl_Interp * interp)); /* 280 */
|
||||
Tcl_Channel (*tcl_StackChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_ChannelType * typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 281 */
|
||||
void (*tcl_UnstackChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 282 */
|
||||
int (*tcl_UnstackChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 282 */
|
||||
Tcl_Channel (*tcl_GetStackedChannel) _ANSI_ARGS_((Tcl_Channel chan)); /* 283 */
|
||||
void *reserved284;
|
||||
void *reserved285;
|
||||
@@ -1689,6 +1741,24 @@ typedef struct TclStubs {
|
||||
void (*tcl_ConditionFinalize) _ANSI_ARGS_((Tcl_Condition * condPtr)); /* 391 */
|
||||
void (*tcl_MutexFinalize) _ANSI_ARGS_((Tcl_Mutex * mutex)); /* 392 */
|
||||
int (*tcl_CreateThread) _ANSI_ARGS_((Tcl_ThreadId * idPtr, Tcl_ThreadCreateProc proc, ClientData clientData, int stackSize, int flags)); /* 393 */
|
||||
int (*tcl_ReadRaw) _ANSI_ARGS_((Tcl_Channel chan, char * dst, int bytesToRead)); /* 394 */
|
||||
int (*tcl_WriteRaw) _ANSI_ARGS_((Tcl_Channel chan, char * src, int srcLen)); /* 395 */
|
||||
Tcl_Channel (*tcl_GetTopChannel) _ANSI_ARGS_((Tcl_Channel chan)); /* 396 */
|
||||
int (*tcl_ChannelBuffered) _ANSI_ARGS_((Tcl_Channel chan)); /* 397 */
|
||||
char * (*tcl_ChannelName) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 398 */
|
||||
Tcl_ChannelTypeVersion (*tcl_ChannelVersion) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 399 */
|
||||
Tcl_DriverBlockModeProc * (*tcl_ChannelBlockModeProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 400 */
|
||||
Tcl_DriverCloseProc * (*tcl_ChannelCloseProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 401 */
|
||||
Tcl_DriverClose2Proc * (*tcl_ChannelClose2Proc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 402 */
|
||||
Tcl_DriverInputProc * (*tcl_ChannelInputProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 403 */
|
||||
Tcl_DriverOutputProc * (*tcl_ChannelOutputProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 404 */
|
||||
Tcl_DriverSeekProc * (*tcl_ChannelSeekProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 405 */
|
||||
Tcl_DriverSetOptionProc * (*tcl_ChannelSetOptionProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 406 */
|
||||
Tcl_DriverGetOptionProc * (*tcl_ChannelGetOptionProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 407 */
|
||||
Tcl_DriverWatchProc * (*tcl_ChannelWatchProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 408 */
|
||||
Tcl_DriverGetHandleProc * (*tcl_ChannelGetHandleProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 409 */
|
||||
Tcl_DriverFlushProc * (*tcl_ChannelFlushProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 410 */
|
||||
Tcl_DriverHandlerProc * (*tcl_ChannelHandlerProc) _ANSI_ARGS_((Tcl_ChannelType * chanTypePtr)); /* 411 */
|
||||
} TclStubs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -3310,6 +3380,78 @@ extern TclStubs *tclStubsPtr;
|
||||
#define Tcl_CreateThread \
|
||||
(tclStubsPtr->tcl_CreateThread) /* 393 */
|
||||
#endif
|
||||
#ifndef Tcl_ReadRaw
|
||||
#define Tcl_ReadRaw \
|
||||
(tclStubsPtr->tcl_ReadRaw) /* 394 */
|
||||
#endif
|
||||
#ifndef Tcl_WriteRaw
|
||||
#define Tcl_WriteRaw \
|
||||
(tclStubsPtr->tcl_WriteRaw) /* 395 */
|
||||
#endif
|
||||
#ifndef Tcl_GetTopChannel
|
||||
#define Tcl_GetTopChannel \
|
||||
(tclStubsPtr->tcl_GetTopChannel) /* 396 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelBuffered
|
||||
#define Tcl_ChannelBuffered \
|
||||
(tclStubsPtr->tcl_ChannelBuffered) /* 397 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelName
|
||||
#define Tcl_ChannelName \
|
||||
(tclStubsPtr->tcl_ChannelName) /* 398 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelVersion
|
||||
#define Tcl_ChannelVersion \
|
||||
(tclStubsPtr->tcl_ChannelVersion) /* 399 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelBlockModeProc
|
||||
#define Tcl_ChannelBlockModeProc \
|
||||
(tclStubsPtr->tcl_ChannelBlockModeProc) /* 400 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelCloseProc
|
||||
#define Tcl_ChannelCloseProc \
|
||||
(tclStubsPtr->tcl_ChannelCloseProc) /* 401 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelClose2Proc
|
||||
#define Tcl_ChannelClose2Proc \
|
||||
(tclStubsPtr->tcl_ChannelClose2Proc) /* 402 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelInputProc
|
||||
#define Tcl_ChannelInputProc \
|
||||
(tclStubsPtr->tcl_ChannelInputProc) /* 403 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelOutputProc
|
||||
#define Tcl_ChannelOutputProc \
|
||||
(tclStubsPtr->tcl_ChannelOutputProc) /* 404 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelSeekProc
|
||||
#define Tcl_ChannelSeekProc \
|
||||
(tclStubsPtr->tcl_ChannelSeekProc) /* 405 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelSetOptionProc
|
||||
#define Tcl_ChannelSetOptionProc \
|
||||
(tclStubsPtr->tcl_ChannelSetOptionProc) /* 406 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelGetOptionProc
|
||||
#define Tcl_ChannelGetOptionProc \
|
||||
(tclStubsPtr->tcl_ChannelGetOptionProc) /* 407 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelWatchProc
|
||||
#define Tcl_ChannelWatchProc \
|
||||
(tclStubsPtr->tcl_ChannelWatchProc) /* 408 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelGetHandleProc
|
||||
#define Tcl_ChannelGetHandleProc \
|
||||
(tclStubsPtr->tcl_ChannelGetHandleProc) /* 409 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelFlushProc
|
||||
#define Tcl_ChannelFlushProc \
|
||||
(tclStubsPtr->tcl_ChannelFlushProc) /* 410 */
|
||||
#endif
|
||||
#ifndef Tcl_ChannelHandlerProc
|
||||
#define Tcl_ChannelHandlerProc \
|
||||
(tclStubsPtr->tcl_ChannelHandlerProc) /* 411 */
|
||||
#endif
|
||||
|
||||
#endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */
|
||||
|
||||
|
||||
+2197
-2187
File diff suppressed because it is too large
Load Diff
+379
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* tclIO.h --
|
||||
*
|
||||
* 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.h,v 1.1.4.1 2000/07/27 01:39:17 hobbs Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Make sure that both EAGAIN and EWOULDBLOCK are defined. This does not
|
||||
* compile on systems where neither is defined. We want both defined so
|
||||
* that we can test safely for both. In the code we still have to test for
|
||||
* both because there may be systems on which both are defined and have
|
||||
* different values.
|
||||
*/
|
||||
|
||||
#if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN)))
|
||||
# define EWOULDBLOCK EAGAIN
|
||||
#endif
|
||||
#if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK)))
|
||||
# define EAGAIN EWOULDBLOCK
|
||||
#endif
|
||||
#if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK)))
|
||||
error one of EWOULDBLOCK or EAGAIN must be defined
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following structure encapsulates the state for a background channel
|
||||
* copy. Note that the data buffer for the copy will be appended to this
|
||||
* structure.
|
||||
*/
|
||||
|
||||
typedef struct CopyState {
|
||||
struct Channel *readPtr; /* Pointer to input channel. */
|
||||
struct Channel *writePtr; /* Pointer to output channel. */
|
||||
int readFlags; /* Original read channel flags. */
|
||||
int writeFlags; /* Original write channel flags. */
|
||||
int toRead; /* Number of bytes to copy, or -1. */
|
||||
int total; /* Total bytes transferred (written). */
|
||||
Tcl_Interp *interp; /* Interp that started the copy. */
|
||||
Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */
|
||||
int bufSize; /* Size of appended buffer. */
|
||||
char buffer[1]; /* Copy buffer, this must be the last
|
||||
* field. */
|
||||
} CopyState;
|
||||
|
||||
/*
|
||||
* struct ChannelBuffer:
|
||||
*
|
||||
* Buffers data being sent to or from a channel.
|
||||
*/
|
||||
|
||||
typedef struct ChannelBuffer {
|
||||
int nextAdded; /* The next position into which a character
|
||||
* will be put in the buffer. */
|
||||
int nextRemoved; /* Position of next byte to be removed
|
||||
* from the buffer. */
|
||||
int bufLength; /* How big is the buffer? */
|
||||
struct ChannelBuffer *nextPtr;
|
||||
/* Next buffer in chain. */
|
||||
char buf[4]; /* Placeholder for real buffer. The real
|
||||
* buffer occuppies this space + bufSize-4
|
||||
* bytes. This must be the last field in
|
||||
* the structure. */
|
||||
} ChannelBuffer;
|
||||
|
||||
#define CHANNELBUFFER_HEADER_SIZE (sizeof(ChannelBuffer) - 4)
|
||||
|
||||
/*
|
||||
* How much extra space to allocate in buffer to hold bytes from previous
|
||||
* buffer (when converting to UTF-8) or to hold bytes that will go to
|
||||
* next buffer (when converting from UTF-8).
|
||||
*/
|
||||
|
||||
#define BUFFER_PADDING 16
|
||||
|
||||
/*
|
||||
* The following defines the *default* buffer size for channels.
|
||||
*/
|
||||
|
||||
#define CHANNELBUFFER_DEFAULT_SIZE (1024 * 4)
|
||||
|
||||
/*
|
||||
* Structure to record a close callback. One such record exists for
|
||||
* each close callback registered for a channel.
|
||||
*/
|
||||
|
||||
typedef struct CloseCallback {
|
||||
Tcl_CloseProc *proc; /* The procedure to call. */
|
||||
ClientData clientData; /* Arbitrary one-word data to pass
|
||||
* to the callback. */
|
||||
struct CloseCallback *nextPtr; /* For chaining close callbacks. */
|
||||
} CloseCallback;
|
||||
|
||||
/*
|
||||
* The following structure describes the information saved from a call to
|
||||
* "fileevent". This is used later when the event being waited for to
|
||||
* invoke the saved script in the interpreter designed in this record.
|
||||
*/
|
||||
|
||||
typedef struct EventScriptRecord {
|
||||
struct Channel *chanPtr; /* The channel for which this script is
|
||||
* registered. This is used only when an
|
||||
* error occurs during evaluation of the
|
||||
* script, to delete the handler. */
|
||||
Tcl_Obj *scriptPtr; /* Script to invoke. */
|
||||
Tcl_Interp *interp; /* In what interpreter to invoke script? */
|
||||
int mask; /* Events must overlap current mask for the
|
||||
* stored script to be invoked. */
|
||||
struct EventScriptRecord *nextPtr;
|
||||
/* Next in chain of records. */
|
||||
} EventScriptRecord;
|
||||
|
||||
/*
|
||||
* struct Channel:
|
||||
*
|
||||
* One of these structures is allocated for each open channel. It contains data
|
||||
* specific to the channel but which belongs to the generic part of the Tcl
|
||||
* channel mechanism, and it points at an instance specific (and type
|
||||
* specific) * instance data, and at a channel type structure.
|
||||
*/
|
||||
|
||||
typedef struct Channel {
|
||||
struct ChannelState *state; /* Split out state information */
|
||||
|
||||
ClientData instanceData; /* Instance-specific data provided by
|
||||
* creator of channel. */
|
||||
Tcl_ChannelType *typePtr; /* Pointer to channel type structure. */
|
||||
|
||||
struct Channel *downChanPtr;/* Refers to channel this one was stacked
|
||||
* upon. This reference is NULL for normal
|
||||
* channels. See Tcl_StackChannel. */
|
||||
struct Channel *upChanPtr; /* Refers to the channel above stacked this
|
||||
* one. NULL for the top most channel. */
|
||||
|
||||
/*
|
||||
* Intermediate buffers to hold pre-read data for consumption by a
|
||||
* newly stacked transformation. See 'Tcl_StackChannel'.
|
||||
*/
|
||||
ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
|
||||
ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
|
||||
} Channel;
|
||||
|
||||
/*
|
||||
* struct ChannelState:
|
||||
*
|
||||
* One of these structures is allocated for each open channel. It contains data
|
||||
* specific to the channel but which belongs to the generic part of the Tcl
|
||||
* channel mechanism, and it points at an instance specific (and type
|
||||
* specific) * instance data, and at a channel type structure.
|
||||
*/
|
||||
|
||||
typedef struct ChannelState {
|
||||
char *channelName; /* The name of the channel instance in Tcl
|
||||
* commands. Storage is owned by the generic IO
|
||||
* code, is dynamically allocated. */
|
||||
int flags; /* ORed combination of the flags defined
|
||||
* below. */
|
||||
Tcl_Encoding encoding; /* Encoding to apply when reading or writing
|
||||
* data on this channel. NULL means no
|
||||
* encoding is applied to data. */
|
||||
Tcl_EncodingState inputEncodingState;
|
||||
/* Current encoding state, used when converting
|
||||
* input data bytes to UTF-8. */
|
||||
int inputEncodingFlags; /* Encoding flags to pass to conversion
|
||||
* routine when converting input data bytes to
|
||||
* UTF-8. May be TCL_ENCODING_START before
|
||||
* converting first byte and TCL_ENCODING_END
|
||||
* when EOF is seen. */
|
||||
Tcl_EncodingState outputEncodingState;
|
||||
/* Current encoding state, used when converting
|
||||
* UTF-8 to output data bytes. */
|
||||
int outputEncodingFlags; /* Encoding flags to pass to conversion
|
||||
* routine when converting UTF-8 to output
|
||||
* data bytes. May be TCL_ENCODING_START
|
||||
* before converting first byte and
|
||||
* TCL_ENCODING_END when EOF is seen. */
|
||||
Tcl_EolTranslation inputTranslation;
|
||||
/* What translation to apply for end of line
|
||||
* sequences on input? */
|
||||
Tcl_EolTranslation outputTranslation;
|
||||
/* What translation to use for generating
|
||||
* end of line sequences in output? */
|
||||
int inEofChar; /* If nonzero, use this as a signal of EOF
|
||||
* on input. */
|
||||
int outEofChar; /* If nonzero, append this to the channel
|
||||
* when it is closed if it is open for
|
||||
* writing. */
|
||||
int unreportedError; /* Non-zero if an error report was deferred
|
||||
* because it happened in the background. The
|
||||
* value is the POSIX error code. */
|
||||
int refCount; /* How many interpreters hold references to
|
||||
* this IO channel? */
|
||||
|
||||
CloseCallback *closeCbPtr; /* Callbacks registered to be called when the
|
||||
* channel is closed. */
|
||||
char *outputStage; /* Temporary staging buffer used when
|
||||
* translating EOL before converting from
|
||||
* UTF-8 to external form. */
|
||||
ChannelBuffer *curOutPtr; /* Current output buffer being filled. */
|
||||
ChannelBuffer *outQueueHead;/* Points at first buffer in output queue. */
|
||||
ChannelBuffer *outQueueTail;/* Points at last buffer in output queue. */
|
||||
|
||||
ChannelBuffer *saveInBufPtr;/* Buffer saved for input queue - eliminates
|
||||
* need to allocate a new buffer for "gets"
|
||||
* that crosses buffer boundaries. */
|
||||
ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
|
||||
ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
|
||||
|
||||
struct ChannelHandler *chPtr;/* List of channel handlers registered
|
||||
* for this channel. */
|
||||
int interestMask; /* Mask of all events this channel has
|
||||
* handlers for. */
|
||||
EventScriptRecord *scriptRecordPtr;
|
||||
/* Chain of all scripts registered for
|
||||
* event handlers ("fileevent") on this
|
||||
* channel. */
|
||||
|
||||
int bufSize; /* What size buffers to allocate? */
|
||||
Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */
|
||||
CopyState *csPtr; /* State of background copy, or NULL. */
|
||||
Channel *topChanPtr; /* Refers to topmost channel in a stack.
|
||||
* Never NULL. */
|
||||
Channel *bottomChanPtr; /* Refers to bottommost channel in a stack.
|
||||
* This channel can be relied on to live as
|
||||
* long as the channel state. Never NULL. */
|
||||
struct ChannelState *nextCSPtr;
|
||||
/* Next in list of channels currently open. */
|
||||
} ChannelState;
|
||||
|
||||
/*
|
||||
* Values for the flags field in Channel. Any ORed combination of the
|
||||
* following flags can be stored in the field. These flags record various
|
||||
* options and state bits about the channel. In addition to the flags below,
|
||||
* the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set.
|
||||
*/
|
||||
|
||||
#define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in
|
||||
* nonblocking mode. */
|
||||
#define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be
|
||||
* flushed after every newline. */
|
||||
#define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always
|
||||
* be flushed immediately. */
|
||||
#define BUFFER_READY (1<<6) /* Current output buffer (the
|
||||
* curOutPtr field in the
|
||||
* channel structure) should be
|
||||
* output as soon as possible even
|
||||
* though it may not be full. */
|
||||
#define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the
|
||||
* queued output buffers has been
|
||||
* scheduled. */
|
||||
#define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No
|
||||
* further Tcl-level IO on the
|
||||
* channel is allowed. */
|
||||
#define CHANNEL_EOF (1<<9) /* EOF occurred on this channel.
|
||||
* This bit is cleared before every
|
||||
* input operation. */
|
||||
#define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because
|
||||
* we saw the input eofChar. This bit
|
||||
* prevents clearing of the EOF bit
|
||||
* before every input operation. */
|
||||
#define CHANNEL_BLOCKED (1<<11) /* EWOULDBLOCK or EAGAIN occurred
|
||||
* on this channel. This bit is
|
||||
* cleared before every input or
|
||||
* output operation. */
|
||||
#define INPUT_SAW_CR (1<<12) /* Channel is in CRLF eol input
|
||||
* translation mode and the last
|
||||
* byte seen was a "\r". */
|
||||
#define INPUT_NEED_NL (1<<15) /* Saw a '\r' at end of last buffer,
|
||||
* and there should be a '\n' at
|
||||
* beginning of next buffer. */
|
||||
#define CHANNEL_DEAD (1<<13) /* The channel has been closed by
|
||||
* the exit handler (on exit) but
|
||||
* not deallocated. When any IO
|
||||
* operation sees this flag on a
|
||||
* channel, it does not call driver
|
||||
* level functions to avoid referring
|
||||
* to deallocated data. */
|
||||
#define CHANNEL_NEED_MORE_DATA (1<<14) /* The last input operation failed
|
||||
* because there was not enough data
|
||||
* to complete the operation. This
|
||||
* flag is set when gets fails to
|
||||
* get a complete line or when read
|
||||
* fails to get a complete character.
|
||||
* When set, file events will not be
|
||||
* delivered for buffered data until
|
||||
* the state of the channel changes. */
|
||||
#define CHANNEL_RAW_MODE (1<<16) /* When set, notes that the Raw API is
|
||||
* being used. */
|
||||
|
||||
/*
|
||||
* For each channel handler registered in a call to Tcl_CreateChannelHandler,
|
||||
* there is one record of the following type. All of records for a specific
|
||||
* channel are chained together in a singly linked list which is stored in
|
||||
* the channel structure.
|
||||
*/
|
||||
|
||||
typedef struct ChannelHandler {
|
||||
Channel *chanPtr; /* The channel structure for this channel. */
|
||||
int mask; /* Mask of desired events. */
|
||||
Tcl_ChannelProc *proc; /* Procedure to call in the type of
|
||||
* Tcl_CreateChannelHandler. */
|
||||
ClientData clientData; /* Argument to pass to procedure. */
|
||||
struct ChannelHandler *nextPtr;
|
||||
/* Next one in list of registered handlers. */
|
||||
} ChannelHandler;
|
||||
|
||||
/*
|
||||
* This structure keeps track of the current ChannelHandler being invoked in
|
||||
* the current invocation of ChannelHandlerEventProc. There is a potential
|
||||
* problem if a ChannelHandler is deleted while it is the current one, since
|
||||
* ChannelHandlerEventProc needs to look at the nextPtr field. To handle this
|
||||
* problem, structures of the type below indicate the next handler to be
|
||||
* processed for any (recursively nested) dispatches in progress. The
|
||||
* nextHandlerPtr field is updated if the handler being pointed to is deleted.
|
||||
* The nextPtr field is used to chain together all recursive invocations, so
|
||||
* that Tcl_DeleteChannelHandler can find all the recursively nested
|
||||
* invocations of ChannelHandlerEventProc and compare the handler being
|
||||
* deleted against the NEXT handler to be invoked in that invocation; when it
|
||||
* finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr
|
||||
* field of the structure to the next handler.
|
||||
*/
|
||||
|
||||
typedef struct NextChannelHandler {
|
||||
ChannelHandler *nextHandlerPtr; /* The next handler to be invoked in
|
||||
* this invocation. */
|
||||
struct NextChannelHandler *nestedHandlerPtr;
|
||||
/* Next nested invocation of
|
||||
* ChannelHandlerEventProc. */
|
||||
} NextChannelHandler;
|
||||
|
||||
|
||||
/*
|
||||
* The following structure describes the event that is added to the Tcl
|
||||
* event queue by the channel handler check procedure.
|
||||
*/
|
||||
|
||||
typedef struct ChannelHandlerEvent {
|
||||
Tcl_Event header; /* Standard header for all events. */
|
||||
Channel *chanPtr; /* The channel that is ready. */
|
||||
int readyMask; /* Events that have occurred. */
|
||||
} ChannelHandlerEvent;
|
||||
|
||||
/*
|
||||
* The following structure is used by Tcl_GetsObj() to encapsulates the
|
||||
* state for a "gets" operation.
|
||||
*/
|
||||
|
||||
typedef struct GetsState {
|
||||
Tcl_Obj *objPtr; /* The object to which UTF-8 characters
|
||||
* will be appended. */
|
||||
char **dstPtr; /* Pointer into objPtr's string rep where
|
||||
* next character should be stored. */
|
||||
Tcl_Encoding encoding; /* The encoding to use to convert raw bytes
|
||||
* to UTF-8. */
|
||||
ChannelBuffer *bufPtr; /* The current buffer of raw bytes being
|
||||
* emptied. */
|
||||
Tcl_EncodingState state; /* The encoding state just before the last
|
||||
* external to UTF-8 conversion in
|
||||
* FilterInputBytes(). */
|
||||
int rawRead; /* The number of bytes removed from bufPtr
|
||||
* in the last call to FilterInputBytes(). */
|
||||
int bytesWrote; /* The number of bytes of UTF-8 data
|
||||
* appended to objPtr during the last call to
|
||||
* FilterInputBytes(). */
|
||||
int charsWrote; /* The corresponding number of UTF-8
|
||||
* characters appended to objPtr during the
|
||||
* last call to FilterInputBytes(). */
|
||||
int totalChars; /* The total number of UTF-8 characters
|
||||
* appended to objPtr so far, just before the
|
||||
* last call to FilterInputBytes(). */
|
||||
} GetsState;
|
||||
+1361
File diff suppressed because it is too large
Load Diff
+20
-9
@@ -10,7 +10,7 @@
|
||||
# See the file "license.terms" for information on usage and redistribution
|
||||
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
#
|
||||
# RCS: @(#) $Id: tclInt.decls,v 1.20 2000/03/31 08:52:04 hobbs Exp $
|
||||
# RCS: @(#) $Id: tclInt.decls,v 1.20.2.1 2000/07/27 01:39:18 hobbs Exp $
|
||||
|
||||
library tcl
|
||||
|
||||
@@ -577,14 +577,16 @@ declare 153 generic {
|
||||
Tcl_Obj *TclGetLibraryPath(void)
|
||||
}
|
||||
|
||||
declare 154 generic {
|
||||
int TclTestChannelCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int argc, char **argv)
|
||||
}
|
||||
declare 155 generic {
|
||||
int TclTestChannelEventCmd(ClientData clientData, \
|
||||
Tcl_Interp *interp, int argc, char **argv)
|
||||
}
|
||||
# moved to tclTest.c in 8.3.2/8.4a2
|
||||
#declare 154 generic {
|
||||
# int TclTestChannelCmd(ClientData clientData,
|
||||
# Tcl_Interp *interp, int argc, char **argv)
|
||||
#}
|
||||
#declare 155 generic {
|
||||
# int TclTestChannelEventCmd(ClientData clientData, \
|
||||
# Tcl_Interp *interp, int argc, char **argv)
|
||||
#}
|
||||
|
||||
declare 156 generic {
|
||||
void TclRegError (Tcl_Interp *interp, char *msg, \
|
||||
int status)
|
||||
@@ -603,6 +605,15 @@ declare 160 generic {
|
||||
Tcl_DString *dirPtr, char *pattern, char *tail, GlobTypeData *types)
|
||||
}
|
||||
|
||||
# new in 8.3.2/8.4a2
|
||||
declare 161 generic {
|
||||
int TclChannelTransform(Tcl_Interp *interp, Tcl_Channel chan, \
|
||||
Tcl_Obj *cmdObjPtr)
|
||||
}
|
||||
declare 162 generic {
|
||||
void TclChannelEventScriptInvoker(ClientData clientData, int flags)
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
|
||||
# Define the platform specific internal Tcl interface. These functions are
|
||||
|
||||
+23
-18
@@ -11,7 +11,7 @@
|
||||
* See the file "license.terms" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*
|
||||
* RCS: @(#) $Id: tclIntDecls.h,v 1.19 1999/12/12 22:46:42 hobbs Exp $
|
||||
* RCS: @(#) $Id: tclIntDecls.h,v 1.19.2.1 2000/07/27 01:39:18 hobbs Exp $
|
||||
*/
|
||||
|
||||
#ifndef _TCLINTDECLS
|
||||
@@ -506,13 +506,8 @@ EXTERN void TclRegExpRangeUniChar _ANSI_ARGS_((Tcl_RegExp re,
|
||||
EXTERN void TclSetLibraryPath _ANSI_ARGS_((Tcl_Obj * pathPtr));
|
||||
/* 153 */
|
||||
EXTERN Tcl_Obj * TclGetLibraryPath _ANSI_ARGS_((void));
|
||||
/* 154 */
|
||||
EXTERN int TclTestChannelCmd _ANSI_ARGS_((ClientData clientData,
|
||||
Tcl_Interp * interp, int argc, char ** argv));
|
||||
/* 155 */
|
||||
EXTERN int TclTestChannelEventCmd _ANSI_ARGS_((
|
||||
ClientData clientData, Tcl_Interp * interp,
|
||||
int argc, char ** argv));
|
||||
/* Slot 154 is reserved */
|
||||
/* Slot 155 is reserved */
|
||||
/* 156 */
|
||||
EXTERN void TclRegError _ANSI_ARGS_((Tcl_Interp * interp,
|
||||
char * msg, int status));
|
||||
@@ -529,6 +524,12 @@ EXTERN int TclpMatchFilesTypes _ANSI_ARGS_((Tcl_Interp * interp,
|
||||
char * separators, Tcl_DString * dirPtr,
|
||||
char * pattern, char * tail,
|
||||
GlobTypeData * types));
|
||||
/* 161 */
|
||||
EXTERN int TclChannelTransform _ANSI_ARGS_((Tcl_Interp * interp,
|
||||
Tcl_Channel chan, Tcl_Obj * cmdObjPtr));
|
||||
/* 162 */
|
||||
EXTERN void TclChannelEventScriptInvoker _ANSI_ARGS_((
|
||||
ClientData clientData, int flags));
|
||||
|
||||
typedef struct TclIntStubs {
|
||||
int magic;
|
||||
@@ -720,13 +721,15 @@ typedef struct TclIntStubs {
|
||||
void (*tclRegExpRangeUniChar) _ANSI_ARGS_((Tcl_RegExp re, int index, int * startPtr, int * endPtr)); /* 151 */
|
||||
void (*tclSetLibraryPath) _ANSI_ARGS_((Tcl_Obj * pathPtr)); /* 152 */
|
||||
Tcl_Obj * (*tclGetLibraryPath) _ANSI_ARGS_((void)); /* 153 */
|
||||
int (*tclTestChannelCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char ** argv)); /* 154 */
|
||||
int (*tclTestChannelEventCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char ** argv)); /* 155 */
|
||||
void *reserved154;
|
||||
void *reserved155;
|
||||
void (*tclRegError) _ANSI_ARGS_((Tcl_Interp * interp, char * msg, int status)); /* 156 */
|
||||
Var * (*tclVarTraceExists) _ANSI_ARGS_((Tcl_Interp * interp, char * varName)); /* 157 */
|
||||
void (*tclSetStartupScriptFileName) _ANSI_ARGS_((char * filename)); /* 158 */
|
||||
char * (*tclGetStartupScriptFileName) _ANSI_ARGS_((void)); /* 159 */
|
||||
int (*tclpMatchFilesTypes) _ANSI_ARGS_((Tcl_Interp * interp, char * separators, Tcl_DString * dirPtr, char * pattern, char * tail, GlobTypeData * types)); /* 160 */
|
||||
int (*tclChannelTransform) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan, Tcl_Obj * cmdObjPtr)); /* 161 */
|
||||
void (*tclChannelEventScriptInvoker) _ANSI_ARGS_((ClientData clientData, int flags)); /* 162 */
|
||||
} TclIntStubs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -1352,14 +1355,8 @@ extern TclIntStubs *tclIntStubsPtr;
|
||||
#define TclGetLibraryPath \
|
||||
(tclIntStubsPtr->tclGetLibraryPath) /* 153 */
|
||||
#endif
|
||||
#ifndef TclTestChannelCmd
|
||||
#define TclTestChannelCmd \
|
||||
(tclIntStubsPtr->tclTestChannelCmd) /* 154 */
|
||||
#endif
|
||||
#ifndef TclTestChannelEventCmd
|
||||
#define TclTestChannelEventCmd \
|
||||
(tclIntStubsPtr->tclTestChannelEventCmd) /* 155 */
|
||||
#endif
|
||||
/* Slot 154 is reserved */
|
||||
/* Slot 155 is reserved */
|
||||
#ifndef TclRegError
|
||||
#define TclRegError \
|
||||
(tclIntStubsPtr->tclRegError) /* 156 */
|
||||
@@ -1380,6 +1377,14 @@ extern TclIntStubs *tclIntStubsPtr;
|
||||
#define TclpMatchFilesTypes \
|
||||
(tclIntStubsPtr->tclpMatchFilesTypes) /* 160 */
|
||||
#endif
|
||||
#ifndef TclChannelTransform
|
||||
#define TclChannelTransform \
|
||||
(tclIntStubsPtr->tclChannelTransform) /* 161 */
|
||||
#endif
|
||||
#ifndef TclChannelEventScriptInvoker
|
||||
#define TclChannelEventScriptInvoker \
|
||||
(tclIntStubsPtr->tclChannelEventScriptInvoker) /* 162 */
|
||||
#endif
|
||||
|
||||
#endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */
|
||||
|
||||
|
||||
+23
-3
@@ -8,7 +8,7 @@
|
||||
* 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.35 2000/04/09 16:04:18 kupries Exp $
|
||||
* RCS: @(#) $Id: tclStubInit.c,v 1.35.2.1 2000/07/27 01:39:19 hobbs Exp $
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
@@ -229,13 +229,15 @@ TclIntStubs tclIntStubs = {
|
||||
TclRegExpRangeUniChar, /* 151 */
|
||||
TclSetLibraryPath, /* 152 */
|
||||
TclGetLibraryPath, /* 153 */
|
||||
TclTestChannelCmd, /* 154 */
|
||||
TclTestChannelEventCmd, /* 155 */
|
||||
NULL, /* 154 */
|
||||
NULL, /* 155 */
|
||||
TclRegError, /* 156 */
|
||||
TclVarTraceExists, /* 157 */
|
||||
TclSetStartupScriptFileName, /* 158 */
|
||||
TclGetStartupScriptFileName, /* 159 */
|
||||
TclpMatchFilesTypes, /* 160 */
|
||||
TclChannelTransform, /* 161 */
|
||||
TclChannelEventScriptInvoker, /* 162 */
|
||||
};
|
||||
|
||||
TclIntPlatStubs tclIntPlatStubs = {
|
||||
@@ -791,6 +793,24 @@ TclStubs tclStubs = {
|
||||
Tcl_ConditionFinalize, /* 391 */
|
||||
Tcl_MutexFinalize, /* 392 */
|
||||
Tcl_CreateThread, /* 393 */
|
||||
Tcl_ReadRaw, /* 394 */
|
||||
Tcl_WriteRaw, /* 395 */
|
||||
Tcl_GetTopChannel, /* 396 */
|
||||
Tcl_ChannelBuffered, /* 397 */
|
||||
Tcl_ChannelName, /* 398 */
|
||||
Tcl_ChannelVersion, /* 399 */
|
||||
Tcl_ChannelBlockModeProc, /* 400 */
|
||||
Tcl_ChannelCloseProc, /* 401 */
|
||||
Tcl_ChannelClose2Proc, /* 402 */
|
||||
Tcl_ChannelInputProc, /* 403 */
|
||||
Tcl_ChannelOutputProc, /* 404 */
|
||||
Tcl_ChannelSeekProc, /* 405 */
|
||||
Tcl_ChannelSetOptionProc, /* 406 */
|
||||
Tcl_ChannelGetOptionProc, /* 407 */
|
||||
Tcl_ChannelWatchProc, /* 408 */
|
||||
Tcl_ChannelGetHandleProc, /* 409 */
|
||||
Tcl_ChannelFlushProc, /* 410 */
|
||||
Tcl_ChannelHandlerProc, /* 411 */
|
||||
};
|
||||
|
||||
/* !END!: Do not edit above this line. */
|
||||
|
||||
+581
-4
@@ -8,12 +8,12 @@
|
||||
*
|
||||
* Copyright (c) 1993-1994 The Regents of the University of California.
|
||||
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
|
||||
* Copyright (c) 1998-1999 by Scriptics Corporation.
|
||||
* Copyright (c) 1998-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: tclTest.c,v 1.17 1999/10/13 02:22:18 hobbs Exp $
|
||||
* RCS: @(#) $Id: tclTest.c,v 1.17.2.1 2000/07/27 01:39:19 hobbs Exp $
|
||||
*/
|
||||
|
||||
#define TCL_TEST
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "tclInt.h"
|
||||
#include "tclPort.h"
|
||||
#include "tclRegexp.h"
|
||||
#include "tclIO.h"
|
||||
#include <locale.h>
|
||||
|
||||
/*
|
||||
@@ -276,6 +277,10 @@ static int TesttranslatefilenameCmd _ANSI_ARGS_((ClientData dummy,
|
||||
Tcl_Interp *interp, int argc, char **argv));
|
||||
static int TestupvarCmd _ANSI_ARGS_((ClientData dummy,
|
||||
Tcl_Interp *interp, int argc, char **argv));
|
||||
static int TestChannelCmd _ANSI_ARGS_((ClientData dummy,
|
||||
Tcl_Interp *interp, int argc, char **argv));
|
||||
static int TestChannelEventCmd _ANSI_ARGS_((ClientData dummy,
|
||||
Tcl_Interp *interp, int argc, char **argv));
|
||||
|
||||
/*
|
||||
* External (platform specific) initialization routine, these declarations
|
||||
@@ -329,9 +334,9 @@ Tcltest_Init(interp)
|
||||
(Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, "testasync", TestasyncCmd, (ClientData) 0,
|
||||
(Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, "testchannel", TclTestChannelCmd,
|
||||
Tcl_CreateCommand(interp, "testchannel", TestChannelCmd,
|
||||
(ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, "testchannelevent", TclTestChannelEventCmd,
|
||||
Tcl_CreateCommand(interp, "testchannelevent", TestChannelEventCmd,
|
||||
(ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, "testchmod", TestchmodCmd,
|
||||
(ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
|
||||
@@ -4242,3 +4247,575 @@ TestOpenFileChannelProc3(interp, fileName, modeString, permissions)
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TestChannelCmd --
|
||||
*
|
||||
* Implements the Tcl "testchannel" debugging command and its
|
||||
* subcommands. This is part of the testing environment.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
TestChannelCmd(clientData, interp, argc, argv)
|
||||
ClientData clientData; /* Not used. */
|
||||
Tcl_Interp *interp; /* Interpreter for result. */
|
||||
int argc; /* Count of additional args. */
|
||||
char **argv; /* Additional arg strings. */
|
||||
{
|
||||
char *cmdName; /* Sub command. */
|
||||
Tcl_HashTable *hTblPtr; /* Hash table of channels. */
|
||||
Tcl_HashSearch hSearch; /* Search variable. */
|
||||
Tcl_HashEntry *hPtr; /* Search variable. */
|
||||
Channel *chanPtr; /* The actual channel. */
|
||||
ChannelState *statePtr; /* state info for channel */
|
||||
Tcl_Channel chan; /* The opaque type. */
|
||||
size_t len; /* Length of subcommand string. */
|
||||
int IOQueued; /* How much IO is queued inside channel? */
|
||||
ChannelBuffer *bufPtr; /* For iterating over queued IO. */
|
||||
char buf[TCL_INTEGER_SPACE];/* For sprintf. */
|
||||
int mode; /* rw mode of the channel */
|
||||
|
||||
if (argc < 2) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" subcommand ?additional args..?\"", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
cmdName = argv[1];
|
||||
len = strlen(cmdName);
|
||||
|
||||
chanPtr = (Channel *) NULL;
|
||||
|
||||
if (argc > 2) {
|
||||
chan = Tcl_GetChannel(interp, argv[2], &mode);
|
||||
if (chan == (Tcl_Channel) NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
chanPtr = (Channel *) chan;
|
||||
statePtr = chanPtr->state;
|
||||
chanPtr = statePtr->topChanPtr;
|
||||
chan = (Tcl_Channel) chanPtr;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 'i') && (strncmp(cmdName, "info", len) == 0)) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" info channelName\"", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_AppendElement(interp, argv[2]);
|
||||
Tcl_AppendElement(interp, chanPtr->typePtr->typeName);
|
||||
if (statePtr->flags & TCL_READABLE) {
|
||||
Tcl_AppendElement(interp, "read");
|
||||
} else {
|
||||
Tcl_AppendElement(interp, "");
|
||||
}
|
||||
if (statePtr->flags & TCL_WRITABLE) {
|
||||
Tcl_AppendElement(interp, "write");
|
||||
} else {
|
||||
Tcl_AppendElement(interp, "");
|
||||
}
|
||||
if (statePtr->flags & CHANNEL_NONBLOCKING) {
|
||||
Tcl_AppendElement(interp, "nonblocking");
|
||||
} else {
|
||||
Tcl_AppendElement(interp, "blocking");
|
||||
}
|
||||
if (statePtr->flags & CHANNEL_LINEBUFFERED) {
|
||||
Tcl_AppendElement(interp, "line");
|
||||
} else if (statePtr->flags & CHANNEL_UNBUFFERED) {
|
||||
Tcl_AppendElement(interp, "none");
|
||||
} else {
|
||||
Tcl_AppendElement(interp, "full");
|
||||
}
|
||||
if (statePtr->flags & BG_FLUSH_SCHEDULED) {
|
||||
Tcl_AppendElement(interp, "async_flush");
|
||||
} else {
|
||||
Tcl_AppendElement(interp, "");
|
||||
}
|
||||
if (statePtr->flags & CHANNEL_EOF) {
|
||||
Tcl_AppendElement(interp, "eof");
|
||||
} else {
|
||||
Tcl_AppendElement(interp, "");
|
||||
}
|
||||
if (statePtr->flags & CHANNEL_BLOCKED) {
|
||||
Tcl_AppendElement(interp, "blocked");
|
||||
} else {
|
||||
Tcl_AppendElement(interp, "unblocked");
|
||||
}
|
||||
if (statePtr->inputTranslation == TCL_TRANSLATE_AUTO) {
|
||||
Tcl_AppendElement(interp, "auto");
|
||||
if (statePtr->flags & INPUT_SAW_CR) {
|
||||
Tcl_AppendElement(interp, "saw_cr");
|
||||
} else {
|
||||
Tcl_AppendElement(interp, "");
|
||||
}
|
||||
} else if (statePtr->inputTranslation == TCL_TRANSLATE_LF) {
|
||||
Tcl_AppendElement(interp, "lf");
|
||||
Tcl_AppendElement(interp, "");
|
||||
} else if (statePtr->inputTranslation == TCL_TRANSLATE_CR) {
|
||||
Tcl_AppendElement(interp, "cr");
|
||||
Tcl_AppendElement(interp, "");
|
||||
} else if (statePtr->inputTranslation == TCL_TRANSLATE_CRLF) {
|
||||
Tcl_AppendElement(interp, "crlf");
|
||||
if (statePtr->flags & INPUT_SAW_CR) {
|
||||
Tcl_AppendElement(interp, "queued_cr");
|
||||
} else {
|
||||
Tcl_AppendElement(interp, "");
|
||||
}
|
||||
}
|
||||
if (statePtr->outputTranslation == TCL_TRANSLATE_AUTO) {
|
||||
Tcl_AppendElement(interp, "auto");
|
||||
} else if (statePtr->outputTranslation == TCL_TRANSLATE_LF) {
|
||||
Tcl_AppendElement(interp, "lf");
|
||||
} else if (statePtr->outputTranslation == TCL_TRANSLATE_CR) {
|
||||
Tcl_AppendElement(interp, "cr");
|
||||
} else if (statePtr->outputTranslation == TCL_TRANSLATE_CRLF) {
|
||||
Tcl_AppendElement(interp, "crlf");
|
||||
}
|
||||
for (IOQueued = 0, bufPtr = statePtr->inQueueHead;
|
||||
bufPtr != (ChannelBuffer *) NULL;
|
||||
bufPtr = bufPtr->nextPtr) {
|
||||
IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved;
|
||||
}
|
||||
TclFormatInt(buf, IOQueued);
|
||||
Tcl_AppendElement(interp, buf);
|
||||
|
||||
IOQueued = 0;
|
||||
if (statePtr->curOutPtr != (ChannelBuffer *) NULL) {
|
||||
IOQueued = statePtr->curOutPtr->nextAdded -
|
||||
statePtr->curOutPtr->nextRemoved;
|
||||
}
|
||||
for (bufPtr = statePtr->outQueueHead;
|
||||
bufPtr != (ChannelBuffer *) NULL;
|
||||
bufPtr = bufPtr->nextPtr) {
|
||||
IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved);
|
||||
}
|
||||
TclFormatInt(buf, IOQueued);
|
||||
Tcl_AppendElement(interp, buf);
|
||||
|
||||
TclFormatInt(buf, Tcl_Tell((Tcl_Channel) chanPtr));
|
||||
Tcl_AppendElement(interp, buf);
|
||||
|
||||
TclFormatInt(buf, statePtr->refCount);
|
||||
Tcl_AppendElement(interp, buf);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 'i') &&
|
||||
(strncmp(cmdName, "inputbuffered", len) == 0)) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "channel name required",
|
||||
(char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
for (IOQueued = 0, bufPtr = statePtr->inQueueHead;
|
||||
bufPtr != (ChannelBuffer *) NULL;
|
||||
bufPtr = bufPtr->nextPtr) {
|
||||
IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved;
|
||||
}
|
||||
TclFormatInt(buf, IOQueued);
|
||||
Tcl_AppendResult(interp, buf, (char *) NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 'm') && (strncmp(cmdName, "mode", len) == 0)) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "channel name required",
|
||||
(char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (statePtr->flags & TCL_READABLE) {
|
||||
Tcl_AppendElement(interp, "read");
|
||||
} else {
|
||||
Tcl_AppendElement(interp, "");
|
||||
}
|
||||
if (statePtr->flags & TCL_WRITABLE) {
|
||||
Tcl_AppendElement(interp, "write");
|
||||
} else {
|
||||
Tcl_AppendElement(interp, "");
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "channel name required",
|
||||
(char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_AppendResult(interp, statePtr->channelName, (char *) NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) {
|
||||
hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
|
||||
if (hTblPtr == (Tcl_HashTable *) NULL) {
|
||||
return TCL_OK;
|
||||
}
|
||||
for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
|
||||
hPtr != (Tcl_HashEntry *) NULL;
|
||||
hPtr = Tcl_NextHashEntry(&hSearch)) {
|
||||
Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 'o') &&
|
||||
(strncmp(cmdName, "outputbuffered", len) == 0)) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "channel name required",
|
||||
(char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
IOQueued = 0;
|
||||
if (statePtr->curOutPtr != (ChannelBuffer *) NULL) {
|
||||
IOQueued = statePtr->curOutPtr->nextAdded -
|
||||
statePtr->curOutPtr->nextRemoved;
|
||||
}
|
||||
for (bufPtr = statePtr->outQueueHead;
|
||||
bufPtr != (ChannelBuffer *) NULL;
|
||||
bufPtr = bufPtr->nextPtr) {
|
||||
IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved);
|
||||
}
|
||||
TclFormatInt(buf, IOQueued);
|
||||
Tcl_AppendResult(interp, buf, (char *) NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 'q') &&
|
||||
(strncmp(cmdName, "queuedcr", len) == 0)) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "channel name required",
|
||||
(char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Tcl_AppendResult(interp,
|
||||
(statePtr->flags & INPUT_SAW_CR) ? "1" : "0",
|
||||
(char *) NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) {
|
||||
hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
|
||||
if (hTblPtr == (Tcl_HashTable *) NULL) {
|
||||
return TCL_OK;
|
||||
}
|
||||
for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
|
||||
hPtr != (Tcl_HashEntry *) NULL;
|
||||
hPtr = Tcl_NextHashEntry(&hSearch)) {
|
||||
chanPtr = (Channel *) Tcl_GetHashValue(hPtr);
|
||||
statePtr = chanPtr->state;
|
||||
if (statePtr->flags & TCL_READABLE) {
|
||||
Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr));
|
||||
}
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 'r') && (strncmp(cmdName, "refcount", len) == 0)) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "channel name required",
|
||||
(char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
TclFormatInt(buf, statePtr->refCount);
|
||||
Tcl_AppendResult(interp, buf, (char *) NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 't') && (strncmp(cmdName, "type", len) == 0)) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "channel name required",
|
||||
(char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_AppendResult(interp, chanPtr->typePtr->typeName,
|
||||
(char *) NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) {
|
||||
hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
|
||||
if (hTblPtr == (Tcl_HashTable *) NULL) {
|
||||
return TCL_OK;
|
||||
}
|
||||
for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
|
||||
hPtr != (Tcl_HashEntry *) NULL;
|
||||
hPtr = Tcl_NextHashEntry(&hSearch)) {
|
||||
chanPtr = (Channel *) Tcl_GetHashValue(hPtr);
|
||||
statePtr = chanPtr->state;
|
||||
if (statePtr->flags & TCL_WRITABLE) {
|
||||
Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr));
|
||||
}
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 't') && (strncmp(cmdName, "transform", len) == 0)) {
|
||||
/*
|
||||
* Syntax: transform channel -command command
|
||||
*/
|
||||
|
||||
if (argc != 5) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" transform channelId -command cmd\"", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (strcmp(argv[3], "-command") != 0) {
|
||||
Tcl_AppendResult(interp, "bad argument \"", argv[3],
|
||||
"\": should be \"-command\"", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
return TclChannelTransform(interp, chan,
|
||||
Tcl_NewStringObj(argv[4], -1));
|
||||
}
|
||||
|
||||
if ((cmdName[0] == 'u') && (strncmp(cmdName, "unstack", len) == 0)) {
|
||||
/*
|
||||
* Syntax: unstack channel
|
||||
*/
|
||||
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" unstack channel\"", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return Tcl_UnstackChannel(interp, chan);
|
||||
}
|
||||
|
||||
Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be ",
|
||||
"info, open, readable, writable, transform, unstack",
|
||||
(char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TestChannelEventCmd --
|
||||
*
|
||||
* This procedure implements the "testchannelevent" command. It is
|
||||
* used to test the Tcl channel event mechanism.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* Creates, deletes and returns channel event handlers.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
TestChannelEventCmd(dummy, interp, argc, argv)
|
||||
ClientData dummy; /* Not used. */
|
||||
Tcl_Interp *interp; /* Current interpreter. */
|
||||
int argc; /* Number of arguments. */
|
||||
char **argv; /* Argument strings. */
|
||||
{
|
||||
Tcl_Obj *resultListPtr;
|
||||
Channel *chanPtr;
|
||||
ChannelState *statePtr; /* state info for channel */
|
||||
EventScriptRecord *esPtr, *prevEsPtr, *nextEsPtr;
|
||||
char *cmd;
|
||||
int index, i, mask, len;
|
||||
|
||||
if ((argc < 3) || (argc > 5)) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" channelName cmd ?arg1? ?arg2?\"", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
chanPtr = (Channel *) Tcl_GetChannel(interp, argv[1], NULL);
|
||||
if (chanPtr == (Channel *) NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
statePtr = chanPtr->state;
|
||||
|
||||
cmd = argv[2];
|
||||
len = strlen(cmd);
|
||||
if ((cmd[0] == 'a') && (strncmp(cmd, "add", (unsigned) len) == 0)) {
|
||||
if (argc != 5) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" channelName add eventSpec script\"", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (strcmp(argv[3], "readable") == 0) {
|
||||
mask = TCL_READABLE;
|
||||
} else if (strcmp(argv[3], "writable") == 0) {
|
||||
mask = TCL_WRITABLE;
|
||||
} else if (strcmp(argv[3], "none") == 0) {
|
||||
mask = 0;
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "bad event name \"", argv[3],
|
||||
"\": must be readable, writable, or none", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
esPtr = (EventScriptRecord *) ckalloc((unsigned)
|
||||
sizeof(EventScriptRecord));
|
||||
esPtr->nextPtr = statePtr->scriptRecordPtr;
|
||||
statePtr->scriptRecordPtr = esPtr;
|
||||
|
||||
esPtr->chanPtr = chanPtr;
|
||||
esPtr->interp = interp;
|
||||
esPtr->mask = mask;
|
||||
esPtr->scriptPtr = Tcl_NewStringObj(argv[4], -1);
|
||||
Tcl_IncrRefCount(esPtr->scriptPtr);
|
||||
|
||||
Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
|
||||
TclChannelEventScriptInvoker, (ClientData) esPtr);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmd[0] == 'd') && (strncmp(cmd, "delete", (unsigned) len) == 0)) {
|
||||
if (argc != 4) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" channelName delete index\"", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (index < 0) {
|
||||
Tcl_AppendResult(interp, "bad event index: ", argv[3],
|
||||
": must be nonnegative", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for (i = 0, esPtr = statePtr->scriptRecordPtr;
|
||||
(i < index) && (esPtr != (EventScriptRecord *) NULL);
|
||||
i++, esPtr = esPtr->nextPtr) {
|
||||
/* Empty loop body. */
|
||||
}
|
||||
if (esPtr == (EventScriptRecord *) NULL) {
|
||||
Tcl_AppendResult(interp, "bad event index ", argv[3],
|
||||
": out of range", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (esPtr == statePtr->scriptRecordPtr) {
|
||||
statePtr->scriptRecordPtr = esPtr->nextPtr;
|
||||
} else {
|
||||
for (prevEsPtr = statePtr->scriptRecordPtr;
|
||||
(prevEsPtr != (EventScriptRecord *) NULL) &&
|
||||
(prevEsPtr->nextPtr != esPtr);
|
||||
prevEsPtr = prevEsPtr->nextPtr) {
|
||||
/* Empty loop body. */
|
||||
}
|
||||
if (prevEsPtr == (EventScriptRecord *) NULL) {
|
||||
panic("TestChannelEventCmd: damaged event script list");
|
||||
}
|
||||
prevEsPtr->nextPtr = esPtr->nextPtr;
|
||||
}
|
||||
Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
|
||||
TclChannelEventScriptInvoker, (ClientData) esPtr);
|
||||
Tcl_DecrRefCount(esPtr->scriptPtr);
|
||||
ckfree((char *) esPtr);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmd[0] == 'l') && (strncmp(cmd, "list", (unsigned) len) == 0)) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" channelName list\"", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
resultListPtr = Tcl_GetObjResult(interp);
|
||||
for (esPtr = statePtr->scriptRecordPtr;
|
||||
esPtr != (EventScriptRecord *) NULL;
|
||||
esPtr = esPtr->nextPtr) {
|
||||
if (esPtr->mask) {
|
||||
Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj(
|
||||
(esPtr->mask == TCL_READABLE) ? "readable" : "writable", -1));
|
||||
} else {
|
||||
Tcl_ListObjAppendElement(interp, resultListPtr,
|
||||
Tcl_NewStringObj("none", -1));
|
||||
}
|
||||
Tcl_ListObjAppendElement(interp, resultListPtr, esPtr->scriptPtr);
|
||||
}
|
||||
Tcl_SetObjResult(interp, resultListPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmd[0] == 'r') && (strncmp(cmd, "removeall", (unsigned) len) == 0)) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" channelName removeall\"", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for (esPtr = statePtr->scriptRecordPtr;
|
||||
esPtr != (EventScriptRecord *) NULL;
|
||||
esPtr = nextEsPtr) {
|
||||
nextEsPtr = esPtr->nextPtr;
|
||||
Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
|
||||
TclChannelEventScriptInvoker, (ClientData) esPtr);
|
||||
Tcl_DecrRefCount(esPtr->scriptPtr);
|
||||
ckfree((char *) esPtr);
|
||||
}
|
||||
statePtr->scriptRecordPtr = (EventScriptRecord *) NULL;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((cmd[0] == 's') && (strncmp(cmd, "set", (unsigned) len) == 0)) {
|
||||
if (argc != 5) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" channelName delete index event\"", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (index < 0) {
|
||||
Tcl_AppendResult(interp, "bad event index: ", argv[3],
|
||||
": must be nonnegative", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for (i = 0, esPtr = statePtr->scriptRecordPtr;
|
||||
(i < index) && (esPtr != (EventScriptRecord *) NULL);
|
||||
i++, esPtr = esPtr->nextPtr) {
|
||||
/* Empty loop body. */
|
||||
}
|
||||
if (esPtr == (EventScriptRecord *) NULL) {
|
||||
Tcl_AppendResult(interp, "bad event index ", argv[3],
|
||||
": out of range", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (strcmp(argv[4], "readable") == 0) {
|
||||
mask = TCL_READABLE;
|
||||
} else if (strcmp(argv[4], "writable") == 0) {
|
||||
mask = TCL_WRITABLE;
|
||||
} else if (strcmp(argv[4], "none") == 0) {
|
||||
mask = 0;
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "bad event name \"", argv[4],
|
||||
"\": must be readable, writable, or none", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
esPtr->mask = mask;
|
||||
Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
|
||||
TclChannelEventScriptInvoker, (ClientData) esPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
Tcl_AppendResult(interp, "bad command ", cmd, ", must be one of ",
|
||||
"add, delete, list, set, or removeall", (char *) NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
+40
-23
@@ -9,7 +9,7 @@
|
||||
# See the file "license.terms" for information on usage and
|
||||
# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
#
|
||||
# RCS: @(#) $Id: http.tcl,v 1.32 2000/04/22 07:07:59 sandeep Exp $
|
||||
# RCS: @(#) $Id: http.tcl,v 1.32.2.1 2000/05/31 01:28:57 sandeep Exp $
|
||||
|
||||
# Rough version history:
|
||||
# 1.0 Old http_get interface
|
||||
@@ -280,7 +280,7 @@ proc http::geturl { url args } {
|
||||
if {![regexp -nocase {^(([^:]*)://)?([^/:]+)(:([0-9]+))?(/.*)?$} $url \
|
||||
x prefix proto host y port srvurl]} {
|
||||
unset $token
|
||||
error "Unsupported URL: $url"
|
||||
return -code error "Unsupported URL: $url"
|
||||
}
|
||||
if {[string length $proto] == 0} {
|
||||
set proto http
|
||||
@@ -288,7 +288,7 @@ proc http::geturl { url args } {
|
||||
}
|
||||
if {![info exists urlTypes($proto)]} {
|
||||
unset $token
|
||||
return -code error "unsupported url type \"$proto\""
|
||||
return -code error "Unsupported URL type \"$proto\""
|
||||
}
|
||||
set defport [lindex $urlTypes($proto) 0]
|
||||
set defcmd [lindex $urlTypes($proto) 1]
|
||||
@@ -345,12 +345,17 @@ proc http::geturl { url args } {
|
||||
if {$state(-timeout) > 0} {
|
||||
fileevent $s writable [list http::Connect $token]
|
||||
http::wait $token
|
||||
if {$state(status) != "connect"} {
|
||||
|
||||
# Likely to be connection timeout. If there was a connection
|
||||
# error, (e.g., bad port), then http::wait will have
|
||||
# raised an error already
|
||||
|
||||
if {[string equal $state(status) "error"]} {
|
||||
# something went wrong while trying to establish the connection
|
||||
# Clean up after events and such, but DON'T call the command
|
||||
# callback (if available) because we're going to throw an
|
||||
# exception from here instead.
|
||||
set err [lindex $state(error) 0]
|
||||
cleanup $token
|
||||
return -code error $err
|
||||
} elseif {![string equal $state(status) "connect"]} {
|
||||
# Likely to be connection timeout
|
||||
return $token
|
||||
}
|
||||
set state(status) ""
|
||||
@@ -449,6 +454,11 @@ proc http::geturl { url args } {
|
||||
# calls it synchronously, we just do a wait here.
|
||||
|
||||
wait $token
|
||||
if {[string equal $state(status) "error"]} {
|
||||
# Something went wrong, so throw the exception, and the
|
||||
# enclosing catch will do cleanup.
|
||||
return -code error [lindex $state(error) 0]
|
||||
}
|
||||
}
|
||||
} err]} {
|
||||
# The socket probably was never connected,
|
||||
@@ -457,8 +467,12 @@ proc http::geturl { url args } {
|
||||
# Clean up after events and such, but DON'T call the command callback
|
||||
# (if available) because we're going to throw an exception from here
|
||||
# instead.
|
||||
|
||||
Finish $token $err 1
|
||||
|
||||
# if state(status) is error, it means someone's already called Finish
|
||||
# to do the above-described clean up.
|
||||
if {[string equal $state(status) "error"]} {
|
||||
Finish $token $err 1
|
||||
}
|
||||
cleanup $token
|
||||
return -code error $err
|
||||
}
|
||||
@@ -502,6 +516,15 @@ proc http::size {token} {
|
||||
return $state(currentsize)
|
||||
}
|
||||
|
||||
proc http::error {token} {
|
||||
variable $token
|
||||
upvar 0 $token state
|
||||
if {[info exists state(error)]} {
|
||||
return $state(error)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
# http::cleanup
|
||||
#
|
||||
# Garbage collect the state associated with a transaction
|
||||
@@ -531,21 +554,19 @@ proc http::cleanup {token} {
|
||||
# Sets the status of the connection, which unblocks
|
||||
# the waiting geturl call
|
||||
|
||||
proc http::Connect {token} {
|
||||
proc http::Connect {token} {
|
||||
variable $token
|
||||
upvar 0 $token state
|
||||
global errorInfo errorCode
|
||||
if {[eof $state(sock)] ||
|
||||
[string length [fconfigure $state(sock) -error]]} {
|
||||
set state(status) error
|
||||
set state(error) [list \
|
||||
"connect failed [fconfigure $state(sock) -error]" \
|
||||
$errorInfo $errorCode]
|
||||
[string length [fconfigure $state(sock) -error]]} {
|
||||
Finish $token "connect failed [fconfigure $state(sock) -error]" 1
|
||||
} else {
|
||||
set state(status) connect
|
||||
fileevent $state(sock) writable {}
|
||||
}
|
||||
fileevent $state(sock) writable {}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# http::Write
|
||||
#
|
||||
@@ -780,11 +801,7 @@ proc http::wait {token} {
|
||||
# We must wait on the original variable name, not the upvar alias
|
||||
vwait $token\(status)
|
||||
}
|
||||
if {[info exists state(error)]} {
|
||||
set errorlist $state(error)
|
||||
unset state
|
||||
eval error $errorlist
|
||||
}
|
||||
|
||||
return $state(status)
|
||||
}
|
||||
|
||||
|
||||
+40
-23
@@ -9,7 +9,7 @@
|
||||
# See the file "license.terms" for information on usage and
|
||||
# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
#
|
||||
# RCS: @(#) $Id: http.tcl,v 1.32 2000/04/22 07:07:59 sandeep Exp $
|
||||
# RCS: @(#) $Id: http.tcl,v 1.32.2.1 2000/05/31 01:28:57 sandeep Exp $
|
||||
|
||||
# Rough version history:
|
||||
# 1.0 Old http_get interface
|
||||
@@ -280,7 +280,7 @@ proc http::geturl { url args } {
|
||||
if {![regexp -nocase {^(([^:]*)://)?([^/:]+)(:([0-9]+))?(/.*)?$} $url \
|
||||
x prefix proto host y port srvurl]} {
|
||||
unset $token
|
||||
error "Unsupported URL: $url"
|
||||
return -code error "Unsupported URL: $url"
|
||||
}
|
||||
if {[string length $proto] == 0} {
|
||||
set proto http
|
||||
@@ -288,7 +288,7 @@ proc http::geturl { url args } {
|
||||
}
|
||||
if {![info exists urlTypes($proto)]} {
|
||||
unset $token
|
||||
return -code error "unsupported url type \"$proto\""
|
||||
return -code error "Unsupported URL type \"$proto\""
|
||||
}
|
||||
set defport [lindex $urlTypes($proto) 0]
|
||||
set defcmd [lindex $urlTypes($proto) 1]
|
||||
@@ -345,12 +345,17 @@ proc http::geturl { url args } {
|
||||
if {$state(-timeout) > 0} {
|
||||
fileevent $s writable [list http::Connect $token]
|
||||
http::wait $token
|
||||
if {$state(status) != "connect"} {
|
||||
|
||||
# Likely to be connection timeout. If there was a connection
|
||||
# error, (e.g., bad port), then http::wait will have
|
||||
# raised an error already
|
||||
|
||||
if {[string equal $state(status) "error"]} {
|
||||
# something went wrong while trying to establish the connection
|
||||
# Clean up after events and such, but DON'T call the command
|
||||
# callback (if available) because we're going to throw an
|
||||
# exception from here instead.
|
||||
set err [lindex $state(error) 0]
|
||||
cleanup $token
|
||||
return -code error $err
|
||||
} elseif {![string equal $state(status) "connect"]} {
|
||||
# Likely to be connection timeout
|
||||
return $token
|
||||
}
|
||||
set state(status) ""
|
||||
@@ -449,6 +454,11 @@ proc http::geturl { url args } {
|
||||
# calls it synchronously, we just do a wait here.
|
||||
|
||||
wait $token
|
||||
if {[string equal $state(status) "error"]} {
|
||||
# Something went wrong, so throw the exception, and the
|
||||
# enclosing catch will do cleanup.
|
||||
return -code error [lindex $state(error) 0]
|
||||
}
|
||||
}
|
||||
} err]} {
|
||||
# The socket probably was never connected,
|
||||
@@ -457,8 +467,12 @@ proc http::geturl { url args } {
|
||||
# Clean up after events and such, but DON'T call the command callback
|
||||
# (if available) because we're going to throw an exception from here
|
||||
# instead.
|
||||
|
||||
Finish $token $err 1
|
||||
|
||||
# if state(status) is error, it means someone's already called Finish
|
||||
# to do the above-described clean up.
|
||||
if {[string equal $state(status) "error"]} {
|
||||
Finish $token $err 1
|
||||
}
|
||||
cleanup $token
|
||||
return -code error $err
|
||||
}
|
||||
@@ -502,6 +516,15 @@ proc http::size {token} {
|
||||
return $state(currentsize)
|
||||
}
|
||||
|
||||
proc http::error {token} {
|
||||
variable $token
|
||||
upvar 0 $token state
|
||||
if {[info exists state(error)]} {
|
||||
return $state(error)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
# http::cleanup
|
||||
#
|
||||
# Garbage collect the state associated with a transaction
|
||||
@@ -531,21 +554,19 @@ proc http::cleanup {token} {
|
||||
# Sets the status of the connection, which unblocks
|
||||
# the waiting geturl call
|
||||
|
||||
proc http::Connect {token} {
|
||||
proc http::Connect {token} {
|
||||
variable $token
|
||||
upvar 0 $token state
|
||||
global errorInfo errorCode
|
||||
if {[eof $state(sock)] ||
|
||||
[string length [fconfigure $state(sock) -error]]} {
|
||||
set state(status) error
|
||||
set state(error) [list \
|
||||
"connect failed [fconfigure $state(sock) -error]" \
|
||||
$errorInfo $errorCode]
|
||||
[string length [fconfigure $state(sock) -error]]} {
|
||||
Finish $token "connect failed [fconfigure $state(sock) -error]" 1
|
||||
} else {
|
||||
set state(status) connect
|
||||
fileevent $state(sock) writable {}
|
||||
}
|
||||
fileevent $state(sock) writable {}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# http::Write
|
||||
#
|
||||
@@ -780,11 +801,7 @@ proc http::wait {token} {
|
||||
# We must wait on the original variable name, not the upvar alias
|
||||
vwait $token\(status)
|
||||
}
|
||||
if {[info exists state(error)]} {
|
||||
set errorlist $state(error)
|
||||
unset state
|
||||
eval error $errorlist
|
||||
}
|
||||
|
||||
return $state(status)
|
||||
}
|
||||
|
||||
|
||||
+3061
-2943
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -4,10 +4,10 @@
|
||||
# tests. Execute it by invoking "source all.test" when running tcltest
|
||||
# in this directory.
|
||||
#
|
||||
# Copyright (c) 1998-1999 by Scriptics Corporation.
|
||||
# Copyright (c) 1998-2000 Ajuba Solutions.
|
||||
# All rights reserved.
|
||||
#
|
||||
# RCS: @(#) $Id: all.tcl,v 1.10 2000/04/10 17:18:56 ericm Exp $
|
||||
# RCS: @(#) $Id: all.tcl,v 1.10.2.1 2000/07/27 01:39:20 hobbs Exp $
|
||||
|
||||
if {[lsearch [namespace children] ::tcltest] == -1} {
|
||||
package require tcltest
|
||||
|
||||
+11
-2
@@ -6,13 +6,13 @@
|
||||
#
|
||||
# Copyright (c) 1991-1993 The Regents of the University of California.
|
||||
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
|
||||
# Copyright (c) 1998-1999 by Scriptics Corporation.
|
||||
# Copyright (c) 1998-2000 by 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: http.test,v 1.19 2000/04/22 07:07:59 sandeep Exp $
|
||||
# RCS: @(#) $Id: http.test,v 1.19.2.2 2000/06/02 23:44:07 hobbs Exp $
|
||||
|
||||
if {[lsearch [namespace children] ::tcltest] == -1} {
|
||||
package require tcltest
|
||||
@@ -290,6 +290,15 @@ test http-3.12 {http::geturl querychannel with aborted request} {nonPortable} {
|
||||
list [http::status $t] [http::code $t]
|
||||
} {ok {HTTP/1.0 200 Data follows}}
|
||||
|
||||
test http-3.13 {http::geturl socket leak test} {
|
||||
set chanCount [llength [file channels]]
|
||||
for {set i 0} {$i < 3} {incr i} {
|
||||
catch {http::geturl $badurl -timeout 5000}
|
||||
}
|
||||
|
||||
# No extra channels should be taken
|
||||
expr {[llength [file channels]] == $chanCount}
|
||||
} 1
|
||||
|
||||
test http-4.1 {http::Event} {
|
||||
set token [http::geturl $url]
|
||||
|
||||
+940
@@ -0,0 +1,940 @@
|
||||
# -*- tcl -*-
|
||||
# Commands covered: transform, and stacking in general
|
||||
#
|
||||
# This file contains a collection of tests for Giot
|
||||
#
|
||||
# See the file "license.terms" for information on usage and redistribution
|
||||
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
#
|
||||
# Copyright (c) 2000 Ajuba Solutions.
|
||||
# Copyright (c) 2000 Andreas Kupries.
|
||||
# All rights reserved.
|
||||
#
|
||||
# RCS: @(#) $Id: iogt.test,v 1.1.4.1 2000/07/27 01:39:20 hobbs Exp $
|
||||
|
||||
|
||||
if {[lsearch [namespace children] ::tcltest] == -1} {
|
||||
package require tcltest
|
||||
namespace import -force ::tcltest::*
|
||||
}
|
||||
|
||||
if {[info commands testchannel] == ""} {
|
||||
puts "Skipping io tests. This application does not seem to have the"
|
||||
puts "testchannel command that is needed to run these tests."
|
||||
return
|
||||
}
|
||||
|
||||
::tcltest::saveState
|
||||
|
||||
#::tcltest::makeFile contents name
|
||||
|
||||
::tcltest::makeFile {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=} dummy
|
||||
|
||||
# " capture coloring of quotes
|
||||
|
||||
::tcltest::makeFile {} dummyout
|
||||
|
||||
::tcltest::makeFile {
|
||||
#!/usr/local/bin/tclsh
|
||||
# -*- tcl -*-
|
||||
# echo server
|
||||
#
|
||||
# arguments, options: port to listen on for connections.
|
||||
# delay till echo of first block
|
||||
# delay between blocks
|
||||
# blocksize ...
|
||||
|
||||
set port [lindex $argv 0]
|
||||
set fdelay [lindex $argv 1]
|
||||
set idelay [lindex $argv 2]
|
||||
set bsizes [lrange $argv 3 end]
|
||||
set c 0
|
||||
|
||||
proc newconn {sock rhost rport} {
|
||||
global c fdelay
|
||||
incr c
|
||||
|
||||
#puts stdout "C $sock $rhost $rport / $fdelay" ; flush stdout
|
||||
|
||||
upvar #0 c$c conn
|
||||
set conn(after) {}
|
||||
set conn(state) 0
|
||||
set conn(size) 0
|
||||
set conn(data) ""
|
||||
set conn(delay) $fdelay
|
||||
|
||||
fileevent $sock readable [list echoGet $c $sock]
|
||||
fconfigure $sock -translation binary -buffering none -blocking 0
|
||||
}
|
||||
|
||||
proc echoGet {c sock} {
|
||||
global fdelay
|
||||
upvar #0 c$c conn
|
||||
|
||||
if {[eof $sock]} {
|
||||
# one-shot echo
|
||||
exit
|
||||
}
|
||||
|
||||
append conn(data) [read $sock]
|
||||
|
||||
#puts stdout "G $c $sock $conn(data) <<$conn(data)>>" ; flush stdout
|
||||
|
||||
if {$conn(after) == {}} {
|
||||
set conn(after) [after $conn(delay) [list echoPut $c $sock]]
|
||||
}
|
||||
}
|
||||
|
||||
proc echoPut {c sock} {
|
||||
global idelay fdelay bsizes
|
||||
upvar #0 c$c conn
|
||||
|
||||
if {[string length $conn(data)] == 0} {
|
||||
#puts stdout "C $c $sock" ; flush stdout
|
||||
# auto terminate
|
||||
close $sock
|
||||
exit
|
||||
#set conn(delay) $fdelay
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
set conn(delay) $idelay
|
||||
|
||||
set n [lindex $bsizes $conn(size)]
|
||||
|
||||
#puts stdout "P $c $sock $n >>" ; flush stdout
|
||||
|
||||
#puts __________________________________________
|
||||
#parray conn
|
||||
#puts n=<$n>
|
||||
|
||||
|
||||
if {[string length $conn(data)] >= $n} {
|
||||
puts -nonewline $sock [string range $conn(data) 0 $n]
|
||||
set conn(data) [string range $conn(data) [incr n] end]
|
||||
}
|
||||
|
||||
incr conn(size)
|
||||
if {$conn(size) >= [llength $bsizes]} {
|
||||
set conn(size) [expr {[llength $bsizes]-1}]
|
||||
}
|
||||
|
||||
set conn(after) [after $conn(delay) [list echoPut $c $sock]]
|
||||
}
|
||||
|
||||
#fileevent stdin readable {exit ;#cut}
|
||||
|
||||
# main
|
||||
socket -server newconn $port
|
||||
vwait forever
|
||||
} __echo_srv__.tcl
|
||||
|
||||
|
||||
########################################################################
|
||||
|
||||
proc fevent {fdelay idelay blocks script data} {
|
||||
# start and initialize an echo server, prepare data
|
||||
# transmission, then hand over to the test script.
|
||||
# this has to start real transmission via 'flush'.
|
||||
# The server is stopped after completion of the test.
|
||||
|
||||
# fixed port, not so good. lets hope for the best, for now.
|
||||
set port 4000
|
||||
|
||||
eval exec tclsh __echo_srv__.tcl \
|
||||
$port $fdelay $idelay $blocks >@stdout &
|
||||
|
||||
after 500
|
||||
|
||||
#puts stdout "> $port" ; flush stdout
|
||||
|
||||
set sk [socket localhost $port]
|
||||
fconfigure $sk \
|
||||
-blocking 0 \
|
||||
-buffering full \
|
||||
-buffersize [expr {10+[llength $data]}]
|
||||
|
||||
puts -nonewline $sk $data
|
||||
|
||||
# The channel is prepared to go off.
|
||||
|
||||
#puts stdout ">>>>>" ; flush stdout
|
||||
|
||||
uplevel #0 set sock $sk
|
||||
set res [uplevel #0 $script]
|
||||
|
||||
catch {close $sk}
|
||||
return $res
|
||||
}
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# utility transformations ...
|
||||
|
||||
proc id {op data} {
|
||||
switch -- $op {
|
||||
create/write -
|
||||
create/read -
|
||||
delete/write -
|
||||
delete/read -
|
||||
clear_read {;#ignore}
|
||||
flush/write -
|
||||
flush/read -
|
||||
write -
|
||||
read {
|
||||
return $data
|
||||
}
|
||||
query/maxRead {return -1}
|
||||
}
|
||||
}
|
||||
|
||||
proc id_optrail {var op data} {
|
||||
upvar #0 $var trail
|
||||
|
||||
lappend trail $op
|
||||
|
||||
switch -- $op {
|
||||
create/write - create/read -
|
||||
delete/write - delete/read -
|
||||
flush/read -
|
||||
clear/read { #ignore }
|
||||
flush/write -
|
||||
write -
|
||||
read {
|
||||
return $data
|
||||
}
|
||||
query/maxRead {
|
||||
return -1
|
||||
}
|
||||
default {
|
||||
lappend trail "error $op"
|
||||
error $op
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc id_fulltrail {var op data} {
|
||||
upvar #0 $var trail
|
||||
|
||||
#puts stdout ">> $var $op $data" ; flush stdout
|
||||
|
||||
switch -- $op {
|
||||
create/write - create/read -
|
||||
delete/write - delete/read -
|
||||
clear_read {
|
||||
set res *ignored*
|
||||
}
|
||||
flush/write - flush/read -
|
||||
write -
|
||||
read {
|
||||
set res $data
|
||||
}
|
||||
query/maxRead {
|
||||
set res -1
|
||||
}
|
||||
}
|
||||
|
||||
#catch {puts stdout "\t>* $res" ; flush stdout}
|
||||
#catch {puts stdout "x$res"} msg
|
||||
|
||||
lappend trail [list $op $data $res]
|
||||
return $res
|
||||
}
|
||||
|
||||
proc counter {var op data} {
|
||||
upvar #0 $var n
|
||||
|
||||
switch -- $op {
|
||||
create/write - create/read -
|
||||
delete/write - delete/read -
|
||||
clear_read {;#ignore}
|
||||
flush/write - flush/read {return {}}
|
||||
write {
|
||||
return $data
|
||||
}
|
||||
read {
|
||||
if {$n > 0} {
|
||||
incr n -[string length $data]
|
||||
if {$n < 0} {
|
||||
set n 0
|
||||
}
|
||||
}
|
||||
return $data
|
||||
}
|
||||
query/maxRead {
|
||||
return $n
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc counter_audit {var vtrail op data} {
|
||||
upvar #0 $var n $vtrail trail
|
||||
|
||||
switch -- $op {
|
||||
create/write - create/read -
|
||||
delete/write - delete/read -
|
||||
clear_read {
|
||||
set res {}
|
||||
}
|
||||
flush/write - flush/read {
|
||||
set res {}
|
||||
}
|
||||
write {
|
||||
set res $data
|
||||
}
|
||||
read {
|
||||
if {$n > 0} {
|
||||
incr n -[string length $data]
|
||||
if {$n < 0} {
|
||||
set n 0
|
||||
}
|
||||
}
|
||||
set res $data
|
||||
}
|
||||
query/maxRead {
|
||||
set res $n
|
||||
}
|
||||
}
|
||||
|
||||
lappend trail [list counter:$op $data $res]
|
||||
return $res
|
||||
}
|
||||
|
||||
|
||||
proc rblocks {var vtrail n op data} {
|
||||
upvar #0 $var buf $vtrail trail
|
||||
|
||||
set res {}
|
||||
|
||||
switch -- $op {
|
||||
create/write - create/read -
|
||||
delete/write - delete/read -
|
||||
clear_read {
|
||||
set buf {}
|
||||
}
|
||||
flush/write {
|
||||
}
|
||||
flush/read {
|
||||
set res $buf
|
||||
set buf {}
|
||||
}
|
||||
write {
|
||||
set data
|
||||
}
|
||||
read {
|
||||
append buf $data
|
||||
|
||||
set b [expr {$n * ([string length $buf] / $n)}]
|
||||
|
||||
append op " $n [string length $buf] :- $b"
|
||||
|
||||
set res [string range $buf 0 [incr b -1]]
|
||||
set buf [string range $buf [incr b] end]
|
||||
#return $res
|
||||
}
|
||||
query/maxRead {
|
||||
set res -1
|
||||
}
|
||||
}
|
||||
|
||||
lappend trail [list rblock | $op $data $res | $buf]
|
||||
return $res
|
||||
}
|
||||
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# ... and convenience procedures to stack them
|
||||
|
||||
proc identity {-attach channel} {
|
||||
testchannel transform $channel -command id
|
||||
}
|
||||
|
||||
proc audit_ops {var -attach channel} {
|
||||
testchannel transform $channel -command [list id_optrail $var]
|
||||
}
|
||||
|
||||
proc audit_flow {var -attach channel} {
|
||||
testchannel transform $channel -command [list id_fulltrail $var]
|
||||
}
|
||||
|
||||
proc stopafter {var n -attach channel} {
|
||||
upvar #0 $var vn
|
||||
set vn $n
|
||||
testchannel transform $channel -command [list counter $var]
|
||||
}
|
||||
|
||||
proc stopafter_audit {var trail n -attach channel} {
|
||||
upvar #0 $var vn
|
||||
set vn $n
|
||||
testchannel transform $channel -command [list counter_audit $var $trail]
|
||||
}
|
||||
|
||||
proc rblocks_t {var trail n -attach channel} {
|
||||
testchannel transform $channel -command [list rblocks $var $trail $n]
|
||||
}
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# serialize an array, with keys in sorted order.
|
||||
|
||||
proc array_sget {v} {
|
||||
upvar $v a
|
||||
|
||||
set res [list]
|
||||
foreach n [lsort [array names a]] {
|
||||
lappend res $n $a($n)
|
||||
}
|
||||
set res
|
||||
}
|
||||
|
||||
proc asort {alist} {
|
||||
# sort a list of key/value pairs by key, removes duplicates too.
|
||||
|
||||
array set a $alist
|
||||
array_sget a
|
||||
}
|
||||
|
||||
########################################################################
|
||||
|
||||
|
||||
test iogt-1.1 {stack/unstack} {
|
||||
set fh [open dummy r]
|
||||
identity -attach $fh
|
||||
testchannel unstack $fh
|
||||
close $fh
|
||||
} {}
|
||||
|
||||
test iogt-1.2 {stack/close} {
|
||||
set fh [open dummy r]
|
||||
identity -attach $fh
|
||||
close $fh
|
||||
} {}
|
||||
|
||||
test iogt-1.3 {stack/unstack, configuration, options} {
|
||||
set fh [open dummy r]
|
||||
set ca [asort [fconfigure $fh]]
|
||||
identity -attach $fh
|
||||
set cb [asort [fconfigure $fh]]
|
||||
testchannel unstack $fh
|
||||
set cc [asort [fconfigure $fh]]
|
||||
close $fh
|
||||
|
||||
# With this system none of the buffering, translation and
|
||||
# encoding option may change their values with channels
|
||||
# stacked upon each other or not.
|
||||
|
||||
# cb == ca == cc
|
||||
|
||||
list [string equal $ca $cb] [string equal $cb $cc] [string equal $ca $cc]
|
||||
} {1 1 1}
|
||||
|
||||
test iogt-1.4 {stack/unstack, configuration} {
|
||||
set fh [open dummy r]
|
||||
set ca [asort [fconfigure $fh]]
|
||||
identity -attach $fh
|
||||
fconfigure $fh \
|
||||
-buffering line \
|
||||
-translation cr \
|
||||
-encoding shiftjis
|
||||
testchannel unstack $fh
|
||||
set cc [asort [fconfigure $fh]]
|
||||
|
||||
set res [list \
|
||||
[string equal $ca $cc] \
|
||||
[fconfigure $fh -buffering] \
|
||||
[fconfigure $fh -translation] \
|
||||
[fconfigure $fh -encoding] \
|
||||
]
|
||||
|
||||
close $fh
|
||||
set res
|
||||
} {0 line cr shiftjis}
|
||||
|
||||
test iogt-2.0 {basic I/O going through transform} {
|
||||
set fin [open dummy r]
|
||||
set fout [open dummyout w]
|
||||
|
||||
identity -attach $fin
|
||||
identity -attach $fout
|
||||
|
||||
fcopy $fin $fout
|
||||
|
||||
close $fin
|
||||
close $fout
|
||||
|
||||
set fin [open dummy r]
|
||||
set fout [open dummyout r]
|
||||
|
||||
set res [string equal [set in [read $fin]] [set out [read $fout]]]
|
||||
lappend res [string length $in] [string length $out]
|
||||
|
||||
close $fin
|
||||
close $fout
|
||||
|
||||
set res
|
||||
} {1 71 71}
|
||||
|
||||
|
||||
test iogt-2.1 {basic I/O, operation trail} {unixOnly} {
|
||||
set fin [open dummy r]
|
||||
set fout [open dummyout w]
|
||||
|
||||
set ain [list] ; set aout [list]
|
||||
audit_ops ain -attach $fin
|
||||
audit_ops aout -attach $fout
|
||||
|
||||
fconfigure $fin -buffersize 10
|
||||
fconfigure $fout -buffersize 5
|
||||
|
||||
fcopy $fin $fout
|
||||
|
||||
close $fin
|
||||
close $fout
|
||||
|
||||
set res "[join $ain \n]\n--------\n[join $aout \n]"
|
||||
} {create/read
|
||||
query/maxRead
|
||||
read
|
||||
query/maxRead
|
||||
read
|
||||
query/maxRead
|
||||
read
|
||||
query/maxRead
|
||||
read
|
||||
query/maxRead
|
||||
read
|
||||
query/maxRead
|
||||
read
|
||||
query/maxRead
|
||||
read
|
||||
query/maxRead
|
||||
read
|
||||
query/maxRead
|
||||
flush/read
|
||||
query/maxRead
|
||||
delete/read
|
||||
--------
|
||||
create/write
|
||||
write
|
||||
write
|
||||
write
|
||||
write
|
||||
write
|
||||
write
|
||||
write
|
||||
write
|
||||
flush/write
|
||||
delete/write}
|
||||
|
||||
test iogt-2.2 {basic I/O, data trail} {unixOnly} {
|
||||
set fin [open dummy r]
|
||||
set fout [open dummyout w]
|
||||
|
||||
set ain [list] ; set aout [list]
|
||||
audit_flow ain -attach $fin
|
||||
audit_flow aout -attach $fout
|
||||
|
||||
fconfigure $fin -buffersize 10
|
||||
fconfigure $fout -buffersize 5
|
||||
|
||||
fcopy $fin $fout
|
||||
|
||||
close $fin
|
||||
close $fout
|
||||
|
||||
set res "[join $ain \n]\n--------\n[join $aout \n]"
|
||||
} {create/read {} *ignored*
|
||||
query/maxRead {} -1
|
||||
read abcdefghij abcdefghij
|
||||
query/maxRead {} -1
|
||||
read klmnopqrst klmnopqrst
|
||||
query/maxRead {} -1
|
||||
read uvwxyz0123 uvwxyz0123
|
||||
query/maxRead {} -1
|
||||
read 456789,./? 456789,./?
|
||||
query/maxRead {} -1
|
||||
read {><;'\|":[]} {><;'\|":[]}
|
||||
query/maxRead {} -1
|
||||
read {\}\{`~!@#$} {\}\{`~!@#$}
|
||||
query/maxRead {} -1
|
||||
read %^&*()_+-= %^&*()_+-=
|
||||
query/maxRead {} -1
|
||||
read {
|
||||
} {
|
||||
}
|
||||
query/maxRead {} -1
|
||||
flush/read {} {}
|
||||
query/maxRead {} -1
|
||||
delete/read {} *ignored*
|
||||
--------
|
||||
create/write {} *ignored*
|
||||
write abcdefghij abcdefghij
|
||||
write klmnopqrst klmnopqrst
|
||||
write uvwxyz0123 uvwxyz0123
|
||||
write 456789,./? 456789,./?
|
||||
write {><;'\|":[]} {><;'\|":[]}
|
||||
write {\}\{`~!@#$} {\}\{`~!@#$}
|
||||
write %^&*()_+-= %^&*()_+-=
|
||||
write {
|
||||
} {
|
||||
}
|
||||
flush/write {} {}
|
||||
delete/write {} *ignored*}
|
||||
|
||||
|
||||
test iogt-2.3 {basic I/O, mixed trail} {unixOnly} {
|
||||
set fin [open dummy r]
|
||||
set fout [open dummyout w]
|
||||
|
||||
set trail [list]
|
||||
audit_flow trail -attach $fin
|
||||
audit_flow trail -attach $fout
|
||||
|
||||
fconfigure $fin -buffersize 20
|
||||
fconfigure $fout -buffersize 10
|
||||
|
||||
fcopy $fin $fout
|
||||
|
||||
close $fin
|
||||
close $fout
|
||||
|
||||
join $trail \n
|
||||
} {create/read {} *ignored*
|
||||
create/write {} *ignored*
|
||||
query/maxRead {} -1
|
||||
read abcdefghijklmnopqrst abcdefghijklmnopqrst
|
||||
write abcdefghij abcdefghij
|
||||
write klmnopqrst klmnopqrst
|
||||
query/maxRead {} -1
|
||||
read uvwxyz0123456789,./? uvwxyz0123456789,./?
|
||||
write uvwxyz0123 uvwxyz0123
|
||||
write 456789,./? 456789,./?
|
||||
query/maxRead {} -1
|
||||
read {><;'\|":[]\}\{`~!@#$} {><;'\|":[]\}\{`~!@#$}
|
||||
write {><;'\|":[]} {><;'\|":[]}
|
||||
write {\}\{`~!@#$} {\}\{`~!@#$}
|
||||
query/maxRead {} -1
|
||||
read {%^&*()_+-=
|
||||
} {%^&*()_+-=
|
||||
}
|
||||
query/maxRead {} -1
|
||||
flush/read {} {}
|
||||
write %^&*()_+-= %^&*()_+-=
|
||||
write {
|
||||
} {
|
||||
}
|
||||
query/maxRead {} -1
|
||||
delete/read {} *ignored*
|
||||
flush/write {} {}
|
||||
delete/write {} *ignored*}
|
||||
|
||||
|
||||
test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} \
|
||||
{unknownFailure} {
|
||||
# This test to check the validity of aquired Tcl_Channel references is
|
||||
# not possible because even a backgrounded fcopy will immediately start
|
||||
# to copy data, without waiting for the event loop. This is done only in
|
||||
# case of an underflow on the read size!. So stacking transforms after the
|
||||
# fcopy will miss information, or are not used at all.
|
||||
#
|
||||
# I was able to circumvent this by using the echo.tcl server with a big
|
||||
# delay, causing the fcopy to underflow immediately.
|
||||
|
||||
proc DoneCopy {n {err {}}} {
|
||||
global copy ; set copy 1
|
||||
}
|
||||
|
||||
set fin [open dummy r]
|
||||
|
||||
fevent 1000 500 {20 20 20 10 1 1} {
|
||||
close $fin
|
||||
|
||||
set fout [open dummyout w]
|
||||
|
||||
flush $sock ; # now, or fcopy will error us out
|
||||
# But the 1 second delay should be enough to
|
||||
# initialize everything else here.
|
||||
|
||||
fcopy $sock $fout -command DoneCopy
|
||||
|
||||
# transform after fcopy got its handles !
|
||||
# They should be still valid for fcopy.
|
||||
|
||||
set trail [list]
|
||||
audit_ops trail -attach $fout
|
||||
|
||||
vwait copy
|
||||
} [read $fin] ; # {}
|
||||
|
||||
close $fout
|
||||
|
||||
rename DoneCopy {}
|
||||
|
||||
# Check result of copy.
|
||||
|
||||
set fin [open dummy r]
|
||||
set fout [open dummyout r]
|
||||
|
||||
set res [string equal [read $fin] [read $fout]]
|
||||
|
||||
close $fin
|
||||
close $fout
|
||||
|
||||
list $res $trail
|
||||
} {1 {create/write create/read write flush/write flush/read delete/write delete/read}}
|
||||
|
||||
|
||||
test iogt-4.0 {fileevent readable, after transform} {unknownFailure} {
|
||||
set fin [open dummy r]
|
||||
set data [read $fin]
|
||||
close $fin
|
||||
|
||||
set trail [list]
|
||||
set got [list]
|
||||
|
||||
proc Done {args} {
|
||||
global stop
|
||||
set stop 1
|
||||
}
|
||||
|
||||
proc Get {sock} {
|
||||
global trail got
|
||||
if {[eof $sock]} {
|
||||
Done
|
||||
lappend trail "xxxxxxxxxxxxx"
|
||||
close $sock
|
||||
return
|
||||
}
|
||||
lappend trail "vvvvvvvvvvvvv"
|
||||
lappend trail "\tgot: [lappend got "\[\[[read $sock]\]\]"]"
|
||||
lappend trail "============="
|
||||
#puts stdout $__ ; flush stdout
|
||||
#read $sock
|
||||
}
|
||||
|
||||
fevent 1000 500 {20 20 20 10 1} {
|
||||
audit_flow trail -attach $sock
|
||||
rblocks_t rbuf trail 23 -attach $sock
|
||||
|
||||
fileevent $sock readable [list Get $sock]
|
||||
|
||||
flush $sock ; # now, or fcopy will error us out
|
||||
# But the 1 second delay should be enough to
|
||||
# initialize everything else here.
|
||||
|
||||
vwait stop
|
||||
} $data
|
||||
|
||||
|
||||
rename Done {}
|
||||
rename Get {}
|
||||
|
||||
join [list [join $got \n] ~~~~~~~~ [join $trail \n]] \n
|
||||
} {[[]]
|
||||
[[abcdefghijklmnopqrstuvw]]
|
||||
[[xyz0123456789,./?><;'\|]]
|
||||
[[]]
|
||||
[[]]
|
||||
[[":[]\}\{`~!@#$%^&*()]]
|
||||
[[]]
|
||||
~~~~~~~~
|
||||
create/write {} *ignored*
|
||||
create/read {} *ignored*
|
||||
rblock | create/write {} {} | {}
|
||||
rblock | create/read {} {} | {}
|
||||
vvvvvvvvvvvvv
|
||||
rblock | query/maxRead {} -1 | {}
|
||||
query/maxRead {} -1
|
||||
read abcdefghijklmnopqrstu abcdefghijklmnopqrstu
|
||||
query/maxRead {} -1
|
||||
rblock | {read 23 21 :- 0} abcdefghijklmnopqrstu {} | abcdefghijklmnopqrstu
|
||||
rblock | query/maxRead {} -1 | abcdefghijklmnopqrstu
|
||||
query/maxRead {} -1
|
||||
got: {[[]]}
|
||||
=============
|
||||
vvvvvvvvvvvvv
|
||||
rblock | query/maxRead {} -1 | abcdefghijklmnopqrstu
|
||||
query/maxRead {} -1
|
||||
read vwxyz0123456789,./?>< vwxyz0123456789,./?><
|
||||
query/maxRead {} -1
|
||||
rblock | {read 23 42 :- 23} vwxyz0123456789,./?>< abcdefghijklmnopqrstuvw | xyz0123456789,./?><
|
||||
rblock | query/maxRead {} -1 | xyz0123456789,./?><
|
||||
query/maxRead {} -1
|
||||
got: {[[]]} {[[abcdefghijklmnopqrstuvw]]}
|
||||
=============
|
||||
vvvvvvvvvvvvv
|
||||
rblock | query/maxRead {} -1 | xyz0123456789,./?><
|
||||
query/maxRead {} -1
|
||||
read {;'\|":[]\}\{`~!@#$%^&} {;'\|":[]\}\{`~!@#$%^&}
|
||||
query/maxRead {} -1
|
||||
rblock | {read 23 40 :- 23} {;'\|":[]\}\{`~!@#$%^&} {xyz0123456789,./?><;'\|} | {":[]\}\{`~!@#$%^&}
|
||||
rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&}
|
||||
query/maxRead {} -1
|
||||
got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]}
|
||||
=============
|
||||
vvvvvvvvvvvvv
|
||||
rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&}
|
||||
query/maxRead {} -1
|
||||
read *( *(
|
||||
query/maxRead {} -1
|
||||
rblock | {read 23 19 :- 0} *( {} | {":[]\}\{`~!@#$%^&*(}
|
||||
rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*(}
|
||||
query/maxRead {} -1
|
||||
got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]}
|
||||
=============
|
||||
vvvvvvvvvvvvv
|
||||
rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*(}
|
||||
query/maxRead {} -1
|
||||
read ) )
|
||||
query/maxRead {} -1
|
||||
rblock | {read 23 20 :- 0} ) {} | {":[]\}\{`~!@#$%^&*()}
|
||||
rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*()}
|
||||
query/maxRead {} -1
|
||||
got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]}
|
||||
=============
|
||||
vvvvvvvvvvvvv
|
||||
rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*()}
|
||||
query/maxRead {} -1
|
||||
flush/read {} {}
|
||||
rblock | flush/read {} {":[]\}\{`~!@#$%^&*()} | {}
|
||||
rblock | query/maxRead {} -1 | {}
|
||||
query/maxRead {} -1
|
||||
got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]} {[[":[]\}\{`~!@#$%^&*()]]}
|
||||
=============
|
||||
vvvvvvvvvvvvv
|
||||
rblock | query/maxRead {} -1 | {}
|
||||
query/maxRead {} -1
|
||||
got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]} {[[":[]\}\{`~!@#$%^&*()]]} {[[]]}
|
||||
xxxxxxxxxxxxx
|
||||
rblock | flush/write {} {} | {}
|
||||
rblock | delete/write {} {} | {}
|
||||
rblock | delete/read {} {} | {}
|
||||
flush/write {} {}
|
||||
delete/write {} *ignored*
|
||||
delete/read {} *ignored*} ; # catch unescaped quote "
|
||||
|
||||
|
||||
test iogt-5.0 {EOF simulation} {unknownFailure} {
|
||||
set fin [open dummy r]
|
||||
set fout [open dummyout w]
|
||||
|
||||
set trail [list]
|
||||
|
||||
audit_flow trail -attach $fin
|
||||
stopafter_audit d trail 20 -attach $fin
|
||||
audit_flow trail -attach $fout
|
||||
|
||||
fconfigure $fin -buffersize 20
|
||||
fconfigure $fout -buffersize 10
|
||||
|
||||
fcopy $fin $fout
|
||||
testchannel unstack $fin
|
||||
|
||||
# now copy the rest in the channel
|
||||
lappend trail {**after unstack**}
|
||||
|
||||
fcopy $fin $fout
|
||||
|
||||
close $fin
|
||||
close $fout
|
||||
|
||||
join $trail \n
|
||||
} {create/read {} *ignored*
|
||||
counter:create/read {} {}
|
||||
create/write {} *ignored*
|
||||
counter:query/maxRead {} 20
|
||||
query/maxRead {} -1
|
||||
read {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
|
||||
} {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
|
||||
}
|
||||
query/maxRead {} -1
|
||||
flush/read {} {}
|
||||
counter:read abcdefghijklmnopqrst abcdefghijklmnopqrst
|
||||
write abcdefghij abcdefghij
|
||||
write klmnopqrst klmnopqrst
|
||||
counter:query/maxRead {} 0
|
||||
counter:flush/read {} {}
|
||||
counter:delete/read {} {}
|
||||
**after unstack**
|
||||
query/maxRead {} -1
|
||||
write uvwxyz0123 uvwxyz0123
|
||||
write 456789,./? 456789,./?
|
||||
write {><;'\|":[]} {><;'\|":[]}
|
||||
write {\}\{`~!@#$} {\}\{`~!@#$}
|
||||
write %^&*()_+-= %^&*()_+-=
|
||||
write {
|
||||
} {
|
||||
}
|
||||
query/maxRead {} -1
|
||||
delete/read {} *ignored*
|
||||
flush/write {} {}
|
||||
delete/write {} *ignored*}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
proc constX {op data} {
|
||||
# replace anything coming in with a same-length string of x'es.
|
||||
switch -- $op {
|
||||
create/write - create/read -
|
||||
delete/write - delete/read -
|
||||
clear_read {;#ignore}
|
||||
flush/write - flush/read -
|
||||
write -
|
||||
read {
|
||||
return [string repeat x [string length $data]]
|
||||
}
|
||||
query/maxRead {return -1}
|
||||
}
|
||||
}
|
||||
|
||||
proc constx {-attach channel} {
|
||||
testchannel transform $channel -command constX
|
||||
}
|
||||
|
||||
test iogt-6.0 {Push back} {
|
||||
set f [open dummy r]
|
||||
|
||||
# contents of dummy = "abcdefghi..."
|
||||
read $f 3 ; # skip behind "abc"
|
||||
|
||||
constx -attach $f
|
||||
|
||||
# expect to get "xxx" from the transform because
|
||||
# of unread "def" input to transform which returns "xxx".
|
||||
#
|
||||
# Actually the IO layer pre-read the whole file and will
|
||||
# read "def" directly from the buffer without bothering
|
||||
# to consult the newly stacked transformation. This is
|
||||
# wrong.
|
||||
|
||||
set res [read $f 3]
|
||||
close $f
|
||||
set res
|
||||
} {xxx}
|
||||
|
||||
test iogt-6.1 {Push back and up} {knownBug} {
|
||||
set f [open dummy r]
|
||||
|
||||
# contents of dummy = "abcdefghi..."
|
||||
read $f 3 ; # skip behind "abc"
|
||||
|
||||
constx -attach $f
|
||||
set res [read $f 3]
|
||||
|
||||
testchannel unstack $f
|
||||
append res [read $f 3]
|
||||
close $f
|
||||
set res
|
||||
} {xxxghi}
|
||||
|
||||
|
||||
# cleanup
|
||||
foreach file [list dummy dummyout __echo_srv__.tcl] {
|
||||
::tcltest::removeFile $file
|
||||
}
|
||||
::tcltest::restoreState
|
||||
::tcltest::cleanupTests
|
||||
return
|
||||
+23
-38
@@ -5,12 +5,12 @@
|
||||
# generates output for errors. No output means no errors were found.
|
||||
#
|
||||
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
|
||||
# Copyright (c) 1998-1999 by Scriptics Corporation.
|
||||
# Copyright (c) 1998-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: socket.test,v 1.14 2000/04/10 17:19:04 ericm Exp $
|
||||
# RCS: @(#) $Id: socket.test,v 1.14.2.1 2000/07/27 01:39:21 hobbs Exp $
|
||||
|
||||
# Running socket tests with a remote server:
|
||||
# ------------------------------------------
|
||||
@@ -67,10 +67,11 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
|
||||
namespace import -force ::tcltest::*
|
||||
}
|
||||
|
||||
# Some tests require the testthread command
|
||||
# Some tests require the testthread and exec commands
|
||||
|
||||
set ::tcltest::testConstraints(testthread) \
|
||||
[expr {[info commands testthread] != {}}]
|
||||
set ::tcltest::testConstraints(exec) [expr {[info commands exec] != {}}]
|
||||
|
||||
#
|
||||
# If remoteServerIP or remoteServerPort are not set, check in the
|
||||
@@ -551,19 +552,19 @@ test socket-2.11 {detecting new data} {socket} {
|
||||
flush $s2
|
||||
after 500
|
||||
fconfigure $sock -blocking 0
|
||||
set result [gets $sock]
|
||||
lappend result [gets $sock]
|
||||
set result a:[gets $sock]
|
||||
lappend result b:[gets $sock]
|
||||
fconfigure $sock -blocking 1
|
||||
puts $s2 two
|
||||
flush $s2
|
||||
fconfigure $sock -blocking 0
|
||||
lappend result [gets $sock]
|
||||
lappend result c:[gets $sock]
|
||||
fconfigure $sock -blocking 1
|
||||
close $s2
|
||||
close $s
|
||||
close $sock
|
||||
set result
|
||||
} {one {} two}
|
||||
} {a:one b: c:two}
|
||||
|
||||
|
||||
test socket-3.1 {socket conflict} {socket stdio} {
|
||||
@@ -1276,6 +1277,7 @@ test socket-11.11 {testing spurious events} {socket doTestsWithRemoteServer} {
|
||||
sendCommand {close $socket10_13_test_server}
|
||||
list $spurious $len
|
||||
} {0 2690}
|
||||
|
||||
test socket-11.12 {testing EOF stickyness} {socket doTestsWithRemoteServer} {
|
||||
set counter 0
|
||||
set done 0
|
||||
@@ -1303,12 +1305,13 @@ test socket-11.12 {testing EOF stickyness} {socket doTestsWithRemoteServer} {
|
||||
}
|
||||
}
|
||||
set c [socket $remoteServerIP 2836]
|
||||
fileevent $c readable "count_up $c"
|
||||
fileevent $c readable [list count_up $c]
|
||||
set after_id [after 1000 timed_out]
|
||||
vwait done
|
||||
sendCommand {close $socket10_14_test_server}
|
||||
set done
|
||||
} {EOF is sticky}
|
||||
|
||||
test socket-11.13 {testing async write, async flush, async close} \
|
||||
{socket doTestsWithRemoteServer} {
|
||||
proc readit {s} {
|
||||
@@ -1363,8 +1366,7 @@ test socket-11.13 {testing async write, async flush, async close} \
|
||||
set count
|
||||
} 65566
|
||||
|
||||
test socket-12.1 {testing inheritance of server sockets} \
|
||||
{socket doTestsWithRemoteServer} {
|
||||
test socket-12.1 {testing inheritance of server sockets} {socket exec} {
|
||||
removeFile script1
|
||||
removeFile script2
|
||||
|
||||
@@ -1383,14 +1385,13 @@ test socket-12.1 {testing inheritance of server sockets} \
|
||||
# be closed unless script1 inherited it.
|
||||
|
||||
set f [open script2 w]
|
||||
puts $f [list set tcltest $::tcltest::tcltest]
|
||||
puts $f [list set tclsh $::tcltest::tcltest]
|
||||
puts $f {
|
||||
package require tcltest
|
||||
set f [socket -server accept 2828]
|
||||
proc accept { file addr port } {
|
||||
close $file
|
||||
}
|
||||
exec $::tcltest::tcltest script1 &
|
||||
exec $tclsh script1 &
|
||||
close $f
|
||||
after 1000 exit
|
||||
vwait forever
|
||||
@@ -1416,8 +1417,7 @@ test socket-12.1 {testing inheritance of server sockets} \
|
||||
removeFile script2
|
||||
set x
|
||||
} {server socket was not inherited}
|
||||
test socket-12.2 {testing inheritance of client sockets} \
|
||||
{socket doTestsWithRemoteServer} {
|
||||
test socket-12.2 {testing inheritance of client sockets} {socket exec} {
|
||||
removeFile script1
|
||||
removeFile script2
|
||||
|
||||
@@ -1436,10 +1436,10 @@ test socket-12.2 {testing inheritance of client sockets} \
|
||||
# client socket, the socket will still be open.
|
||||
|
||||
set f [open script2 w]
|
||||
puts $f [list set tcltest $::tcltest::tcltest]
|
||||
puts $f [list set tclsh $::tcltest::tcltest]
|
||||
puts $f {
|
||||
set f [socket 127.0.0.1 2829]
|
||||
exec $::tcltest::tcltest script1 &
|
||||
exec $tclsh script1 &
|
||||
puts $f testing
|
||||
flush $f
|
||||
after 1000 exit
|
||||
@@ -1451,7 +1451,6 @@ test socket-12.2 {testing inheritance of client sockets} \
|
||||
|
||||
set server [socket -server accept 2829]
|
||||
proc accept { file host port } {
|
||||
|
||||
# When the client connects, establish the read handler
|
||||
global server
|
||||
close $server
|
||||
@@ -1460,7 +1459,6 @@ test socket-12.2 {testing inheritance of client sockets} \
|
||||
return
|
||||
}
|
||||
proc getdata { file } {
|
||||
|
||||
# Read handler on the accepted socket.
|
||||
global x
|
||||
global failed
|
||||
@@ -1502,8 +1500,7 @@ test socket-12.2 {testing inheritance of client sockets} \
|
||||
removeFile script2
|
||||
set x
|
||||
} {client socket was not inherited}
|
||||
test socket-12.3 {testing inheritance of accepted sockets} \
|
||||
{socket doTestsWithRemoteServer} {
|
||||
test socket-12.3 {testing inheritance of accepted sockets} {socket exec} {
|
||||
removeFile script1
|
||||
removeFile script2
|
||||
|
||||
@@ -1515,13 +1512,13 @@ test socket-12.3 {testing inheritance of accepted sockets} \
|
||||
close $f
|
||||
|
||||
set f [open script2 w]
|
||||
puts $f [list set tcltest $::tcltest::tcltest]
|
||||
puts $f [list set tclsh $::tcltest::tcltest]
|
||||
puts $f {
|
||||
set server [socket -server accept 2930]
|
||||
set server [socket -server accept 2931]
|
||||
proc accept { file host port } {
|
||||
global tcltest
|
||||
global tclsh
|
||||
puts $file {test data on socket}
|
||||
exec $::tcltest::tcltest script1 &
|
||||
exec $tclsh script1 &
|
||||
after 1000 exit
|
||||
}
|
||||
vwait forever
|
||||
@@ -1536,7 +1533,7 @@ test socket-12.3 {testing inheritance of accepted sockets} \
|
||||
after 1000 set ok_to_proceed 1
|
||||
vwait ok_to_proceed
|
||||
|
||||
set f [socket 127.0.0.1 2930]
|
||||
set f [socket 127.0.0.1 2931]
|
||||
fconfigure $f -buffering full -blocking 0
|
||||
fileevent $f readable [list getdata $f]
|
||||
|
||||
@@ -1547,7 +1544,6 @@ test socket-12.3 {testing inheritance of accepted sockets} \
|
||||
after 5000 set failed 1
|
||||
|
||||
proc getdata { file } {
|
||||
|
||||
# Read handler on the client socket.
|
||||
global x
|
||||
global failed
|
||||
@@ -1642,14 +1638,3 @@ catch {close $remoteProcChan}
|
||||
::tcltest::cleanupTests
|
||||
flush stdout
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ item: Global
|
||||
Log Pathname=%MAINDIR%\INSTALL.LOG
|
||||
Message Font=MS Sans Serif
|
||||
Font Size=8
|
||||
Disk Label=tcl8.3.1
|
||||
Disk Label=tcl8.3.2
|
||||
Disk Filename=setup
|
||||
Patch Flags=0000000000000001
|
||||
Patch Threshold=85
|
||||
|
||||
+8
-4
@@ -5,7 +5,7 @@
|
||||
# "autoconf" program (constructs like "@foo@" will get replaced in the
|
||||
# actual Makefile.
|
||||
#
|
||||
# RCS: @(#) $Id: Makefile.in,v 1.63 2000/04/25 20:58:48 hobbs Exp $
|
||||
# RCS: @(#) $Id: Makefile.in,v 1.63.2.1 2000/07/27 01:39:22 hobbs Exp $
|
||||
|
||||
VERSION = @TCL_VERSION@
|
||||
|
||||
@@ -266,8 +266,8 @@ GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \
|
||||
tclCkalloc.o tclClock.o tclCmdAH.o tclCmdIL.o tclCmdMZ.o \
|
||||
tclCompCmds.o tclCompExpr.o tclCompile.o tclDate.o tclEncoding.o \
|
||||
tclEnv.o tclEvent.o tclExecute.o tclFCmd.o tclFileName.o tclGet.o \
|
||||
tclHash.o tclHistory.o tclIndexObj.o tclInterp.o tclIO.o \
|
||||
tclIOCmd.o tclIOSock.o tclIOUtil.o tclLink.o tclListObj.o \
|
||||
tclHash.o tclHistory.o tclIndexObj.o tclInterp.o tclIO.o tclIOCmd.o \
|
||||
tclIOGT.o tclIOSock.o tclIOUtil.o tclLink.o tclListObj.o \
|
||||
tclLiteral.o tclLoad.o tclMain.o tclNamesp.o tclNotify.o \
|
||||
tclObj.o tclPanic.o tclParse.o tclParseExpr.o tclPipe.o \
|
||||
tclPkg.o tclPosixStr.o tclPreserve.o tclProc.o tclRegexp.o \
|
||||
@@ -324,6 +324,7 @@ GENERIC_SRCS = \
|
||||
$(GENERIC_DIR)/tclInterp.c \
|
||||
$(GENERIC_DIR)/tclIO.c \
|
||||
$(GENERIC_DIR)/tclIOCmd.c \
|
||||
$(GENERIC_DIR)/tclIOGT.c \
|
||||
$(GENERIC_DIR)/tclIOSock.c \
|
||||
$(GENERIC_DIR)/tclIOUtil.c \
|
||||
$(GENERIC_DIR)/tclLink.c \
|
||||
@@ -473,7 +474,7 @@ topDirName:
|
||||
gendate:
|
||||
yacc -l $(GENERIC_DIR)/tclGetDate.y
|
||||
sed -e 's/yy/TclDate/g' -e '/^#include <values.h>/d' \
|
||||
-e 's?SCCSID?RCS: @(#) $$Id: Makefile.in,v 1.63 2000/04/25 20:58:48 hobbs Exp $$?' \
|
||||
-e 's?SCCSID?RCS: @(#) $$Id: Makefile.in,v 1.63.2.1 2000/07/27 01:39:22 hobbs Exp $$?' \
|
||||
-e '/#ifdef __STDC__/,/#endif/d' -e '/TclDateerrlab:/d' \
|
||||
-e '/TclDatenewstate:/d' -e '/#pragma/d' \
|
||||
-e '/#include <inttypes.h>/d' -e 's/const /CONST /g' \
|
||||
@@ -782,6 +783,9 @@ tclIO.o: $(GENERIC_DIR)/tclIO.c
|
||||
tclIOCmd.o: $(GENERIC_DIR)/tclIOCmd.c
|
||||
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclIOCmd.c
|
||||
|
||||
tclIOGT.o: $(GENERIC_DIR)/tclIOGT.c
|
||||
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclIOGT.c
|
||||
|
||||
tclIOSock.o: $(GENERIC_DIR)/tclIOSock.c
|
||||
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclIOSock.c
|
||||
|
||||
|
||||
+2
-2
@@ -3,12 +3,12 @@ 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.
|
||||
AC_INIT(../generic/tcl.h)
|
||||
# RCS: @(#) $Id: configure.in,v 1.57 2000/04/19 08:32:45 hobbs Exp $
|
||||
# RCS: @(#) $Id: configure.in,v 1.57.2.1 2000/07/27 01:39:22 hobbs Exp $
|
||||
|
||||
TCL_VERSION=8.3
|
||||
TCL_MAJOR_VERSION=8
|
||||
TCL_MINOR_VERSION=3
|
||||
TCL_PATCH_LEVEL=".1"
|
||||
TCL_PATCH_LEVEL=".2"
|
||||
VERSION=${TCL_VERSION}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
+974
-651
File diff suppressed because it is too large
Load Diff
+13
-21
@@ -47,31 +47,23 @@ foreach file $argv {
|
||||
if {[regexp "^.SH NAME" $line]} {
|
||||
set state name
|
||||
}
|
||||
}
|
||||
name {
|
||||
regsub {\\-.*} $line {} line
|
||||
set rmOutput ""
|
||||
set lnOutput ""
|
||||
set namelist {}
|
||||
foreach name [split $line ,] {
|
||||
regsub -all {(\\)? } $name "" name
|
||||
if {![string match $name*$ext $tail]} {
|
||||
lappend namelist $name$ext
|
||||
append rmOutput " rm -f $name$ext\n"
|
||||
append lnOutput " ln $tail $name$ext\n"
|
||||
}
|
||||
}
|
||||
if { [llength $namelist] } {
|
||||
}
|
||||
name {
|
||||
regsub {\\-.*} $line {} line
|
||||
foreach name [split $line ,] {
|
||||
regsub -all { } $name "" name
|
||||
if {![string match $name*$ext $tail]} {
|
||||
puts "if test -r $tail; then"
|
||||
puts -nonewline $rmOutput
|
||||
puts -nonewline $lnOutput
|
||||
puts " rm -f $name$ext"
|
||||
puts " ln $tail $name$ext"
|
||||
puts "fi"
|
||||
}
|
||||
set state end
|
||||
}
|
||||
end {
|
||||
break
|
||||
}
|
||||
set state end
|
||||
}
|
||||
end {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
close $in
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
# $Id: tcl.spec,v 1.4 2000/04/26 17:31:21 hobbs Exp $
|
||||
# $Id: tcl.spec,v 1.4.2.1 2000/07/27 01:39:23 hobbs Exp $
|
||||
# This file is the basis for a binary Tcl RPM for Linux.
|
||||
|
||||
%define version 8.3.1
|
||||
%define version 8.3.2
|
||||
%define directory /usr/local
|
||||
|
||||
Summary: Tcl scripting language development environment
|
||||
|
||||
+11
-2
@@ -5,7 +5,7 @@
|
||||
# "autoconf" program (constructs like "@foo@" will get replaced in the
|
||||
# actual Makefile.
|
||||
#
|
||||
# RCS: @(#) $Id: Makefile.in,v 1.33 2000/04/25 20:58:48 hobbs Exp $
|
||||
# RCS: @(#) $Id: Makefile.in,v 1.33.2.2 2000/07/27 01:39:23 hobbs Exp $
|
||||
|
||||
VERSION = @TCL_VERSION@
|
||||
|
||||
@@ -134,7 +134,7 @@ PIPE_DLL_FILE = tclpip$(VER).dll
|
||||
|
||||
SHARED_LIBRARIES = $(TCL_DLL_FILE) $(TCL_STUB_LIB_FILE) \
|
||||
$(DDE_DLL_FILE) $(REG_DLL_FILE) $(PIPE_DLL_FILE)
|
||||
STATIC_LIBRARIES = $(TCL_LIB_FILE)
|
||||
STATIC_LIBRARIES = $(TCL_LIB_FILE) $(REG_LIB_FILE) $(DDE_LIB_FILE)
|
||||
|
||||
TCLSH = tclsh$(VER)${EXESUFFIX}
|
||||
TCLTEST = tcltest${EXEEXT}
|
||||
@@ -229,6 +229,7 @@ GENERIC_OBJS = \
|
||||
tclInterp.$(OBJEXT) \
|
||||
tclIO.$(OBJEXT) \
|
||||
tclIOCmd.$(OBJEXT) \
|
||||
tclIOGT.$(OBJEXT) \
|
||||
tclIOSock.$(OBJEXT) \
|
||||
tclIOUtil.$(OBJEXT) \
|
||||
tclLink.$(OBJEXT) \
|
||||
@@ -345,10 +346,18 @@ ${DDE_DLL_FILE}: ${DDE_OBJS} ${TCL_STUB_LIB_FILE}
|
||||
@$(RM) ${DDE_DLL_FILE}
|
||||
@MAKE_DLL@ ${DDE_OBJS} ${TCL_STUB_LIB_FILE}
|
||||
|
||||
${DDE_LIB_FILE}: ${DDE_OBJS} ${TCL_LIB_FILE}
|
||||
@$(RM) ${DDE_LIB_FILE}
|
||||
@MAKE_LIB@ ${DDE_OBJS} ${TCL_LIB_FILE}
|
||||
|
||||
${REG_DLL_FILE}: ${REG_OBJS} ${TCL_STUB_LIB_FILE}
|
||||
@$(RM) ${REG_DLL_FILE}
|
||||
@MAKE_DLL@ ${REG_OBJS} ${TCL_STUB_LIB_FILE}
|
||||
|
||||
${REG_LIB_FILE}: ${REG_OBJS} ${TCL_LIB_FILE}
|
||||
@$(RM) ${REG_LIB_FILE}
|
||||
@MAKE_LIB@ ${REG_OBJS} ${TCL_LIB_FILE}
|
||||
|
||||
# PIPE_DLL_FILE is actually an executable, don't build it
|
||||
# like a DLL.
|
||||
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
Tcl/Tk 8.3 for Windows, Binary Distribution
|
||||
|
||||
RCS: @(#) $Id: README.binary,v 1.19 2000/04/26 17:31:22 hobbs Exp $
|
||||
RCS: @(#) $Id: README.binary,v 1.19.2.1 2000/07/27 01:39:23 hobbs Exp $
|
||||
|
||||
1. Introduction
|
||||
---------------
|
||||
|
||||
This directory contains the binary distribution of Tcl/Tk 8.3.1 for
|
||||
This directory contains the binary distribution of Tcl/Tk 8.3.2 for
|
||||
Windows. It was compiled with Microsoft Visual C++ 5.0 using Win32
|
||||
API, so that it will run under Windows NT, 95, 98 and 2000.
|
||||
|
||||
@@ -29,7 +29,7 @@ The home page for the Tcl/Tk 8.3 release is
|
||||
http://dev.scriptics.com/software/tcltk/8.3.html
|
||||
|
||||
Detailed release notes can be found at
|
||||
http://dev.scriptics.com/software/tcltk/relnotes/tcl8.3.1.txt
|
||||
http://dev.scriptics.com/software/tcltk/relnotes/tcl8.3.2.txt
|
||||
|
||||
Information about Tcl itself can be found at
|
||||
http://dev.scriptics.com/scripting/
|
||||
|
||||
+2
-2
@@ -2,14 +2,14 @@
|
||||
# generate the file "configure", which is run during Tcl installation
|
||||
# to configure the system for the local environment.
|
||||
#
|
||||
# RCS: @(#) $Id: configure.in,v 1.20 2000/04/19 08:32:46 hobbs Exp $
|
||||
# RCS: @(#) $Id: configure.in,v 1.20.2.1 2000/07/27 01:39:24 hobbs Exp $
|
||||
|
||||
AC_INIT(../generic/tcl.h)
|
||||
|
||||
TCL_VERSION=8.3
|
||||
TCL_MAJOR_VERSION=8
|
||||
TCL_MINOR_VERSION=3
|
||||
TCL_PATCH_LEVEL=".1"
|
||||
TCL_PATCH_LEVEL=".2"
|
||||
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
+2
-1
@@ -6,7 +6,7 @@
|
||||
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
|
||||
# Copyright (c) 1998-1999 by Scriptics Corporation.
|
||||
#
|
||||
# RCS: @(#) $Id: makefile.vc,v 1.50 2000/04/25 20:58:48 hobbs Exp $
|
||||
# RCS: @(#) $Id: makefile.vc,v 1.50.2.1 2000/07/27 01:39:24 hobbs Exp $
|
||||
|
||||
# Does not depend on the presence of any environment variables in
|
||||
# order to compile tcl; all needed information is derived from
|
||||
@@ -152,6 +152,7 @@ TCLOBJS = \
|
||||
$(TMPDIR)\tclInterp.obj \
|
||||
$(TMPDIR)\tclIO.obj \
|
||||
$(TMPDIR)\tclIOCmd.obj \
|
||||
$(TMPDIR)\tclIOGT.obj \
|
||||
$(TMPDIR)\tclIOSock.obj \
|
||||
$(TMPDIR)\tclIOUtil.obj \
|
||||
$(TMPDIR)\tclLink.obj \
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# The information in this file is specific to a single platform.
|
||||
#
|
||||
# RCS: @(#) $Id: tclConfig.sh.in,v 1.3 1999/07/29 19:21:32 wart Exp $
|
||||
# RCS: @(#) $Id: tclConfig.sh.in,v 1.3.10.1 2000/07/13 01:08:47 welch Exp $
|
||||
|
||||
|
||||
TCL_SRC_DIR="@TCL_SRC_DIR@"
|
||||
@@ -60,7 +60,7 @@ TCL_NEEDS_EXP_FILE=@TCL_NEEDS_EXP_FILE@
|
||||
TCL_EXPORT_FILE_SUFFIX='@CFG_TCL_EXPORT_FILE_SUFFIX@'
|
||||
|
||||
# Additional libraries to use when linking Tcl.
|
||||
TCL_LIBS='@DL_LIBS@ @LIBS@ @MATH_LIBS@'
|
||||
TCL_LIBS='@LIBS@'
|
||||
|
||||
# Top-level directory in which Tcl's platform-independent files are
|
||||
# installed.
|
||||
|
||||
+6
-2
@@ -9,7 +9,7 @@
|
||||
* 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.10 2000/04/20 01:30:20 hobbs Exp $
|
||||
* RCS: @(#) $Id: tclWinChan.c,v 1.10.2.1 2000/07/27 01:39:24 hobbs Exp $
|
||||
*/
|
||||
|
||||
#include "tclWinInt.h"
|
||||
@@ -101,7 +101,7 @@ static void FileWatchProc _ANSI_ARGS_((ClientData instanceData,
|
||||
|
||||
static Tcl_ChannelType fileChannelType = {
|
||||
"file", /* Type name. */
|
||||
FileBlockProc, /* Set blocking or non-blocking mode.*/
|
||||
TCL_CHANNEL_VERSION_2, /* v2 channel */
|
||||
FileCloseProc, /* Close proc. */
|
||||
FileInputProc, /* Input proc. */
|
||||
FileOutputProc, /* Output proc. */
|
||||
@@ -110,6 +110,10 @@ static Tcl_ChannelType fileChannelType = {
|
||||
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. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
+6
-2
@@ -9,7 +9,7 @@
|
||||
* 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.3 1999/07/27 01:42:25 redman Exp $
|
||||
* RCS: @(#) $Id: tclWinConsole.c,v 1.3.10.1 2000/07/27 01:39:25 hobbs Exp $
|
||||
*/
|
||||
|
||||
#include "tclWinInt.h"
|
||||
@@ -171,7 +171,7 @@ static int WaitForRead(ConsoleInfo *infoPtr, int blocking);
|
||||
|
||||
static Tcl_ChannelType consoleChannelType = {
|
||||
"console", /* Type name. */
|
||||
ConsoleBlockModeProc, /* Set blocking or non-blocking mode.*/
|
||||
TCL_CHANNEL_VERSION_2, /* v2 channel */
|
||||
ConsoleCloseProc, /* Close proc. */
|
||||
ConsoleInputProc, /* Input proc. */
|
||||
ConsoleOutputProc, /* Output proc. */
|
||||
@@ -180,6 +180,10 @@ static Tcl_ChannelType consoleChannelType = {
|
||||
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. */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+6
-3
@@ -9,7 +9,7 @@
|
||||
* 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.11 2000/04/11 21:42:12 ericm Exp $
|
||||
* RCS: @(#) $Id: tclWinPipe.c,v 1.11.2.1 2000/07/27 01:39:25 hobbs Exp $
|
||||
*/
|
||||
|
||||
#include "tclWinInt.h"
|
||||
@@ -209,7 +209,7 @@ static int WaitForRead(PipeInfo *infoPtr, int blocking);
|
||||
|
||||
static Tcl_ChannelType pipeChannelType = {
|
||||
"pipe", /* Type name. */
|
||||
PipeBlockModeProc, /* Set blocking or non-blocking mode.*/
|
||||
TCL_CHANNEL_VERSION_2, /* v2 channel */
|
||||
TCL_CLOSE2PROC, /* Close proc. */
|
||||
PipeInputProc, /* Input proc. */
|
||||
PipeOutputProc, /* Output proc. */
|
||||
@@ -218,7 +218,10 @@ static Tcl_ChannelType pipeChannelType = {
|
||||
NULL, /* Get option proc. */
|
||||
PipeWatchProc, /* Set up notifier to watch the channel. */
|
||||
PipeGetHandleProc, /* Get an OS handle from channel. */
|
||||
PipeClose2Proc
|
||||
PipeClose2Proc, /* close2proc */
|
||||
PipeBlockModeProc, /* Set blocking or non-blocking mode.*/
|
||||
NULL, /* flush proc. */
|
||||
NULL, /* handler proc. */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+15
-11
@@ -10,7 +10,7 @@
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
* Changes by Rolf.Schroedter@dlr.de June 25-27, 1999
|
||||
*
|
||||
* RCS: @(#) $Id: tclWinSerial.c,v 1.9 1999/11/24 20:55:17 hobbs Exp $
|
||||
* RCS: @(#) $Id: tclWinSerial.c,v 1.9.2.1 2000/07/27 01:39:26 hobbs Exp $
|
||||
*/
|
||||
|
||||
#include "tclWinInt.h"
|
||||
@@ -154,16 +154,20 @@ static int SerialSetOptionProc _ANSI_ARGS_((ClientData instanceData,
|
||||
*/
|
||||
|
||||
static Tcl_ChannelType serialChannelType = {
|
||||
"serial", /* Type name. */
|
||||
SerialBlockProc, /* Set blocking or non-blocking mode.*/
|
||||
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. */
|
||||
"serial", /* Type name. */
|
||||
TCL_CHANNEL_VERSION_2, /* v2 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. */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+15
-11
@@ -8,7 +8,7 @@
|
||||
* 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.18 1999/12/09 14:44:11 hobbs Exp $
|
||||
* RCS: @(#) $Id: tclWinSock.c,v 1.18.2.1 2000/07/27 01:39:26 hobbs Exp $
|
||||
*/
|
||||
|
||||
#include "tclWinInt.h"
|
||||
@@ -215,16 +215,20 @@ static DWORD WINAPI SocketThread _ANSI_ARGS_((LPVOID arg));
|
||||
*/
|
||||
|
||||
static Tcl_ChannelType tcpChannelType = {
|
||||
"tcp", /* Type name. */
|
||||
TcpBlockProc, /* Set socket into blocking/non-blocking mode. */
|
||||
TcpCloseProc, /* Close proc. */
|
||||
TcpInputProc, /* Input proc. */
|
||||
TcpOutputProc, /* Output proc. */
|
||||
NULL, /* Seek proc. */
|
||||
NULL, /* Set option proc. */
|
||||
TcpGetOptionProc, /* Get option proc. */
|
||||
TcpWatchProc, /* Initialize notifier to watch this channel. */
|
||||
TcpGetHandleProc, /* Get an OS handle from channel. */
|
||||
"tcp", /* Type name. */
|
||||
TCL_CHANNEL_VERSION_2, /* v2 channel */
|
||||
TcpCloseProc, /* Close proc. */
|
||||
TcpInputProc, /* Input proc. */
|
||||
TcpOutputProc, /* Output proc. */
|
||||
NULL, /* Seek proc. */
|
||||
NULL, /* 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 blocking/non-blocking mode. */
|
||||
NULL, /* flush proc. */
|
||||
NULL, /* handler proc. */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user