[GRASS-dev] gis.m crashes on zoom to map existing in more than one mapset

Hi Michael,

I don't know if this is just another manifestation of the changes in g.region, but gis.m crashes when I try to zoom to a map which exists in more than one mapset of the current location.

To reproduce in spearfish, in mapset user1:

1) g.copy rast=bugsites@PERMANENT,bugsites (or any other raster or vector map)

2) display bugsites

3) zoom to selected map

The command used in mapcanvas.tcl is g.region -ugp rast=bugsites. This gives:

GRASS 6.3.cvs (spearfish60):~ > g.region -ugp rast=bugsites
WARNING: 'cell/bugsites' was found in more mapsets (also found in user1).
projection=1
zone=13
datum=nad27
ellipsoid=clark66
n=4928000
s=4914000
w=590000
e=609000
nsres=100
ewres=100
rows=140
cols=190
cells=26600

So I imagine that the WARNING is what causes the problem.

Just as a side note: I have always found it illogical that when I work with the map in mapset user1 (or at least I think I do), the warning tells me that the map _also_ exists in user1, as if it was currently working with the one in PERMANENT.
Does this mean, that being in mapset user1, and launching a command on a map that exists both in user1 and in PERMANENT makes the command work with the version in PERMANENT, or is it just a confusing formulation ?
I have always worked with the idea that it is the second. Any reason for this formulation or could we change this to "map also exists in PERMANENT (or whatever _other_ mapsets than the one you are currently in)" ?

Moritz

Moritz,

Yes, this warning will again break the GUI. This seems like a warning that
is not terribly useful. So what if a map with the same name exists in
another mapset?

May I suggest that the -g flag, which means print in shell *SCRIPT* format,
does exactly that--print the output in a format that can easily be parsed by
scripts. A warning at the beginning of output for scripting cannot easily be
parsed. The warning should be for the format that is to be read by humans.
Any warnings or similar messages should be surpressed in scripting output
format.

Even for humans, I'm not sure that this particular warning is especially
useful. What is it "warning" about? The design of independent mapsets, with
the option of "name@MAPSET" construction permits maps of the same name to
reside in different mapsets of the same location.

Michael

On 1/4/07 6:12 AM, "Moritz Lennert" <mlennert@club.worldonline.be> wrote:

Hi Michael,

I don't know if this is just another manifestation of the changes in
g.region, but gis.m crashes when I try to zoom to a map which exists in
more than one mapset of the current location.

To reproduce in spearfish, in mapset user1:

1) g.copy rast=bugsites@PERMANENT,bugsites (or any other raster or
vector map)

2) display bugsites

3) zoom to selected map

The command used in mapcanvas.tcl is g.region -ugp rast=bugsites. This
gives:

GRASS 6.3.cvs (spearfish60):~ > g.region -ugp rast=bugsites
WARNING: 'cell/bugsites' was found in more mapsets (also found in user1).
projection=1
zone=13
datum=nad27
ellipsoid=clark66
n=4928000
s=4914000
w=590000
e=609000
nsres=100
ewres=100
rows=140
cols=190
cells=26600

So I imagine that the WARNING is what causes the problem.

Just as a side note: I have always found it illogical that when I work
with the map in mapset user1 (or at least I think I do), the warning
tells me that the map _also_ exists in user1, as if it was currently
working with the one in PERMANENT.
Does this mean, that being in mapset user1, and launching a command on a
map that exists both in user1 and in PERMANENT makes the command work
with the version in PERMANENT, or is it just a confusing formulation ?
I have always worked with the idea that it is the second. Any reason for
this formulation or could we change this to "map also exists in
PERMANENT (or whatever _other_ mapsets than the one you are currently in)" ?

Moritz

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics & Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

On Thu, 4 Jan 2007, Michael Barton wrote:

scripts. A warning at the beginning of output for scripting cannot easily be
parsed. The warning should be for the format that is to be read by humans.

Just to point out, a warning shouldn't really have to be easily parsed - warnings and related messages always go to stderr while only parseable output should go to stdout. It is only because of a design flaw in Tcl that we have to merge stderr and stdout, thus greatly complicating things - using most any other system for parsing the warnings wouldn't go near stdout and we wouldn't even have to worry about them.

I agree that this warning in particular is an anomaly though - it has been discussed on the list before.

Paul

On 04/01/07 16:18, Michael Barton wrote:

Moritz,

Yes, this warning will again break the GUI. This seems like a warning that
is not terribly useful. So what if a map with the same name exists in
another mapset?

May I suggest that the -g flag, which means print in shell *SCRIPT* format,
does exactly that--print the output in a format that can easily be parsed by
scripts. A warning at the beginning of output for scripting cannot easily be
parsed. The warning should be for the format that is to be read by humans.
Any warnings or similar messages should be surpressed in scripting output
format.

I don't necessarily agree that warnings should not be printed in scripts. I would rather argue with Paul that scripts should be made in a way to deal with such issues more robustly.

Even for humans, I'm not sure that this particular warning is especially
useful. What is it "warning" about? The design of independent mapsets, with
the option of "name@MAPSET" construction permits maps of the same name to
reside in different mapsets of the same location.

Personally I have never found it useful, but it might be useful to some as a reminder, in order to make sure that they are really working on the map they want to work on. But then this should probably read something like: "Map exists in several mapsets. Currently working with map@XXX."

Moritz

Michael

On 1/4/07 6:12 AM, "Moritz Lennert" <mlennert@club.worldonline.be> wrote:

Hi Michael,

I don't know if this is just another manifestation of the changes in
g.region, but gis.m crashes when I try to zoom to a map which exists in
more than one mapset of the current location.

To reproduce in spearfish, in mapset user1:

1) g.copy rast=bugsites@PERMANENT,bugsites (or any other raster or
vector map)

2) display bugsites

3) zoom to selected map

The command used in mapcanvas.tcl is g.region -ugp rast=bugsites. This
gives:

GRASS 6.3.cvs (spearfish60):~ > g.region -ugp rast=bugsites
WARNING: 'cell/bugsites' was found in more mapsets (also found in user1).
projection=1
zone=13
datum=nad27
ellipsoid=clark66
n=4928000
s=4914000
w=590000
e=609000
nsres=100
ewres=100
rows=140
cols=190
cells=26600

So I imagine that the WARNING is what causes the problem.

Just as a side note: I have always found it illogical that when I work
with the map in mapset user1 (or at least I think I do), the warning
tells me that the map _also_ exists in user1, as if it was currently
working with the one in PERMANENT.
Does this mean, that being in mapset user1, and launching a command on a
map that exists both in user1 and in PERMANENT makes the command work
with the version in PERMANENT, or is it just a confusing formulation ?
I have always worked with the idea that it is the second. Any reason for
this formulation or could we change this to "map also exists in
PERMANENT (or whatever _other_ mapsets than the one you are currently in)" ?

On 1/4/07 8:47 AM, "Moritz Lennert" <mlennert@club.worldonline.be> wrote:

Moritz and Paul,

The following construction will trap errors in TclTk, but it doesn't help
this particular issue.

    if {![catch {open [concat "|g.region" "-ugp" $args] r} input]} {
        while {[gets $input line] >= 0} {
            regexp -nocase {^([a-z]+)=(.*)$} $line trash key value
            set parts($key) $value
        }
....

If there if no error, "catch" returns 0 and the routine goes on.
If there is an error, "catch" returns a value >0 and the error message is
stored in the variable "input". Input can be printed to the terminal or to a
TclTk dialog if desired.

This is trapping errors fine as far as I can tell. Try getting rid of
libgdal (which produces an error if you run g.region) and running the GUI.
It will exit with a message to the terminal.

In this case, the warning in g.region -g seems to be part of the command
output rather than a valid error message. I don't know why.

Michael

On 04/01/07 16:18, Michael Barton wrote:

Moritz,

Yes, this warning will again break the GUI. This seems like a warning that
is not terribly useful. So what if a map with the same name exists in
another mapset?

May I suggest that the -g flag, which means print in shell *SCRIPT* format,
does exactly that--print the output in a format that can easily be parsed by
scripts. A warning at the beginning of output for scripting cannot easily be
parsed. The warning should be for the format that is to be read by humans.
Any warnings or similar messages should be surpressed in scripting output
format.

I don't necessarily agree that warnings should not be printed in
scripts. I would rather argue with Paul that scripts should be made in a
way to deal with such issues more robustly.

Even for humans, I'm not sure that this particular warning is especially
useful. What is it "warning" about? The design of independent mapsets, with
the option of "name@MAPSET" construction permits maps of the same name to
reside in different mapsets of the same location.

Personally I have never found it useful, but it might be useful to some
as a reminder, in order to make sure that they are really working on the
map they want to work on. But then this should probably read something
like: "Map exists in several mapsets. Currently working with map@XXX."

Moritz

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics & Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

Hello Michael

On Thu, 4 Jan 2007, Michael Barton wrote:

On 1/4/07 8:47 AM, "Moritz Lennert" <mlennert@club.worldonline.be> wrote:

Moritz and Paul,

The following construction will trap errors in TclTk, but it doesn't help
this particular issue.

   if {![catch {open [concat "|g.region" "-ugp" $args] r} input]} {
       while {[gets $input line] >= 0} {
           regexp -nocase {^([a-z]+)=(.*)$} $line trash key value
           set parts($key) $value
       }
....

If there if no error, "catch" returns 0 and the routine goes on.
If there is an error, "catch" returns a value >0 and the error message is
stored in the variable "input". Input can be printed to the terminal or to a
TclTk dialog if desired.

Try this instead:
     if {![catch {open [concat "|g.region" "-ugp" $args "|& $env(GISBASE)/etc/grocat"] r} input]} {
         while {[gets $input line] >= 0} {
             if { [regexp -nocase {^([a-z]+)=(.*)$} $line trash key value] }
             {
     set parts($key) $value
             }
         }

I am guessing that "catch" catches errors by seeing if anything is written to stderr - if a warning is written to stderr will it incorrectly catch it as an error? I'm not sure, but merging stderr into stdout with the grocat program will stop anything being written to stderr so will stop this. This will work on Windows - in fact I wrote it specifically because the previous way it was done (see my recent changes to lib/gtcltk/gronsole.tcl) was Unix-specific - the grocat trick works on Unix and Windows.

Then within the while loop I've used an if to check the return value of regexp - there are only two possible values - 1 if it matches the line and 0 if it doesn't. So it won't match the Warning line, will return 0, and thus stops you trying to assign non-existent values to key and value.

Paul

Paul

On 1/4/07 9:42 AM, "Paul Kelly" <paul-grass@stjohnspoint.co.uk> wrote:

Hello Michael

On Thu, 4 Jan 2007, Michael Barton wrote:

On 1/4/07 8:47 AM, "Moritz Lennert" <mlennert@club.worldonline.be> wrote:

Moritz and Paul,

The following construction will trap errors in TclTk, but it doesn't help
this particular issue.

   if {![catch {open [concat "|g.region" "-ugp" $args] r} input]} {
       while {[gets $input line] >= 0} {
           regexp -nocase {^([a-z]+)=(.*)$} $line trash key value
           set parts($key) $value
       }
....

If there if no error, "catch" returns 0 and the routine goes on.
If there is an error, "catch" returns a value >0 and the error message is
stored in the variable "input". Input can be printed to the terminal or to a
TclTk dialog if desired.

Try this instead:
     if {![catch {open [concat "|g.region" "-ugp" $args "|&
$env(GISBASE)/etc/grocat"] r} input]} {
         while {[gets $input line] >= 0} {
             if { [regexp -nocase {^([a-z]+)=(.*)$} $line trash key value] }
             {
set parts($key) $value
             }
         }

I can confirm that this works. What is grocat??

I am guessing that "catch" catches errors by seeing if anything is written
to stderr - if a warning is written to stderr will it incorrectly catch it
as an error?

Yes, this is what seems to be happening. The program exits with the warning
printed to the terminal.

I'm not sure, but merging stderr into stdout with the grocat
program will stop anything being written to stderr so will stop this. This
will work on Windows - in fact I wrote it specifically because the
previous way it was done (see my recent changes to
lib/gtcltk/gronsole.tcl) was Unix-specific - the grocat trick works on
Unix and Windows.

OK. If you've tested this on Windows, then it should be OK. I'm just trying
not to do anything that will jeopardize a native Windows build.

Then within the while loop I've used an if to check the return value of
regexp - there are only two possible values - 1 if it matches the line and
0 if it doesn't. So it won't match the Warning line, will return 0, and
thus stops you trying to assign non-existent values to key and value.

OK. This works fine too. Thanks. After fixing stuff yesterday, I was
thinking it might be simpler to switch to

set key [string trim [lindex [split $line "="] 0]]

I wonder if this could be made to test in a similar way?

Thanks for your help.
Michael

Paul

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

On Thu, January 4, 2007 21:35, Michael Barton wrote:

Paul

On 1/4/07 9:42 AM, "Paul Kelly" <paul-grass@stjohnspoint.co.uk> wrote:

Hello Michael

On Thu, 4 Jan 2007, Michael Barton wrote:

On 1/4/07 8:47 AM, "Moritz Lennert" <mlennert@club.worldonline.be>
wrote:

Moritz and Paul,

The following construction will trap errors in TclTk, but it doesn't
help
this particular issue.

   if {![catch {open [concat "|g.region" "-ugp" $args] r} input]} {
       while {[gets $input line] >= 0} {
           regexp -nocase {^([a-z]+)=(.*)$} $line trash key value
           set parts($key) $value
       }
....

If there if no error, "catch" returns 0 and the routine goes on.
If there is an error, "catch" returns a value >0 and the error message
is
stored in the variable "input". Input can be printed to the terminal or
to a
TclTk dialog if desired.

Try this instead:
     if {![catch {open [concat "|g.region" "-ugp" $args "|&
$env(GISBASE)/etc/grocat"] r} input]} {
         while {[gets $input line] >= 0} {
             if { [regexp -nocase {^([a-z]+)=(.*)$} $line trash key
value] }
             {
set parts($key) $value
             }
         }

I can confirm that this works. What is grocat??

A small program that Paul wrote. Here's the description from the source file:

* PURPOSE: Copies stdin to stdout in line-buffered mode until end
* of file is received.
* Used with Tcl/Tk gronsole system to merge stdout and
* stderr streams to be caught by Tcl "open" command.

OK. If you've tested this on Windows, then it should be OK. I'm just
trying
not to do anything that will jeopardize a native Windows build.

I think as the main developer working on the Win port we can trust Paul to
have the same worries :wink:

Moritz

Hello Michael

On Thu, 4 Jan 2007, Michael Barton wrote:

[...]

Try this instead:
     if {![catch {open [concat "|g.region" "-ugp" $args "|&
$env(GISBASE)/etc/grocat"] r} input]} {
         while {[gets $input line] >= 0} {
             if { [regexp -nocase {^([a-z]+)=(.*)$} $line trash key value] }
             {
set parts($key) $value
             }
         }

I can confirm that this works. What is grocat??

It's a little C program I wrote (with lots of hints from Glynn) that very simply copies its standard input to standard output. Tcl allows you to pipe both stdout and stderr to an external program (using the |& operator) but doesn't allow you to redirect stderr to stdout like you can do on the command-line. So we created this little program to combine stdout and stderr and write them to stdout.
It's source is in lib/gtcltk/grocat.c but it doesn't use any GRASS functions or libraries so is in effect standalone.

I am guessing that "catch" catches errors by seeing if anything is written
to stderr - if a warning is written to stderr will it incorrectly catch it
as an error?

Yes, this is what seems to be happening. The program exits with the warning
printed to the terminal.

Right. So catch isn't useful for GRASS commands then as in GRASS, a module writing to stderr is not equivalent to an error condition. Messages and warnings also go to stderr, and we need to use something like grocat to redirect these away from stderr and stop them making Tcl think there is an error.

I'm not sure, but merging stderr into stdout with the grocat
program will stop anything being written to stderr so will stop this. This
will work on Windows - in fact I wrote it specifically because the
previous way it was done (see my recent changes to
lib/gtcltk/gronsole.tcl) was Unix-specific - the grocat trick works on
Unix and Windows.

OK. If you've tested this on Windows, then it should be OK. I'm just trying
not to do anything that will jeopardize a native Windows build.

Yes, totally understand. It does look like a Unix command I know but it's contained within the GRASS source so will be available on any platform (it's very simple basic C, really only uses stdio.h).

Then within the while loop I've used an if to check the return value of
regexp - there are only two possible values - 1 if it matches the line and
0 if it doesn't. So it won't match the Warning line, will return 0, and
thus stops you trying to assign non-existent values to key and value.

OK. This works fine too. Thanks. After fixing stuff yesterday, I was
thinking it might be simpler to switch to

set key [string trim [lindex [split $line "="] 0]]

I wonder if this could be made to test in a similar way?

I actually think using the regexp command is more powerful. Because the lindex construction above assumes that the output from the command is valid. But e.g. if there is a warning or an extra message, then not every line will be valid. The regexp is powerful because if the line doesn't match what you're expecting, then you're able to skip over it. I can't easily see a way to that with the set key... line above, although it might be possible I suppose with a lot of thinking.

Thanks for your help.

No problem. Working around the inadequacies and limitations of Tcl would appear to be an interesting challenge but I'm sure there are more productive things we could be doing!

Paul

Paul Kelly wrote:

I am guessing that "catch" catches errors by seeing if anything is written
to stderr - if a warning is written to stderr will it incorrectly catch it
as an error?

"catch" catches exceptions thrown by Tcl. It isn't limited to I/O,
e.g.:

  % set foo [expr 1 / 0]
  divide by zero
  % catch {set foo [expr 1 / 0]} res
  1
  % puts $res
  divide by zero
  % catch {set foo [expr 10 / 2]} res
  0
  % puts $res
  5

Tcl's process-creation code throws an exception if anything is written
to stderr. For "exec", it's the exec call which throws the exception.

For "open |...", the corresponding "close" will throw an exception
(the error won't have occurred at the point that open returns, which
will typically be soon after the fork(), possibly before the child has
even called execve()).

I'm not sure, but it's possible that reading from the pipe may also
throw an exception. In simple cases, the entire open/read/close loop
should be contained within a single catch; in more complex cases, each
individual function needs its own catch.

I'm not sure, but merging stderr into stdout with the grocat
program will stop anything being written to stderr so will stop this. This
will work on Windows - in fact I wrote it specifically because the
previous way it was done (see my recent changes to
lib/gtcltk/gronsole.tcl) was Unix-specific - the grocat trick works on
Unix and Windows.

In this case, an alternative is to simply redirect stderr elsewhere,
e.g. to @stdout (may not work on Windows) or /dev/null (nul on
Windows).

Then within the while loop I've used an if to check the return value of
regexp - there are only two possible values - 1 if it matches the line and
0 if it doesn't. So it won't match the Warning line, will return 0, and
thus stops you trying to assign non-existent values to key and value.

In general, any Tcl code which attempts to parse program output needs
to silently ignore unexpected output, as stderr often has to be merged
with stdout due to Tcl's "writing to stderr == error" behaviour.

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

Moritz Lennert wrote:

I don't know if this is just another manifestation of the changes in
g.region, but gis.m crashes when I try to zoom to a map which exists in
more than one mapset of the current location.

To reproduce in spearfish, in mapset user1:

1) g.copy rast=bugsites@PERMANENT,bugsites (or any other raster or
vector map)

2) display bugsites

3) zoom to selected map

The command used in mapcanvas.tcl is g.region -ugp rast=bugsites. This
gives:

GRASS 6.3.cvs (spearfish60):~ > g.region -ugp rast=bugsites
WARNING: 'cell/bugsites' was found in more mapsets (also found in user1).

This is a good example of why the solution to the recent
g.region/gis.m issues is to make gis.m handle warnings correctly
rather than trying to eliminate specific warnings.

Even the simplest program can potentially result in warnings (or
similar diagnostics) being generated by libgis (or other libraries) in
some cases. And for third-party libraries (of which GDAL may use a
significant number), there is nothing which can be done about it.

Tcl's behaviour of treating anything written to stderr as an error is
a nuisance, but one which has to be dealt with so long as we continue
to use Tcl.

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

On 1/5/07, Glynn Clements <glynn@gclements.plus.com> wrote:

Moritz Lennert wrote:

> The command used in mapcanvas.tcl is g.region -ugp rast=bugsites. This
> gives:
>
> GRASS 6.3.cvs (spearfish60):~ > g.region -ugp rast=bugsites
> WARNING: 'cell/bugsites' was found in more mapsets (also found in user1).

This is a good example of why the solution to the recent
g.region/gis.m issues is to make gis.m handle warnings correctly
rather than trying to eliminate specific warnings.

Even the simplest program can potentially result in warnings (or
similar diagnostics) being generated by libgis (or other libraries) in
some cases. And for third-party libraries (of which GDAL may use a
significant number), there is nothing which can be done about it.

Would having G_warning() output "#WARNING:" help? The initial '#'
would be parseable as a comment, as it is in the shell. And alongside,
eval of output in scripts wouldn't be affected. Of course, strict
discipline of using G_* messages is compulsory.

Tcl's behaviour of treating anything written to stderr as an error is
a nuisance, but one which has to be dealt with so long as we continue
to use Tcl.

IMO, this is THE reason to get serious about wxPython.

2c.

Daniel.

--
-- Daniel Calvelo Aros

I just committed Paul's fix that pipes g.region commands through grocat.
Maybe check to see if this fixes this crash on warning too.

Michael

On 1/5/07 6:49 AM, "Glynn Clements" <glynn@gclements.plus.com> wrote:

Moritz Lennert wrote:

I don't know if this is just another manifestation of the changes in
g.region, but gis.m crashes when I try to zoom to a map which exists in
more than one mapset of the current location.

To reproduce in spearfish, in mapset user1:

1) g.copy rast=bugsites@PERMANENT,bugsites (or any other raster or
vector map)

2) display bugsites

3) zoom to selected map

The command used in mapcanvas.tcl is g.region -ugp rast=bugsites. This
gives:

GRASS 6.3.cvs (spearfish60):~ > g.region -ugp rast=bugsites
WARNING: 'cell/bugsites' was found in more mapsets (also found in user1).

This is a good example of why the solution to the recent
g.region/gis.m issues is to make gis.m handle warnings correctly
rather than trying to eliminate specific warnings.

Even the simplest program can potentially result in warnings (or
similar diagnostics) being generated by libgis (or other libraries) in
some cases. And for third-party libraries (of which GDAL may use a
significant number), there is nothing which can be done about it.

Tcl's behaviour of treating anything written to stderr as an error is
a nuisance, but one which has to be dealt with so long as we continue
to use Tcl.

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics & Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

Daniel Calvelo wrote:

> > The command used in mapcanvas.tcl is g.region -ugp rast=bugsites. This
> > gives:
> >
> > GRASS 6.3.cvs (spearfish60):~ > g.region -ugp rast=bugsites
> > WARNING: 'cell/bugsites' was found in more mapsets (also found in user1).
>
> This is a good example of why the solution to the recent
> g.region/gis.m issues is to make gis.m handle warnings correctly
> rather than trying to eliminate specific warnings.
>
> Even the simplest program can potentially result in warnings (or
> similar diagnostics) being generated by libgis (or other libraries) in
> some cases. And for third-party libraries (of which GDAL may use a
> significant number), there is nothing which can be done about it.

Would having G_warning() output "#WARNING:" help? The initial '#'
would be parseable as a comment, as it is in the shell. And alongside,
eval of output in scripts wouldn't be affected. Of course, strict
discipline of using G_* messages is compulsory.

Programs shouldn't attempt to parse stderr.

Merging stdout and stderr is purely a workaround for a Tcl misfeature
(treating anything written to stderr as an error). In the case where
you're actually parsing the output (rather than just dumping it to the
"gronsole" widget), it's the wrong workaround. In that case, stderr
should be redirected to a file or discarded (redirected to /dev/null
or NUL).

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

Paul Kelly wrote:

Right. So catch isn't useful for GRASS commands then as in GRASS, a module
writing to stderr is not equivalent to an error condition.

It's useful insofar as it allows you to ignore the error and continue.

Messages and
warnings also go to stderr, and we need to use something like grocat to
redirect these away from stderr and stop them making Tcl think there is an
error.

The problem with the "|& grocat" approach is that you then get stderr
output merged with normal module output. This isn't an issue if you're
just dumping everything to the gronsole for the user to read, but it
is an issue if you plan to parse the output.

Even if the parser silently ignores everything which it doesn't
understand, there's no guarantee that messages written to stderr won't
conform to the parsed syntax and thus be interpreted as "output".

I would suggest having a global variable which refers to a "sink" to
which stderr can be safely redirected in situations like this. Valid
values would be anything which can appear after "2>" in an exec (or
"open |...") command, e.g. @stderr (i.e. gis.m's stderr, typically a
terminal, although this may not be valid on non-Unix systems), the
name of a log file, or /dev/null (or NUL on Windows).

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

Glynn Clements wrote:

I would suggest having a global variable which refers to a "sink" to
which stderr can be safely redirected in situations like this. Valid
values would be anything which can appear after "2>" in an exec (or
"open |...") command, e.g. @stderr (i.e. gis.m's stderr, typically a
terminal, although this may not be valid on non-Unix systems), the
name of a log file, or /dev/null (or NUL on Windows).

In case it wasn't obvious, the idea is that code which doesn't want
stderr mixed with stdout and doesn't want exceptions can just add
"2> $sink" to make stderr "go away". We can argue over where to send
it later.

Apart from the terminal, a log file or /dev/null, there's also the
possibility of redirecting it to a FIFO, from where gis.m can read it
and send it to the gronsole. However, this approach can potentially
stall the child process if gis.m doesn't keep the FIFO drained. In
most cases, writing stderr to a temporary file then dumping the
contents to the gronsole afterwards would be preferable.

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

On Sat, 6 Jan 2007, Glynn Clements wrote:

Merging stdout and stderr is purely a workaround for a Tcl misfeature
(treating anything written to stderr as an error). In the case where
you're actually parsing the output (rather than just dumping it to the
"gronsole" widget), it's the wrong workaround. In that case, stderr
should be redirected to a file or discarded (redirected to /dev/null
or NUL).

Of course. That's the simple and more obvious fix for the recent g.region issues. I've updated gui/tcltk/gis.m/mapcanvas.tcl (after Michael's fixes last night) to just discard stderr after all those g.region calls instead of merging it with stdout. So the calls to g.region should be tripley robust now (catch, discarding stderr, and checking the output lines match a regexp).

Thanks much Paul.

The problem with the warning about duplicate map names, especially, was a
long-standing bug that I previously saw no way around.

This seems fixed very nicely now.

Michael

On 1/6/07 2:22 AM, "Paul Kelly" <paul-grass@stjohnspoint.co.uk> wrote:

On Sat, 6 Jan 2007, Glynn Clements wrote:

Merging stdout and stderr is purely a workaround for a Tcl misfeature
(treating anything written to stderr as an error). In the case where
you're actually parsing the output (rather than just dumping it to the
"gronsole" widget), it's the wrong workaround. In that case, stderr
should be redirected to a file or discarded (redirected to /dev/null
or NUL).

Of course. That's the simple and more obvious fix for the recent g.region
issues. I've updated gui/tcltk/gis.m/mapcanvas.tcl (after Michael's fixes
last night) to just discard stderr after all those g.region calls instead
of merging it with stdout. So the calls to g.region should be tripley
robust now (catch, discarding stderr, and checking the output lines match
a regexp).

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics & Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

On 06/01/07 00:28, Michael Barton wrote:

I just committed Paul's fix that pipes g.region commands through grocat.
Maybe check to see if this fixes this crash on warning too.

Sorry for the delay. Yes, this seems fixed now. Thanks !

Moritz