From b97786c85dbd70fd4445f8161b205d5dbc56e844 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 19 Jan 2022 14:21:38 +0000 Subject: (partial) fix for [https://core.tcl-lang.org/tk/tktview?name=a9929f112a|a9929f112a]. WIP --- generic/tclUtil.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 32721f6..86b6369 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3647,12 +3647,15 @@ GetWideForIndex( if (numType == TCL_NUMBER_INT) { /* objPtr holds an integer in the signed wide range */ *widePtr = *(Tcl_WideInt *)cd; + if (*widePtr < -1) { + *widePtr = -1; + } return TCL_OK; } if (numType == TCL_NUMBER_BIG) { /* objPtr holds an integer outside the signed wide range */ /* Truncate to the signed wide range. */ - *widePtr = ((mp_isneg((mp_int *)cd)) ? WIDE_MIN : WIDE_MAX); + *widePtr = ((mp_isneg((mp_int *)cd)) ? -1 : WIDE_MAX); return TCL_OK; } } -- cgit v0.12 From e433c571581eae56161e5c4dc8dcae36e31d8039 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 21 Jan 2022 08:43:13 +0000 Subject: Add test-cases for Tcl_GetIntForIndex(). This reveals a minor bug --- generic/tclTest.c | 29 +++++++++++++++++++++++++++++ generic/tclUtil.c | 7 ++----- tests/indexObj.test | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/generic/tclTest.c b/generic/tclTest.c index 7ec3c41..95ef5b7 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, @@ -7036,6 +7039,32 @@ TestFindLastCmd( return TCL_OK; } +static int +TestGetIntForIndexCmd( + TCL_UNUSED(void *), + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + int result, endvalue; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "index endvalue"); + return TCL_ERROR; + } + + if (Tcl_GetIntFromObj(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_NewIntObj(result)); + return TCL_OK; +} + + + #if defined(HAVE_CPUID) || defined(_WIN32) /* *---------------------------------------------------------------------- diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 86b6369..10153fb 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3647,15 +3647,12 @@ GetWideForIndex( if (numType == TCL_NUMBER_INT) { /* objPtr holds an integer in the signed wide range */ *widePtr = *(Tcl_WideInt *)cd; - if (*widePtr < -1) { - *widePtr = -1; - } return TCL_OK; } if (numType == TCL_NUMBER_BIG) { /* objPtr holds an integer outside the signed wide range */ /* Truncate to the signed wide range. */ - *widePtr = ((mp_isneg((mp_int *)cd)) ? -1 : WIDE_MAX); + *widePtr = ((mp_isneg((mp_int *)cd)) ? WIDE_MIN : WIDE_MAX); return TCL_OK; } } @@ -3706,7 +3703,7 @@ Tcl_GetIntForIndex( 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 40418b3..9fd31b4 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 { @@ -165,6 +166,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 -- cgit v0.12 From d4e2ae119e3f6d6e5d430cf810ea4dc396ecd9b7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 21 Jan 2022 14:44:58 +0000 Subject: Undo part of [26539e78a7]. Although Tcl_GetRange() does it's own parameter check, it's caller doesn't have to do it any more. However, put back these check, better not depend on the improved behavior of Tcl_GetRange (yet). This gives the freedom to bring back Tcl_GetRange() to how it was in Tcl 8.6.10, if desired --- generic/tclCmdMZ.c | 20 +++++++++++--------- generic/tclExecute.c | 26 ++++++++++++++++++++++---- generic/tclStringObj.c | 7 ++++--- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index bf75d44..34fd6bf 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); } @@ -2187,7 +2183,13 @@ StringRangeCmd( return TCL_ERROR; } - if (last >= 0) { + if (first < 0) { + first = 0; + } + if (last >= length) { + last = length; + } + if (last >= first) { Tcl_SetObjResult(interp, Tcl_GetRange(objv[1], first, last)); } return TCL_OK; diff --git a/generic/tclExecute.c b/generic/tclExecute.c index a3b0401..e5a6b71 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5609,10 +5609,16 @@ TEBCresume( goto gotError; } - if (toIdx < 0) { - TclNewObj(objResultPtr); - } else { + if (fromIdx < 0) { + fromIdx = 0; + } + if (toIdx >= length) { + toIdx = length; + } + if (toIdx >= fromIdx) { objResultPtr = Tcl_GetRange(OBJ_AT_DEPTH(2), fromIdx, toIdx); + } else { + TclNewObj(objResultPtr); } TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); NEXT_INST_V(1, 3, 1); @@ -5646,6 +5652,13 @@ TEBCresume( } toIdx = TclIndexDecode(toIdx, length - 1); + if (toIdx < 0) { + goto emptyRange; + } else if (toIdx >= length) { + toIdx = length - 1; + } + + assert ( toIdx >= 0 && toIdx < length ); /* assert ( fromIdx != TCL_INDEX_BEFORE ); @@ -5659,8 +5672,13 @@ TEBCresume( if (fromIdx == TCL_INDEX_AFTER) { goto emptyRange; } + fromIdx = TclIndexDecode(fromIdx, length - 1); - if (toIdx >= 0) { + if (fromIdx < 0) { + fromIdx = 0; + } + + if (fromIdx <= toIdx) { objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx); } else { emptyRange: diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index b4f05dd..9e0e4af 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -819,6 +819,7 @@ Tcl_GetRange( FillUnicodeRep(objPtr); stringPtr = GET_STRING(objPtr); } + if (last < 0 || last >= stringPtr->numChars) { last = stringPtr->numChars - 1; } @@ -829,12 +830,12 @@ Tcl_GetRange( #if TCL_UTF_MAX == 4 /* See: bug [11ae2be95dac9417] */ if ((first > 0) && ((stringPtr->unicode[first] & 0xFC00) == 0xDC00) - && ((stringPtr->unicode[first-1] & 0xFC00) == 0xD800)) { + && ((stringPtr->unicode[first-1] & 0xFC00) == 0xD800)) { ++first; } if ((last + 1 < stringPtr->numChars) - && ((stringPtr->unicode[last+1] & 0xFC00) == 0xDC00) - && ((stringPtr->unicode[last] & 0xFC00) == 0xD800)) { + && ((stringPtr->unicode[last+1] & 0xFC00) == 0xDC00) + && ((stringPtr->unicode[last] & 0xFC00) == 0xD800)) { ++last; } #endif -- cgit v0.12 From 641cba82ec80d575338440d9d8bbf84f711eb12c Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 22 Jan 2022 14:47:29 +0000 Subject: Rewrite of documentation for [chan] --- doc/chan.n | 1106 +++++++++++++++++++++++++----------------------------------- 1 file changed, 466 insertions(+), 640 deletions(-) diff --git a/doc/chan.n b/doc/chan.n index f788bbf..aa8bbca 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 } -- cgit v0.12 From 511e85013ac111a96845721348abc019321ab15e Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 23 Jan 2022 16:21:42 +0000 Subject: eol-spacing from previous commit --- doc/chan.n | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/chan.n b/doc/chan.n index aa8bbca..9589f98 100644 --- a/doc/chan.n +++ b/doc/chan.n @@ -113,7 +113,7 @@ connect to terminal-like devices, the default value is \fBline\fR. For \fB\-buffersize\fR \fInewSize\fR . \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. +any input or output buffers subsequently allocated for this channel. .TP \fB\-encoding\fR ?\fIname\fR? . @@ -148,7 +148,7 @@ interface with the operating system, . \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 +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 @@ -279,14 +279,14 @@ first words of a command that provides the interface for a \fBrefchan\fR. \fBImode\fR is a list of one or more of the strings .QW \fBread\fR or -.QW \fBwrite\fR +.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. +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 @@ -374,7 +374,7 @@ to the channel at the right time. . 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. +while all buffered output is flushed in the background as soon as possible. .TP \fBchan gets \fIchannelName\fR ?\fIvarName\fR? . @@ -522,7 +522,7 @@ Reads and returns the next \fInumChars\fR characters from the channel. If 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. +may be given, causing any any trailing line feed to be trimmed. .RS .PP If the channel is in non-blocking mode, fewer characters than requested may be @@ -562,7 +562,7 @@ The origin is the current position. .TP 10 \fBend\fR . -The origin is the end of the data. +The origin is the end of the data. .PP \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 -- cgit v0.12 From bc8c2ad47a5fc72622020a829493e50e449bd040 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 24 Jan 2022 11:01:07 +0000 Subject: Fix another bug in Tcl_GetIntForIndex() (demonstrated by the new testcases from the previous commit) --- generic/tclTest.c | 7 ++++--- generic/tclUtil.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/generic/tclTest.c b/generic/tclTest.c index 95ef5b7..5e6ca8c 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -7046,20 +7046,21 @@ TestGetIntForIndexCmd( int objc, Tcl_Obj *const objv[]) { - int result, endvalue; + int result; + Tcl_WideInt endvalue; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "index endvalue"); return TCL_ERROR; } - if (Tcl_GetIntFromObj(interp, objv[2], &endvalue) != TCL_OK) { + 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_NewIntObj(result)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result)); return TCL_OK; } diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 10153fb..e29afcc 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3699,7 +3699,7 @@ 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) { -- cgit v0.12 From d46657f1f739cdf35daf961140c922498eb151f7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 24 Jan 2022 11:15:39 +0000 Subject: Don't document the size_t form of Tcl_GetStringFromObj() (yet), because it's only available if TCL_NO_DEPRECATED is defined --- doc/StringObj.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 -- cgit v0.12 From 5d9db7d9acbe609d68bb6f81daeaa5abeea212aa Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 24 Jan 2022 15:29:36 +0000 Subject: intPtr -> lengthPtr in Tcl_ListObjLength() documentation, so the documentation matches the signature in the header file --- doc/ListObj.3 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/ListObj.3 b/doc/ListObj.3 index ab836d8..f282039 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 -- cgit v0.12