diff options
author | hobbs <hobbs> | 2007-12-05 21:47:25 (GMT) |
---|---|---|
committer | hobbs <hobbs> | 2007-12-05 21:47:25 (GMT) |
commit | d2cafa17fbc0ba124639514618fcdefecc66d927 (patch) | |
tree | 4699636d41848d0d0642de636144a9faad783163 /generic/tclIOCmd.c | |
parent | 23b63fa1bae88cf7965c0113afc1738d23b51dd4 (diff) | |
download | tcl-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.c | 130 |
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; } |