summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/ListObj.36
-rw-r--r--doc/StringObj.32
-rw-r--r--doc/chan.n1106
-rw-r--r--generic/tclCmdMZ.c12
-rw-r--r--generic/tclTest.c30
-rw-r--r--generic/tclUtil.c4
-rw-r--r--tests/indexObj.test47
7 files changed, 553 insertions, 654 deletions
diff --git a/doc/ListObj.3 b/doc/ListObj.3
index 67721c9..c5c1dc7 100644
--- a/doc/ListObj.3
+++ b/doc/ListObj.3
@@ -28,7 +28,7 @@ int
\fBTcl_ListObjGetElements\fR(\fIinterp, listPtr, objcPtr, objvPtr\fR)
.sp
int
-\fBTcl_ListObjLength\fR(\fIinterp, listPtr, intPtr\fR)
+\fBTcl_ListObjLength\fR(\fIinterp, listPtr, lengthPtr\fR)
.sp
int
\fBTcl_ListObjIndex\fR(\fIinterp, listPtr, index, objPtrPtr\fR)
@@ -76,7 +76,7 @@ An array of pointers to values.
\fBTcl_NewListObj\fR will insert these values into a new list value
and \fBTcl_ListObjReplace\fR will insert them into an existing \fIlistPtr\fR.
Each value will become a separate list element.
-.AP int *intPtr out
+.AP int *lengthPtr out
Points to location where \fBTcl_ListObjLength\fR
stores the length of the list.
.AP int index in
@@ -162,7 +162,7 @@ Otherwise it returns \fBTCL_OK\fR after storing the count and array pointer.
.PP
\fBTcl_ListObjLength\fR returns the number of elements in the list value
referenced by \fIlistPtr\fR.
-It returns this count by storing an integer in the address \fIintPtr\fR.
+It returns this count by storing an integer in the address \fIlengthPtr\fR.
If the value is not already a list value,
\fBTcl_ListObjLength\fR will attempt to convert it to one;
if the conversion fails, it returns \fBTCL_ERROR\fR
diff --git a/doc/StringObj.3 b/doc/StringObj.3
index 90b53f2..1b04dd4 100644
--- a/doc/StringObj.3
+++ b/doc/StringObj.3
@@ -121,7 +121,7 @@ the last one available.
Points to a value to manipulate.
.AP Tcl_Obj *appendObjPtr in
The value to append to \fIobjPtr\fR in \fBTcl_AppendObjToObj\fR.
-.AP size_t | int *lengthPtr out
+.AP int *lengthPtr out
The location where \fBTcl_GetStringFromObj\fR will store the length
of a value's string representation. May be (int *)NULL when not used.
.AP "const char" *string in
diff --git a/doc/chan.n b/doc/chan.n
index f788bbf..9589f98 100644
--- a/doc/chan.n
+++ b/doc/chan.n
@@ -1,5 +1,6 @@
'\"
'\" Copyright (c) 2005-2006 Donal K. Fellows
+'\" Copyright (c) 2021 Nathan Coulter
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -8,761 +9,586 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-chan \- Read, write and manipulate channels
+chan \- Reads, writes and manipulates channels.
.SH SYNOPSIS
-\fBchan \fIoption\fR ?\fIarg arg ...\fR?
+\fBchan \fIoperation\fR ?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
-This command provides several operations for reading from, writing to
-and otherwise manipulating open channels (such as have been created
-with the \fBopen\fR and \fBsocket\fR commands, or the default named
-channels \fBstdin\fR, \fBstdout\fR or \fBstderr\fR which correspond to
-the process's standard input, output and error streams respectively).
-\fIOption\fR indicates what to do with the channel; any unique
-abbreviation for \fIoption\fR is acceptable. Valid options are:
-.TP
-\fBchan blocked \fIchannelId\fR
-.
-This tests whether the last input operation on the channel called
-\fIchannelId\fR failed because it would have otherwise caused the
-process to block, and returns 1 if that was the case. It returns 0
-otherwise. Note that this only ever returns 1 when the channel has
-been configured to be non-blocking; all Tcl channels have blocking
-turned on by default.
-.TP
-\fBchan close \fIchannelId\fR ?\fIdirection\fR?
-.
-Close and destroy the channel called \fIchannelId\fR. Note that this
-deletes all existing file-events registered on the channel.
-If the \fIdirection\fR argument (which must be \fBread\fR or \fBwrite\fR or
-any unique abbreviation of them) is present, the channel will only be
-half-closed, so that it can go from being read-write to write-only or
-read-only respectively. If a read-only channel is closed for reading, it is
-the same as if the channel is fully closed, and respectively similar for
-write-only channels. Without the \fIdirection\fR argument, the channel is
-closed for both reading and writing (but only if those directions are
-currently open). It is an error to close a read-only channel for writing, or a
-write-only channel for reading.
+\fBchan\fR provides several operations for reading from, writing to, and
+otherwise manipulating channels, e.g. those created by \fBopen\fR and
+\fBsocket\fR, or the default channels \fBstdin\fR, \fBstdout\fR or \fBstderr\fR
+which correspond respectively to the standard input, output, and error streams
+of the process. Any unique abbreviation for \fIoperation\fR is acceptable.
+Available operations are:
+.TP
+\fBchan blocked \fIchannelName\fR
+.
+Returns 1 when the channel is in non-blocking mode and the last input operation
+on the channel failed because it would have otherwise caused the process to
+block, and 0 otherwise. Each Tcl channel is in blocking mode unless configured
+otherwise.
+.TP
+\fBchan close \fIchannelName\fR ?\fIdirection\fR?
+.
+Closes and destroys the named channel, deleting any existing event handlers
+established for the channel, and returns the empty string. If \fIdirection\fR is
+given, it is
+.QW\fBread\fR
+or
+.QW\fBwrite\fR
+or any unique abbreviation of those words, and only that side of the channel is
+closed. I.e. a read-write channel may become read-only or write-only.
+Closing a read-only channel for reading, or closing a write-only channel for
+writing is the same as simply closing the channel. It is an error to close a
+read-only channel for writing or to close a write-only channel for reading.
.RS
.PP
-As part of closing the channel, all buffered output is flushed to the
-channel's output device (only if the channel is ceasing to be writable), any
-buffered input is discarded (only if the channel is ceasing to be readable),
-the underlying operating system resource is closed and \fIchannelId\fR becomes
-unavailable for future use (both only if the channel is being completely
-closed).
-.PP
-If the channel is blocking and the channel is ceasing to be writable, the
-command does not return until all output is flushed. If the channel is
-non-blocking and there is unflushed output, the channel remains open and the
-command returns immediately; output will be flushed in the background and the
-channel will be closed when all the flushing is complete.
-.PP
-If \fIchannelId\fR is a blocking channel for a command pipeline then
-\fBchan close\fR waits for the child processes to complete.
-.PP
-If the channel is shared between interpreters, then \fBchan close\fR
-makes \fIchannelId\fR unavailable in the invoking interpreter but has
-no other effect until all of the sharing interpreters have closed the
-channel. When the last interpreter in which the channel is registered
-invokes \fBchan close\fR (or \fBclose\fR), the cleanup actions
-described above occur. With half-closing, the half-close of the channel only
-applies to the current interpreter's view of the channel until all channels
-have closed it in that direction (or completely).
-See the \fBinterp\fR command for a description of channel sharing.
-.PP
-Channels are automatically fully closed when an interpreter is destroyed and
-when the process exits. Channels are switched to blocking mode, to
-ensure that all output is correctly flushed before the process exits.
-.PP
-The command returns an empty string, and may generate an error if
-an error occurs while flushing output. If a command in a command
-pipeline created with \fBopen\fR returns an error, \fBchan close\fR
-generates an error (similar to the \fBexec\fR command.)
-.PP
-Note that half-closes of sockets and command pipelines can have important side
-effects because they result in a shutdown() or close() of the underlying
-system resource, which can change how other processes or systems respond to
-the Tcl program.
+When a channel is closed for writing, any buffered output on the channel is
+flushed. When a channel is closed for reading, any buffered input is discarded.
+When a channel is destroyed the underlying resource is closed and the channel
+is thereafter unavailable.
+.PP
+\fBchan close\fR fully flushes any output before closing the write side of a
+channel unless it is non-blocking mode, where it returns immediately and the
+channel is flushed in the background before finally being closed.
+.PP
+\fBchan close\fR may return an error if an error occurs while flushing
+output. If a process in a command pipeline created by \fBopen\fR returns an
+error, \fBchan close\fR generates an error in the same manner as \fBexec\fR.
+.PP
+Closing one side of a socket or command pipeline may lead to the shutdown() or
+close() of the underlying system resource, leading to a reaction from whatever
+is on the other side of the pipeline or socket.
+.PP
+If the channel for a command pipeline is in blocking mode, \fBchan close\fR
+waits for the connected processes to complete.
+.PP
+\fBchan close\fR only affects the current interpreter. If the channel is open
+in any other interpreter, its state is unchanged there. See \fBinterp\fR for a
+description of channel sharing.
+.PP
+When the last interpreter sharing a channel is destroyed, the channel is
+switched to blocking mode and fully flushed and then closed.
.RE
.TP
-\fBchan configure \fIchannelId\fR ?\fIoptionName\fR? ?\fIvalue\fR? ?\fIoptionName value\fR?...
+\fBchan configure \fIchannelName\fR ?\fIoptionName\fR? ?\fIvalue\fR? ?\fIoptionName value\fR?...
.
-Query or set the configuration options of the channel named
-\fIchannelId\fR.
+Configures or reports the configuration of \fIchannelName\fR.
.RS
.PP
-If no \fIoptionName\fR or \fIvalue\fR arguments are supplied, the
-command returns a list containing alternating option names and values
-for the channel. If \fIoptionName\fR is supplied but no \fIvalue\fR
-then the command returns the current value of the given option. If
-one or more pairs of \fIoptionName\fR and \fIvalue\fR are supplied,
-the command sets each of the named options to the corresponding
-\fIvalue\fR; in this case the return value is an empty string.
-.PP
-The options described below are supported for all channels. In
-addition, each channel type may add options that only it supports. See
-the manual entry for the command that creates each type of channel
-for the options supported by that specific type of channel. For
-example, see the manual entry for the \fBsocket\fR command for additional
-options for sockets, and the \fBopen\fR command for additional options for
-serial devices.
+If no \fIoptionName\fR or \fIvalue\fR arguments are given,
+\fBchan configure\fR returns a dictionary of option names and
+values for the channel. If \fIoptionName\fR is supplied without a \fIvalue\fR,
+\fBchan configure\fR returns the current value of the named option. If one or
+more pairs of \fIoptionName\fR and \fIvalue\fR are supplied,
+\fBchan configure\fR sets each of the named options to the corresponding
+\fIvalue\fR and returns the empty string.
+.PP
+The options described below are supported for all channels. Each type of
+channel may provide additional options. Those options are described in the
+relevant documentation. For example, additional options are documented for
+\fBsocket\fR, and also for serial devices at \fBopen\fR.
.TP
\fB\-blocking\fR \fIboolean\fR
.
-The \fB\-blocking\fR option determines whether I/O operations on the
-channel can cause the process to block indefinitely. The value of the
-option must be a proper boolean value. Channels are normally in
-blocking mode; if a channel is placed into non-blocking mode it will
-affect the operation of the \fBchan gets\fR, \fBchan read\fR, \fBchan
-puts\fR, \fBchan flush\fR, and \fBchan close\fR commands; see the
-documentation for those commands for details. For non-blocking mode to
-work correctly, the application must be using the Tcl event loop
-(e.g. by calling \fBTcl_DoOneEvent\fR or invoking the \fBvwait\fR
-command).
+If \fB\-blocking\fR is set to \fBtrue\fR, which is the default, reading from or
+writing to the channel may cause the process to block indefinitely. Otherwise,
+operations such as \fBchan gets\fR, \fBchan read\fR, \fBchan puts\fR, \fBchan
+flush\fR, and \fBchan close\fR take care not to block. Non-blocking mode in
+generally requires that the event loop is entered, e.g. by calling
+\fBTcl_DoOneEvent\fR or \fBvwait\fR or by using Tk, to give Tcl a chance to
+process events on the channel.
.TP
\fB\-buffering\fR \fInewValue\fR
.
-If \fInewValue\fR is \fBfull\fR then the I/O system will buffer output
-until its internal buffer is full or until the \fBchan flush\fR
-command is invoked. If \fInewValue\fR is \fBline\fR, then the I/O
-system will automatically flush output for the channel whenever a
-newline character is output. If \fInewValue\fR is \fBnone\fR, the I/O
-system will flush automatically after every output operation. The
-default is for \fB\-buffering\fR to be set to \fBfull\fR except for
-channels that connect to terminal-like devices; for these channels the
-initial setting is \fBline\fR. Additionally, \fBstdin\fR and
-\fBstdout\fR are initially set to \fBline\fR, and \fBstderr\fR is set
-to \fBnone\fR.
+If \fInewValue\fR is \fBfull\fR, which is the default, output is buffered
+until the internal buffer is full or until \fBchan flush\fR is called. If
+\fInewValue\fR is \fBline\fR, output is flushed each time a end-of-line
+character is written. If \fInewValue\fR is \fBnone\fR, output is flushed after
+every output operation. For \fBstdin\fR, \fBstdout\fR, and channels that
+connect to terminal-like devices, the default value is \fBline\fR. For
+\fBstderr\fR the default value is \fBnone\fR.
.TP
\fB\-buffersize\fR \fInewSize\fR
.
-\fINewvalue\fR must be an integer; its value is used to set the size
-of buffers, in bytes, subsequently allocated for this channel to store
-input or output. \fINewvalue\fR must be a number of no more than one
-million, allowing buffers of up to one million bytes in size.
-.TP
-\fB\-encoding\fR \fIname\fR
-.
-This option is used to specify the encoding of the channel as one of
-the named encodings returned by \fBencoding names\fR or the special
-value \fBbinary\fR, so that the data can be converted to and from
-Unicode for use in Tcl. For instance, in order for Tcl to read
-characters from a Japanese file in \fBshiftjis\fR and properly process
-and display the contents, the encoding would be set to \fBshiftjis\fR.
-Thereafter, when reading from the channel, the bytes in the Japanese
-file would be converted to Unicode as they are read. Writing is also
-supported \- as Tcl strings are written to the channel they will
-automatically be converted to the specified encoding on output.
+\fInewSize\fR, an integer no greater than one million, is the size in bytes of
+any input or output buffers subsequently allocated for this channel.
+.TP
+\fB\-encoding\fR ?\fIname\fR?
+.
+Sets the encoding of the channel. \fIname\fR is either one of the names
+returned by \fBencoding names\fR, or
+.QW \fBbinary\fR
+\&. Input is converted from the encoding into Unicode, and output is converted
+from Unicode to the encoding.
.RS
.PP
-If a file contains pure binary data (for instance, a JPEG image), the
-encoding for the channel should be configured to be \fBbinary\fR. Tcl
-will then assign no interpretation to the data in the file and simply
-read or write raw bytes. The Tcl \fBbinary\fR command can be used to
-manipulate this byte-oriented data. It is usually better to set the
-\fB\-translation\fR option to \fBbinary\fR when you want to transfer
-binary data, as this turns off the other automatic interpretations of
-the bytes in the stream as well.
-.PP
-The default encoding for newly opened channels is the same platform-
-and locale-dependent system encoding used for interfacing with the
-operating system, as returned by \fBencoding system\fR.
+\fBbinary\fR is an alias for \fBiso8859-1\fR: Each byte read from the
+channel becomes the Unicode character having the same value as that byte, and
+each character written to the channel becomes a single byte in the output,
+allowing Tcl to work seamlessly with binary data as long as each "character" in
+the data remains in the range of 0 to 255 so that there is no distinction between
+binary data and text. For example, A JPEG image can be read from a
+\fBbinary\fR channel, manipulated, and then written back to a \fBbinary\fR
+channel.
+
+For working with binary data \fB\-translation binary\fR is usually used
+instead, as it sets the encoding to \fBbinary\fR and also disables other
+translations on the channel.
+.PP
+The encoding of a new channel is the value of \fBencoding system\fR,
+which returns the platform- and locale-dependent system encoding used to
+interface with the operating system,
.RE
.TP
\fB\-eofchar\fR \fIchar\fR
.TP
\fB\-eofchar\fR \fB{\fIinChar outChar\fB}\fR
.
-This option supports DOS file systems that use Control-z (\ex1A) as an
-end of file marker. If \fIchar\fR is not an empty string, then this
-character signals end-of-file when it is encountered during input.
-For output, the end-of-file character is output when the channel is
-closed. If \fIchar\fR is the empty string, then there is no special
-end of file character marker. For read-write channels, a two-element
-list specifies the end of file marker for input and output,
-respectively. As a convenience, when setting the end-of-file
-character for a read-write channel you can specify a single value that
-will apply to both reading and writing. When querying the end-of-file
-character of a read-write channel, a two-element list will always be
-returned. The default value for \fB\-eofchar\fR is the empty string
-in all cases except for files under Windows. In that case the
-\fB\-eofchar\fR is Control-z (\ex1A) for reading and the empty string
-for writing.
-The acceptable range for \fB\-eofchar\fR values is \ex01 - \ex7f;
-attempting to set \fB\-eofchar\fR to a value outside of this range will
-generate an error.
-.TP
-\fB\-translation\fR \fImode\fR
-.TP
-\fB\-translation\fR \fB{\fIinMode outMode\fB}\fR
-.
-In Tcl scripts the end of a line is always represented using a single
-newline character (\en). However, in actual files and devices the end
-of a line may be represented differently on different platforms, or
-even for different devices on the same platform. For example, under
-UNIX newlines are used in files, whereas carriage-return-linefeed
-sequences are normally used in network connections. On input (i.e.,
-with \fBchan gets\fR and \fBchan read\fR) the Tcl I/O system
-automatically translates the external end-of-line representation into
-newline characters. Upon output (i.e., with \fBchan puts\fR), the I/O
-system translates newlines to the external end-of-line representation.
-The default translation mode, \fBauto\fR, handles all the common cases
-automatically, but the \fB\-translation\fR option provides explicit
-control over the end of line translations.
+\fIchar\fR signals the end of the data when it is encountered in the input.
+For output, the character is added when the channel is closed. If \fIchar\fR
+is the empty string, there is no special character that marks the end of the
+data. For read-write channels, one end-of-file character for input and another
+for output may be given. When only one end-of-file character is given it is
+applied to both input and output. For a read-write channel two values are
+returned even if they are are identical.
+
+The default value is the empty string, except that under Windows the default
+value for reading is Control-z (\ex1A). The acceptable range is \ex01 -
+\ex7f. A value outside this range results in an error.
+.TP
+\fB\-translation\fR \fItranslation\fR
+.TP
+\fB\-translation\fR \fB{\fIinTranslation outTranslation\fB}\fR
+.
+In Tcl a single line feed (\en) represents the end of a line. However,
+at the destination the end of a line may be represented differently on
+different platforms, or even for different devices on the same platform. For
+example, under UNIX line feed is used in files and a
+carriage-return-linefeed sequence is normally used in network connections.
+Therefore, on input, e.g. with \fBchan gets\fR and \fBchan read\fR, each
+external end-of-line character is translated into a line feed. On
+output, e.g. with \fBchan puts\fR, each line feed is translated to the external
+end-of-line character. The default translation, \fBauto\fR, handles all the common
+cases, and \fB\-translation\fR provides explicit control over the end-of-line
+character.
.RS
.PP
-The value associated with \fB\-translation\fR is a single item for
-read-only and write-only channels. The value is a two-element list for
-read-write channels; the read translation mode is the first element of
-the list, and the write translation mode is the second element. As a
-convenience, when setting the translation mode for a read-write channel
-you can specify a single value that will apply to both reading and
-writing. When querying the translation mode of a read-write channel, a
-two-element list will always be returned. The following values are
-currently supported:
+Returns the input translation for a read-only channel, the output translation
+for a write-only channel, and both the input translation and the the output
+translation for a read-write channel. When two translations are given, they
+are the input and output translation, respectively. When only one translation
+is given for a read-write channel, it is the translation for both input and
+output. The following values are currently supported:
.TP
\fBauto\fR
.
-As the input translation mode, \fBauto\fR treats any of newline
-(\fBlf\fR), carriage return (\fBcr\fR), or carriage return followed by
-a newline (\fBcrlf\fR) as the end of line representation. The end of
-line representation can even change from line-to-line, and all cases
-are translated to a newline. As the output translation mode,
-\fBauto\fR chooses a platform specific representation; for sockets on
-all platforms Tcl chooses \fBcrlf\fR, for all Unix flavors, it chooses
-\fBlf\fR, and for the various flavors of Windows it chooses
-\fBcrlf\fR. The default setting for \fB\-translation\fR is \fBauto\fR
-for both input and output.
+The default. For input each occurrence of a line feed (\fBlf\fR), carriage
+return (\fBcr\fR), or carriage return followed by a line feed (\fBcrlf\fR) is
+translated into a line feed. For output, each line feed is translated into a
+platform-specific representation: For all Unix variants it is \fBlf\fR, and
+for all Windows variants it is \fBcrlf\fR, except that for sockets on all
+platforms it is \fBcrlf\fR for both input and output.
.TP
\fBbinary\fR
.
-No end-of-line translations are performed. This is nearly identical
-to \fBlf\fR mode, except that in addition \fBbinary\fR mode also sets
-the end-of-file character to the empty string (which disables it) and
-sets the encoding to \fBbinary\fR (which disables encoding filtering).
-See the description of \fB\-eofchar\fR and \fB\-encoding\fR for more
-information.
+Like \fBlf\fR, no end-of-line translation is performed, but in addition,
+\fB\-eofchar\fR is set to the empty string to disable it, and \fB\-encoding\fR
+is set to \fBbinary\fR. With this one setting, a channel is fully configured
+for binary input and output.
.TP
\fBcr\fR
.
-The end of a line in the underlying file or device is represented by a
-single carriage return character. As the input translation mode,
-\fBcr\fR mode converts carriage returns to newline characters. As the
-output translation mode, \fBcr\fR mode translates newline characters
-to carriage returns.
+The end of a line is represented in the external data by a single carriage
+return character. For input, each carriage return is translated to a line
+feed, and for output each line feed character is translated to a carriage
+return.
.TP
\fBcrlf\fR
.
-The end of a line in the underlying file or device is represented by a
-carriage return character followed by a linefeed character. As the
-input translation mode, \fBcrlf\fR mode converts
-carriage-return-linefeed sequences to newline characters. As the
-output translation mode, \fBcrlf\fR mode translates newline characters
-to carriage-return-linefeed sequences. This mode is typically used on
-Windows platforms and for network connections.
+The end of a line is represented in the external data by a carriage return
+character followed by a line feed. For input, each carriage-return-linefeed
+sequence is translated to a line feed. For output, each line feed is
+translated to a carriage-return-linefeed sequence. This translation is
+typically used for network connections, and also on Windows systems.
.TP
\fBlf\fR
.
-The end of a line in the underlying file or device is represented by a
-single newline (linefeed) character. In this mode no translations
-occur during either input or output. This mode is typically used on
-UNIX platforms.
+The end of a line in the external data is represented by a line feed so no
+translations occur during either input or output. This translation is
+typically used on UNIX platforms,
.RE
.RE
.TP
\fBchan copy \fIinputChan outputChan\fR ?\fB\-size \fIsize\fR? ?\fB\-command \fIcallback\fR?
.
-Copy data from the channel \fIinputChan\fR, which must have been
-opened for reading, to the channel \fIoutputChan\fR, which must have
-been opened for writing. The \fBchan copy\fR command leverages the
-buffering in the Tcl I/O system to avoid extra copies and to avoid
-buffering too much data in main memory when copying large files to
-slow destinations like network sockets.
+Copies data from \fIinputChan\fR to \fIoutputChan\fR, leveraging internal
+buffers to avoid extra copies and to avoid buffering too much data in main
+memory when copying large files to slow destinations like network sockets.
.RS
.PP
-The \fBchan copy\fR command transfers data from \fIinputChan\fR until
-end of file or \fIsize\fR bytes or characters have been transferred;
-\fIsize\fR is in bytes if the two channels are using the same encoding,
-and is in characters otherwise. If no \fB\-size\fR argument is given,
-then the copy goes until end of file. All the data read from
-\fIinputChan\fR is copied to \fIoutputChan\fR. Without the
-\fB\-command\fR option, \fBchan copy\fR blocks until the copy is
-complete and returns the number of bytes or characters (using the same
-rules as for the \fB\-size\fR option) written to \fIoutputChan\fR.
-.PP
-The \fB\-command\fR argument makes \fBchan copy\fR work in the
-background. In this case it returns immediately and the
-\fIcallback\fR is invoked later when the copy completes. The
-\fIcallback\fR is called with one or two additional arguments that
-indicates how many bytes were written to \fIoutputChan\fR. If an
-error occurred during the background copy, the second argument is the
-error string associated with the error. With a background copy, it is
-not necessary to put \fIinputChan\fR or \fIoutputChan\fR into
-non-blocking mode; the \fBchan copy\fR command takes care of that
-automatically. However, it is necessary to enter the event loop by
-using the \fBvwait\fR command or by using Tk.
-.PP
-You are not allowed to do other I/O operations with \fIinputChan\fR or
-\fIoutputChan\fR during a background \fBchan copy\fR. If either
-\fIinputChan\fR or \fIoutputChan\fR get closed while the copy is in
-progress, the current copy is stopped and the command callback is
-\fInot\fR made. If \fIinputChan\fR is closed, then all data already
-queued for \fIoutputChan\fR is written out.
-.PP
-Note that \fIinputChan\fR can become readable during a background
-copy. You should turn off any \fBchan event\fR or \fBfileevent\fR
-handlers during a background copy so those handlers do not interfere
-with the copy. Any I/O attempted by a \fBchan event\fR or
-\fBfileevent\fR handler will get a
-.QW "channel busy"
-error.
-.PP
-\fBChan copy\fR translates end-of-line sequences in \fIinputChan\fR
-and \fIoutputChan\fR according to the \fB\-translation\fR option for
-these channels (see \fBchan configure\fR above). The translations
-mean that the number of bytes read from \fIinputChan\fR can be
-different than the number of bytes written to \fIoutputChan\fR. Only
-the number of bytes written to \fIoutputChan\fR is reported, either as
-the return value of a synchronous \fBchan copy\fR or as the argument
-to the callback for an asynchronous \fBchan copy\fR.
-.PP
-\fBChan copy\fR obeys the encodings and character translations
-configured for the channels. This means that the incoming characters
-are converted internally first UTF-8 and then into the encoding of the
-channel \fBchan copy\fR writes to (see \fBchan configure\fR above for
-details on the \fB\-encoding\fR and \fB\-translation\fR options). No
-conversion is done if both channels are set to encoding \fBbinary\fR
-and have matching translations. If only the output channel is set to
-encoding \fBbinary\fR the system will write the internal UTF-8
-representation of the incoming characters. If only the input channel
-is set to encoding \fBbinary\fR the system will assume that the
-incoming bytes are valid UTF-8 characters and convert them according
-to the output encoding. The behaviour of the system for bytes which
-are not valid UTF-8 characters is undefined in this case.
+If \fB\-size\fR is given, the size is in bytes if the two channels have the
+same encoding and in characters otherwise, and only that amount is copied.
+Otherwise, all data until the end of the file is copied.
+
+\fBchan copy\fR blocks until the copy is complete and returns the number of
+bytes or characters written to \fIoutputChan\fR.
+.PP
+If \fB\-command\fR is given, \fBchan copy\fR returns immediately, the copy is
+carried out in the background, and then \fIcallback\fR is called with the
+number of bytes written to \fIoutputChan\fR as its first argument, and the
+error message for any error that occurred as its second argument.
+\fIinputChan\fR and \fIoutputChan\fR are automatically configured for
+non-blocking mode if needed. Background copying only works correctly if the
+event loop is active, e.g. via \fBvwait\fR or Tk.
+.PP
+During a background copy no other read or write operation may be performed on
+\fIinputChan\fR or \fIoutputChan\fR. If either \fIinputChan\fR or
+\fIoutputChan\fR is closed while the copy is in progress copying ceases and
+\fBno\fR callback is made. If \fIinputChan\fR is closed all data already queued
+is written to \fIoutputChan\fR.
+.PP
+The should be no event handler established for \fIinputChan\fR because it may
+become readable during a background copy. An attempt to read or write
+from within an event handler results result in the error, "channel busy".
+.PP
+Due to end-of-line translation the number of bytes read from \fIinputChan\fR
+may be different than the number of bytes written to \fIoutputChan\fR. Only
+the number of bytes written to \fIoutputChan\fR is reported.
+.PP
+\fBChan copy\fR reads the data according to the \fB\-encoding\fR,
+\fB\-translation\fR, and \fB\-eofchar\fR of the source and writes to the
+destination according to the configuration for that channel. If the encoding
+and translation of both channels is \fBbinary\fR and the \fB\-eofchar\fR of
+both channels is the empty string, an identical copy is made. If only the
+encoding of the destination is \fBbinary\fR, Tcl's internal modified UTF-8
+representation of the characters read from the source is written to the
+destination. If only the encoding of the source is \fBbinary\fR, each byte read
+becomes one Unicode character in the range of 0 to 255, and that character is
+subject to the encoding and translation of the destination as it is written.
.RE
.TP
\fBchan create \fImode cmdPrefix\fR
.
-This subcommand creates a new script level channel using the command
-prefix \fIcmdPrefix\fR as its handler. Any such channel is called a
-\fBreflected\fR channel. The specified command prefix, \fBcmdPrefix\fR,
-must be a non-empty list, and should provide the API described in the
-\fBrefchan\fR manual page. The handle of the new channel is
-returned as the result of the \fBchan create\fR command, and the
-channel is open. Use either \fBclose\fR or \fBchan close\fR to remove
-the channel.
+Creates a new channel, called a \fBreflected\fR channel, with \fIcmdPrefix\fR
+as its handler, and returns the name of the channel. \fBcmdPrefix\fR is the
+first words of a command that provides the interface for a \fBrefchan\fR.
.RS
.PP
-The argument \fImode\fR specifies if the new channel is opened for
-reading, writing, or both. It has to be a list containing any of the
-strings
+\fBImode\fR is a list of one or more of the strings
.QW \fBread\fR
or
-.QW \fBwrite\fR .
-The list must have at least one
-element, as a channel you can neither write to nor read from makes no
-sense. The handler command for the new channel must support the chosen
-mode, or an error is thrown.
-.PP
-The command prefix is executed in the global namespace, at the top of
-call stack, following the appending of arguments as described in the
-\fBrefchan\fR manual page. Command resolution happens at the
-time of the call. Renaming the command, or destroying it means that
-the next call of a handler method may fail, causing the channel
-command invoking the handler to fail as well. Depending on the
-subcommand being invoked, the error message may not be able to explain
-the reason for that failure.
-.PP
-Every channel created with this subcommand knows which interpreter it
-was created in, and only ever executes its handler command in that
-interpreter, even if the channel was shared with and/or was moved into
-a different interpreter. Each reflected channel also knows the thread
-it was created in, and executes its handler command only in that
-thread, even if the channel was moved into a different thread. To this
-end all invocations of the handler are forwarded to the original
-thread by posting special events to it. This means that the original
-thread (i.e. the thread that executed the \fBchan create\fR command)
-must have an active event loop, i.e. it must be able to process such
-events. Otherwise the thread sending them will \fIblock
-indefinitely\fR. Deadlock may occur.
-.PP
-Note that this permits the creation of a channel whose two endpoints
-live in two different threads, providing a stream-oriented bridge
-between these threads. In other words, we can provide a way for
-regular stream communication between threads instead of having to send
-commands.
-.PP
-When a thread or interpreter is deleted, all channels created with
-this subcommand and using this thread/interpreter as their computing
-base are deleted as well, in all interpreters they have been shared
-with or moved into, and in whatever thread they have been transferred
-to. While this pulls the rug out under the other thread(s) and/or
-interpreter(s), this cannot be avoided. Trying to use such a channel
-will cause the generation of a regular error about unknown channel
-handles.
-.PP
-This subcommand is \fBsafe\fR and made accessible to safe
-interpreters. While it arranges for the execution of arbitrary Tcl
-code the system also makes sure that the code is always executed
-within the safe interpreter.
+.QW \fBwrite\fR
+, indicating whether the channel is a read channel, a write channel, or both.
+It is an error if the handler does not support the chosen mode.
+.PP
+The handler is called as needed from the global namespace at the top level, and
+command resolution happens there at the time of the call. If the handler is
+renamed or deleted any subsequent attempt to call it is an error, which may
+not be able to describe the failure.
+.PP
+The handler is always called in the interpreter and thread it was created in,
+even if the channel was shared with or moved into a different interpreter in a
+different thread. This is achieved through event dispatch, so if the event
+loop is not entered, e.g. by calling \fBTcl_DoOneEvent\fR or \fBvwait\fR or
+using Tk, the thread performing the channel operation \fIblocks
+indefinitely\fR, resulting in deadlock.
+.PP
+One side of a channel may be in one thread while the other side is in a
+different thread, providing a stream-oriented bridge between the threads. This
+provides a method for regular stream communication between threads as an
+alternative to sending commands.
+.PP
+When the interpreter the handler is in is deleted each channel associated with
+the handler is deleted as well, regardless of which interpreter or thread it
+is currently in or shared with.
+.PP
+\fBchan create\fR is \fBsafe\fR and is accessible to safe interpreters. The
+handler is always called in the safe interpreter it was created in.
.RE
.TP
-\fBchan eof \fIchannelId\fR
-.
-Test whether the last input operation on the channel called
-\fIchannelId\fR failed because the end of the data stream was reached,
-returning 1 if end-of-file was reached, and 0 otherwise.
-.TP
-\fBchan event \fIchannelId event\fR ?\fIscript\fR?
-.
-Arrange for the Tcl script \fIscript\fR to be installed as a \fIfile
-event handler\fR to be called whenever the channel called
-\fIchannelId\fR enters the state described by \fIevent\fR (which must
-be either \fBreadable\fR or \fBwritable\fR); only one such handler may
-be installed per event per channel at a time. If \fIscript\fR is the
-empty string, the current handler is deleted (this also happens if the
-channel is closed or the interpreter deleted). If \fIscript\fR is
-omitted, the currently installed script is returned (or an empty
-string if no such handler is installed). The callback is only
-performed if the event loop is being serviced (e.g. via \fBvwait\fR or
-\fBupdate\fR).
-.RS
-.PP
-A file event handler is a binding between a channel and a script, such
-that the script is evaluated whenever the channel becomes readable or
-writable. File event handlers are most commonly used to allow data to
-be received from another process on an event-driven basis, so that the
-receiver can continue to interact with the user or with other channels
-while waiting for the data to arrive. If an application invokes
-\fBchan gets\fR or \fBchan read\fR on a blocking channel when there is
-no input data available, the process will block; until the input data
-arrives, it will not be able to service other events, so it will
-appear to the user to
-.QW "freeze up" .
-With \fBchan event\fR, the
-process can tell when data is present and only invoke \fBchan gets\fR
-or \fBchan read\fR when they will not block.
-.PP
-A channel is considered to be readable if there is unread data
-available on the underlying device. A channel is also considered to
-be readable if there is unread data in an input buffer, except in the
-special case where the most recent attempt to read from the channel
-was a \fBchan gets\fR call that could not find a complete line in the
-input buffer. This feature allows a file to be read a line at a time
-in non-blocking mode using events. A channel is also considered to be
-readable if an end of file or error condition is present on the
-underlying file or device. It is important for \fIscript\fR to check
-for these conditions and handle them appropriately; for example, if
-there is no special check for end of file, an infinite loop may occur
-where \fIscript\fR reads no data, returns, and is immediately invoked
-again.
-.PP
-A channel is considered to be writable if at least one byte of data
-can be written to the underlying file or device without blocking, or
-if an error condition is present on the underlying file or device.
-Note that client sockets opened in asynchronous mode become writable
-when they become connected or if the connection fails.
-.PP
-Event-driven I/O works best for channels that have been placed into
-non-blocking mode with the \fBchan configure\fR command. In blocking
-mode, a \fBchan puts\fR command may block if you give it more data
-than the underlying file or device can accept, and a \fBchan gets\fR
-or \fBchan read\fR command will block if you attempt to read more data
-than is ready; no events will be processed while the commands block.
-In non-blocking mode \fBchan puts\fR, \fBchan read\fR, and \fBchan
-gets\fR never block.
-.PP
-The script for a file event is executed at global level (outside the
-context of any Tcl procedure) in the interpreter in which the \fBchan
-event\fR command was invoked. If an error occurs while executing the
-script then the command registered with \fBinterp bgerror\fR is used
-to report the error. In addition, the file event handler is deleted
-if it ever returns an error; this is done in order to prevent infinite
-loops due to buggy handlers.
-.RE
+\fBchan eof \fIchannelName\fR
+.
+Returns 1 if the last read on the channel failed because the end of the data
+was already reached, and 0 otherwise.
.TP
-\fBchan flush \fIchannelId\fR
+\fBchan event \fIchannelName event\fR ?\fIscript\fR?
.
-Ensures that all pending output for the channel called \fIchannelId\fR
-is written.
+Arranges for the given script, called a \fBchannel event hndler\fR, to be
+called whenever the given event, one of
+.QW \fBreadable\fR
+or
+.QW \fBwritable\fR
+occurs on the given channel, replacing any script that was previously set. If
+\fIscript\fR is the empty string the current handler is deleted. It is also
+deleted when the channel is closed. If \fIscript\fR is omitted, either the
+existing script or the empty string is returned. The event loop must be
+entered, e.g. via \fBvwait\fR or \fBupdate\fR, or by using Tk, for handlers to
+be evaluated.
+
.RS
.PP
-If the channel is in blocking mode the command does not return until
-all the buffered output has been flushed to the channel. If the
-channel is in non-blocking mode, the command may return before all
-buffered output has been flushed; the remainder will be flushed in the
-background as fast as the underlying file or device is able to absorb
-it.
+\fIscript\fR is evaluated at the global level in the interpreter it was
+established in. Any resulting error is handled in the background, i.e. via
+\fBinterp bgerror\fR. In order to prevent an endless loop due to a buggy
+handler, the handler is deleted if \fIscript\fR returns an error so that it is
+not evaluated again.
+
+.PP
+Without an event handler, \fBchan gets\fR or \fBchan read\fR on a channel in
+blocking mode may block until data becomes available, become during which the
+thread is unable to perform other work or respond to events on other channels.
+This could cause the application to appear to
+.QW "freeze up"
+\&.
+Channel event handlers allow events on the channel to direct channel handling
+so that the reader or writer can continue to perform other processing while
+waiting for a channel to become available and then handle channel operations
+when the channel is ready for the operation.
+.PP
+A
+.QW readable
+event occurs when there is data that can be read from the channel and also when
+there is an error on the channel. The handler must check for these conditions
+and handle them appropriately. For example, a handler that does not check
+whether the end of the data has been reached may be repeatedly evaluated in a
+busy loop until the channel is closed.
+.PP
+A
+.QW writable
+event occurs when at least one byte of data can be written, or if there is an
+error on the channel. A client socket opened in non-blocking mode becomes
+writable when it becomes connected or if the connection fails.
+.PP
+Event-driven channel handling works best for channels in non-blocking mode. A
+channel in blocking mode blocks when \fBchan puts\fR writes more data than the
+channel can accept at the moment, and when \fBchan gets\fR or \fBchan read\fR
+requests more data than is currently available. When a channel blocks, the
+thread can not do any other processing or service any other events. A channel
+in non-blocking mode allows a thread to carry on with other work and get back
+to the channel at the right time.
.RE
.TP
-\fBchan gets \fIchannelId\fR ?\fIvarName\fR?
-.
-Reads the next line from the channel called \fIchannelId\fR. If
-\fIvarName\fR is not specified, the result of the command will be the
-line that has been read (without a trailing newline character) or an
-empty string upon end-of-file or, in non-blocking mode, if the data
-available is exhausted. If \fIvarName\fR is specified, the line that
-has been read will be written to the variable called \fIvarName\fR and
-result will be the number of characters that have been read or -1 if
-end-of-file was reached or, in non-blocking mode, if the data
-available is exhausted.
+\fBchan flush \fIchannelName\fR
+.
+For a channel in blocking mode, flushes all buffered output to the destination,
+and then returns. For a channel in non-blocking mode, returns immediately
+while all buffered output is flushed in the background as soon as possible.
+.TP
+\fBchan gets \fIchannelName\fR ?\fIvarName\fR?
+.
+Returns the next line from the channel, removing the trailing line feed, or if
+\fIvarName\fR is given, assigns the line to that variable and returns the
+number of characters read.
+the line that was read, removing the trailing line feed, or returns the
+empty string if there is no data to return and the end of the file has been
+reached, or in non-blocking mode, if no complete line is currently available.
+If \fIvarName\fR is given, assigns the line that was read to variable named
+\fIvarName\fR and returns the number of characters that were read, or -1 if
+there no data available and the end of the channel was reached or the channel
+is in non-blocking mode.
.RS
.PP
-If an end-of-file occurs while part way through reading a line, the
-partial line will be returned (or written into \fIvarName\fR). When
-\fIvarName\fR is not specified, the end-of-file case can be
-distinguished from an empty line using the \fBchan eof\fR command, and
-the partial-line-but-non-blocking case can be distinguished with the
-\fBchan blocked\fR command.
+If the end of the channel is reached the data read so far is returned or
+assigned to \fIvarName\fR. When \fIvarName\fR is not given, \fBchan eof\fR may
+indicate that the empty string means that the end of the data has been reached,
+and \fBchan blocked\fR may indicate that that the empty string means there
+isn't currently enough data do return the next line.
.RE
.TP
\fBchan names\fR ?\fIpattern\fR?
.
-Produces a list of all channel names. If \fIpattern\fR is specified,
-only those channel names that match it (according to the rules of
-\fBstring match\fR) will be returned.
+Returns a list of all channel names, or if \fIpattern\fR is given, only those
+names that match according to the rules of \fBstring match\fR.
.TP
-\fBchan pending \fImode channelId\fR
+\fBchan pending \fImode channelName\fR
.
-Depending on whether \fImode\fR is \fBinput\fR or \fBoutput\fR,
-returns the number of
-bytes of input or output (respectively) currently buffered
-internally for \fIchannelId\fR (especially useful in a readable event
-callback to impose application-specific limits on input line lengths to avoid
-a potential denial-of-service attack where a hostile user crafts
-an extremely long line that exceeds the available memory to buffer it).
-Returns -1 if the channel was not opened for the mode in question.
+Returns the number of bytes of input
+when \fImode\fR is
+.QW\fBinput\fR
+, or output when \fImode\fR is
+.QW\fBoutput\fR
+, that are currently internally buffered for the channel. Useful in a readable
+event callback to impose limits on input line length to avoid a potential
+denial-of-service attack where an extremely long line exceeds the available
+memory to buffer it. Returns -1 if the channel was not opened for the mode in
+question.
.TP
\fBchan pipe\fR
-Creates a standalone pipe whose read- and write-side channels are
-returned as a 2-element list, the first element being the read side and
-the second the write side. Can be useful e.g. to redirect
-separately \fBstderr\fR and \fBstdout\fR from a subprocess. To do
-this, spawn with "2>@" or
-">@" redirection operators onto the write side of a pipe, and then
-immediately close it in the parent. This is necessary to get an EOF on
-the read side once the child has exited or otherwise closed its output.
+Creates a pipe, i.e. a readable channel and a writable channel, and returns the
+names of the readable channel and the writable channel. Data written to the
+writable channel can be read from the readable channel. Because the pipe is a
+real system-level pipe, it can be connected to other processes using
+redirection. For example, to redirect \fBstderr\fR from a subprocess into one
+channel, and \fBstdout\fR into another, \fBexec\fR with "2>@" and ">@", each
+onto the writable side of a pipe, closing the writable side immediately
+thereafter so that EOF is signaled on the read side once the subprocess has
+closed its output, typically on exit.
.RS
.PP
-Note that the pipe buffering semantics can vary at the operating system level
-substantially; it is not safe to assume that a write performed on the output
-side of the pipe will appear instantly to the input side. This is a
-fundamental difference and Tcl cannot conceal it. The overall stream semantics
-\fIare\fR compatible, so blocking reads and writes will not see most of the
-differences, but the details of what exactly gets written when are not. This
-is most likely to show up when using pipelines for testing; care should be
-taken to ensure that deadlocks do not occur and that potential short reads are
-allowed for.
+Due to buffering, data written to one side of a pipe might not immediately
+become available on the other side. Tcl's own buffers can be configured via
+\fBchan configure -buffering\fR, but overall behaviour still depends on
+operating system buffers outside of Tcl's control. Once the write side of the
+channel is closed, any data remaining in the buffers is flushed through to the
+read side. It may be useful to arrange for the connected process to flush at
+some point after writing to the channel or to have it use some system-provided
+mechanism to configure buffering. When two pipes are connected to the same
+process, one to send data to the process, and one to read data from the
+process, a deadlock may occur if the channels are in blocking mode: If
+reading, the channel may block waiting for data that can never come because
+buffers are only flushed on subsequent writes, and if writing, the channel may
+block while waiting for the buffers to become free, which can never happen
+because the reader can not read while the writer is blocking. To avoid this
+issue, either put the channels into non-blocking mode and use event handlers,
+or place the read channel and the write channel in separate interpreters in
+separate threads.
.RE
.TP
-\fBchan pop \fIchannelId\fR
-Removes the topmost transformation from the channel \fIchannelId\fR, if there
-is any. If there are no transformations added to \fIchannelId\fR, this is
-equivalent to \fBchan close\fR of that channel. The result is normally the
-empty string, but can be an error in some situations (i.e. where the
-underlying system stream is closed and that results in an error).
-.TP
-\fBchan postevent \fIchannelId eventSpec\fR
-.
-This subcommand is used by command handlers specified with \fBchan
-create\fR. It notifies the channel represented by the handle
-\fIchannelId\fR that the event(s) listed in the \fIeventSpec\fR have
-occurred. The argument has to be a list containing any of the strings
-\fBread\fR and \fBwrite\fR. The list must contain at least one
-element as it does not make sense to invoke the command if there are
-no events to post.
+\fBchan pop \fIchannelName\fR
+Removes the topmost transformation handler from the channel if there is one,
+and closes the channel otherwise. The result is normally the empty string, but
+may be an error in some situations, e.g. when closing the underlying resource
+results in an error.
+.TP
+\fBchan postevent \fIchannelName eventSpec\fR
+.
+For use by handlers established with \fBchan create\fR. Notifies Tcl that
+that one or more event(s) listed in \fIeventSpec\fR, each of which is either
+.QW\fBread\fR
+or
+.QW\fBwrite\fR.
+, have occurred.
.RS
.PP
-Note that this subcommand can only be used with channel handles that
-were created/opened by \fBchan create\fR. All other channels will
-cause this subcommand to report an error.
-.PP
-As only the Tcl level of a channel, i.e. its command handler, should
-post events to it we also restrict the usage of this command to the
-interpreter that created the channel. In other words, posting events
-to a reflected channel from an interpreter that does not contain it's
-implementation is not allowed. Attempting to post an event from any
-other interpreter will cause this subcommand to report an error.
-.PP
-Another restriction is that it is not possible to post events that the
-I/O core has not registered an interest in. Trying to do so will cause
-the method to throw an error. See the command handler method
-\fBwatch\fR described in \fBrefchan\fR, the document specifying
-the API of command handlers for reflected channels.
-.PP
-This command is \fBsafe\fR and made accessible to safe interpreters.
-It can trigger the execution of \fBchan event\fR handlers, whether in the
-current interpreter or in other interpreters or other threads, even
-where the event is posted from a safe interpreter and listened for by
-a trusted interpreter. \fBChan event\fR handlers are \fIalways\fR
-executed in the interpreter that set them up.
+For use only by handlers for a channel created by \fBchan create\fR. It is an
+error to post an event for any other channel.
+.PP
+Since only the handler for a reflected channel channel should post events it is
+an error to post an event from any interpreter other than the interpreter that
+created the channel.
+.PP
+It is an error to post an event that the channel has no interest in. See
+\fBwatch\fR in the \fBrefchan\fR documentation for more information
+.PP
+\fBchan postevent\fR is available in safe interpreters, as any handler for a
+reflected channel would have been created, and will be evaluated in that
+interpreter as well.
.RE
.TP
-\fBchan push \fIchannelId cmdPrefix\fR
-Adds a new transformation on top of the channel \fIchannelId\fR. The
-\fIcmdPrefix\fR argument describes a list of one or more words which represent
-a handler that will be used to implement the transformation. The command
-prefix must provide the API described in the \fBtranschan\fR manual page.
-The result of this subcommand is a handle to the transformation. Note that it
-is important to make sure that the transformation is capable of supporting the
-channel mode that it is used with or this can make the channel neither
-readable nor writable.
-.TP
-\fBchan puts\fR ?\fB\-nonewline\fR? ?\fIchannelId\fR? \fIstring\fR
-.
-Writes \fIstring\fR to the channel named \fIchannelId\fR followed by a
-newline character. A trailing newline character is written unless the
-optional flag \fB\-nonewline\fR is given. If \fIchannelId\fR is
-omitted, the string is written to the standard output channel,
+\fBchan push \fIchannelName cmdPrefix\fR
+Adds a new transformation handler on top of the channel and returns a handle
+for the transformation. \fIcmdPrefix\fR is the first words of a command that
+provides the interface documented for \fBtranschan\fR, and transforms data on
+the channel, It is an error if handler does not support the mode(s) the channel
+is in.
+.TP
+\fBchan puts\fR ?\fB\-nonewline\fR? ?\fIchannelName\fR? \fIstring\fR
+.
+Writes \fIstring\fR and a line feed to the channel. If \fB\-nonewline\fR is
+given, the trailing line feed is not written. The default channel is
\fBstdout\fR.
.RS
.PP
-Newline characters in the output are translated by \fBchan puts\fR to
-platform-specific end-of-line sequences according to the currently
-configured value of the \fB\-translation\fR option for the channel
-(for example, on PCs newlines are normally replaced with
-carriage-return-linefeed sequences; see \fBchan configure\fR above for
-details).
-.PP
-Tcl buffers output internally, so characters written with \fBchan
-puts\fR may not appear immediately on the output file or device; Tcl
-will normally delay output until the buffer is full or the channel is
-closed. You can force output to appear immediately with the \fBchan
-flush\fR command.
-.PP
-When the output buffer fills up, the \fBchan puts\fR command will
-normally block until all the buffered data has been accepted for
-output by the operating system. If \fIchannelId\fR is in non-blocking
-mode then the \fBchan puts\fR command will not block even if the
-operating system cannot accept the data. Instead, Tcl continues to
-buffer the data and writes it in the background as fast as the
-underlying file or device can accept it. The application must use the
-Tcl event loop for non-blocking output to work; otherwise Tcl never
-finds out that the file or device is ready for more output data. It
-is possible for an arbitrarily large amount of data to be buffered for
-a channel in non-blocking mode, which could consume a large amount of
-memory. To avoid wasting memory, non-blocking I/O should normally be
-used in an event-driven fashion with the \fBchan event\fR command
-(do not invoke \fBchan puts\fR unless you have recently been notified
-via a file event that the channel is ready for more output data).
+Each line feed in the output is translated according to the configuration of
+\fB\-translation\fR.
+.PP
+Because Tcl internally buffers output, characters written to a channel may not
+immediately be available at the destination. Tcl normally delays output until
+the buffer is full or the channel is closed. \fBchan flush\fR forces output in
+the direction of the destination.
+.PP
+When the output for a channel in blocking mode fills up, \fBchan puts\fR blocks
+until space in the buffer is available again, but for a channel in non-blocking
+mode, it returns immediately and the data is written in the background as fast
+possible, constrained by the speed at which as the destination accepts it.
+Output to a channel in non-blocking mode only works properly when the
+application enters the event loop, giving Tcl a chance to find out that the
+destination is ready to accept more data. When a channel is in non-blocking
+mode, Tcl's internal buffers can hold an arbitrary amount of data, possibly
+consuming a large amount of memory. To avoid wasting memory, channels in
+non-blocking mode should normally be handled using \fBchan event\fR, where the
+application only invokes \fBchan puts\fR after being recently notified through
+a file event handler that the channel is ready for more output data.
.RE
.TP
-\fBchan read \fIchannelId\fR ?\fInumChars\fR?
+\fBchan read \fIchannelName\fR ?\fInumChars\fR?
.TP
-\fBchan read \fR?\fB\-nonewline\fR? \fIchannelId\fR
+\fBchan read \fR?\fB\-nonewline\fR? \fIchannelName\fR
.
-In the first form, the result will be the next \fInumChars\fR
-characters read from the channel named \fIchannelId\fR; if
-\fInumChars\fR is omitted, all characters up to the point when the
-channel would signal a failure (whether an end-of-file, blocked or
-other error condition) are read. In the second form (i.e. when
-\fInumChars\fR has been omitted) the flag \fB\-nonewline\fR may be
-given to indicate that any trailing newline in the string that has
-been read should be trimmed.
+Reads and returns the next \fInumChars\fR characters from the channel. If
+\fInumChars\fR is omitted, all available characters up to the end of the file
+are read, or if the channel is in non-blocking mode, all currently-available
+characters are read. If there is an error on the channel, reading ceases and
+an error is returned. If \fInumChars\fR is not given, \fB\-nonewline\fR
+may be given, causing any any trailing line feed to be trimmed.
.RS
.PP
-If \fIchannelId\fR is in non-blocking mode, \fBchan read\fR may not
-read as many characters as requested: once all available input has
-been read, the command will return the data that is available rather
-than blocking for more input. If the channel is configured to use a
-multi-byte encoding, then there may actually be some bytes remaining
-in the internal buffers that do not form a complete character. These
-bytes will not be returned until a complete character is available or
-end-of-file is reached. The \fB\-nonewline\fR switch is ignored if
-the command returns before reaching the end of the file.
-.PP
-\fBChan read\fR translates end-of-line sequences in the input into
-newline characters according to the \fB\-translation\fR option for the
-channel (see \fBchan configure\fR above for a discussion on the ways
-in which \fBchan configure\fR will alter input).
-.PP
-When reading from a serial port, most applications should configure
-the serial port channel to be non-blocking, like this:
-.PP
-.CS
-\fBchan configure \fIchannelId \fB\-blocking \fI0\fR.
-.CE
-.PP
-Then \fBchan read\fR behaves much like described above. Note that
-most serial ports are comparatively slow; it is entirely possible to
-get a \fBreadable\fR event for each character read from them. Care
-must be taken when using \fBchan read\fR on blocking serial ports:
-.TP
-\fBchan read \fIchannelId numChars\fR
-.
-In this form \fBchan read\fR blocks until \fInumChars\fR have been
-received from the serial port.
-.TP
-\fBchan read \fIchannelId\fR
-.
-In this form \fBchan read\fR blocks until the reception of the
-end-of-file character, see \fBchan configure -eofchar\fR. If there no
-end-of-file character has been configured for the channel, then
-\fBchan read\fR will block forever.
+If the channel is in non-blocking mode, fewer characters than requested may be
+returned. If the channel is configured to use a multi-byte encoding, bytes
+that do not form a complete character are retained in the buffers until enough
+bytes to complete the character accumulate, or the end of the data is reached.
+\fB\-nonewline\fR is ignored if characters are returned before reaching the end
+of the file.
+.PP
+Each end-of-line sequence according to the value of \fB\-translation\fR is
+translated into a line feed.
+.PP
+When reading from a serial port, most applications should configure the serial
+port channel to be in non-blocking mode, but not necessarily use an event
+handler since most serial ports are comparatively slow. It is entirely
+possible to get a \fBreadable\fR event for each individual character. In
+blocking mode, \fBchan read\fR blocks forever when reading to the end of the
+data if there is no \fBchan configure -eofchar\fR configured for the channel.
.RE
.TP
-\fBchan seek \fIchannelId offset\fR ?\fIorigin\fR?
+\fBchan seek \fIchannelName offset\fR ?\fIorigin\fR?
.
-Sets the current access position within the underlying data stream for
-the channel named \fIchannelId\fR to be \fIoffset\fR bytes relative to
-\fIorigin\fR. \fIOffset\fR must be an integer (which may be negative)
-and \fIorigin\fR must be one of the following:
+Sets the current position for the data in the channel to integer \fIoffset\fR
+bytes relative to \fIorigin\fR. A negative offset moves the current position
+backwards from the origin. \fIorigin\fR is one of the
+following:
.RS
+.PP
.TP 10
\fBstart\fR
.
-The new access position will be \fIoffset\fR bytes from the start
-of the underlying file or device.
+The origin is the start of the data. This is the default.
.TP 10
\fBcurrent\fR
.
-The new access position will be \fIoffset\fR bytes from the current
-access position; a negative \fIoffset\fR moves the access position
-backwards in the underlying file or device.
+The origin is the current position.
.TP 10
\fBend\fR
.
-The new access position will be \fIoffset\fR bytes from the end of the
-file or device. A negative \fIoffset\fR places the access position
-before the end of file, and a positive \fIoffset\fR places the access
-position after the end of file.
-.PP
-The \fIorigin\fR argument defaults to \fBstart\fR.
+The origin is the end of the data.
.PP
-\fBChan seek\fR flushes all buffered output for the channel before the
-command returns, even if the channel is in non-blocking mode. It also
-discards any buffered and unread input. This command returns an empty
-string. An error occurs if this command is applied to channels whose
-underlying file or device does not support seeking.
+\fBChan seek\fR flushes all buffered output even if the channel is in
+non-blocking mode, discards any buffered and unread input, and returns the
+empty string or an error if the channel does not support seeking.
.PP
-Note that \fIoffset\fR values are byte offsets, not character offsets.
-Both \fBchan seek\fR and \fBchan tell\fR operate in terms of bytes,
-not characters, unlike \fBchan read\fR.
+\fIoffset\fR values are byte offsets, not character offsets. Unlike \fBchan
+read\fR, both \fBchan seek\fR and \fBchan tell\fR operate in terms of bytes,
+not characters,
.RE
.TP
-\fBchan tell \fIchannelId\fR
+\fBchan tell \fIchannelName\fR
.
-Returns a number giving the current access position within the
-underlying data stream for the channel named \fIchannelId\fR. This
-value returned is a byte offset that can be passed to \fBchan seek\fR
-in order to set the channel to a particular position. Note that this
-value is in terms of bytes, not characters like \fBchan read\fR. The
-value returned is -1 for channels that do not support seeking.
+Returns the offset in bytes of the current position in the underlying data, or
+-1 if the channel does not suport seeking. The value can be passed to \fBchan
+seek\fR to set current position to that offset.
.TP
-\fBchan truncate \fIchannelId\fR ?\fIlength\fR?
+\fBchan truncate \fIchannelName\fR ?\fIlength\fR?
.
-Sets the byte length of the underlying data stream for the channel
-named \fIchannelId\fR to be \fIlength\fR (or to the current byte
-offset within the underlying data stream if \fIlength\fR is
-omitted). The channel is flushed before truncation.
+Flushes the channel and truncates the data in the channel to \fIlength\fR
+bytes, or to the current position in bytes if \fIlength\fR is omitted.
.
.SH EXAMPLES
.PP
-This opens a file using a known encoding (CP1252, a very common encoding
-on Windows), searches for a string, rewrites that part, and truncates the
-file after a further two lines.
+In the following example a file is opened using the encoding CP1252, which is
+common on Windows, searches for a string, rewrites that part, and truncates the
+file two lines later.
.PP
.CS
set f [open somefile.txt r+]
@@ -793,12 +619,12 @@ while {[\fBchan gets\fR $f line] >= 0} {
\fBchan close\fR $f
.CE
.PP
-A network server that does echoing of its input line-by-line without
-preventing servicing of other connections at the same time.
+A network server that echoes its input line-by-line without
+preventing servicing of other connections at the same time:
.PP
.CS
# This is a very simple logger...
-proc log {message} {
+proc log message {
\fBchan puts\fR stdout $message
}
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index c0c3b6f..e4946ee 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -394,14 +394,10 @@ Tcl_RegexpObjCmd(
newPtr = Tcl_NewListObj(2, objs);
} else {
- if (i <= info.nsubs) {
- if (info.matches[i].end <= 0) {
- TclNewObj(newPtr);
- } else {
- newPtr = Tcl_GetRange(objPtr,
- offset + info.matches[i].start,
- offset + info.matches[i].end - 1);
- }
+ if ((i <= info.nsubs) && (info.matches[i].end > 0)) {
+ newPtr = Tcl_GetRange(objPtr,
+ offset + info.matches[i].start,
+ offset + info.matches[i].end - 1);
} else {
TclNewObj(newPtr);
}
diff --git a/generic/tclTest.c b/generic/tclTest.c
index d8e5b2f..33d10b5 100644
--- a/generic/tclTest.c
+++ b/generic/tclTest.c
@@ -327,6 +327,7 @@ static Tcl_ObjCmdProc TestNumUtfCharsCmd;
static Tcl_ObjCmdProc TestFindFirstCmd;
static Tcl_ObjCmdProc TestFindLastCmd;
static Tcl_ObjCmdProc TestHashSystemHashCmd;
+static Tcl_ObjCmdProc TestGetIntForIndexCmd;
static Tcl_NRPostProc NREUnwind_callback;
static Tcl_ObjCmdProc TestNREUnwind;
@@ -598,6 +599,8 @@ Tcltest_Init(
TestFindFirstCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "testfindlast",
TestFindLastCmd, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "testgetintforindex",
+ TestGetIntForIndexCmd, NULL, NULL);
Tcl_CreateCommand(interp, "testsetplatform", TestsetplatformCmd,
NULL, NULL);
Tcl_CreateCommand(interp, "testsocket", TestSocketCmd,
@@ -7041,6 +7044,33 @@ TestFindLastCmd(
return TCL_OK;
}
+static int
+TestGetIntForIndexCmd(
+ TCL_UNUSED(void *),
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ int result;
+ Tcl_WideInt endvalue;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "index endvalue");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetWideIntFromObj(interp, objv[2], &endvalue) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIntForIndex(interp, objv[1], endvalue, &result) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
+ return TCL_OK;
+}
+
+
+
#if defined(HAVE_CPUID) || defined(_WIN32)
/*
*----------------------------------------------------------------------
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index 32721f6..e29afcc 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -3699,11 +3699,11 @@ Tcl_GetIntForIndex(
{
Tcl_WideInt wide;
- if (GetWideForIndex(interp, objPtr, (size_t)(endValue + 1) - 1, &wide) == TCL_ERROR) {
+ if (GetWideForIndex(interp, objPtr, endValue, &wide) == TCL_ERROR) {
return TCL_ERROR;
}
if (indexPtr != NULL) {
- if ((wide < 0) && (endValue > TCL_INDEX_END)) {
+ if ((wide < 0) && (endValue >= 0)) {
*indexPtr = -1;
} else if (wide > INT_MAX) {
*indexPtr = INT_MAX;
diff --git a/tests/indexObj.test b/tests/indexObj.test
index 42c67b2..c327274 100644
--- a/tests/indexObj.test
+++ b/tests/indexObj.test
@@ -17,6 +17,7 @@ if {"::tcltest" ni [namespace children]} {
catch [list package require -exact tcl::test [info patchlevel]]
testConstraint testindexobj [llength [info commands testindexobj]]
+testConstraint testgetintforindex [llength [info commands testgetintforindex]]
testConstraint testparseargs [llength [info commands testparseargs]]
test indexObj-1.1 {exact match} testindexobj {
@@ -169,6 +170,52 @@ test indexObj-7.7 {Tcl_ParseArgsObjv memory management} testparseargs {
testparseargs 1 2 3 4 5 6 7 8 9 0 -bool 1 2 3 4 5 6 7 8 9 0
} {1 21 {testparseargs 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0}}
+test indexObj-8.1 {Tcl_GetIntForIndex integer} testgetintforindex {
+ testgetintforindex 0 0
+} 0
+test indexObj-8.2 {Tcl_GetIntForIndex integer} testgetintforindex {
+ testgetintforindex -1 0
+} -1
+test indexObj-8.3 {Tcl_GetIntForIndex integer} testgetintforindex {
+ testgetintforindex -2 0
+} -1
+test indexObj-8.4 {Tcl_GetIntForIndex INT_MAX} testgetintforindex {
+ testgetintforindex 2147483647 0
+} 2147483647
+test indexObj-8.5 {Tcl_GetIntForIndex INT_MAX+1} testgetintforindex {
+ testgetintforindex 2147483648 0
+} 2147483647
+test indexObj-8.6 {Tcl_GetIntForIndex end-1} testgetintforindex {
+ testgetintforindex end-1 2147483646
+} 2147483645
+test indexObj-8.7 {Tcl_GetIntForIndex end-1} testgetintforindex {
+ testgetintforindex end-1 2147483647
+} 2147483646
+test indexObj-8.8 {Tcl_GetIntForIndex end} testgetintforindex {
+ testgetintforindex end 2147483646
+} 2147483646
+test indexObj-8.9 {Tcl_GetIntForIndex end} testgetintforindex {
+ testgetintforindex end 2147483647
+} 2147483647
+test indexObj-8.10 {Tcl_GetIntForIndex end-1} testgetintforindex {
+ testgetintforindex end-1 -1
+} -2
+test indexObj-8.11 {Tcl_GetIntForIndex end-1} testgetintforindex {
+ testgetintforindex end-1 -2
+} -3
+test indexObj-8.12 {Tcl_GetIntForIndex end} testgetintforindex {
+ testgetintforindex end -1
+} -1
+test indexObj-8.13 {Tcl_GetIntForIndex end} testgetintforindex {
+ testgetintforindex end -2
+} -2
+test indexObj-8.14 {Tcl_GetIntForIndex end+1} testgetintforindex {
+ testgetintforindex end+1 -1
+} 0
+test indexObj-8.15 {Tcl_GetIntForIndex end+1} testgetintforindex {
+ testgetintforindex end+1 -2
+} -1
+
# cleanup
::tcltest::cleanupTests
return