summaryrefslogtreecommitdiffstats
path: root/tests/io.test
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2023-05-30 11:25:13 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2023-05-30 11:25:13 (GMT)
commit13f6f72bb70d2f85f1ca638290bab6c606d9ae33 (patch)
tree8cdf156940220e778d7a410fdce5168dfe72f185 /tests/io.test
parent8091425c93b8846adbfd2667a6b30120241d1552 (diff)
downloadtcl-13f6f72bb70d2f85f1ca638290bab6c606d9ae33.zip
tcl-13f6f72bb70d2f85f1ca638290bab6c606d9ae33.tar.gz
tcl-13f6f72bb70d2f85f1ca638290bab6c606d9ae33.tar.bz2
Backport IO-related changes from Tcl 9.0. Needed for preparation of TIP #653
Diffstat (limited to 'tests/io.test')
-rw-r--r--tests/io.test724
1 files changed, 421 insertions, 303 deletions
diff --git a/tests/io.test b/tests/io.test
index 1efd69c..54ccaac 100644
--- a/tests/io.test
+++ b/tests/io.test
@@ -1119,7 +1119,7 @@ test io-7.2 {FilterInputBytes: split up character in middle of buffer} {
puts -nonewline $f "1234567890\n123\x82\x4F\x82\x50\x82"
close $f
set f [open $path(test1)]
- fconfigure $f -encoding shiftjis
+ fconfigure $f -encoding shiftjis -profile tcl8
set x [list [gets $f line] $line [eof $f]]
close $f
set x
@@ -1130,7 +1130,7 @@ test io-7.3 {FilterInputBytes: split up character at EOF} {testchannel} {
puts -nonewline $f "1234567890123\x82\x4F\x82\x50\x82"
close $f
set f [open $path(test1)]
- fconfigure $f -encoding shiftjis
+ fconfigure $f -encoding shiftjis -profile tcl8
set x [list [gets $f line] $line]
lappend x [tell $f] [testchannel inputbuffered $f] [eof $f]
lappend x [gets $f line] $line
@@ -1474,67 +1474,67 @@ test io-12.5 {ReadChars: fileevents on partial characters} {stdio fileevent} {
} "{} timeout {} timeout 牦 {} eof 0 {}"
test io-12.6 {ReadChars: too many chars read} {
proc driver {cmd args} {
- variable buffer
- variable index
- set chan [lindex $args 0]
- switch -- $cmd {
- initialize {
- set index($chan) 0
- set buffer($chan) [encoding convertto utf-8 \
- [string repeat 뻯 20][string repeat . 20]]
- return {initialize finalize watch read}
- }
- finalize {
- unset index($chan) buffer($chan)
- return
- }
- watch {}
- read {
- set n [lindex $args 1]
- set new [expr {$index($chan) + $n}]
- set result [string range $buffer($chan) $index($chan) $new-1]
- set index($chan) $new
- return $result
- }
- }
+ variable buffer
+ variable index
+ set chan [lindex $args 0]
+ switch -- $cmd {
+ initialize {
+ set index($chan) 0
+ set buffer($chan) [encoding convertto utf-8 \
+ [string repeat 뻯 20][string repeat . 20]]
+ return {initialize finalize watch read}
+ }
+ finalize {
+ unset index($chan) buffer($chan)
+ return
+ }
+ watch {}
+ read {
+ set n [lindex $args 1]
+ set new [expr {$index($chan) + $n}]
+ set result [string range $buffer($chan) $index($chan) $new-1]
+ set index($chan) $new
+ return $result
+ }
+ }
}
set c [chan create read [namespace which driver]]
chan configure $c -encoding utf-8
while {![eof $c]} {
- read $c 15
+ read $c 15
}
close $c
} {}
test io-12.7 {ReadChars: too many chars read [bc5b790099]} {
proc driver {cmd args} {
- variable buffer
- variable index
- set chan [lindex $args 0]
- switch -- $cmd {
- initialize {
- set index($chan) 0
- set buffer($chan) [encoding convertto utf-8 \
- [string repeat 뻯 10]....뻯]
- return {initialize finalize watch read}
- }
- finalize {
- unset index($chan) buffer($chan)
- return
- }
- watch {}
- read {
- set n [lindex $args 1]
- set new [expr {$index($chan) + $n}]
- set result [string range $buffer($chan) $index($chan) $new-1]
- set index($chan) $new
- return $result
- }
- }
+ variable buffer
+ variable index
+ set chan [lindex $args 0]
+ switch -- $cmd {
+ initialize {
+ set index($chan) 0
+ set buffer($chan) [encoding convertto utf-8 \
+ [string repeat 뻯 10]....뻯]
+ return {initialize finalize watch read}
+ }
+ finalize {
+ unset index($chan) buffer($chan)
+ return
+ }
+ watch {}
+ read {
+ set n [lindex $args 1]
+ set new [expr {$index($chan) + $n}]
+ set result [string range $buffer($chan) $index($chan) $new-1]
+ set index($chan) $new
+ return $result
+ }
+ }
}
set c [chan create read [namespace which driver]]
chan configure $c -encoding utf-8
while {![eof $c]} {
- read $c 7
+ read $c 7
}
close $c
} {}
@@ -1925,7 +1925,7 @@ test io-14.9 {reuse of stdio special channels} {stdio fileevent} {
file delete $path(test1)
set f [open $path(script) w]
puts $f {
- array set path [lindex $argv 0]
+ array set path [lindex $argv 0]
set f [open $path(test1) w]
puts $f hello
close $f
@@ -2272,7 +2272,7 @@ test io-27.6 {FlushChannel, async flushing, async close} \
close $f
set x 01234567890123456789012345678901
for {set i 0} {$i < 11} {incr i} {
- set x "$x$x"
+ set x "$x$x"
}
set f [open $path(output) w]
close $f
@@ -2286,9 +2286,9 @@ test io-27.6 {FlushChannel, async flushing, async close} \
vwait [namespace which -variable counter]
}
if {$counter == 1000} {
- set result "file size only [file size $path(output)]"
+ set result "file size only [file size $path(output)]"
} else {
- set result ok
+ set result ok
}
} ok
@@ -2347,7 +2347,7 @@ test io-28.3 {CloseChannel, not called before output queue is empty} \
close $f
set x 01234567890123456789012345678901
for {set i 0} {$i < 11} {incr i} {
- set x "$x$x"
+ set x "$x$x"
}
set f [open $path(output) w]
close $f
@@ -2362,9 +2362,9 @@ test io-28.3 {CloseChannel, not called before output queue is empty} \
vwait [namespace which -variable counter]
}
if {$counter == 1000} {
- set result probably_broken
+ set result probably_broken
} else {
- set result ok
+ set result ok
}
} ok
test io-28.4 Tcl_Close testchannel {
@@ -4552,29 +4552,29 @@ test io-33.10 {Tcl_Gets, exercising double buffering} {
} 300
test io-33.11 {TclGetsObjBinary, [10dc6daa37]} -setup {
proc driver {cmd args} {
- variable buffer
- variable index
- set chan [lindex $args 0]
- switch -- $cmd {
- initialize {
- set index($chan) 0
- set buffer($chan) .......
- return {initialize finalize watch read}
- }
- finalize {
- unset index($chan) buffer($chan)
- return
- }
- watch {}
- read {
- set n [lindex $args 1]
+ variable buffer
+ variable index
+ set chan [lindex $args 0]
+ switch -- $cmd {
+ initialize {
+ set index($chan) 0
+ set buffer($chan) .......
+ return {initialize finalize watch read}
+ }
+ finalize {
+ unset index($chan) buffer($chan)
+ return
+ }
+ watch {}
+ read {
+ set n [lindex $args 1]
if {$n > 3} {set n 3}
- set new [expr {$index($chan) + $n}]
- set result [string range $buffer($chan) $index($chan) $new-1]
- set index($chan) $new
- return $result
- }
- }
+ set new [expr {$index($chan) + $n}]
+ set result [string range $buffer($chan) $index($chan) $new-1]
+ set index($chan) $new
+ return $result
+ }
+ }
}
} -body {
set c [chan create read [namespace which driver]]
@@ -4586,29 +4586,29 @@ test io-33.11 {TclGetsObjBinary, [10dc6daa37]} -setup {
} -result {{} {} {} .......}
test io-33.12 {Tcl_GetsObj, [10dc6daa37]} -setup {
proc driver {cmd args} {
- variable buffer
- variable index
- set chan [lindex $args 0]
- switch -- $cmd {
- initialize {
- set index($chan) 0
- set buffer($chan) .......
- return {initialize finalize watch read}
- }
- finalize {
- unset index($chan) buffer($chan)
- return
- }
- watch {}
- read {
- set n [lindex $args 1]
+ variable buffer
+ variable index
+ set chan [lindex $args 0]
+ switch -- $cmd {
+ initialize {
+ set index($chan) 0
+ set buffer($chan) .......
+ return {initialize finalize watch read}
+ }
+ finalize {
+ unset index($chan) buffer($chan)
+ return
+ }
+ watch {}
+ read {
+ set n [lindex $args 1]
if {$n > 3} {set n 3}
- set new [expr {$index($chan) + $n}]
- set result [string range $buffer($chan) $index($chan) $new-1]
- set index($chan) $new
- return $result
- }
- }
+ set new [expr {$index($chan) + $n}]
+ set result [string range $buffer($chan) $index($chan) $new-1]
+ set index($chan) $new
+ return $result
+ }
+ }
}
} -body {
set c [chan create read [namespace which driver]]
@@ -4620,30 +4620,30 @@ test io-33.12 {Tcl_GetsObj, [10dc6daa37]} -setup {
} -result {{} {} {} .......}
test io-33.13 {Tcl_GetsObj, [10dc6daa37]} -setup {
proc driver {cmd args} {
- variable buffer
- variable index
- set chan [lindex $args 0]
- switch -- $cmd {
- initialize {
- set index($chan) 0
- set buffer($chan) [string repeat \
- [string repeat . 64]\n[string repeat . 25] 2]
- return {initialize finalize watch read}
- }
- finalize {
- unset index($chan) buffer($chan)
- return
- }
- watch {}
- read {
- set n [lindex $args 1]
- if {$n > 65} {set n 65}
- set new [expr {$index($chan) + $n}]
- set result [string range $buffer($chan) $index($chan) $new-1]
- set index($chan) $new
- return $result
- }
- }
+ variable buffer
+ variable index
+ set chan [lindex $args 0]
+ switch -- $cmd {
+ initialize {
+ set index($chan) 0
+ set buffer($chan) [string repeat \
+ [string repeat . 64]\n[string repeat . 25] 2]
+ return {initialize finalize watch read}
+ }
+ finalize {
+ unset index($chan) buffer($chan)
+ return
+ }
+ watch {}
+ read {
+ set n [lindex $args 1]
+ if {$n > 65} {set n 65}
+ set new [expr {$index($chan) + $n}]
+ set result [string range $buffer($chan) $index($chan) $new-1]
+ set index($chan) $new
+ return $result
+ }
+ }
}
} -body {
set c [chan create read [namespace which driver]]
@@ -5364,8 +5364,8 @@ test io-36.3 {Tcl_InputBlocked vs files, short read} {
} {0 abc 0 defghijklmnop 0 1}
test io-36.4 {Tcl_InputBlocked vs files, event driven read} {fileevent} {
proc in {f} {
- variable l
- variable x
+ variable l
+ variable x
lappend l [read $f 3]
if {[eof $f]} {lappend l eof; close $f; set x done}
}
@@ -5400,8 +5400,8 @@ test io-36.5 {Tcl_InputBlocked vs files, short read, nonblocking} {nonBlockFiles
} {0 abc 0 defghijklmnop 0 1}
test io-36.6 {Tcl_InputBlocked vs files, event driven read} {nonBlockFiles fileevent} {
proc in {f} {
- variable l
- variable x
+ variable l
+ variable x
lappend l [read $f 3]
if {[eof $f]} {lappend l eof; close $f; set x done}
}
@@ -5790,7 +5790,7 @@ test io-39.22a {Tcl_SetChannelOption, invariance} {
set l
} {{O G} {D D} {1 {bad value for -eofchar: should be a list of zero, one, or two elements}}}
test io-39.23 {Tcl_GetChannelOption, server socket is not readable or
- writable, it should still have valid -eofchar and -translation options } {
+ writable, it should still have valid -eofchar and -translation options } {
set l [list]
set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
lappend l [fconfigure $sock -eofchar] [fconfigure $sock -translation]
@@ -5798,7 +5798,7 @@ test io-39.23 {Tcl_GetChannelOption, server socket is not readable or
set l
} {{{}} auto}
test io-39.24 {Tcl_SetChannelOption, server socket is not readable or
- writable so we can't change -eofchar or -translation } {
+ writable so we can't change -eofchar or -translation } {
set l [list]
set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
fconfigure $sock -eofchar D -translation lf
@@ -6296,23 +6296,23 @@ test io-46.1 {Tcl event loop vs multiple interpreters} {testfevent fileevent not
test io-46.2 {Tcl event loop vs multiple interpreters} testfevent {
testfevent create
testfevent cmd {
- variable x 0
- after 100 {set x triggered}
- vwait [namespace which -variable x]
- set x
+ variable x 0
+ after 100 {set x triggered}
+ vwait [namespace which -variable x]
+ set x
}
} {triggered}
test io-46.3 {Tcl event loop vs multiple interpreters} testfevent {
testfevent create
testfevent cmd {
- set x 0
- after 10 {lappend x timer}
- after 30
- set result $x
- update idletasks
- lappend result $x
- update
- lappend result $x
+ set x 0
+ after 10 {lappend x timer}
+ after 30
+ set result $x
+ update idletasks
+ lappend result $x
+ update
+ lappend result $x
}
} {0 0 {0 timer}}
@@ -6329,7 +6329,7 @@ test io-47.1 {fileevent vs multiple interpreters} {testfevent fileevent} {
lappend x [fileevent $f2 readable]
testfevent delete
lappend x [fileevent $f readable] [fileevent $f2 readable] \
- [fileevent $f3 readable]
+ [fileevent $f3 readable]
close $f
close $f2
close $f3
@@ -6345,11 +6345,11 @@ test io-47.2 {deleting fileevent on interpreter delete} {testfevent fileevent} {
testfevent share $f2
testfevent share $f3
testfevent cmd "fileevent $f2 readable {script 2}
- fileevent $f3 readable {script 3}"
+ fileevent $f3 readable {script 3}"
fileevent $f4 readable {script 4}
testfevent delete
set x [list [fileevent $f readable] [fileevent $f2 readable] \
- [fileevent $f3 readable] [fileevent $f4 readable]]
+ [fileevent $f3 readable] [fileevent $f4 readable]]
close $f
close $f2
close $f3
@@ -6370,7 +6370,7 @@ test io-47.3 {deleting fileevent on interpreter delete} {testfevent fileevent} {
fileevent $f4 readable {script 4}"
testfevent delete
set x [list [fileevent $f readable] [fileevent $f2 readable] \
- [fileevent $f3 readable] [fileevent $f4 readable]]
+ [fileevent $f3 readable] [fileevent $f4 readable]]
close $f
close $f2
close $f3
@@ -6386,8 +6386,8 @@ test io-47.4 {file events on shared files and multiple interpreters} {testfevent
fileevent $f readable {script 2}
fileevent $f2 readable {script 3}
set x [list [fileevent $f2 readable] \
- [testfevent cmd "fileevent $f readable"] \
- [fileevent $f readable]]
+ [testfevent cmd "fileevent $f readable"] \
+ [fileevent $f readable]]
testfevent delete
close $f
close $f2
@@ -6401,7 +6401,7 @@ test io-47.5 {file events on shared files, deleting file events} {testfevent fil
fileevent $f readable {script 2}
testfevent cmd "fileevent $f readable {}"
set x [list [testfevent cmd "fileevent $f readable"] \
- [fileevent $f readable]]
+ [fileevent $f readable]]
testfevent delete
close $f
set x
@@ -6414,7 +6414,7 @@ test io-47.6 {file events on shared files, deleting file events} {testfevent fil
fileevent $f readable {script 2}
fileevent $f readable {}
set x [list [testfevent cmd "fileevent $f readable"] \
- [fileevent $f readable]]
+ [fileevent $f readable]]
testfevent delete
close $f
set x
@@ -7257,7 +7257,7 @@ test io-52.3 {TclCopyChannel} {fcopy} {
set s1 [file size $thisScript]
set s2 [file size $path(test1)]
if {("$s1" == "$s2") && ($s0 == $s1)} {
- lappend result ok
+ lappend result ok
}
set result
} {0 0 ok}
@@ -7298,7 +7298,7 @@ test io-52.5 {TclCopyChannel, all} {fcopy} {
set s1 [file size $thisScript]
set s2 [file size $path(test1)]
if {"$s1" == "$s2"} {
- lappend result ok
+ lappend result ok
}
set result
} {0 0 ok}
@@ -7315,7 +7315,7 @@ test io-52.5a {TclCopyChannel, all, other negative value} {fcopy} {
set s1 [file size $thisScript]
set s2 [file size $path(test1)]
if {"$s1" == "$s2"} {
- lappend result ok
+ lappend result ok
}
set result
} {0 0 ok}
@@ -7332,7 +7332,7 @@ test io-52.5b {TclCopyChannel, all, wrap to negative value} {fcopy} {
set s1 [file size $thisScript]
set s2 [file size $path(test1)]
if {"$s1" == "$s2"} {
- lappend result ok
+ lappend result ok
}
set result
} {0 0 ok}
@@ -7349,7 +7349,7 @@ test io-52.6 {TclCopyChannel} {fcopy} {
set s1 [file size $thisScript]
set s2 [file size $path(test1)]
if {("$s1" == "$s2") && ($s0 == $s1)} {
- lappend result ok
+ lappend result ok
}
set result
} {0 0 ok}
@@ -7366,7 +7366,7 @@ test io-52.7 {TclCopyChannel} {fcopy} {
close $f1
close $f2
if {"$s1" == "$s2"} {
- lappend result ok
+ lappend result ok
}
set result
} {0 0 ok}
@@ -7676,7 +7676,7 @@ test io-52.22 {TclCopyChannel & encodings} -setup {
fconfigure $in -encoding ascii -profile strict
fconfigure $out -encoding koi8-r -translation lf
proc ::xxx args {
- set ::s0 $args
+ set ::s0 $args
}
fcopy $in $out -command ::xxx
@@ -7703,7 +7703,7 @@ test io-52.23 {TclCopyChannel & encodings} -setup {
fconfigure $in -encoding utf-8
fconfigure $out -encoding ascii -translation lf -profile strict
proc ::xxx args {
- set ::s0 $args
+ set ::s0 $args
}
fcopy $in $out -command ::xxx
@@ -7743,7 +7743,7 @@ test io-53.2 {CopyData} {fcopy} {
set s1 [file size $thisScript]
set s2 [file size $path(test1)]
if {("$s1" == "$s2") && ($s0 == $s1)} {
- lappend result ok
+ lappend result ok
}
set result
} {0 0 ok}
@@ -7861,6 +7861,8 @@ test io-53.5 {CopyData: error during fcopy} {socket fcopy} {
set out [socket 127.0.0.1 [lindex [fconfigure $listen -sockname] 2]]
catch {unset fcopyTestDone}
close $listen ;# This means the socket open never really succeeds
+ fconfigure $in -encoding utf-8
+ fconfigure $out -encoding utf-8
fcopy $in $out -command [namespace code FcopyTestDone]
variable fcopyTestDone
if {![info exists fcopyTestDone]} {
@@ -7898,8 +7900,8 @@ proc doFcopy {in out {bytes 0} {error {}}} {
} elseif {[eof $in]} {
set fcopyTestDone 0
} else {
- # Delay next fcopy to wait for size>0 input bytes
- after 100 [list fcopy $in $out -size 1000 \
+ # Delay next fcopy to wait for size>0 input bytes
+ after 100 [list fcopy $in $out -size 1000 \
-command [namespace code [list doFcopy $in $out]]]
}
}
@@ -7914,9 +7916,9 @@ test io-53.7 {CopyData: Flooding fcopy from pipe} {stdio fcopy} {
proc Write {count} {
puts -nonewline "1234567890"
if {[incr count -1]} {
- after 10 [list Write $count]
+ after 10 [list Write $count]
} else {
- set ::ready 1
+ set ::ready 1
}
}
fconfigure stdout -buffering none
@@ -8258,21 +8260,21 @@ test io-53.12.1 {
} A
test io-53.13 {TclCopyChannel: read error reporting} -setup {
proc driver {cmd args} {
- variable buffer
- variable index
- set chan [lindex $args 0]
- switch -- $cmd {
- initialize {
- return {initialize finalize watch read}
- }
- finalize {
- return
- }
- watch {}
- read {
+ variable buffer
+ variable index
+ set chan [lindex $args 0]
+ switch -- $cmd {
+ initialize {
+ return {initialize finalize watch read}
+ }
+ finalize {
+ return
+ }
+ watch {}
+ read {
error FAIL
- }
- }
+ }
+ }
}
set outFile [makeFile {} out]
} -body {
@@ -8285,24 +8287,24 @@ test io-53.13 {TclCopyChannel: read error reporting} -setup {
catch {close $out}
removeFile out
rename driver {}
-} -result {error reading "*": *} -returnCodes error -match glob
+} -result {error reading "rc*": *} -returnCodes error -match glob
test io-53.14 {TclCopyChannel: write error reporting} -setup {
proc driver {cmd args} {
- variable buffer
- variable index
- set chan [lindex $args 0]
- switch -- $cmd {
- initialize {
- return {initialize finalize watch write}
- }
- finalize {
- return
- }
- watch {}
- write {
- error FAIL
- }
- }
+ variable buffer
+ variable index
+ set chan [lindex $args 0]
+ switch -- $cmd {
+ initialize {
+ return {initialize finalize watch write}
+ }
+ finalize {
+ return
+ }
+ watch {}
+ write {
+ error FAIL
+ }
+ }
}
set inFile [makeFile {aaa} in]
} -body {
@@ -8318,35 +8320,35 @@ test io-53.14 {TclCopyChannel: write error reporting} -setup {
} -result {error writing "*": *} -returnCodes error -match glob
test io-53.15 {[ed29c4da21] DoRead: fblocked seen as error} -setup {
proc driver {cmd args} {
- variable buffer
- variable index
- variable blocked
- set chan [lindex $args 0]
- switch -- $cmd {
- initialize {
- set index($chan) 0
- set buffer($chan) [encoding convertto utf-8 \
- [string repeat a 100]]
- set blocked($chan) 1
- return {initialize finalize watch read}
- }
- finalize {
- unset index($chan) buffer($chan) blocked($chan)
- return
- }
- watch {}
- read {
- if {$blocked($chan)} {
- set blocked($chan) [expr {!$blocked($chan)}]
- return -code error EAGAIN
- }
- set n [lindex $args 1]
- set new [expr {$index($chan) + $n}]
- set result [string range $buffer($chan) $index($chan) $new-1]
- set index($chan) $new
- return $result
- }
- }
+ variable buffer
+ variable index
+ variable blocked
+ set chan [lindex $args 0]
+ switch -- $cmd {
+ initialize {
+ set index($chan) 0
+ set buffer($chan) [encoding convertto utf-8 \
+ [string repeat a 100]]
+ set blocked($chan) 1
+ return {initialize finalize watch read}
+ }
+ finalize {
+ unset index($chan) buffer($chan) blocked($chan)
+ return
+ }
+ watch {}
+ read {
+ if {$blocked($chan)} {
+ set blocked($chan) [expr {!$blocked($chan)}]
+ return -code error EAGAIN
+ }
+ set n [lindex $args 1]
+ set new [expr {$index($chan) + $n}]
+ set result [string range $buffer($chan) $index($chan) $new-1]
+ set index($chan) $new
+ return $result
+ }
+ }
}
set c [chan create read [namespace which driver]]
chan configure $c -encoding utf-8
@@ -8362,35 +8364,35 @@ test io-53.15 {[ed29c4da21] DoRead: fblocked seen as error} -setup {
} -result 100
test io-53.16 {[ed29c4da21] MBRead: fblocked seen as error} -setup {
proc driver {cmd args} {
- variable buffer
- variable index
- variable blocked
- set chan [lindex $args 0]
- switch -- $cmd {
- initialize {
- set index($chan) 0
- set buffer($chan) [encoding convertto utf-8 \
- [string repeat a 100]]
- set blocked($chan) 1
- return {initialize finalize watch read}
- }
- finalize {
- unset index($chan) buffer($chan) blocked($chan)
- return
- }
- watch {}
- read {
- if {$blocked($chan)} {
- set blocked($chan) [expr {!$blocked($chan)}]
- return -code error EAGAIN
- }
- set n [lindex $args 1]
- set new [expr {$index($chan) + $n}]
- set result [string range $buffer($chan) $index($chan) $new-1]
- set index($chan) $new
- return $result
- }
- }
+ variable buffer
+ variable index
+ variable blocked
+ set chan [lindex $args 0]
+ switch -- $cmd {
+ initialize {
+ set index($chan) 0
+ set buffer($chan) [encoding convertto utf-8 \
+ [string repeat a 100]]
+ set blocked($chan) 1
+ return {initialize finalize watch read}
+ }
+ finalize {
+ unset index($chan) buffer($chan) blocked($chan)
+ return
+ }
+ watch {}
+ read {
+ if {$blocked($chan)} {
+ set blocked($chan) [expr {!$blocked($chan)}]
+ return -code error EAGAIN
+ }
+ set n [lindex $args 1]
+ set new [expr {$index($chan) + $n}]
+ set result [string range $buffer($chan) $index($chan) $new-1]
+ set index($chan) $new
+ return $result
+ }
+ }
}
set c [chan create read [namespace which driver]]
chan configure $c -encoding utf-8 -translation lf
@@ -8406,29 +8408,29 @@ test io-53.16 {[ed29c4da21] MBRead: fblocked seen as error} -setup {
} -result 100
test io-53.17 {[7c187a3773] MBWrite: proper inQueueTail handling} -setup {
proc driver {cmd args} {
- variable buffer
- variable index
- set chan [lindex $args 0]
- switch -- $cmd {
- initialize {
- set index($chan) 0
- set buffer($chan) [encoding convertto utf-8 \
- line\n[string repeat a 100]line\n]
- return {initialize finalize watch read}
- }
- finalize {
- unset index($chan) buffer($chan)
- return
- }
- watch {}
- read {
- set n [lindex $args 1]
- set new [expr {$index($chan) + $n}]
- set result [string range $buffer($chan) $index($chan) $new-1]
- set index($chan) $new
- return $result
- }
- }
+ variable buffer
+ variable index
+ set chan [lindex $args 0]
+ switch -- $cmd {
+ initialize {
+ set index($chan) 0
+ set buffer($chan) [encoding convertto utf-8 \
+ line\n[string repeat a 100]line\n]
+ return {initialize finalize watch read}
+ }
+ finalize {
+ unset index($chan) buffer($chan)
+ return
+ }
+ watch {}
+ read {
+ set n [lindex $args 1]
+ set new [expr {$index($chan) + $n}]
+ set result [string range $buffer($chan) $index($chan) $new-1]
+ set index($chan) $new
+ return $result
+ }
+ }
}
set c [chan create read [namespace which driver]]
chan configure $c -encoding utf-8 -translation lf -buffersize 107
@@ -9084,10 +9086,7 @@ test io-74.1 {[104f2885bb] improper cache validity check} -setup {
removeFile io-74.1
} -returnCodes error -match glob -result {can not find channel named "*"}
-# The following tests 75.1 to 75.5 exercise strict or tolerant channel
-# encoding.
-# TCL 8.7 only offers tolerant channel encoding, what is tested here.
-test io-75.1 {multibyte encoding error read results in raw bytes} -setup {
+test io-75.1 {multibyte encoding error read results in raw bytes (-profile tcl8)} -setup {
set fn [makeFile {} io-75.1]
set f [open $fn w+]
fconfigure $f -encoding binary
@@ -9178,23 +9177,27 @@ test io-75.5 {invalid utf-8 encoding read is ignored (-profile tcl8)} -setup {
removeFile io-75.5
} -result 4181
-test io-75.6 {invalid utf-8 encoding gets is not ignored (-profile strict)} -setup {
+test io-75.6 {invalid utf-8 encoding, gets is not ignored (-profile strict)} -setup {
set fn [makeFile {} io-75.6]
set f [open $fn w+]
fconfigure $f -encoding binary
- # \x81 is invalid in utf-8
+ # \x81 is an incomplete byte sequence in utf-8
puts -nonewline $f A\x81
flush $f
seek $f 0
- fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf -profile strict
+ fconfigure $f -encoding utf-8 -buffering none -eofchar {} \
+ -translation lf -profile strict
} -body {
gets $f
} -cleanup {
close $f
removeFile io-75.6
-} -match glob -returnCodes 1 -result {error reading "*": invalid or incomplete multibyte or wide character}
+} -match glob -returnCodes 1 -result {error reading "file*":\
+ invalid or incomplete multibyte or wide character}
-test io-75.7 {invalid utf-8 encoding gets is not ignored (-profile strict)} -setup {
+test io-75.7 {
+ invalid utf-8 encoding gets is not ignored (-profile strict)
+} -setup {
set fn [makeFile {} io-75.7]
set f [open $fn w+]
fconfigure $f -encoding binary
@@ -9202,23 +9205,27 @@ test io-75.7 {invalid utf-8 encoding gets is not ignored (-profile strict)} -set
puts -nonewline $f A\x81
flush $f
seek $f 0
- fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf -profile strict
+ fconfigure $f -encoding utf-8 -buffering none -eofchar {} -translation lf \
+ -profile strict
} -body {
- read $f
+ list [catch {read $f} msg] $msg
} -cleanup {
close $f
removeFile io-75.7
-} -match glob -returnCodes 1 -result {error reading "*": invalid or incomplete multibyte or wide character}
+} -match glob -result {1 {error reading "file*":\
+ invalid or incomplete multibyte or wide character}}
test io-75.8 {invalid utf-8 encoding eof handling (-profile strict)} -setup {
set fn [makeFile {} io-75.8]
set f [open $fn w+]
fconfigure $f -encoding binary
- # \x81 is invalid in utf-8, but since \x1A comes first, -eofchar takes precedence.
+ # \x81 is invalid in utf-8, but since \x1A comes first, -eofchar takes
+ # precedence.
puts -nonewline $f A\x1A\x81
flush $f
seek $f 0
- fconfigure $f -encoding utf-8 -buffering none -eofchar \x1A -translation lf -profile strict
+ fconfigure $f -encoding utf-8 -buffering none -eofchar \x1A \
+ -translation lf -profile strict
} -body {
set d [read $f]
binary scan $d H* hd
@@ -9230,6 +9237,52 @@ test io-75.8 {invalid utf-8 encoding eof handling (-profile strict)} -setup {
removeFile io-75.8
} -result {41 1 {}}
+test io-75.8.eoflater {invalid utf-8 encoding eof handling (-profile strict)} -setup {
+ set fn [makeFile {} io-75.8]
+ set f [open $fn w+]
+ # This also configures the channel encoding profile as strict.
+ fconfigure $f -encoding binary
+ # \x81 is invalid in utf-8. -eofchar is not detected, because it comes later.
+ puts -nonewline $f A\x81\x81\x1A
+ flush $f
+ seek $f 0
+ fconfigure $f -encoding utf-8 -buffering none -eofchar \x1A \
+ -translation lf -profile strict
+} -body {
+ set res [list [catch {read $f} cres] [eof $f]]
+ chan configure $f -encoding iso8859-1
+ lappend res [read $f 1]
+ chan configure $f -encoding utf-8
+ catch {read $f 1} cres
+ lappend res $cres
+ close $f
+ set res
+} -cleanup {
+ removeFile io-75.8
+} -match glob -result "1 0 \x81 {error reading \"*\":\
+ invalid or incomplete multibyte or wide character}"
+
+
+test io-strict-multibyte-eof {
+ incomplete utf-8 sequence immediately prior to eof character
+
+ See issue 25cdcb7e8fb381fb
+} -setup {
+ set res {}
+ set chan [file tempfile];
+ fconfigure $chan -encoding binary
+ puts -nonewline $chan \x81\x1A
+ flush $chan
+ seek $chan 0
+ chan configure $chan -encoding utf-8 -profile strict
+} -body {
+ list [catch {read $chan 1} cres] $cres
+} -cleanup {
+ close $chan
+ unset res
+} -match glob -result {1 {error reading "*":\
+ invalid or incomplete multibyte or wide character}}
+
test io-75.9 {unrepresentable character write passes and is replaced by ?} -setup {
set fn [makeFile {} io-75.9]
set f [open $fn w+]
@@ -9242,7 +9295,8 @@ test io-75.9 {unrepresentable character write passes and is replaced by ?} -setu
} -cleanup {
close $f
removeFile io-75.9
-} -match glob -result [list {A} {error writing "*": invalid or incomplete multibyte or wide character}]
+} -match glob -result [list {A} {error writing "*":\
+ invalid or incomplete multibyte or wide character}]
# Incomplete sequence test.
# This error may IMHO only be detected with the close.
@@ -9277,16 +9331,17 @@ test io-75.11 {shiftjis encoding error read results in raw bytes} -setup {
puts -nonewline $f A\x81\xFFA
flush $f
seek $f 0
- fconfigure $f -encoding shiftjis -blocking 0 -eofchar "" -translation lf -profile strict
+ fconfigure $f -encoding shiftjis -blocking 0 -eofchar {} -translation lf \
+ -profile strict
} -body {
set d [read $f]
binary scan $d H* hd
- lappend hd [catch {set d [read $f]} msg]
- lappend hd $msg
+ lappend hd [catch {set d [read $f]} msg] $msg
} -cleanup {
close $f
removeFile io-75.11
-} -match glob -result {41 1 {error reading "*": invalid or incomplete multibyte or wide character}}
+} -match glob -result {41 1 {error reading "file*":\
+ invalid or incomplete multibyte or wide character}}
test io-75.12 {invalid utf-8 encoding read is ignored} -setup {
set fn [makeFile {} io-75.12]
@@ -9295,7 +9350,7 @@ test io-75.12 {invalid utf-8 encoding read is ignored} -setup {
puts -nonewline $f A\x81
flush $f
seek $f 0
- fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf
+ fconfigure $f -encoding utf-8 -buffering none -eofchar {} -translation lf
} -body {
set d [read $f]
binary scan $d H* hd
@@ -9316,16 +9371,75 @@ test io-75.13 {
puts -nonewline $f A\x81
flush $f
seek $f 0
- fconfigure $f -encoding utf-8 -blocking 0 -eofchar "" -translation lf -profile strict
+ fconfigure $f -encoding utf-8 -blocking 0 -eofchar {} -translation lf \
+ -profile strict
} -body {
set d [read $f]
binary scan $d H* hd
- lappend hd [catch {read $f} msg]
- lappend hd $msg
+ lappend hd [catch {read $f} msg] $msg
} -cleanup {
close $f
removeFile io-75.13
-} -match glob -result {41 1 {error reading "*": invalid or incomplete multibyte or wide character}}
+} -match glob -result {41 1 {error reading "file*":\
+ invalid or incomplete multibyte or wide character}}
+
+test io-75.14 {
+ [gets] succesfully returns lines prior to error
+
+ invalid utf-8 encoding [gets] continues in non-strict mode after error
+} -setup {
+ set chan [file tempfile]
+ fconfigure $chan -encoding binary
+ # \xC0\n is an invalid utf-8 sequence
+ puts -nonewline $chan a\nb\nc\xC0\nd\n
+ flush $chan
+ seek $chan 0
+ fconfigure $chan -encoding utf-8 -buffering none -eofchar {} \
+ -translation auto -profile strict
+} -body {
+ lappend res [gets $chan]
+ lappend res [gets $chan]
+ lappend res [catch {gets $chan} cres] $cres
+ chan configure $chan -profile tcl8
+ lappend res [gets $chan]
+ lappend res [gets $chan]
+ close $chan
+ return $res
+} -match glob -result {a b 1 {error reading "*":\
+ invalid or incomplete multibyte or wide character} cÀ d}
+
+test io-75.15 {
+ invalid utf-8 encoding strict
+ gets does not hang
+ gets succeeds for the first two lines
+} -setup {
+ set res {}
+ set chan [file tempfile]
+ fconfigure $chan -encoding binary
+ # \xC0\x40 is an invalid utf-8 sequence
+ puts $chan hello\nAB\nCD\xC0\x40EF\nGHI
+ seek $chan 0
+} -body {
+ #Now try to read it with [gets]
+ fconfigure $chan -encoding utf-8 -profile strict
+ lappend res [gets $chan]
+ lappend res [gets $chan]
+ lappend res [catch {gets $chan} cres] $cres
+ lappend res [catch {gets $chan} cres] $cres
+ chan configure $chan -translation binary
+ set data [read $chan 4]
+ foreach char [split $data {}] {
+ scan $char %c ord
+ lappend res [format %x $ord]
+ }
+ fconfigure $chan -encoding utf-8 -profile strict -translation auto
+ lappend res [gets $chan]
+ lappend res [gets $chan]
+ return $res
+} -cleanup {
+ close $chan
+} -match glob -result {hello AB 1 {error reading "*": invalid or incomplete multibyte or wide character}\
+ 1 {error reading "*": invalid or incomplete multibyte or wide character} 43 44 c0 40 EF GHI}
# ### ### ### ######### ######### #########
@@ -9380,7 +9494,8 @@ test io-76.4 {channel mode dropping} -setup {
} -returnCodes error -cleanup {
close $f
removeFile dummy
-} -match glob -result {Tcl_RemoveChannelMode error: Bad mode, would make channel inacessible. Channel: "*"}
+} -match glob -result {Tcl_RemoveChannelMode error:\
+ Bad mode, would make channel inacessible. Channel: "*"}
test io-76.5 {channel mode dropping} -setup {
set datafile [makeFile {some characters} dummy]
@@ -9401,7 +9516,8 @@ test io-76.6 {channel mode dropping} -setup {
} -returnCodes error -cleanup {
close $f
removeFile dummy
-} -match glob -result {Tcl_RemoveChannelMode error: Bad mode, would make channel inacessible. Channel: "*"}
+} -match glob -result {Tcl_RemoveChannelMode error:\
+ Bad mode, would make channel inacessible. Channel: "*"}
test io-76.7 {channel mode dropping} -setup {
set datafile [makeFile {some characters} dummy]
@@ -9434,7 +9550,8 @@ test io-76.9 {channel mode dropping} -setup {
} -returnCodes error -cleanup {
close $f
removeFile dummy
-} -match glob -result {Tcl_RemoveChannelMode error: Bad mode, would make channel inacessible. Channel: "*"}
+} -match glob -result {Tcl_RemoveChannelMode error:\
+ Bad mode, would make channel inacessible. Channel: "*"}
test io-76.10 {channel mode dropping} -setup {
set datafile [makeFile {some characters} dummy]
@@ -9445,7 +9562,8 @@ test io-76.10 {channel mode dropping} -setup {
} -returnCodes error -cleanup {
close $f
removeFile dummy
-} -match glob -result {Tcl_RemoveChannelMode error: Bad mode, would make channel inacessible. Channel: "*"}
+} -match glob -result {Tcl_RemoveChannelMode error:\
+ Bad mode, would make channel inacessible. Channel: "*"}
# cleanup
foreach file [list fooBar longfile script script2 output test1 pipe my_script \