[GRASS-dev] problem with r.colors on Mac

Glynn Clements glynn at gclements.plus.com
Tue Apr 17 11:35:02 EDT 2007


Michael Barton wrote:

> >> If read is a problem, what is an alternative?
> > 
> > gets.
> > 
> > Gronsole::output_to_gronsole is written on the assumption that it will
> > get complete lines. Gronsole::readout tries to do this, but fails to
> > allow for the fact that "read" may return arbitrary chunks of data
> > (i.e. partial lines).
> > 
> > If the stream is in non-blocking mode, gets will return an empty
> > string if a complete line isn't available. The fblocked function can
> > be used to distinguish this from the case where the process wrote a
> > blank line. Also, after this case occurs, another readable event won't
> > be generated for the stream until a complete line is available.
> > 
> >> I don't understand the
> >> gronsole code very well (didn't write it), but I might be able to fix a
> >> specific issue like this.
> > 
> > Gronsole::readout is the relevant function.
> 
> Glynn,
> 
> Now that I have cvs access again and could update, I tried to fix this. I
> changed Gronsole::readout as indicated below. Gronsole seems to work OK with
> the change, but the TckTk GUI still crashes when I run r.colors ­e. It also
> seems to crash more often with other commands too. I¹m guessing its the same
> cause. The change below does not seem to fix it, but I want to know if this
> is what you had in mind.
> 
> ##### ORIGINAL CODE #####
> proc Gronsole::readout {path ci mark fh} {
>     set str [read $fh]
>     if {[string length $str] != 0} {
>         Gronsole::add_data_tag $path $ci out
>     }
>     set lines [split $str "\n"]
>     foreach line [lrange $lines 0 [expr [llength $lines] - 2]] {
>         Gronsole::output_to_gronsole $path $mark $ci [list cmd$ci
> cmd$ci-out] "$line\n"
>     }
>     set last [lindex $lines end]
>     if {$last != {}} {
>         Gronsole::output_to_gronsole $path $mark $ci [list cmd$ci
> cmd$ci-out] $last
>     }
>     $path.text see $mark
> }
> 
> ##### REVISED CODE #####
> proc Gronsole::readout {path ci mark fh} {
> 
> # I left this first part in because it seems to simply make an output locale
> if there is something in $fh
> 
>     set str [read $fh]

This is "stealing" the data from the subsequent gets calls.

In the original version, the data returned by "read" was being split
into lines and fed to the gronsole. In the new version, it's simply
being discarded.

>     if {[string length $str] != 0} {
>         Gronsole::add_data_tag $path $ci out
>     }
>     
> # here I changed all the above code to use gets and read line by line rather
> than create line by line output with split
> 
>     while {[gets $fh line] >= 0} {

This test will never be true; the preceding "read" will have consumed
all available data, leaving none for the "gets".

-- 
Glynn Clements <glynn at gclements.plus.com>




More information about the grass-dev mailing list