summaryrefslogtreecommitdiffstats
path: root/generic/tclIO.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2022-10-07 22:49:27 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2022-10-07 22:49:27 (GMT)
commit9f59ec07c0f380bd4766fd9f2c54afebfe44c1f9 (patch)
tree6870966777dbd8c9f443f6aa015af4e46b739a8a /generic/tclIO.c
parentd347d3e4ffe6c51e5c8daeaa742632a392f60357 (diff)
parent2799ad9f6c20f61947f9ab30a8a884a0d2e359a6 (diff)
downloadtcl-9f59ec07c0f380bd4766fd9f2c54afebfe44c1f9.zip
tcl-9f59ec07c0f380bd4766fd9f2c54afebfe44c1f9.tar.gz
tcl-9f59ec07c0f380bd4766fd9f2c54afebfe44c1f9.tar.bz2
Merge tip-346
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r--generic/tclIO.c95
1 files changed, 74 insertions, 21 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 57a3de5..85067f2 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -1478,7 +1478,7 @@ Tcl_GetChannel(
chanPtr = (Channel *)Tcl_GetHashValue(hPtr);
chanPtr = chanPtr->state->bottomChanPtr;
if (modePtr != NULL) {
- *modePtr = chanPtr->state->flags & (TCL_READABLE|TCL_WRITABLE);
+ *modePtr = GotFlag(chanPtr->state, TCL_READABLE|TCL_WRITABLE);
}
return (Tcl_Channel) chanPtr;
@@ -1572,7 +1572,7 @@ TclGetChannelFromObj(
*channelPtr = (Tcl_Channel) statePtr->bottomChanPtr;
if (modePtr != NULL) {
- *modePtr = statePtr->flags & (TCL_READABLE|TCL_WRITABLE);
+ *modePtr = GotFlag(statePtr, TCL_READABLE|TCL_WRITABLE);
}
return TCL_OK;
@@ -1877,7 +1877,7 @@ Tcl_StackChannel(
* --+---+---+---+----+
*/
- if ((mask & (statePtr->flags & (TCL_READABLE | TCL_WRITABLE))) == 0) {
+ if ((mask & GotFlag(statePtr, TCL_READABLE|TCL_WRITABLE)) == 0) {
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"reading and writing both disallowed for channel \"%s\"",
@@ -2170,8 +2170,8 @@ Tcl_UnstackChannel(
* TIP #220: This is done with maximum privileges (as created).
*/
- statePtr->flags &= ~(TCL_READABLE|TCL_WRITABLE);
- statePtr->flags |= statePtr->maxPerms;
+ ResetFlag(statePtr, TCL_READABLE|TCL_WRITABLE);
+ SetFlag(statePtr, statePtr->maxPerms);
result = ChanClose(chanPtr, interp);
ChannelFree(chanPtr);
@@ -2378,7 +2378,7 @@ Tcl_GetChannelMode(
ChannelState *statePtr = ((Channel *) chan)->state;
/* State of actual channel. */
- return (statePtr->flags & (TCL_READABLE | TCL_WRITABLE));
+ return GotFlag(statePtr, TCL_READABLE|TCL_WRITABLE);
}
/*
@@ -2481,12 +2481,12 @@ Tcl_RemoveChannelMode(
emsg = "Illegal mode value.";
goto error;
}
- if (0 == (statePtr->flags & (TCL_READABLE | TCL_WRITABLE) & ~mode)) {
+ if (0 == (GotFlag(statePtr, TCL_READABLE|TCL_WRITABLE) & ~mode)) {
emsg = "Bad mode, would make channel inacessible";
goto error;
}
- statePtr->flags &= ~mode;
+ ResetFlag(statePtr, mode);
return TCL_OK;
error:
@@ -3706,7 +3706,7 @@ Tcl_CloseEx(
* opened for that direction).
*/
- if (!(statePtr->flags & (TCL_READABLE | TCL_WRITABLE) & flags)) {
+ if (!(GotFlag(statePtr, TCL_READABLE|TCL_WRITABLE) & flags)) {
const char *msg;
if (flags & TCL_CLOSE_READ) {
@@ -4394,6 +4394,14 @@ Write(
}
/*
+ * Transfer encoding strict option to the encoding flags
+ */
+
+ if (statePtr->flags & CHANNEL_ENCODING_STRICT) {
+ statePtr->outputEncodingFlags |= TCL_ENCODING_STRICT;
+ }
+
+ /*
* Write the terminated escape sequence even if srcLen is 0.
*/
@@ -4709,6 +4717,14 @@ Tcl_GetsObj(
}
/*
+ * Transfer encoding strict option to the encoding flags
+ */
+
+ if (statePtr->flags & CHANNEL_ENCODING_STRICT) {
+ statePtr->inputEncodingFlags |= TCL_ENCODING_STRICT;
+ }
+
+ /*
* Object used by FilterInputBytes to keep track of how much data has been
* consumed from the channel buffers.
*/
@@ -5464,6 +5480,15 @@ FilterInputBytes(
*gsPtr->dstPtr = dst;
}
gsPtr->state = statePtr->inputEncodingState;
+
+ /*
+ * Transfer encoding strict option to the encoding flags
+ */
+
+ if (statePtr->flags & CHANNEL_ENCODING_STRICT) {
+ statePtr->inputEncodingFlags |= TCL_ENCODING_STRICT;
+ }
+
result = Tcl_ExternalToUtf(NULL, gsPtr->encoding, raw, rawLen,
statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE,
&statePtr->inputEncodingState, dst, spaceLeft, &gsPtr->rawRead,
@@ -6237,6 +6262,14 @@ ReadChars(
}
/*
+ * Transfer encoding strict option to the encoding flags
+ */
+
+ if (statePtr->flags & CHANNEL_ENCODING_STRICT) {
+ statePtr->inputEncodingFlags |= TCL_ENCODING_STRICT;
+ }
+
+ /*
* This routine is burdened with satisfying several constraints. It cannot
* append more than 'charsToRead` chars onto objPtr. This is measured
* after encoding and translation transformations are completed. There is
@@ -6416,7 +6449,7 @@ ReadChars(
return 1;
}
- } else if (statePtr->flags & CHANNEL_EOF) {
+ } else if (GotFlag(statePtr, CHANNEL_EOF)) {
/*
* The bare \r is the only char and we will never read a
* subsequent char to make the determination.
@@ -6682,7 +6715,7 @@ TranslateInputEOL(
char *dst = dstStart;
int lesser;
- if ((statePtr->flags & INPUT_SAW_CR) && srcLen) {
+ if (GotFlag(statePtr, INPUT_SAW_CR) && srcLen) {
if (*src == '\n') { src++; srcLen--; }
ResetFlag(statePtr, INPUT_SAW_CR);
}
@@ -7452,7 +7485,7 @@ CheckChannelErrors(
* Fail if the channel is not opened for desired operation.
*/
- if ((statePtr->flags & direction) == 0) {
+ if (GotFlag(statePtr, direction) == 0) {
Tcl_SetErrno(EACCES);
return -1;
}
@@ -7981,6 +8014,16 @@ Tcl_GetChannelOption(
return TCL_OK;
}
}
+ if (len == 0 || HaveOpt(1, "-strictencoding")) {
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-strictencoding");
+ }
+ Tcl_DStringAppendElement(dsPtr,
+ (flags & CHANNEL_ENCODING_STRICT) ? "1" : "0");
+ if (len > 0) {
+ return TCL_OK;
+ }
+ }
if (len == 0 || HaveOpt(1, "-translation")) {
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-translation");
@@ -8249,6 +8292,16 @@ Tcl_SetChannelOption(
return TCL_ERROR;
}
return TCL_OK;
+ } else if (HaveOpt(1, "-strictencoding")) {
+ int newMode;
+
+ if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ if (newMode) {
+ statePtr->flags |= CHANNEL_ENCODING_STRICT;
+ }
+ return TCL_OK;
} else if (HaveOpt(1, "-translation")) {
const char *readMode, *writeMode;
@@ -9162,7 +9215,7 @@ Tcl_FileEventObjCmd(
}
chanPtr = (Channel *) chan;
statePtr = chanPtr->state;
- if ((statePtr->flags & mask) == 0) {
+ if (GotFlag(statePtr, mask) == 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf("channel is not %s",
(mask == TCL_READABLE) ? "readable" : "writable"));
return TCL_ERROR;
@@ -9329,8 +9382,8 @@ TclCopyChannel(
* Make sure the output side is unbuffered.
*/
- outStatePtr->flags = (outStatePtr->flags & ~CHANNEL_LINEBUFFERED)
- | CHANNEL_UNBUFFERED;
+ ResetFlag(outStatePtr, CHANNEL_LINEBUFFERED);
+ SetFlag(outStatePtr, CHANNEL_UNBUFFERED);
/*
* Test for conditions where we know we can just move bytes from input
@@ -10109,7 +10162,7 @@ DoRead(
* There's no more buffered data...
*/
- if (statePtr->flags & CHANNEL_EOF) {
+ if (GotFlag(statePtr, CHANNEL_EOF)) {
/*
* ...and there never will be.
*/
@@ -10117,7 +10170,7 @@ DoRead(
*p++ = '\r';
bytesToRead--;
bufPtr->nextRemoved++;
- } else if (statePtr->flags & CHANNEL_BLOCKED) {
+ } else if (GotFlag(statePtr, CHANNEL_BLOCKED)) {
/*
* ...and we cannot get more now.
*/
@@ -10250,20 +10303,20 @@ StopCopy(
*/
nonBlocking = csPtr->readFlags & CHANNEL_NONBLOCKING;
- if (nonBlocking != (inStatePtr->flags & CHANNEL_NONBLOCKING)) {
+ if (nonBlocking != GotFlag(inStatePtr, CHANNEL_NONBLOCKING)) {
SetBlockMode(NULL, csPtr->readPtr,
nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING);
}
if (csPtr->readPtr != csPtr->writePtr) {
nonBlocking = csPtr->writeFlags & CHANNEL_NONBLOCKING;
- if (nonBlocking != (outStatePtr->flags & CHANNEL_NONBLOCKING)) {
+ if (nonBlocking != GotFlag(outStatePtr, CHANNEL_NONBLOCKING)) {
SetBlockMode(NULL, csPtr->writePtr,
nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING);
}
}
ResetFlag(outStatePtr, CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED);
- outStatePtr->flags |=
- csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED);
+ SetFlag(outStatePtr,
+ csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED));
if (csPtr->cmdPtr) {
Tcl_DeleteChannelHandler(inChan, CopyEventProc, csPtr);