summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-05-16 15:23:26 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-05-16 15:23:26 (GMT)
commit0cfd3ae90e7df33b8acac2536459f34060f5e191 (patch)
tree40b47310a803f65ccca24ee2dd818ee3c2ba2989
parentaae8ddb7559427cdda66c3ee2ac36ef3b0c40a05 (diff)
parent2c48da76fc7efc47bef33eff275ecfbf80ccd2a8 (diff)
downloadtcl-0cfd3ae90e7df33b8acac2536459f34060f5e191.zip
tcl-0cfd3ae90e7df33b8acac2536459f34060f5e191.tar.gz
tcl-0cfd3ae90e7df33b8acac2536459f34060f5e191.tar.bz2
merge trunk
-rw-r--r--generic/tclIO.c46
-rw-r--r--tests/io.test79
-rw-r--r--win/tclWinFile.c11
3 files changed, 121 insertions, 15 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index f76fa63..fd1ce4f 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -5922,7 +5922,6 @@ ReadChars(
* record \r or \n yet.
*/
- assert(dstRead + 1 == dstDecoded);
assert(dst[dstRead] == '\r');
assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF);
@@ -5943,7 +5942,6 @@ ReadChars(
assert(dstWrote == 0);
assert(dstRead == 0);
- assert(dstDecoded == 1);
/*
* We decoded only the bare cr, and we cannot read a
@@ -5998,6 +5996,13 @@ ReadChars(
return 1;
}
+ /*
+ * Revise the dstRead value so that the numChars calc
+ * below correctly computes zero characters read.
+ */
+
+ dstRead = numChars;
+
/* FALL THROUGH - get more data (dstWrote == 0) */
}
@@ -6024,16 +6029,38 @@ ReadChars(
}
if (dstWrote == 0) {
+ ChannelBuffer *nextPtr;
- /*
- * We were not able to read any chars. Maybe there were
- * not enough src bytes to decode into a char. Maybe
- * a lone \r could not be translated (crlf mode). Need
- * to combine any unused src bytes we have in the first
- * buffer with subsequent bytes to try again.
+ /* We were not able to read any chars. */
+
+ assert (numChars == 0);
+
+ /*
+ * There is one situation where this is the correct final
+ * result. If the src buffer contains only a single \n
+ * byte, and we are in TCL_TRANSLATE_AUTO mode, and
+ * when the translation pass was made the INPUT_SAW_CR
+ * flag was set on the channel. In that case, the
+ * correct behavior is to consume that \n and produce the
+ * empty string.
+ */
+
+ if (dst[0] == '\n') {
+ assert(statePtr->inputTranslation == TCL_TRANSLATE_AUTO);
+ assert(dstRead == 1);
+
+ goto consume;
+ }
+
+ /* Otherwise, reading zero characters indicates there's
+ * something incomplete at the end of the src buffer.
+ * Maybe there were not enough src bytes to decode into
+ * a char. Maybe a lone \r could not be translated (crlf
+ * mode). Need to combine any unused src bytes we have
+ * in the first buffer with subsequent bytes to try again.
*/
- ChannelBuffer *nextPtr = bufPtr->nextPtr;
+ nextPtr = bufPtr->nextPtr;
if (nextPtr == NULL) {
if (srcLen > 0) {
@@ -6070,6 +6097,7 @@ ReadChars(
statePtr->inputEncodingFlags &= ~TCL_ENCODING_START;
+ consume:
bufPtr->nextRemoved += srcRead;
if (dstWrote > srcRead + 1) {
*factorPtr = dstWrote * UTF_EXPANSION_FACTOR / srcRead;
diff --git a/tests/io.test b/tests/io.test
index 8dd7184..adcc3da 100644
--- a/tests/io.test
+++ b/tests/io.test
@@ -1563,6 +1563,45 @@ test io-13.8 {TranslateInputEOL: auto mode: \r\n} {
close $f
set x
} "abcd\ndef"
+test io-13.8.1 {TranslateInputEOL: auto mode: \r\n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x {}
+ lappend x [read $f 5]
+ lappend x [read $f]
+ close $f
+ set x
+} [list "abcd\n" "def"]
+test io-13.8.2 {TranslateInputEOL: auto mode: \r\n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto -buffersize 6
+ set x {}
+ lappend x [read $f 5]
+ lappend x [read $f]
+ close $f
+ set x
+} [list "abcd\n" "def"]
+test io-13.8.3 {TranslateInputEOL: auto mode: \r\n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\n\r\ndef"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto -buffersize 7
+ set x {}
+ lappend x [read $f 5]
+ lappend x [read $f]
+ close $f
+ set x
+} [list "abcd\n" "\ndef"]
test io-13.9 {TranslateInputEOL: auto mode: \r followed by not \n} {
set f [open $path(test1) w]
fconfigure $f -translation lf
@@ -3984,6 +4023,46 @@ test io-32.11 {Tcl_Read from a pipe} {stdio openpipe} {
} {{hello
} {hello
}}
+test io-32.11.1 {Tcl_Read from a pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {chan configure stdout -translation crlf}
+ puts $f1 {puts [gets stdin]}
+ puts $f1 {puts [gets stdin]}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ flush $f1
+ set x ""
+ lappend x [read $f1 6]
+ puts $f1 hello
+ flush $f1
+ lappend x [read $f1]
+ close $f1
+ set x
+} {{hello
+} {hello
+}}
+test io-32.11.1 {Tcl_Read from a pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {chan configure stdout -translation crlf}
+ puts $f1 {puts [gets stdin]}
+ puts $f1 {puts [gets stdin]}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ flush $f1
+ set x ""
+ lappend x [read $f1 6]
+ puts $f1 hello
+ flush $f1
+ lappend x [read $f1]
+ close $f1
+ set x
+} {{hello
+} {hello
+}}
test io-32.12 {Tcl_Read, -nonewline} {
file delete $path(test1)
set f1 [open $path(test1) w]
diff --git a/win/tclWinFile.c b/win/tclWinFile.c
index 5761eeb..ad4a5c4 100644
--- a/win/tclWinFile.c
+++ b/win/tclWinFile.c
@@ -2962,18 +2962,17 @@ TclNativeCreateNativeRep(
** <http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath>
**/
if (((str[0]>='A'&&str[0]<='Z') || (str[0]>='a'&&str[0]<='z'))
- && str[1]==':' && (str[2]=='\\' || str[2]=='/')) {
- if (wp==nativePathPtr && len>MAX_PATH) {
+ && str[1]==':') {
+ if (wp==nativePathPtr && len>MAX_PATH && (str[2]=='\\' || str[2]=='/')) {
memmove(wp+4, wp, len*sizeof(WCHAR));
memcpy(wp, L"\\\\?\\", 4*sizeof(WCHAR));
wp += 4;
}
/*
- ** If (remainder of) path starts with "<drive>:/" or "<drive>:\",
- ** leave the ':' intact but translate the backslash to a slash.
+ ** If (remainder of) path starts with "<drive>:",
+ ** leave the ':' intact.
*/
- wp[2] = '\\';
- wp += 3;
+ wp += 2;
} else if (wp==nativePathPtr && len>MAX_PATH
&& (str[0]=='\\' || str[0]=='/')
&& (str[1]=='\\' || str[1]=='/') && str[2]!='?') {