Radim Blazek wrote:
>>I have added G_messages and modified a bit G_percent, G_warning
>>and G_fatal_error. If GRASS_MESSAGE_FORMAT enviroment (not GRASS) variable
>>is set to 'gui', those functions print messages in format
>>suitable for parsing by GUI. gui.tcl was also modified and
>>displays progress bar if G_percent is used and adds icons to output box.
>>http://mpa.itc.it/radim/g51/messages1.png
>>
>>Subject for discussion.
>>
>>Question: G_warning/G_messages/G_fatal_error can print more lines,
>>how to tell to GUI that it is one message?
>
>
> Print begin/end markers rather than a prefix in front of each line,
> e.g.
>
> GRASS_INFO_WARNING
> message
> goes
> here
> GRASS_INFO_END
Cannot it happen that messages printed by a module and
a process created by the module (e.g. dbmi driver)
will be mixed together? For example:
GRASS_INFO_ERROR
module message 1
GRASS_INFO_ERROR
driver message 1
module message 2
module message 3
GRASS_INFO_END
driver message 2
GRASS_INFO_ERROR
Only if the actual message is split across multiple write() calls.
Actually, that's quite possible with the current implementation. As
stderr is unbuffered, each fprintf() call will result in a separate
write.
For the GUI case, you don't need to do the formatting (the GUI can do
that if the text widget can't do it automatically). You can just do
e.g.:
fprintf(stderr, "%s\n%s\GRASS_INFO_END\n", prefix, msg);
This should result in a single write(); so long as the total message
is less than PIPE_BUF bytes, the data won't be interleaved with that
from another process. On Linux, PIPE_BUF is 4Kb, and the functions
which call print_error() are already limited by a 2000 byte buffer.
POSIX requires that PIPE_BUF is at least 512 bytes, which should be
sufficient for most error messages.
An alternative would be to prefix each line with a message-ID composed
from the PID and a monotonic counter which increments once per
message. All lines beginning with the same ID would be part of a
single message.
--
Glynn Clements <glynn@gclements.plus.com>