
# # ## ### ##### ######## ############# #####################

proc main {} {
    X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    set rc [chan create {read} rc]
    chan configure $rc -blocking 0
    chan event     $rc readable [list getter $rc]

    X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    vwait forever
    exit
}

proc X {args} {
    puts stderr [join $args]
    return
}

# # ## ### ##### ######## ############# #####################

proc getter {c} {
    Y getter $c ____________

    if {[eof $c]} {
	chan event $c readable ""
	Y "       " got eof in state $::state
	exit
    }

    set len [gets $c line]
    Y "       " got '$line' in state $::state

    Y eof_____ $c is [eof $c] 
    Y fblocked $c is [fblocked $c] 

    if {!$len} {
	Y "       " switching to -> reader in state $::state
	chan event $c readable [list reader $c]
    }

    Y getter $c /done
    return
}

proc reader {c} {
    Y reader $c ____________

    if {[eof $c]} {
	chan close $c
	Y "       " got eof in state $::state, and closed
	exit
    }

    set buf [read $c 10000]

    Y reader $c got [string length $buf] bytes in state $::state
    Y eof_____ $c is [eof $c] 
    Y fblocked $c is [fblocked $c] 
    foreach l [split $buf \n] { Y --- $l }
    Y reader $c /done
}

proc Y {args} {
    X \t\t {*}$args
}

# # ## ### ##### ######## ############# #####################

namespace eval rc {
    proc initialize {c mode} {
	Z $c initialize ____________
	set ::state 0
	set ::data [string repeat [string repeat 1 10]\n 10]\n[string repeat [string repeat 2 10]\n 10]
	foreach l [split $::data \n] { Z *** $l }
	Z $c initialized ___________
	return [list initialize read watch blocking finalize]
    }

    proc blocking {c mode} {
	Z $c blocking $mode in state $::state
	Z $c blocking done
    }

    proc read {c count} {
	Z $c tries to read $count in state $::state
	switch -- [incr ::state] {
	    1 {
		set result $::data
	    }
	    default {
		set result ""
	    }
	}
	Z read yields [string length $result] bytes, now state $::state
	foreach l [split $result \n] { Z ---> $l }
	return $result
    }

    proc finalize {c} {
	Z $c finalized in state: $::state
    }

    proc watch {c events} {
	Z watch $c for ($events)/
	if {[llength $events]} {
	    Z $c watch posting event
	    after 5000 [list chan postevent $c read]
	}
	Z watch $c /done
    }

    namespace export -clear *
    namespace ensemble create -subcommands {}
}

proc Z {args} {
    X RC \t\t\t\t {*}$args
}

# # ## ### ##### ######## ############# #####################

main
