From thomas.friedrichsmeier at ruhr-uni-bochum.de  Mon Oct 17 19:35:56 2005
From: thomas.friedrichsmeier at ruhr-uni-bochum.de (Thomas Friedrichsmeier)
Date: Mon, 17 Oct 2005 19:35:56 +0200
Subject: [Rd] RFC: API to allow identification of warnings and errors in the
	output stream
Message-ID: <200510171935.56499.thomas.friedrichsmeier@ruhr-uni-bochum.de>

Dear R developers,

this mail is basically a summary / clarification of some previous mails I sent 
to this list last week (subject "Catching warning and error output"). Duncan 
Murdoch pointed out that these were badly organized, and suggested I repost, 
collecting the main points previously spread out between several mails.

Problem statement:
In an application embedding R, I would like to identify warnings and errors in 
the output stream. That is, basically, I'm looking for a good way to find 
out, which portions of the output stream are warnings, which are error 
messages, and which are regular output. Such information could be used in a 
GUI to mark up different types of output in different colors, or to ensure 
warnings are brought to the user's attention in situations where output would 
normally be hidden.
I believe this is not currently possible in a good way. For a discussion of 
approaches using the current API, and their drawbacks, refer to 
https://stat.ethz.ch/pipermail/r-devel/2005-October/034975.html.

Suggested solution:
Here are two patches (against R-2.2.0), which I will describe in more detail 
below:
A) http://rkward.sourceforge.net/temp/classify_output_patch.diff
B) http://rkward.sourceforge.net/temp/classify_output_test.diff

Description of and rationale for patch A:
This patch does two things:
1) It adds a function R_WriteErrConsole corresponding to R_WriteConsole. Also, 
a corresponding interface pointer ptr_R_WriteErrConsole is added.
I think this change is highly consistent with output handling in R in general. 
There are different sink ()s for "output" and "message", there is the 
distinction between Rprintf/Rvprintf and REprintf/REvprintf. This basically 
just carries this distinction over to the interface pointers.
You will note that I wrote
ptr_R_WriteErrConsole = R_WriteConsole;
instead of
ptr_R_WriteErrConsole = Rstd_WriteErrConsole;
or
ptr_R_WriteErrConsole = ptr_R_WriteConsole;
This way, code that currently overrides ptr_R_WriteConsole, but does not know 
about ptr_R_WriteErrConsole, will still receive all output in 
ptr_R_WriteConsole. Hence this change is perfectly backwards compatible.
Of course, the naming may not be perfect?

2) While 1 makes it easy to split warning _and_ errors (and messages) from 
regular output, it does not suffice to differentiate _between_ warnings, 
errors, and messages on the error channel. The patch addresses this, by 
making inError, inWarning, and inPrintWarnings from errors.c accessible 
(read-only) in R_ext/Error.h.
This part of the patch may be slightly more delicate, in that inError, 
inWarning, and inPrintWarnings seem to be more internal status indications. 
So the question is: Are those potentially subject to change, if errors.c is 
redesigned some day? My feeling is that this is still relatively safe, 
however. Such indications can easily be set/unset at entry/exit points of the 
corresponding functions, as long as there are separate handlers for warnings, 
errors, and printWarnings. I guess this is not likely to ever change 
fundamentally.
As a slightly safer variation, R_inError (), R_inWarning (), and 
R_inPrintWarnings () could return a boolean indication only, instead of the 
int-code, which might be more subject to change.

Description of and rationale for patch B:
Patch B probably helps a lot to illustrate, how patch A works, and how this is 
useful. It adds an example to tests/embedding/. This example basically just 
generates a number of different types of messages, then catches the output, 
and classifies it into several categories.

I'll gladly provide more explanations or a different format of patches if 
needed.

Looking forward to your comments
Thomas Friedrichsmeier



[Rd] RFC: API to allow identification of warnings and errors in the output stream
Thomas Friedrichsmeier