[GRASS5] Need testers for tcltkgrass update for 5.7

Glynn Clements glynn.clements at virgin.net
Wed Aug 18 10:04:43 EDT 2004

Michael Barton wrote:

> >> I'll check this version on my Mac also and look it over. I'll wait to commit
> >> this until I hear back from Moritz (or anyone else who wants to weigh in on
> >> this). I need to understand which commands need which of the spawn, run, and
> >> term procedures and why.
> > 
> > Well, in general, anything which performs interaction on the terminal
> > needs to use "term", anything else which runs indefinitely needs to
> > use "spawn", and the rest (i.e. anything which isn't interactive and
> > which doesn't run indefinitely) can use "run".
> OK. I understand this distinction and can see what the differences are
> between the execute, spawn, and run procedures.
> But now I suppose I betray my ignorance. If I call a normal GRASS 5.7
> command with no argument (i.e., it is parsed by G_gui() and autogenerates an
> interactive tcltk dialog) through either the spawn or run procedures it
> *appears* to work the same as if I called it via the execute procedure. Is
> there a problem in doing this? Why can't I just use run, for example, to
> call all GRASS programs except those that require an xterm?

Future expansion.

Essentially, I want to allow for the possibility of adding a feature
to G_parser/G_gui such that, when the program is being run from
tcltkgrass, rather than G_gui() generating Tcl/Tk code and feeding it
directly to wish, it would write it to stdout, and tcltkgrass would
read and execute the generated code.

This would allow tcltkgrass to implement features such as scripting,
command history, etc, as tcltkgrass would get to see the user's
argument values.

Implementing this would essentially boil down to:

1. Adding an option to G_gui() to write the code to stdout rather than
calling popen("$GRASS_WISH").

2. Adding a global switch (e.g. --tcltk) to G_parser(), which makes
use of 1.

3. Copying the relevant portions of lib/gis/gui.tcl into tcltkgrass'
gui.tcl, with any necessary modifications.

4. Changing the execute procedure to e.g.:

	proc execute {cmd} {
	    eval [exec -- $cmd --tcltk 2>@ stderr]

So, execute would simply invoke the program to get the Tcl/Tk code for
the dialog, then evaluate it. The actual execution of the program
(with arguments) would occur when the user clicked the dialog's "Run"

In short, while execute currently looks very much like spawn,
ultimately it could look very different.

> > The "runs indefinitely" is actually quite tricky. Primarily because
> > running multiple GRASS programs concurrently is problematic. If you
> > start a long-running program such as v.digit, it's debatable whether
> > you should be allowed to run anything else until it finishes.
> > 
> > From the perspective of neatness, it would be better for the UI to
> > remain functional, but to inhibit the execution of new commands
> > (except those which are always safe, e.g. g.manual) than to simply
> > "hang" until the command completes. However, implementing that would
> > be non-trivial; you would need to start all commands in the
> > background, then manually check for termination (and I have no idea
> > how to do that in Tcl).
> > 
> > And the ideal, i.e. only allowing further commands to be run if they
> > are "compatible" with outstanding commands is, I suspect, so complex
> > as to be practically impossible.
> Is the possibility of running incompatible commands really a potential
> problem? If so, maybe there is a way around it and satisfying at least some
> of the conditions you mention above. I've not yet run into this kind of
> incompatibility probably because in actually working with GRASS, I often
> 'run' several commands, but then leave them 'paused' at the opening dialog.
> I then switch back and forth between commands so that I am actually running
> only a single command at a time, rather than running them concurrently in
> the full sense. I suspect that this is what most people do most of the time.

OK, that usage isn't an issue. It's only when the commands are
actually "running" (i.e. modifying the mapset directory) that the
issues arise.

> Under such circumstances, could pressing the 'run' button on the dialog box
> also inhibit the execution of other commands except for 'safe' ones? If so,
> this would work for most commands, I think, without compromising the
> functionality of the UI. Notable exceptions would be d.m, d.mon, and nviz.

That would work; however:

1. It would require that tcltkgrass was managing the dialogs, as
described above.

2. To actually implement mutual exclusion, you would need to either:

a) have the Run button execute the command in the foreground (without
the trailing "&"), or

b) find some way of determining when a background command has

The problem with 1 is that the UI will remain unresponsive (it won't
even redraw itself) while the command runs, which is ugly.

The problem with 2 is that I don't know how to do this in Tcl. When
the last argument to exec is "&", it returns the process identifier(s)
for the command, but I don't see a Tcl version of waitpid().

> > AFAICT, if you supply one or more arguments on the command-line,
> > G_gui() (or the old interactive() if GRASS_UI_TERM is set) is never
> > called. So I can't see any point in allowing the "execute" procedure
> > to accept arguments (it would be trivial to support, though).
> Hmm. But it seems that commands without arguments can 'run' or 'spawn' like
> commands that need arguments and still manage to go through G_gui(). Given
> this, is there still a need for the 'execute' procedure?
> If I call a GRASS command via the command line shell, it is somehow parsed
> correctly--going to a G_gui() dialog or an interactive xterm if there are no
> arguments, or performing its function if there are arguments. Is it a
> limitation of tcltk that prevents this parser (i.e., that correctly routes
> different kinds of calls from the command line) from operating in the same
> way in this context? Sorry if I'm being dense, but this discussion has been
> very helpful in better understanding how this operates.

See my comments regarding "execute" above.

I initially described the idea a couple of days ago in response to
your comment about scripting not working:

: From: Glynn Clements <glynn.clements at virgin.net>
: Subject: Re: [GRASS5] Need testers for tcltkgrass update for 5.7
: Date: Mon, 16 Aug 2004 14:41:32 +0100
: Message-ID: <16672.47500.961075.166905 at cerise.nosuchdomain.co.uk>
: > The only thing that doesn't work is scripting. I'm not sure whether this is
: > a function of GRASS 5.7 (and that I should take it out of the menu
: > altogether) or it  is simply broken at the moment. If anyone has a clue, let
: > me know.
: The old tcltkgrass constructed and handled the dialogs itself, so it
: got to see the actual command line. The new version simply runs the
: command without arguments; the command generates the dialog, reads the
: arguments, then re-executes itself, without tcltkgrass ever getting to
: see the arguments.
: To make tcltkgrass scripting work, G_gui() would need to e.g. write
: the Tcl/Tk code to stdout so that it could be executed by tcltkgrass. 
: I.e. something like --html-description but which generates Tcl/Tk code
: rather than HTML.

However, I didn't really make clear the connection between this and
the "execute" procedure.

Glynn Clements <glynn.clements at virgin.net>

More information about the grass-dev mailing list