summaryrefslogtreecommitdiffstats
path: root/generic/tclIOCmd.c
diff options
context:
space:
mode:
authorhobbs <hobbs>2007-12-05 21:47:25 (GMT)
committerhobbs <hobbs>2007-12-05 21:47:25 (GMT)
commitd2cafa17fbc0ba124639514618fcdefecc66d927 (patch)
tree4699636d41848d0d0642de636144a9faad783163 /generic/tclIOCmd.c
parent23b63fa1bae88cf7965c0113afc1738d23b51dd4 (diff)
downloadtcl-d2cafa17fbc0ba124639514618fcdefecc66d927.zip
tcl-d2cafa17fbc0ba124639514618fcdefecc66d927.tar.gz
tcl-d2cafa17fbc0ba124639514618fcdefecc66d927.tar.bz2
* generic/tclIO.h: Create Tcl_Obj for Tcl channels to reduce
* generic/tclIO.c: overhead in lookup by Tcl_GetChannel. New * generic/tclIOCmd.c: TclGetChannelFromObj for internal use. * generic/tclIO.c (WriteBytes, WriteChars): add opt check to avoid EOL translation when not linebuffered or using lf. [Bug 1845092]
Diffstat (limited to 'generic/tclIOCmd.c')
-rw-r--r--generic/tclIOCmd.c130
1 files changed, 56 insertions, 74 deletions
diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c
index ceed522..44b3b1d 100644
--- a/generic/tclIOCmd.c
+++ b/generic/tclIOCmd.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIOCmd.c,v 1.47 2007/11/19 14:50:55 dkf Exp $
+ * RCS: @(#) $Id: tclIOCmd.c,v 1.48 2007/12/05 21:47:27 hobbs Exp $
*/
#include "tclInt.h"
@@ -64,6 +64,7 @@ Tcl_PutsObjCmd(
{
Tcl_Channel chan; /* The channel to puts on. */
Tcl_Obj *string; /* String to write. */
+ Tcl_Obj *chanObjPtr = NULL; /* channel object. */
int newline; /* Add a newline at end? */
const char *channelId; /* Name of channel for puts. */
int result; /* Result of puts operation. */
@@ -83,6 +84,7 @@ Tcl_PutsObjCmd(
} else {
newline = 1;
channelId = TclGetString(objv[1]);
+ chanObjPtr = objv[1];
}
string = objv[2];
break;
@@ -90,6 +92,7 @@ Tcl_PutsObjCmd(
case 4: /* [puts -nonewline $chan $x] or [puts $chan $x nonewline] */
if (strcmp(TclGetString(objv[1]), "-nonewline") == 0) {
channelId = TclGetString(objv[2]);
+ chanObjPtr = objv[2];
string = objv[3];
} else {
/*
@@ -109,6 +112,7 @@ Tcl_PutsObjCmd(
return TCL_ERROR;
}
channelId = TclGetString(objv[1]);
+ chanObjPtr = objv[1];
string = objv[2];
}
newline = 0;
@@ -120,9 +124,16 @@ Tcl_PutsObjCmd(
return TCL_ERROR;
}
- chan = Tcl_GetChannel(interp, channelId, &mode);
- if (chan == NULL) {
- return TCL_ERROR;
+ if (chanObjPtr != NULL) {
+ if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ } else {
+ chan = Tcl_GetChannel(interp, channelId, &mode);
+ if (chan == NULL) {
+ return TCL_ERROR;
+ }
}
if ((mode & TCL_WRITABLE) == 0) {
Tcl_AppendResult(interp, "channel \"", channelId,
@@ -182,21 +193,20 @@ Tcl_FlushObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
+ Tcl_Obj *chanObjPtr;
Tcl_Channel chan; /* The channel to flush on. */
- char *channelId;
int mode;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "channelId");
return TCL_ERROR;
}
- channelId = TclGetString(objv[1]);
- chan = Tcl_GetChannel(interp, channelId, &mode);
- if (chan == NULL) {
+ chanObjPtr = objv[1];
+ if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
if ((mode & TCL_WRITABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", channelId,
+ Tcl_AppendResult(interp, "channel \"", TclGetString(chanObjPtr),
"\" wasn't opened for writing", NULL);
return TCL_ERROR;
}
@@ -210,7 +220,8 @@ Tcl_FlushObjCmd(
*/
if (!TclChanCaughtErrorBypass(interp, chan)) {
- Tcl_AppendResult(interp, "error flushing \"", channelId, "\": ",
+ Tcl_AppendResult(interp, "error flushing \"",
+ TclGetString(chanObjPtr), "\": ",
Tcl_PosixError(interp), NULL);
}
return TCL_ERROR;
@@ -246,20 +257,18 @@ Tcl_GetsObjCmd(
Tcl_Channel chan; /* The channel to read from. */
int lineLen; /* Length of line just read. */
int mode; /* Mode in which channel is opened. */
- char *name;
- Tcl_Obj *linePtr;
+ Tcl_Obj *linePtr, *chanObjPtr;
if ((objc != 2) && (objc != 3)) {
Tcl_WrongNumArgs(interp, 1, objv, "channelId ?varName?");
return TCL_ERROR;
}
- name = TclGetString(objv[1]);
- chan = Tcl_GetChannel(interp, name, &mode);
- if (chan == NULL) {
+ chanObjPtr = objv[1];
+ if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
if ((mode & TCL_READABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", name,
+ Tcl_AppendResult(interp, "channel \"", TclGetString(chanObjPtr),
"\" wasn't opened for reading", NULL);
return TCL_ERROR;
}
@@ -279,7 +288,8 @@ Tcl_GetsObjCmd(
if (!TclChanCaughtErrorBypass(interp, chan)) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "error reading \"", name, "\": ",
+ Tcl_AppendResult(interp, "error reading \"",
+ TclGetString(chanObjPtr), "\": ",
Tcl_PosixError(interp), NULL);
}
return TCL_ERROR;
@@ -329,8 +339,7 @@ Tcl_ReadObjCmd(
int toRead; /* How many bytes to read? */
int charactersRead; /* How many characters were read? */
int mode; /* Mode in which channel is opened. */
- char *name;
- Tcl_Obj *resultPtr;
+ Tcl_Obj *resultPtr, *chanObjPtr;
if ((objc != 2) && (objc != 3)) {
Interp *iPtr;
@@ -361,13 +370,12 @@ Tcl_ReadObjCmd(
goto argerror;
}
- name = TclGetString(objv[i]);
- chan = Tcl_GetChannel(interp, name, &mode);
- if (chan == NULL) {
+ chanObjPtr = objv[i];
+ if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
if ((mode & TCL_READABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", name,
+ Tcl_AppendResult(interp, "channel \"", TclGetString(chanObjPtr),
"\" wasn't opened for reading", NULL);
return TCL_ERROR;
}
@@ -409,7 +417,8 @@ Tcl_ReadObjCmd(
if (!TclChanCaughtErrorBypass(interp, chan)) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "error reading \"", name, "\": ",
+ Tcl_AppendResult(interp, "error reading \"",
+ TclGetString(chanObjPtr), "\": ",
Tcl_PosixError(interp), NULL);
}
Tcl_DecrRefCount(resultPtr);
@@ -464,7 +473,6 @@ Tcl_SeekObjCmd(
Tcl_WideInt offset; /* Where to seek? */
int mode; /* How to seek? */
Tcl_WideInt result; /* Of calling Tcl_Seek. */
- char *chanName;
int optionIndex;
static const char *originOptions[] = {
"start", "current", "end", NULL
@@ -475,9 +483,7 @@ Tcl_SeekObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "channelId offset ?origin?");
return TCL_ERROR;
}
- chanName = TclGetString(objv[1]);
- chan = Tcl_GetChannel(interp, chanName, NULL);
- if (chan == NULL) {
+ if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
return TCL_ERROR;
}
if (Tcl_GetWideIntFromObj(interp, objv[2], &offset) != TCL_OK) {
@@ -501,8 +507,9 @@ Tcl_SeekObjCmd(
* regular message if nothing was found in the bypass.
*/
if (!TclChanCaughtErrorBypass(interp, chan)) {
- Tcl_AppendResult(interp, "error during seek on \"", chanName,
- "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_AppendResult(interp, "error during seek on \"",
+ TclGetString(objv[1]), "\": ",
+ Tcl_PosixError(interp), NULL);
}
return TCL_ERROR;
}
@@ -535,7 +542,6 @@ Tcl_TellObjCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Channel chan; /* The channel to tell on. */
- char *chanName;
Tcl_WideInt newLoc;
if (objc != 2) {
@@ -548,9 +554,7 @@ Tcl_TellObjCmd(
* channel table of this interpreter.
*/
- chanName = TclGetString(objv[1]);
- chan = Tcl_GetChannel(interp, chanName, NULL);
- if (chan == NULL) {
+ if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
return TCL_ERROR;
}
@@ -596,16 +600,13 @@ Tcl_CloseObjCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Channel chan; /* The channel to close. */
- char *arg;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "channelId");
return TCL_ERROR;
}
- arg = TclGetString(objv[1]);
- chan = Tcl_GetChannel(interp, arg, NULL);
- if (chan == NULL) {
+ if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
return TCL_ERROR;
}
@@ -664,7 +665,7 @@ Tcl_FconfigureObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- char *chanName, *optionName, *valueName;
+ char *optionName, *valueName;
Tcl_Channel chan; /* The channel to set a mode on. */
int i; /* Iterate over arg-value pairs. */
@@ -674,9 +675,7 @@ Tcl_FconfigureObjCmd(
return TCL_ERROR;
}
- chanName = TclGetString(objv[1]);
- chan = Tcl_GetChannel(interp, chanName, NULL);
- if (chan == NULL) {
+ if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
return TCL_ERROR;
}
@@ -744,17 +743,13 @@ Tcl_EofObjCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Channel chan;
- int dummy;
- char *arg;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "channelId");
return TCL_ERROR;
}
- arg = TclGetString(objv[1]);
- chan = Tcl_GetChannel(interp, arg, &dummy);
- if (chan == NULL) {
+ if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
return TCL_ERROR;
}
@@ -963,20 +958,17 @@ Tcl_FblockedObjCmd(
{
Tcl_Channel chan;
int mode;
- char *arg;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "channelId");
return TCL_ERROR;
}
- arg = TclGetString(objv[1]);
- chan = Tcl_GetChannel(interp, arg, &mode);
- if (chan == NULL) {
+ if (TclGetChannelFromObj(interp, objv[1], &chan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
if ((mode & TCL_READABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", arg,
+ Tcl_AppendResult(interp, "channel \"", TclGetString(objv[1]),
"\" wasn't opened for reading", NULL);
return TCL_ERROR;
}
@@ -1559,7 +1551,6 @@ Tcl_FcopyObjCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Channel inChan, outChan;
- const char *arg;
int mode, i, toRead, index;
Tcl_Obj *cmdPtr;
static const char* switches[] = { "-size", "-command", NULL };
@@ -1576,23 +1567,19 @@ Tcl_FcopyObjCmd(
* writable, as appropriate.
*/
- arg = TclGetString(objv[1]);
- inChan = Tcl_GetChannel(interp, arg, &mode);
- if (inChan == NULL) {
+ if (TclGetChannelFromObj(interp, objv[1], &inChan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
if ((mode & TCL_READABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", arg,
+ Tcl_AppendResult(interp, "channel \"", TclGetString(objv[1]),
"\" wasn't opened for reading", NULL);
return TCL_ERROR;
}
- arg = TclGetString(objv[2]);
- outChan = Tcl_GetChannel(interp, arg, &mode);
- if (outChan == NULL) {
+ if (TclGetChannelFromObj(interp, objv[2], &outChan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
if ((mode & TCL_WRITABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"", arg,
+ Tcl_AppendResult(interp, "channel \"", TclGetString(objv[2]),
"\" wasn't opened for writing", NULL);
return TCL_ERROR;
}
@@ -1648,7 +1635,6 @@ TclChanPendingObjCmd(
{
Tcl_Channel chan;
int index, mode;
- char *arg;
static const char *options[] = {"input", "output", NULL};
enum options {PENDING_INPUT, PENDING_OUTPUT};
@@ -1662,9 +1648,7 @@ TclChanPendingObjCmd(
return TCL_ERROR;
}
- arg = TclGetString(objv[2]);
- chan = Tcl_GetChannel(interp, arg, &mode);
- if (chan == NULL) {
+ if (TclGetChannelFromObj(interp, objv[2], &chan, &mode, 0) != TCL_OK) {
return TCL_ERROR;
}
@@ -1712,17 +1696,13 @@ TclChanTruncateObjCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Channel chan;
- int mode;
Tcl_WideInt length;
- char *chanName;
if ((objc < 2) || (objc > 3)) {
Tcl_WrongNumArgs(interp, 1, objv, "channelId ?length?");
return TCL_ERROR;
}
- chanName = TclGetString(objv[1]);
- chan = Tcl_GetChannel(interp, chanName, &mode);
- if (chan == NULL) {
+ if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
return TCL_ERROR;
}
@@ -1747,15 +1727,17 @@ TclChanTruncateObjCmd(
length = Tcl_Tell(chan);
if (length == Tcl_WideAsLong(-1)) {
Tcl_AppendResult(interp,
- "could not determine current location in \"", chanName,
- "\": ", Tcl_PosixError(interp), NULL);
+ "could not determine current location in \"",
+ TclGetString(objv[1]), "\": ",
+ Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
}
if (Tcl_TruncateChannel(chan, length) != TCL_OK) {
- Tcl_AppendResult(interp, "error during truncate on \"", chanName,
- "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_AppendResult(interp, "error during truncate on \"",
+ TclGetString(objv[1]), "\": ",
+ Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}