Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch bug-td-coroutine Excluding Merge-Ins
This is equivalent to a diff from 7bed475cb2 to 5f50c249bd
2014-04-11
| ||
20:26 | Ticket [c21b57e4fc]. Fixed version number mismatch for "coroutine". See also Ticket [ac8d016077] whose fix (revision [7bed475cb2]) introduced the problem. check-in: 51083f878a user: andreask tags: trunk | |
2014-03-26
| ||
17:29 | In coroutine and coro_auto: 'read' must correctly emulate Tcl's built-in read and not close the chan at EOF. Add command expansion in 'global', which looks like it never worked. Took the opportunity to fix how 'global' stores coro-global values so that we don't tramp on Frame #1's local variables (no compatibility break as 'global' never worked). Bumped versions. Adding tests. Work-in-progress. Leaf check-in: 5f50c249bd user: twylite tags: bug-td-coroutine | |
2014-03-24
| ||
18:24 | Ticket [ac8d016077]. Package coroutine and coroutine::auto. Fixed missing variable "result" in various ok code paths. Bumped versions to 1.1.1 and 1.1.2 respectively. check-in: 7bed475cb2 user: andreask tags: trunk | |
18:03 | Ticket 874dedb816 - struct::matrix - Fixed documentation buglet. check-in: ed580c5543 user: andreask tags: trunk | |
Changes to modules/coroutine/ChangeLog.
1 2 3 4 5 6 7 | 2013-05-31 Andreas Kupries <[email protected]> * coroutine.tcl: Added Colin Macleod and http://wiki/21555 * coro_auto.tcl: to the set of acknowledged contributors and references for the module. 2013-05-15 Andreas Kupries <[email protected]> | > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 2014-03-24 Trevor Davel <[email protected]> * coroutine.tcl: Stopped 'read' closing the channel at EOF, which is * coro_auto.tcl: not the behaviour's of Tcl's built-in read. Bumped versions to 1.1.3. * pkgIndex.tcl: Updated version numbers. 2014-03-24 Andreas Kupries <[email protected]> * coroutine.tcl: Fixed missing variable "result" in various ok code * coro_auto.tcl: paths. Bumped versions to 1.1.1 and 1.1.2 respectively 2013-05-31 Andreas Kupries <[email protected]> * coroutine.tcl: Added Colin Macleod and http://wiki/21555 * coro_auto.tcl: to the set of acknowledged contributors and references for the module. 2013-05-15 Andreas Kupries <[email protected]> |
︙ | ︙ |
Changes to modules/coroutine/coro_auto.tcl.
1 2 3 4 | ## -- Tcl Module -- -*- tcl -*- # # ## ### ##### ######## ############# # @@ Meta Begin | | | 1 2 3 4 5 6 7 8 9 10 11 12 | ## -- Tcl Module -- -*- tcl -*- # # ## ### ##### ######## ############# # @@ Meta Begin # Package coroutine::auto 1.1.3 # Meta platform tcl # Meta require {Tcl 8.6} # Meta require {coroutine 1.1} # Meta license BSD # Meta as::author {Andreas Kupries} # Meta as::origin http://wiki.tcl.tk/21555 # Meta summary Coroutine Event and Channel Support |
︙ | ︙ | |||
222 223 224 225 226 227 228 | yield ::chan event $chan readable {} } else { ::chan configure $chan -blocking $blocking append buf $result if {[::chan eof $chan]} { | < | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | yield ::chan event $chan readable {} } else { ::chan configure $chan -blocking $blocking append buf $result if {[::chan eof $chan]} { break } } } } else { # Loop until total characters have been read, or eof found, # whichever is first. |
︙ | ︙ | |||
253 254 255 256 257 258 259 | ::chan event $chan readable {} } else { ::chan configure $chan -blocking $blocking append buf $result incr left -[string length $result] if {[::chan eof $chan]} { | < | 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | ::chan event $chan readable {} } else { ::chan configure $chan -blocking $blocking append buf $result incr left -[string length $result] if {[::chan eof $chan]} { break } elseif {!$left} { break } } } } |
︙ | ︙ | |||
306 307 308 309 310 311 312 | return } ::coroutine::auto} # # ## ### ##### ######## ############# ## Ready | | | 304 305 306 307 308 309 310 311 312 | return } ::coroutine::auto} # # ## ### ##### ######## ############# ## Ready package provide coroutine::auto 1.1.3 return |
Changes to modules/coroutine/coroutine.tcl.
1 2 3 4 | ## -- Tcl Module -- -*- tcl -*- # # ## ### ##### ######## ############# # @@ Meta Begin | | | 1 2 3 4 5 6 7 8 9 10 11 12 | ## -- Tcl Module -- -*- tcl -*- # # ## ### ##### ######## ############# # @@ Meta Begin # Package coroutine 1.1.3 # Meta platform tcl # Meta require {Tcl 8.6} # Meta license BSD # Meta as::author {Andreas Kupries} # Meta as::author {Colin Macleod} # Meta as::author {Colin McCormack} # Meta as::author {Donal Fellows} |
︙ | ︙ | |||
86 87 88 89 90 91 92 | proc ::coroutine::util::global {args} { # Frame #1 is the coroutine-specific stack frame at its # bottom. Variables there are out of view of the main code, and # can be made visible in the entire coroutine underneath. set cmd [list upvar "#1"] foreach var $args { | | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | proc ::coroutine::util::global {args} { # Frame #1 is the coroutine-specific stack frame at its # bottom. Variables there are out of view of the main code, and # can be made visible in the entire coroutine underneath. set cmd [list upvar "#1"] foreach var $args { lappend cmd COROGLOBAL($var) $var } tailcall {*}$cmd } # - -- --- ----- -------- ------------- proc ::coroutine::util::after {delay} { ::after $delay [info coroutine] yield |
︙ | ︙ | |||
259 260 261 262 263 264 265 | yield ::chan event $chan readable {} } else { ::chan configure $chan -blocking $blocking append buf $result if {[::chan eof $chan]} { | < | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | yield ::chan event $chan readable {} } else { ::chan configure $chan -blocking $blocking append buf $result if {[::chan eof $chan]} { break } } } } else { # Loop until total characters have been read, or eof found, # whichever is first. |
︙ | ︙ | |||
290 291 292 293 294 295 296 | ::chan event $chan readable {} } else { ::chan configure $chan -blocking $blocking append buf $result incr left -[string length $result] if {[::chan eof $chan]} { | < | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | ::chan event $chan readable {} } else { ::chan configure $chan -blocking $blocking append buf $result incr left -[string length $result] if {[::chan eof $chan]} { break } elseif {!$left} { break } } } } |
︙ | ︙ | |||
369 370 371 372 373 374 375 | namespace eval ::coroutine::util { #checker exclude warnShadowVar variable counter 0 } # # ## ### ##### ######## ############# ## Ready | | | 367 368 369 370 371 372 373 374 375 | namespace eval ::coroutine::util { #checker exclude warnShadowVar variable counter 0 } # # ## ### ##### ######## ############# ## Ready package provide coroutine 1.1.3 return |
Added modules/coroutine/coroutine.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | # coroutine.test # # Tests for the coroutine package # # Copyright (C) 2014 Trevor Davel <[email protected]> # ------------------------------------------------------------------------- # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # ------------------------------------------------------------------------- package require tcltest source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ devtools testutilities.tcl] testsNeedTcl 8.6 testsNeedTcltest 2.3 testing { useLocal coroutine.tcl coroutine ::coroutine::util } # ----- Helpers ---------------------------------------------------------------- # Resume a coroutine in a tight loop and collect its output as a list. When # the coroutine terminates return the list. proc Test_collect {coro} { set coro [uplevel 1 [list namespace which -command $coro]] set result {} while { [info commands $coro] ne {} } { lappend result [$coro] } set result } # ----- coroutine::util::create ------------------------------------------------ # coroutine::util::create should create a coroutine with a unique name test coroutine-1.1 {coroutine::util::create} -body { set coroid [namespace eval ::coroutine::util { create apply {{} { yield [info coroutine] yield "alpha" return "beta" }} }] Test_collect $coroid } -result {alpha beta} # ----- coroutine::util::global ------------------------------------------------ # coroutine::util::global should link to a coro-global variable, not an # interp-global variable. It should work at all stack levels _including # the first frame of the coroutine_, should not tramp on the first frame's # local vars, and should be auto-created if necessary by commands like # [incr]/[append] (from any stack level). [global] can be called with # multiple variable names. proc ::coroutine::util::Test_global {} { global myglobal incr myglobal yield $::myglobal yield $myglobal return [apply [list {} { global strglobal myglobal incr myglobal yield $::myglobal yield $myglobal return [append strglobal "ghi"] } [namespace current]]] } test coroutine-2.1 {coroutine::util::global} -body { set myglobal 10 set strglobal "abc" set coroid [namespace eval ::coroutine::util { create apply [list {} { yield [info coroutine] global myglobal incr myglobal ;# Create coro-global that doesn't exist yet yield $::myglobal ;# Dereference interp/real global yield $myglobal ;# Dereference coro-global return [apply [list {} { ;# Push another stack frame global myglobal strglobal incr myglobal append strglobal "def" yield $::myglobal yield $myglobal yield $::strglobal yield $strglobal return [Test_global] ;# And another two stack frames, one is named } [namespace current]]] ;# All the coro's stack frames must have access } [namespace current]] ;# to the overridden [global] command }] Test_collect $coroid } -result {10 1 10 2 abc def 10 3 10 4 defghi} catch { unset myglobal } # ----- coroutine::util::after ------------------------------------------------- # Work in progress # - coroutine::util::global functionality has been slightly modified in # order to work correctly at frame #1. This may need to be reviewed. # The new approach prevents tramping on frame #1's local variables. # If trampling is intended then we may need a workaround to detect use of # 'global' in frame #1 and make it a noop. # - Run tests with: %TCLSH% sak.tcl test run coroutine testsuiteCleanup return |
Changes to modules/coroutine/pkgIndex.tcl.
1 | if {![package vsatisfies [package provide Tcl] 8.6]} {return} | | | | 1 2 3 | if {![package vsatisfies [package provide Tcl] 8.6]} {return} package ifneeded coroutine 1.1.3 [list source [file join $dir coroutine.tcl]] package ifneeded coroutine::auto 1.1.3 [list source [file join $dir coro_auto.tcl]] |